From e214d1657568fcad9eb86358647f910ca7e6aac6 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Mon, 25 Apr 2011 12:52:45 +0200 Subject: [PATCH] mpt(4): Sync with FreeBSD. --- sys/dev/disk/mpt/mpilib/mpi_type.h | 2 +- sys/dev/disk/mpt/mpt.c | 276 +++++++++++++++++++++++++++--------- sys/dev/disk/mpt/mpt.h | 257 +++++----------------------------- sys/dev/disk/mpt/mpt_cam.c | 158 ++++++++++----------- sys/dev/disk/mpt/mpt_cam.h | 13 +-- sys/dev/disk/mpt/mpt_debug.c | 115 +++++---------- sys/dev/disk/mpt/mpt_pci.c | 189 +++++-------------------- sys/dev/disk/mpt/mpt_raid.c | 82 ++++------- sys/dev/disk/mpt/mpt_raid.h | 8 +- sys/dev/disk/mpt/mpt_user.c | 44 ++++--- 10 files changed, 449 insertions(+), 695 deletions(-) diff --git a/sys/dev/disk/mpt/mpilib/mpi_type.h b/sys/dev/disk/mpt/mpilib/mpi_type.h index 69271d6..f4bcbc0 100644 --- a/sys/dev/disk/mpt/mpilib/mpi_type.h +++ b/sys/dev/disk/mpt/mpilib/mpi_type.h @@ -77,7 +77,7 @@ typedef unsigned char U8; typedef signed short S16; typedef unsigned short U16; -#if defined(__FreeBSD__) || defined(__DragonFly__) +#ifdef __DragonFly__ typedef int32_t S32; typedef uint32_t U32; diff --git a/sys/dev/disk/mpt/mpt.c b/sys/dev/disk/mpt/mpt.c index 5279b15..e7ac172 100644 --- a/sys/dev/disk/mpt/mpt.c +++ b/sys/dev/disk/mpt/mpt.c @@ -94,7 +94,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/mpt/mpt.c,v 1.49 2009/01/07 21:52:47 marius Exp $ + * $FreeBSD: src/sys/dev/mpt/mpt.c,v 1.57 2011/04/22 09:59:16 marius Exp $ */ #include @@ -127,6 +127,8 @@ static void mpt_send_event_ack(struct mpt_softc *mpt, request_t *ack_req, static int mpt_send_event_request(struct mpt_softc *mpt, int onoff); static int mpt_soft_reset(struct mpt_softc *mpt); static void mpt_hard_reset(struct mpt_softc *mpt); +static int mpt_dma_buf_alloc(struct mpt_softc *mpt); +static void mpt_dma_buf_free(struct mpt_softc *mpt); static int mpt_configure_ioc(struct mpt_softc *mpt, int, int); static int mpt_enable_ioc(struct mpt_softc *mpt, int); @@ -301,28 +303,28 @@ mpt_modevent(module_t mod, int type, void *data) int mpt_stdload(struct mpt_personality *pers) { - /* Load is always successfull. */ + /* Load is always successful. */ return (0); } int mpt_stdprobe(struct mpt_softc *mpt) { - /* Probe is always successfull. */ + /* Probe is always successful. */ return (0); } int mpt_stdattach(struct mpt_softc *mpt) { - /* Attach is always successfull. */ + /* Attach is always successful. */ return (0); } int mpt_stdenable(struct mpt_softc *mpt) { - /* Enable is always successfull. */ + /* Enable is always successful. */ return (0); } @@ -335,8 +337,7 @@ mpt_stdready(struct mpt_softc *mpt) int mpt_stdevent(struct mpt_softc *mpt, request_t *req, MSG_EVENT_NOTIFY_REPLY *msg) { - mpt_lprt(mpt, MPT_PRT_DEBUG, "mpt_stdevent: 0x%x\n", - msg->Event & 0xFF); + mpt_lprt(mpt, MPT_PRT_DEBUG, "mpt_stdevent: 0x%x\n", msg->Event & 0xFF); /* Event was not for us. */ return (0); } @@ -359,7 +360,7 @@ mpt_stddetach(struct mpt_softc *mpt) int mpt_stdunload(struct mpt_personality *pers) { - /* Unload is always successfull. */ + /* Unload is always successful. */ return (0); } @@ -560,15 +561,13 @@ mpt_event_reply_handler(struct mpt_softc *mpt, request_t *req, mpt_lprt(mpt, MPT_PRT_INFO, "No Handlers For Any Event Notify Frames. " "Event %#x (ACK %sequired).\n", - (unsigned)msg->Event, - msg->AckRequired? "r" : "not r"); + msg->Event, msg->AckRequired? "r" : "not r"); } else if (handled == 0) { mpt_lprt(mpt, msg->AckRequired? MPT_PRT_WARN : MPT_PRT_INFO, "Unhandled Event Notify Frame. Event %#x " "(ACK %sequired).\n", - (unsigned)msg->Event, - msg->AckRequired? "r" : "not r"); + msg->Event, msg->AckRequired? "r" : "not r"); } if (msg->AckRequired) { @@ -651,7 +650,7 @@ mpt_core_event(struct mpt_softc *mpt, request_t *req, MSG_EVENT_NOTIFY_REPLY *msg) { mpt_lprt(mpt, MPT_PRT_DEBUG, "mpt_core_event: 0x%x\n", - (unsigned)(msg->Event & 0xFF)); + msg->Event & 0xFF); switch(msg->Event & 0xFF) { case MPI_EVENT_NONE: break; @@ -659,12 +658,12 @@ mpt_core_event(struct mpt_softc *mpt, request_t *req, { int i; - /* Some error occured that LSI wants logged */ + /* Some error occurred that LSI wants logged */ mpt_prt(mpt, "EvtLogData: IOCLogInfo: 0x%08x\n", - (unsigned)msg->IOCLogInfo); + msg->IOCLogInfo); mpt_prt(mpt, "\tEvtLogData: Event Data:"); for (i = 0; i < msg->EventDataLength; i++) - mpt_prtc(mpt, " %08x", (unsigned)msg->Data[i]); + mpt_prtc(mpt, " %08x", msg->Data[i]); mpt_prtc(mpt, "\n"); break; } @@ -718,15 +717,16 @@ mpt_intr(void *arg) uint32_t ctxt_idx; u_int cb_index; u_int req_index; + u_int offset; int free_rf; req = NULL; reply_frame = NULL; reply_baddr = 0; + offset = 0; if ((reply_desc & MPI_ADDRESS_REPLY_A_BIT) != 0) { - u_int offset; /* - * Insure that the reply frame is coherent. + * Ensure that the reply frame is coherent. */ reply_baddr = MPT_REPLY_BADDR(reply_desc); offset = reply_baddr - (mpt->reply_phys & 0xFFFFFFFF); @@ -808,10 +808,15 @@ mpt_intr(void *arg) " 0x%x)\n", req_index, reply_desc); } + bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); free_rf = mpt_reply_handlers[cb_index](mpt, req, reply_desc, reply_frame); if (reply_frame != NULL && free_rf) { + bus_dmamap_sync_range(mpt->reply_dmat, + mpt->reply_dmap, offset, MPT_REPLY_SIZE, + BUS_DMASYNC_PREREAD); mpt_free_reply(mpt, reply_baddr); } @@ -844,13 +849,16 @@ mpt_complete_request_chain(struct mpt_softc *mpt, struct req_queue *chain, MSG_REQUEST_HEADER *msg_hdr; u_int cb_index; - TAILQ_REMOVE(chain, req, links); + bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); msg_hdr = (MSG_REQUEST_HEADER *)req->req_vbuf; ioc_status_frame.Function = msg_hdr->Function; ioc_status_frame.MsgContext = msg_hdr->MsgContext; cb_index = MPT_CONTEXT_TO_CBI(le32toh(msg_hdr->MsgContext)); mpt_reply_handlers[cb_index](mpt, req, msg_hdr->MsgContext, &ioc_status_frame); + if (mpt_req_on_pending_list(mpt, req) != 0) + TAILQ_REMOVE(chain, req, links); } } @@ -1166,7 +1174,7 @@ mpt_free_request(struct mpt_softc *mpt, request_t *req) { request_t *nxt; struct mpt_evtf_record *record; - uint32_t reply_baddr; + uint32_t offset, reply_baddr; if (req == NULL || req != &mpt->request_pool[req->index]) { panic("mpt_free_request bad req ptr\n"); @@ -1215,8 +1223,10 @@ mpt_free_request(struct mpt_softc *mpt, request_t *req) req->state = REQ_STATE_ALLOCATED; mpt_assign_serno(mpt, req); mpt_send_event_ack(mpt, req, &record->reply, record->context); - reply_baddr = (uint32_t)((uint8_t *)record - mpt->reply) - + (mpt->reply_phys & 0xFFFFFFFF); + offset = (uint32_t)((uint8_t *)record - mpt->reply); + reply_baddr = offset + (mpt->reply_phys & 0xFFFFFFFF); + bus_dmamap_sync_range(mpt->reply_dmat, mpt->reply_dmap, offset, + MPT_REPLY_SIZE, BUS_DMASYNC_PREREAD); mpt_free_reply(mpt, reply_baddr); } @@ -1240,10 +1250,9 @@ retry: req->state = REQ_STATE_ALLOCATED; req->chain = NULL; mpt_assign_serno(mpt, req); - mpt_callout_init(&req->callout); } else if (sleep_ok != 0) { mpt->getreqwaiter = 1; - mpt_sleep(mpt, &mpt->request_free_list, PUSER, "mptgreq", 0); + mpt_sleep(mpt, &mpt->request_free_list, 0, "mptgreq", 0); goto retry; } return (req); @@ -1257,7 +1266,7 @@ mpt_send_cmd(struct mpt_softc *mpt, request_t *req) mpt_dump_request(mpt, req); } bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_PREWRITE); + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); req->state |= REQ_STATE_QUEUED; KASSERT(mpt_req_on_free_list(mpt, req) == 0, ("req %p:%u func %x on freelist list in mpt_send_cmd", @@ -1306,7 +1315,7 @@ mpt_wait_req(struct mpt_softc *mpt, request_t *req, saved_cnt = mpt->reset_cnt; while ((req->state & mask) != state && mpt->reset_cnt == saved_cnt) { if (sleep_ok != 0) { - error = mpt_sleep(mpt, req, PUSER, "mptreq", timeout); + error = mpt_sleep(mpt, req, 0, "mptreq", timeout); if (error == EWOULDBLOCK) { timeout = 0; break; @@ -1436,15 +1445,9 @@ mpt_recv_handshake_reply(struct mpt_softc *mpt, size_t reply_len, void *reply) */ if ((reply_len >> 1) != hdr->MsgLength && (hdr->Function != MPI_FUNCTION_IOC_FACTS)){ -#if __FreeBSD_version >= 500000 mpt_prt(mpt, "reply length does not match message length: " "got %x; expected %zx for function %x\n", hdr->MsgLength << 2, reply_len << 1, hdr->Function); -#else - mpt_prt(mpt, "reply length does not match message length: " - "got %x; expected %zx for function %x\n", - hdr->MsgLength << 2, reply_len << 1, hdr->Function); -#endif } /* Get rest of the reply; but don't overflow the provided buffer */ @@ -1487,7 +1490,7 @@ mpt_get_iocfacts(struct mpt_softc *mpt, MSG_IOC_FACTS_REPLY *freplp) { MSG_IOC_FACTS f_req; int error; - + memset(&f_req, 0, sizeof f_req); f_req.Function = MPI_FUNCTION_IOC_FACTS; f_req.MsgContext = htole32(MPT_REPLY_HANDLER_HANDSHAKE); @@ -1504,7 +1507,7 @@ mpt_get_portfacts(struct mpt_softc *mpt, U8 port, MSG_PORT_FACTS_REPLY *freplp) { MSG_PORT_FACTS f_req; int error; - + memset(&f_req, 0, sizeof f_req); f_req.Function = MPI_FUNCTION_PORT_FACTS; f_req.PortNumber = port; @@ -1696,8 +1699,6 @@ mpt_read_extcfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress, mpt_free_request(mpt, req); return (-1); } - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); memcpy(buf, ((uint8_t *)req->req_vbuf)+MPT_RQSL(mpt), len); mpt_free_request(mpt, req); return (0); @@ -1795,8 +1796,6 @@ mpt_read_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress, mpt_free_request(mpt, req); return (-1); } - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); memcpy(hdr, ((uint8_t *)req->req_vbuf)+MPT_RQSL(mpt), len); mpt_free_request(mpt, req); return (0); @@ -2122,22 +2121,20 @@ mpt_disable_ints(struct mpt_softc *mpt) static void mpt_sysctl_attach(struct mpt_softc *mpt) { -#if __FreeBSD_version >= 500000 - struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev); - struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev); - - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_UINT(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "debug", CTLFLAG_RW, &mpt->verbose, 0, "Debugging/Verbose level"); - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_UINT(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "role", CTLFLAG_RD, &mpt->role, 0, "HBA role"); #ifdef MPT_TEST_MULTIPATH - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_INT(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "failure_id", CTLFLAG_RW, &mpt->failure_id, -1, "Next Target to Fail"); #endif -#endif } int @@ -2249,13 +2246,6 @@ mpt_core_attach(struct mpt_softc *mpt) TAILQ_INIT(&mpt->request_pending_list); TAILQ_INIT(&mpt->request_free_list); TAILQ_INIT(&mpt->request_timeout_list); - MPT_LOCK(mpt); - for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { - request_t *req = &mpt->request_pool[val]; - req->state = REQ_STATE_ALLOCATED; - mpt_free_request(mpt, req); - } - MPT_UNLOCK(mpt); for (val = 0; val < MPT_MAX_LUNS; val++) { STAILQ_INIT(&mpt->trt[val].atios); STAILQ_INIT(&mpt->trt[val].inots); @@ -2266,6 +2256,14 @@ mpt_core_attach(struct mpt_softc *mpt) mpt->failure_id = -1; #endif mpt->scsi_tgt_handler_id = MPT_HANDLER_ID_NONE; + sysctl_ctx_init(&mpt->mpt_sysctl_ctx); + mpt->mpt_sysctl_tree = SYSCTL_ADD_NODE(&mpt->mpt_sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, + device_get_nameunit(mpt->dev), CTLFLAG_RD, 0, ""); + if (mpt->mpt_sysctl_tree == NULL) { + device_printf(mpt->dev, "can't add sysctl node\n"); + return (EINVAL); + } mpt_sysctl_attach(mpt); mpt_lprt(mpt, MPT_PRT_DEBUG, "doorbell req = %s\n", mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL))); @@ -2336,16 +2334,29 @@ mpt_core_shutdown(struct mpt_softc *mpt) void mpt_core_detach(struct mpt_softc *mpt) { + int val; + /* * XXX: FREE MEMORY */ mpt_disable_ints(mpt); + + /* Make sure no request has pending timeouts. */ + for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { + request_t *req = &mpt->request_pool[val]; + callout_stop(&req->callout); + } + + mpt_dma_buf_free(mpt); + + if (mpt->mpt_sysctl_tree != NULL) + sysctl_ctx_free(&mpt->mpt_sysctl_ctx); } int mpt_core_unload(struct mpt_personality *pers) { - /* Unload is always successfull. */ + /* Unload is always successful. */ return (0); } @@ -2363,7 +2374,7 @@ mpt_upload_fw(struct mpt_softc *mpt) SGE_SIMPLE32 *sge; uint32_t flags; int error; - + memset(&fw_req_buf, 0, sizeof(fw_req_buf)); fw_req = (MSG_FW_UPLOAD *)fw_req_buf; fw_req->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM; @@ -2380,10 +2391,12 @@ mpt_upload_fw(struct mpt_softc *mpt) flags <<= MPI_SGE_FLAGS_SHIFT; sge->FlagsLength = htole32(flags | mpt->fw_image_size); sge->Address = htole32(mpt->fw_phys); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_PREREAD); error = mpt_send_handshake_cmd(mpt, sizeof(fw_req_buf), &fw_req_buf); if (error) return(error); error = mpt_recv_handshake_reply(mpt, sizeof(fw_reply), &fw_reply); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_POSTREAD); return (error); } @@ -2428,8 +2441,10 @@ mpt_download_fw(struct mpt_softc *mpt) MPI_DIAG_RW_ENABLE|MPI_DIAG_DISABLE_ARM); fw_hdr = (MpiFwHeader_t *)mpt->fw_image; + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_PREWRITE); mpt_diag_outsl(mpt, fw_hdr->LoadStartAddress, (uint32_t*)fw_hdr, fw_hdr->ImageSize); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, BUS_DMASYNC_POSTWRITE); ext_offset = fw_hdr->NextImageHeaderOffset; while (ext_offset != 0) { @@ -2437,9 +2452,12 @@ mpt_download_fw(struct mpt_softc *mpt) ext = (MpiExtImageHeader_t *)((uintptr_t)fw_hdr + ext_offset); ext_offset = ext->NextImageHeaderOffset; - + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, + BUS_DMASYNC_PREWRITE); mpt_diag_outsl(mpt, ext->LoadStartAddress, (uint32_t*)ext, ext->ImageSize); + bus_dmamap_sync(mpt->fw_dmat, mpt->fw_dmap, + BUS_DMASYNC_POSTWRITE); } if (mpt->is_sas) { @@ -2474,6 +2492,105 @@ mpt_download_fw(struct mpt_softc *mpt) return (0); } +static int +mpt_dma_buf_alloc(struct mpt_softc *mpt) +{ + struct mpt_map_info mi; + uint8_t *vptr; + uint32_t pptr, end; + int i, error; + + /* Create a child tag for data buffers */ + if (mpt_dma_tag_create(mpt, mpt->parent_dmat, 1, + 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, + NULL, NULL, (mpt->max_cam_seg_cnt - 1) * PAGE_SIZE, + mpt->max_cam_seg_cnt, BUS_SPACE_MAXSIZE_32BIT, 0, + &mpt->buffer_dmat) != 0) { + mpt_prt(mpt, "cannot create a dma tag for data buffers\n"); + return (1); + } + + /* Create a child tag for request buffers */ + if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + NULL, NULL, MPT_REQ_MEM_SIZE(mpt), 1, BUS_SPACE_MAXSIZE_32BIT, 0, + &mpt->request_dmat) != 0) { + mpt_prt(mpt, "cannot create a dma tag for requests\n"); + return (1); + } + + /* Allocate some DMA accessible memory for requests */ + if (bus_dmamem_alloc(mpt->request_dmat, (void **)&mpt->request, + BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &mpt->request_dmap) != 0) { + mpt_prt(mpt, "cannot allocate %d bytes of request memory\n", + MPT_REQ_MEM_SIZE(mpt)); + return (1); + } + + mi.mpt = mpt; + mi.error = 0; + + /* Load and lock it into "bus space" */ + bus_dmamap_load(mpt->request_dmat, mpt->request_dmap, mpt->request, + MPT_REQ_MEM_SIZE(mpt), mpt_map_rquest, &mi, 0); + + if (mi.error) { + mpt_prt(mpt, "error %d loading dma map for DMA request queue\n", + mi.error); + return (1); + } + mpt->request_phys = mi.phys; + + /* + * Now create per-request dma maps + */ + i = 0; + pptr = mpt->request_phys; + vptr = mpt->request; + end = pptr + MPT_REQ_MEM_SIZE(mpt); + while(pptr < end) { + request_t *req = &mpt->request_pool[i]; + req->index = i++; + + /* Store location of Request Data */ + req->req_pbuf = pptr; + req->req_vbuf = vptr; + + pptr += MPT_REQUEST_AREA; + vptr += MPT_REQUEST_AREA; + + req->sense_pbuf = (pptr - MPT_SENSE_SIZE); + req->sense_vbuf = (vptr - MPT_SENSE_SIZE); + + error = bus_dmamap_create(mpt->buffer_dmat, 0, &req->dmap); + if (error) { + mpt_prt(mpt, "error %d creating per-cmd DMA maps\n", + error); + return (1); + } + } + + return (0); +} + +static void +mpt_dma_buf_free(struct mpt_softc *mpt) +{ + int i; + if (mpt->request_dmat == 0) { + mpt_lprt(mpt, MPT_PRT_DEBUG, "already released dma memory\n"); + return; + } + for (i = 0; i < MPT_MAX_REQUESTS(mpt); i++) { + bus_dmamap_destroy(mpt->buffer_dmat, mpt->request_pool[i].dmap); + } + bus_dmamap_unload(mpt->request_dmat, mpt->request_dmap); + bus_dmamem_free(mpt->request_dmat, mpt->request, mpt->request_dmap); + bus_dma_tag_destroy(mpt->request_dmat); + mpt->request_dmat = 0; + bus_dma_tag_destroy(mpt->buffer_dmat); +} + /* * Allocate/Initialize data structures for the controller. Called * once at instance startup. @@ -2482,7 +2599,7 @@ static int mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) { PTR_MSG_PORT_FACTS_REPLY pfp; - int error, port; + int error, port, val; size_t len; if (tn == MPT_MAX_TRYS) { @@ -2542,7 +2659,7 @@ mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) /* limited by the number of chain areas the card will support */ if (mpt->max_seg_cnt > mpt->ioc_facts.MaxChainDepth) { - mpt_lprt(mpt, MPT_PRT_DEBUG, + mpt_lprt(mpt, MPT_PRT_INFO, "chain depth limited to %u (from %u)\n", mpt->ioc_facts.MaxChainDepth, mpt->max_seg_cnt); mpt->max_seg_cnt = mpt->ioc_facts.MaxChainDepth; @@ -2551,19 +2668,39 @@ mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) /* converted to the number of simple sges in chain segments. */ mpt->max_seg_cnt *= (MPT_NSGL(mpt) - 1); - mpt_lprt(mpt, MPT_PRT_DEBUG, "Maximum Segment Count: %u\n", - mpt->max_seg_cnt); - mpt_lprt(mpt, MPT_PRT_DEBUG, "MsgLength=%u IOCNumber = %d\n", + /* + * Use this as the basis for reporting the maximum I/O size to CAM. + */ + mpt->max_cam_seg_cnt = min(mpt->max_seg_cnt, (MAXPHYS / PAGE_SIZE) + 1); + + error = mpt_dma_buf_alloc(mpt); + if (error != 0) { + mpt_prt(mpt, "mpt_dma_buf_alloc() failed!\n"); + return (EIO); + } + + for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { + request_t *req = &mpt->request_pool[val]; + req->state = REQ_STATE_ALLOCATED; + mpt_callout_init(mpt, &req->callout); + mpt_free_request(mpt, req); + } + + mpt_lprt(mpt, MPT_PRT_INFO, "Maximum Segment Count: %u, Maximum " + "CAM Segment Count: %u\n", mpt->max_seg_cnt, + mpt->max_cam_seg_cnt); + + mpt_lprt(mpt, MPT_PRT_INFO, "MsgLength=%u IOCNumber = %d\n", mpt->ioc_facts.MsgLength, mpt->ioc_facts.IOCNumber); - mpt_lprt(mpt, MPT_PRT_DEBUG, + mpt_lprt(mpt, MPT_PRT_INFO, "IOCFACTS: GlobalCredits=%d BlockSize=%u bytes " "Request Frame Size %u bytes Max Chain Depth %u\n", mpt->ioc_facts.GlobalCredits, mpt->ioc_facts.BlockSize, mpt->ioc_facts.RequestFrameSize << 2, mpt->ioc_facts.MaxChainDepth); - mpt_lprt(mpt, MPT_PRT_DEBUG, "IOCFACTS: Num Ports %d, FWImageSize %d, " + mpt_lprt(mpt, MPT_PRT_INFO, "IOCFACTS: Num Ports %d, FWImageSize %d, " "Flags=%#x\n", mpt->ioc_facts.NumberOfPorts, - (int)mpt->ioc_facts.FWImageSize, mpt->ioc_facts.Flags); + mpt->ioc_facts.FWImageSize, mpt->ioc_facts.Flags); len = mpt->ioc_facts.NumberOfPorts * sizeof (MSG_PORT_FACTS_REPLY); mpt->port_facts = kmalloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); @@ -2580,7 +2717,7 @@ mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) /* * In some configurations, the IOC's firmware is * stored in a shared piece of system NVRAM that - * is only accessable via the BIOS. In this + * is only accessible via the BIOS. In this * case, the firmware keeps a copy of firmware in * RAM until the OS driver retrieves it. Once * retrieved, we are responsible for re-downloading @@ -2592,11 +2729,12 @@ mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) mpt->fw_image_size, 1, mpt->fw_image_size, 0, &mpt->fw_dmat); if (error != 0) { - mpt_prt(mpt, "cannot create firmwarew dma tag\n"); + mpt_prt(mpt, "cannot create firmware dma tag\n"); return (ENOMEM); } error = bus_dmamem_alloc(mpt->fw_dmat, - (void **)&mpt->fw_image, BUS_DMA_NOWAIT, &mpt->fw_dmap); + (void **)&mpt->fw_image, BUS_DMA_NOWAIT | + BUS_DMA_COHERENT, &mpt->fw_dmap); if (error != 0) { mpt_prt(mpt, "cannot allocate firmware memory\n"); bus_dma_tag_destroy(mpt->fw_dmat); @@ -2661,6 +2799,8 @@ mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) mpt->is_fc = 0; mpt->is_sas = 0; mpt->is_spi = 1; + if (mpt->mpt_ini_id == MPT_INI_ID_NONE) + mpt->mpt_ini_id = pfp->PortSCSIID; } else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_ISCSI) { mpt_prt(mpt, "iSCSI not supported yet\n"); return (ENXIO); @@ -2749,7 +2889,7 @@ mpt_enable_ioc(struct mpt_softc *mpt, int portenable) mpt_send_event_request(mpt, 1); if (mpt_send_port_enable(mpt, 0) != MPT_OK) { - mpt_prt(mpt, "failed to enable port 0\n"); + mpt_prt(mpt, "%s: failed to enable port 0\n", __func__); return (ENXIO); } } diff --git a/sys/dev/disk/mpt/mpt.h b/sys/dev/disk/mpt/mpt.h index 1df6a71..67dbc17 100644 --- a/sys/dev/disk/mpt/mpt.h +++ b/sys/dev/disk/mpt/mpt.h @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/mpt/mpt.h,v 1.48 2009/07/10 08:18:08 scottl Exp $ */ +/* $FreeBSD: src/sys/dev/mpt/mpt.h,v 1.55 2011/04/22 09:59:16 marius Exp $ */ /*- * Generic defines for LSI '909 FC adapters. * FreeBSD Version. @@ -105,28 +105,21 @@ #include #include #include - #include #include #include #include - #include #include #include - #include #include #include +#include -#if __FreeBSD_version < 500000 #include #include -#else -#include -#include -#endif #include "opt_ddb.h" @@ -159,6 +152,8 @@ #define MPT_ROLE_BOTH 3 #define MPT_ROLE_DEFAULT MPT_ROLE_INITIATOR +#define MPT_INI_ID_NONE -1 + /**************************** Forward Declarations ****************************/ struct mpt_softc; struct mpt_personality; @@ -218,20 +213,6 @@ int mpt_modevent(module_t, int, void *); #define bus_dmamap_sync_range(dma_tag, dmamap, offset, len, op) \ bus_dmamap_sync(dma_tag, dmamap, op) -#if __FreeBSD_version < 600000 -#define bus_get_dma_tag(x) NULL -#endif -#if __FreeBSD_version >= 501102 -#define mpt_dma_tag_create(mpt, parent_tag, alignment, boundary, \ - lowaddr, highaddr, filter, filterarg, \ - maxsize, nsegments, maxsegsz, flags, \ - dma_tagp) \ - bus_dma_tag_create(parent_tag, alignment, boundary, \ - lowaddr, highaddr, filter, filterarg, \ - maxsize, nsegments, maxsegsz, flags, \ - busdma_lock_mutex, &(mpt)->mpt_lock, \ - dma_tagp) -#else #define mpt_dma_tag_create(mpt, parent_tag, alignment, boundary, \ lowaddr, highaddr, filter, filterarg, \ maxsize, nsegments, maxsegsz, flags, \ @@ -240,7 +221,6 @@ int mpt_modevent(module_t, int, void *); lowaddr, highaddr, filter, filterarg, \ maxsize, nsegments, maxsegsz, flags, \ dma_tagp) -#endif struct mpt_map_info { struct mpt_softc *mpt; @@ -250,50 +230,18 @@ struct mpt_map_info { void mpt_map_rquest(void *, bus_dma_segment_t *, int, int); /* **************************** NewBUS interrupt Crock ************************/ -#ifdef __DragonFly__ -#define mpt_setup_intr(d, i, f, U, if, ifa, hp) \ - bus_setup_intr(d, i, f, if, ifa, hp, NULL) -#else -#if __FreeBSD_version < 700031 #define mpt_setup_intr(d, i, f, U, if, ifa, hp) \ - bus_setup_intr(d, i, f, if, ifa, hp) -#else -#define mpt_setup_intr bus_setup_intr -#endif -#endif + bus_setup_intr(d, i, f, if, ifa, hp, NULL) /* **************************** NewBUS CAM Support ****************************/ -#if __FreeBSD_version < 700049 #define mpt_xpt_bus_register(sim, parent, bus) \ xpt_bus_register(sim, bus) -#else -#define mpt_xpt_bus_register xpt_bus_register -#endif /**************************** Kernel Thread Support ***************************/ -#if __FreeBSD_version > 800001 -#define mpt_kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \ - kproc_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) -#define mpt_kthread_exit(status) \ - kproc_exit(status) -#elif __FreeBSD_version > 500005 -#define mpt_kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \ - kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) -#define mpt_kthread_exit(status) \ - kthread_exit(status) -#else #define mpt_kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \ kthread_create(func, farg, proc_ptr, fmtstr, arg) #define mpt_kthread_exit(status) \ kthread_exit() -#endif - -/****************************** Timer Facilities ******************************/ -#if __FreeBSD_version > 500000 -#define mpt_callout_init(c) callout_init(c, /*mpsafe*/1); -#else -#define mpt_callout_init(c) callout_init(c); -#endif /********************************** Endianess *********************************/ #define MPT_2_HOST64(ptr, tag) ptr->tag = le64toh(ptr->tag) @@ -363,7 +311,7 @@ struct req_entry { mpt_req_state_t state; /* Request State Information */ uint16_t index; /* Index of this entry */ uint16_t IOCStatus; /* Completion status */ - uint16_t ResponseCode; /* TMF Reponse Code */ + uint16_t ResponseCode; /* TMF Response Code */ uint16_t serno; /* serial number */ union ccb *ccb; /* CAM request */ void *req_vbuf; /* Virtual Address of Entry */ @@ -591,13 +539,8 @@ struct mptsas_portinfo { struct mpt_softc { device_t dev; -#if __FreeBSD_version < 500000 - uint32_t mpt_islocked; - int mpt_splsaved; -#else - struct mtx mpt_lock; + struct lock mpt_lock; int mpt_locksetup; -#endif uint32_t mpt_pers_mask; uint32_t : 8, @@ -636,7 +579,6 @@ struct mpt_softc { * Port Facts */ MSG_PORT_FACTS_REPLY * port_facts; -#define mpt_ini_id port_facts[0].PortSCSIID #define mpt_max_tgtcmds port_facts[0].MaxPostedCmdBuffers /* @@ -649,6 +591,7 @@ struct mpt_softc { CONFIG_PAGE_SCSI_PORT_2 _port_page2; CONFIG_PAGE_SCSI_DEVICE_0 _dev_page0[16]; CONFIG_PAGE_SCSI_DEVICE_1 _dev_page1[16]; + int _ini_id; uint16_t _tag_enable; uint16_t _disc_enable; } spi; @@ -657,6 +600,7 @@ struct mpt_softc { #define mpt_port_page2 cfg.spi._port_page2 #define mpt_dev_page0 cfg.spi._dev_page0 #define mpt_dev_page1 cfg.spi._dev_page1 +#define mpt_ini_id cfg.spi._ini_id #define mpt_tag_enable cfg.spi._tag_enable #define mpt_disc_enable cfg.spi._disc_enable struct mpi_fc_cfg { @@ -666,7 +610,6 @@ struct mpt_softc { #define mpt_fcport_speed cfg.fc._port_speed } fc; } cfg; -#if __FreeBSD_version >= 500000 /* * Device config information stored up for sysctl to access */ @@ -679,7 +622,6 @@ struct mpt_softc { char wwpn[19]; } fc; } scinfo; -#endif /* Controller Info for RAID information */ CONFIG_PAGE_IOC_2 * ioc_page2; @@ -705,7 +647,7 @@ struct mpt_softc { */ int pci_msi_count; struct resource * pci_irq; /* Interrupt map for chip */ - void * ih; /* Interupt handle */ + void * ih; /* Interrupt handle */ struct mpt_pci_cfg pci_cfg; /* saved PCI conf registers */ /* @@ -734,6 +676,7 @@ struct mpt_softc { bus_addr_t request_phys; /* BusAddr of request memory */ uint32_t max_seg_cnt; /* calculated after IOC facts */ + uint32_t max_cam_seg_cnt;/* calculated from MAXPHYS*/ /* * Hardware management @@ -805,6 +748,9 @@ struct mpt_softc { /* Userland management interface. */ struct cdev *cdev; + struct sysctl_ctx_list mpt_sysctl_ctx; + struct sysctl_oid *mpt_sysctl_tree; + TAILQ_ENTRY(mpt_softc) links; }; @@ -819,150 +765,29 @@ mpt_assign_serno(struct mpt_softc *mpt, request_t *req) } /***************************** Locking Primitives *****************************/ -#ifdef __DragonFly__ -#define PUSER 0 -#define MPT_IFLAGS 0 -#define MPT_LOCK(mpt) crit_enter() -#define MPT_UNLOCK(mpt) crit_exit() -#define MPT_LOCK_SETUP(mpt) do { } while(0) -#define MPT_LOCK_DESTROY(mpt) do { } while(0) -#define MPT_LOCK_ASSERT(mpt) do { } while(0) -#define MPTLOCK_2_CAMLOCK MPT_UNLOCK -#define CAMLOCK_2_MPTLOCK MPT_LOCK -#define splx(s) -#define splsoftvm() 0 -static __inline int -mpt_sleep(struct mpt_softc *mpt, void *ident, int priority, - const char *wmesg, int timo) { - int error; - error = tsleep(ident, 0, wmesg, timo); - return(error); -} -#endif -#define mpt_req_timeout(req, ticks, func, arg) \ - callout_reset(&(req)->callout, (ticks), (func), (arg)); -#define mpt_req_untimeout(req, func, arg) \ - callout_stop(&(req)->callout) -#if 0 -#if __FreeBSD_version < 500000 -#define MPT_IFLAGS INTR_TYPE_CAM -#define MPT_LOCK(mpt) mpt_lockspl(mpt) -#define MPT_UNLOCK(mpt) mpt_unlockspl(mpt) -#define MPT_OWNED(mpt) mpt->mpt_islocked -#define MPT_LOCK_ASSERT(mpt) -#define MPTLOCK_2_CAMLOCK MPT_UNLOCK -#define CAMLOCK_2_MPTLOCK MPT_LOCK -#define MPT_LOCK_SETUP(mpt) -#define MPT_LOCK_DESTROY(mpt) - -static __inline void mpt_lockspl(struct mpt_softc *mpt); -static __inline void mpt_unlockspl(struct mpt_softc *mpt); - -static __inline void -mpt_lockspl(struct mpt_softc *mpt) -{ - int s; - - s = splcam(); - if (mpt->mpt_islocked++ == 0) { - mpt->mpt_splsaved = s; - } else { - splx(s); - panic("Recursed lock with mask: 0x%x\n", s); - } -} - -static __inline void -mpt_unlockspl(struct mpt_softc *mpt) -{ - if (mpt->mpt_islocked) { - if (--mpt->mpt_islocked == 0) { - splx(mpt->mpt_splsaved); - } - } else - panic("Negative lock count\n"); -} - -static __inline int -mpt_sleep(struct mpt_softc *mpt, void *ident, int priority, - const char *wmesg, int timo) -{ - int saved_cnt; - int saved_spl; - int error; - - KASSERT(mpt->mpt_islocked <= 1, ("Invalid lock count on tsleep")); - saved_cnt = mpt->mpt_islocked; - saved_spl = mpt->mpt_splsaved; - mpt->mpt_islocked = 0; - error = tsleep(ident, priority, wmesg, timo); - KASSERT(mpt->mpt_islocked == 0, ("Invalid lock count on wakeup")); - mpt->mpt_islocked = saved_cnt; - mpt->mpt_splsaved = saved_spl; - return (error); -} - -#define mpt_req_timeout(req, ticks, func, arg) \ - callout_reset(&(req)->callout, (ticks), (func), (arg)); -#define mpt_req_untimeout(req, func, arg) \ - callout_stop(&(req)->callout) -#else -#if 1 -#define MPT_IFLAGS INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE #define MPT_LOCK_SETUP(mpt) \ - mtx_init(&mpt->mpt_lock, "mpt", NULL, MTX_DEF); \ + lockinit(&mpt->mpt_lock, "mpt", 0, LK_CANRECURSE); \ mpt->mpt_locksetup = 1 #define MPT_LOCK_DESTROY(mpt) \ if (mpt->mpt_locksetup) { \ - mtx_destroy(&mpt->mpt_lock); \ + lockuninit(&mpt->mpt_lock); \ mpt->mpt_locksetup = 0; \ } -#define MPT_LOCK(mpt) mtx_lock(&(mpt)->mpt_lock) -#define MPT_UNLOCK(mpt) mtx_unlock(&(mpt)->mpt_lock) -#define MPT_OWNED(mpt) mtx_owned(&(mpt)->mpt_lock) -#define MPT_LOCK_ASSERT(mpt) mtx_assert(&(mpt)->mpt_lock, MA_OWNED) +#define MPT_LOCK(mpt) lockmgr(&(mpt)->mpt_lock, LK_EXCLUSIVE) +#define MPT_UNLOCK(mpt) lockmgr(&(mpt)->mpt_lock, LK_RELEASE) +#define MPT_OWNED(mpt) lockstatus(&(mpt)->mpt_lock, curthread) +#define MPT_LOCK_ASSERT(mpt) KKASSERT(lockstatus(&(mpt)->mpt_lock, curthread) != 0) #define MPTLOCK_2_CAMLOCK(mpt) #define CAMLOCK_2_MPTLOCK(mpt) #define mpt_sleep(mpt, ident, priority, wmesg, timo) \ - msleep(ident, &(mpt)->mpt_lock, priority, wmesg, timo) + lksleep(ident, &(mpt)->mpt_lock, priority, wmesg, timo) #define mpt_req_timeout(req, ticks, func, arg) \ - callout_reset(&(req)->callout, (ticks), (func), (arg)); + callout_reset(&(req)->callout, (ticks), (func), (arg)) #define mpt_req_untimeout(req, func, arg) \ callout_stop(&(req)->callout) -#else - -#define MPT_IFLAGS INTR_TYPE_CAM | INTR_ENTROPY -#define MPT_LOCK_SETUP(mpt) do { } while (0) -#define MPT_LOCK_DESTROY(mpt) do { } while (0) -#define MPT_LOCK_ASSERT(mpt) mtx_assert(&Giant, MA_OWNED) -#define MPT_LOCK(mpt) mtx_lock(&Giant) -#define MPT_UNLOCK(mpt) mtx_unlock(&Giant) -#define MPTLOCK_2_CAMLOCK(mpt) -#define CAMLOCK_2_MPTLOCK(mpt) - -static __inline int -mpt_sleep(struct mpt_softc *, void *, int, const char *, int); - -#define mpt_ccb_timeout(ccb, ticks, func, arg) \ - do { \ - (ccb)->ccb_h.timeout_ch = timeout((func), (arg), (ticks)); \ - } while (0) -#define mpt_ccb_untimeout(ccb, func, arg) \ - untimeout((func), (arg), (ccb)->ccb_h.timeout_ch) -#define mpt_ccb_timeout_init(ccb) \ - callout_handle_init(&(ccb)->ccb_h.timeout_ch) - -static __inline int -mpt_sleep(struct mpt_softc *mpt, void *i, int p, const char *w, int t) -{ - int r; - r = tsleep(i, p, w, t); - return (r); -} -#endif -#endif -#endif +#define mpt_callout_init(mpt, c) \ + callout_init(c) /******************************* Register Access ******************************/ static __inline void mpt_write(struct mpt_softc *, size_t, uint32_t); @@ -1002,9 +827,6 @@ mpt_pio_read(struct mpt_softc *mpt, int offset) /* Max MPT Reply we are willing to accept (must be power of 2) */ #define MPT_REPLY_SIZE 256 -/* Max i/o size, based on legacy MAXPHYS. Can be increased. */ -#define MPT_MAXPHYS (128 * 1024) - /* * Must be less than 16384 in order for target mode to work */ @@ -1061,7 +883,7 @@ mpt_pop_reply_queue(struct mpt_softc *mpt) void mpt_complete_request_chain(struct mpt_softc *, struct req_queue *, u_int); -/************************** Scatter Gather Managment **************************/ +/************************** Scatter Gather Management **************************/ /* MPT_RQSL- size of request frame, in bytes */ #define MPT_RQSL(mpt) (mpt->ioc_facts.RequestFrameSize << 2) @@ -1114,24 +936,17 @@ enum { MPT_PRT_NONE=100 }; -#if __FreeBSD_version > 500000 #define mpt_lprt(mpt, level, ...) \ do { \ if (level <= (mpt)->verbose) \ mpt_prt(mpt, __VA_ARGS__); \ } while (0) -#define mpt_lprtc(mpt, level, ...) \ -do { \ - if (level <= (mpt)->debug_level) \ - mpt_prtc(mpt, __VA_ARGS__); \ +#define mpt_lprtc(mpt, level, ...) \ +do { \ + if (level <= (mpt)->verbose) \ + mpt_prtc(mpt, __VA_ARGS__); \ } while (0) -#else -void mpt_lprt(struct mpt_softc *, int, const char *, ...) - __printflike(3, 4); -void mpt_lprtc(struct mpt_softc *, int, const char *, ...) - __printflike(3, 4); -#endif void mpt_prt(struct mpt_softc *, const char *, ...) __printflike(2, 3); void mpt_prtc(struct mpt_softc *, const char *, ...) @@ -1166,19 +981,13 @@ mpt_tag_2_req(struct mpt_softc *mpt, uint32_t tag) KASSERT(mpt->tgt_cmd_ptrs[rtg], ("no cmd backpointer")); return (mpt->tgt_cmd_ptrs[rtg]); } - +#endif static __inline int mpt_req_on_free_list(struct mpt_softc *, request_t *); static __inline int mpt_req_on_pending_list(struct mpt_softc *, request_t *); -static __inline void -mpt_req_spcl(struct mpt_softc *, request_t *, const char *, int); -static __inline void -mpt_req_not_spcl(struct mpt_softc *, request_t *, const char *, int); - - /* * Is request on freelist? */ @@ -1211,6 +1020,12 @@ mpt_req_on_pending_list(struct mpt_softc *mpt, request_t *req) return (0); } +#ifdef INVARIANTS +static __inline void +mpt_req_spcl(struct mpt_softc *, request_t *, const char *, int); +static __inline void +mpt_req_not_spcl(struct mpt_softc *, request_t *, const char *, int); + /* * Make sure that req *is* part of one of the special lists */ diff --git a/sys/dev/disk/mpt/mpt_cam.c b/sys/dev/disk/mpt/mpt_cam.c index 92f78bb..2b8a37b 100644 --- a/sys/dev/disk/mpt/mpt_cam.c +++ b/sys/dev/disk/mpt/mpt_cam.c @@ -93,7 +93,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/mpt/mpt_cam.c,v 1.68 2009/07/02 00:43:10 delphij Exp $ + * $FreeBSD: src/sys/dev/mpt/mpt_cam.c,v 1.77 2011/04/22 09:59:16 marius Exp $ */ #include @@ -105,17 +105,13 @@ #include "dev/disk/mpt/mpilib/mpi_targ.h" #include "dev/disk/mpt/mpilib/mpi_fc.h" #include "dev/disk/mpt/mpilib/mpi_sas.h" -#if __FreeBSD_version >= 500000 #include -#endif #include #include -#if __FreeBSD_version >= 700025 || defined(__DragonFly__) #ifndef CAM_NEW_TRAN_CODE #define CAM_NEW_TRAN_CODE 1 #endif -#endif static void mpt_poll(struct cam_sim *); static timeout_t mpt_timeout; @@ -468,38 +464,35 @@ mpt_read_config_info_fc(struct mpt_softc *mpt) mpt_lprt(mpt, MPT_PRT_INFO, "FC Port Page 0: Topology <%s> WWNN 0x%08x%08x WWPN 0x%08x%08x " "Speed %u-Gbit\n", topology, - (unsigned)mpt->mpt_fcport_page0.WWNN.High, - (unsigned)mpt->mpt_fcport_page0.WWNN.Low, - (unsigned)mpt->mpt_fcport_page0.WWPN.High, - (unsigned)mpt->mpt_fcport_page0.WWPN.Low, - (unsigned)mpt->mpt_fcport_speed); -#if __FreeBSD_version >= 500000 + mpt->mpt_fcport_page0.WWNN.High, + mpt->mpt_fcport_page0.WWNN.Low, + mpt->mpt_fcport_page0.WWPN.High, + mpt->mpt_fcport_page0.WWPN.Low, + mpt->mpt_fcport_speed); MPT_UNLOCK(mpt); { - struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev); - struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev); - - snprintf(mpt->scinfo.fc.wwnn, + ksnprintf(mpt->scinfo.fc.wwnn, sizeof (mpt->scinfo.fc.wwnn), "0x%08x%08x", mpt->mpt_fcport_page0.WWNN.High, mpt->mpt_fcport_page0.WWNN.Low); - snprintf(mpt->scinfo.fc.wwpn, + ksnprintf(mpt->scinfo.fc.wwpn, sizeof (mpt->scinfo.fc.wwpn), "0x%08x%08x", mpt->mpt_fcport_page0.WWPN.High, mpt->mpt_fcport_page0.WWPN.Low); - SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_STRING(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "wwnn", CTLFLAG_RD, mpt->scinfo.fc.wwnn, 0, "World Wide Node Name"); - SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_STRING(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "wwpn", CTLFLAG_RD, mpt->scinfo.fc.wwpn, 0, "World Wide Port Name"); } MPT_LOCK(mpt); -#endif return (0); } @@ -983,8 +976,8 @@ mpt_read_config_info_spi(struct mpt_softc *mpt) mpt2host_config_page_scsi_port_0(&mpt->mpt_port_page0); mpt_lprt(mpt, MPT_PRT_NEGOTIATION, "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n", - (unsigned)mpt->mpt_port_page0.Capabilities, - (unsigned)mpt->mpt_port_page0.PhysicalInterface); + mpt->mpt_port_page0.Capabilities, + mpt->mpt_port_page0.PhysicalInterface); } rv = mpt_read_cur_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header, @@ -995,8 +988,8 @@ mpt_read_config_info_spi(struct mpt_softc *mpt) mpt2host_config_page_scsi_port_1(&mpt->mpt_port_page1); mpt_lprt(mpt, MPT_PRT_DEBUG, "SPI Port Page 1: Configuration %x OnBusTimerValue %x\n", - (unsigned)mpt->mpt_port_page1.Configuration, - (unsigned)mpt->mpt_port_page1.OnBusTimerValue); + mpt->mpt_port_page1.Configuration, + mpt->mpt_port_page1.OnBusTimerValue); } rv = mpt_read_cur_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header, @@ -1006,8 +999,8 @@ mpt_read_config_info_spi(struct mpt_softc *mpt) } else { mpt_lprt(mpt, MPT_PRT_NEGOTIATION, "Port Page 2: Flags %x Settings %x\n", - (unsigned)mpt->mpt_port_page2.PortFlags, - (unsigned)mpt->mpt_port_page2.PortSettings); + mpt->mpt_port_page2.PortFlags, + mpt->mpt_port_page2.PortSettings); mpt2host_config_page_scsi_port_2(&mpt->mpt_port_page2); for (i = 0; i < 16; i++) { mpt_lprt(mpt, MPT_PRT_NEGOTIATION, @@ -1030,9 +1023,8 @@ mpt_read_config_info_spi(struct mpt_softc *mpt) mpt2host_config_page_scsi_device_0(&mpt->mpt_dev_page0[i]); mpt_lprt(mpt, MPT_PRT_NEGOTIATION, "target %d page 0: Negotiated Params %x Information %x\n", - i, - (unsigned)mpt->mpt_dev_page0[i].NegotiatedParameters, - (unsigned)mpt->mpt_dev_page0[i].Information); + i, mpt->mpt_dev_page0[i].NegotiatedParameters, + mpt->mpt_dev_page0[i].Information); rv = mpt_read_cur_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header, sizeof(*mpt->mpt_dev_page1), @@ -1045,9 +1037,8 @@ mpt_read_config_info_spi(struct mpt_softc *mpt) mpt2host_config_page_scsi_device_1(&mpt->mpt_dev_page1[i]); mpt_lprt(mpt, MPT_PRT_NEGOTIATION, "target %d page 1: Requested Params %x Configuration %x\n", - i, - (unsigned)mpt->mpt_dev_page1[i].RequestedParameters, - (unsigned)mpt->mpt_dev_page1[i].Configuration); + i, mpt->mpt_dev_page1[i].RequestedParameters, + mpt->mpt_dev_page1[i].Configuration); } return (0); } @@ -1060,19 +1051,18 @@ mpt_read_config_info_spi(struct mpt_softc *mpt) static int mpt_set_initial_config_spi(struct mpt_softc *mpt) { - int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id; - int error; + int error, i, pp1val; mpt->mpt_disc_enable = 0xff; mpt->mpt_tag_enable = 0; + pp1val = ((1 << mpt->mpt_ini_id) << + MPI_SCSIPORTPAGE1_CFG_SHIFT_PORT_RESPONSE_ID) | mpt->mpt_ini_id; if (mpt->mpt_port_page1.Configuration != pp1val) { CONFIG_PAGE_SCSI_PORT_1 tmp; mpt_prt(mpt, "SPI Port Page 1 Config value bad (%x)- should " - "be %x\n", - (unsigned)mpt->mpt_port_page1.Configuration, - (unsigned)pp1val); + "be %x\n", mpt->mpt_port_page1.Configuration, pp1val); tmp = mpt->mpt_port_page1; tmp.Configuration = pp1val; host2mpt_config_page_scsi_port_1(&tmp); @@ -1208,7 +1198,6 @@ mpt_cam_detach(struct mpt_softc *mpt) kfree(mpt->sas_portinfo, M_DEVBUF); mpt->sas_portinfo = NULL; } - MPT_UNLOCK(mpt); if (mpt->sim != NULL) { xpt_free_path(mpt->path); @@ -1223,6 +1212,7 @@ mpt_cam_detach(struct mpt_softc *mpt) cam_sim_free(mpt->phydisk_sim); mpt->phydisk_sim = NULL; } + MPT_UNLOCK(mpt); } /* This routine is used after a system crash to dump core onto the swap device. @@ -1249,7 +1239,7 @@ mpt_timeout(void *arg) ccb = (union ccb *)arg; mpt = ccb->ccb_h.ccb_mpt_ptr; - MPT_LOCK(mpt); + MPT_LOCK_ASSERT(mpt); req = ccb->ccb_h.ccb_req_ptr; mpt_prt(mpt, "request %p:%u timed out for ccb %p (req->ccb %p)\n", req, req->serno, ccb, req->ccb); @@ -1260,7 +1250,6 @@ mpt_timeout(void *arg) req->state |= REQ_STATE_TIMEDOUT; mpt_wakeup_recovery_thread(mpt); } - MPT_UNLOCK(mpt); } /* @@ -2248,9 +2237,11 @@ mpt_start(struct cam_sim *sim, union ccb *ccb) * one or more physical address ranges. */ int error; + crit_enter(); error = bus_dmamap_load(mpt->buffer_dmat, req->dmap, csio->data_ptr, csio->dxfer_len, cb, req, 0); + crit_exit(); if (error == EINPROGRESS) { /* * So as to maintain ordering, @@ -2380,6 +2371,13 @@ mpt_fc_reset_link(struct mpt_softc *mpt, int dowait) return (r); } +static void +mpt_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) +{ + xpt_free_path(ccb->ccb_h.path); + kfree(ccb, M_TEMP); +} + static int mpt_cam_event(struct mpt_softc *mpt, request_t *req, MSG_EVENT_NOTIFY_REPLY *msg) @@ -2412,7 +2410,6 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, break; case MPI_EVENT_RESCAN: -#if __FreeBSD_version >= 600000 { union ccb *ccb; uint32_t pathid; @@ -2433,28 +2430,27 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, * Allocate a CCB, create a wildcard path for this bus, * and schedule a rescan. */ - ccb = xpt_alloc_ccb_nowait(); - if (ccb == NULL) { - mpt_prt(mpt, "unable to alloc CCB for rescan\n"); - CAMLOCK_2_MPTLOCK(mpt); - break; - } + ccb = kmalloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO); if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { CAMLOCK_2_MPTLOCK(mpt); mpt_prt(mpt, "unable to create path for rescan\n"); - xpt_free_ccb(ccb); + kfree(ccb, M_TEMP); break; } - xpt_rescan(ccb); + + xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5/*priority (low)*/); + ccb->ccb_h.func_code = XPT_SCAN_BUS; + ccb->ccb_h.cbfcnp = mpt_cam_rescan_callback; + ccb->crcn.flags = CAM_FLAG_NONE; + xpt_action(ccb); + + /* scan is now in progress */ + CAMLOCK_2_MPTLOCK(mpt); break; } -#else - mpt_prt(mpt, "Rescan Port: %d\n", (data0 >> 8) & 0xff); - break; -#endif case MPI_EVENT_LINK_STATUS_CHANGE: mpt_prt(mpt, "Port %d: LinkState: %s\n", (data1 >> 8) & 0xff, @@ -2555,6 +2551,7 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, } xpt_setup_ccb(&crs.ccb_h, tmppath, 5); crs.ccb_h.func_code = XPT_REL_SIMQ; + crs.ccb_h.flags = CAM_DEV_QFREEZE; crs.release_flags = RELSIM_ADJUST_OPENINGS; crs.openings = pqf->CurrentDepth - 1; xpt_action((union ccb *)&crs); @@ -2566,6 +2563,10 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, CAMLOCK_2_MPTLOCK(mpt); break; } + case MPI_EVENT_IR_RESYNC_UPDATE: + mpt_prt(mpt, "IR resync update %d completed\n", + (data0 >> 16) & 0xff); + break; case MPI_EVENT_EVENT_CHANGE: case MPI_EVENT_INTEGRATED_RAID: case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: @@ -2573,7 +2574,7 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, break; default: mpt_lprt(mpt, MPT_PRT_WARN, "mpt_cam_event: 0x%x\n", - (unsigned)msg->Event & 0xFF); + msg->Event & 0xFF); return (0); } return (1); @@ -2962,7 +2963,7 @@ mpt_fc_els_reply_handler(struct mpt_softc *mpt, request_t *req, } if (tgt_req) { mpt_tgt_state_t *tgt = MPT_TGT_STATE(mpt, tgt_req); - union ccb *ccb = tgt->ccb; + union ccb *ccb; uint32_t ct_id; /* @@ -3006,7 +3007,7 @@ mpt_fc_els_reply_handler(struct mpt_softc *mpt, request_t *req, elsbuf[1] = htobe32((ox_id << 16) | rx_id); elsbuf[2] = htobe32(0x000ffff); /* - * Dork with the reply frame so that the reponse to it + * Dork with the reply frame so that the response to it * will be correct. */ rp->Rctl_Did += ((BA_ACC - ABTS) << MPI_FC_RCTL_SHIFT); @@ -3133,7 +3134,7 @@ XXXX mpt_set_ccb_status(ccb, CAM_AUTOSENSE_FAIL); } else if ((sstate & MPI_SCSI_STATE_RESPONSE_INFO_VALID) != 0) { - /* XXX Handle SPI-Packet and FCP-2 reponse info. */ + /* XXX Handle SPI-Packet and FCP-2 response info. */ mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR); } else mpt_set_ccb_status(ccb, CAM_REQ_CMP); @@ -3573,6 +3574,9 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) cpi->target_sprt = 0; cpi->hba_eng_cnt = 0; cpi->max_target = mpt->port_facts[0].MaxDevices - 1; +#if 0 /* XXX swildner */ + cpi->maxio = (mpt->max_cam_seg_cnt - 1) * PAGE_SIZE; +#endif /* * FC cards report MAX_DEVICES of 512, but * the MSG_SCSI_IO_REQUEST target id field @@ -3785,10 +3789,8 @@ mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts) MPTLOCK_2_CAMLOCK(mpt); mpt_lprt(mpt, MPT_PRT_DEBUG, - "mpt_get_spi_settings[%d]: current NP %x Info %x\n", - tgt, - (unsigned)tmp.NegotiatedParameters, - (unsigned)tmp.Information); + "mpt_get_spi_settings[%d]: current NP %x Info %x\n", tgt, + tmp.NegotiatedParameters, tmp.Information); dval |= (tmp.NegotiatedParameters & MPI_SCSIDEVPAGE0_NP_WIDE) ? DP_WIDE : DP_NARROW; dval |= (mpt->mpt_disc_enable & (1 << tgt)) ? @@ -3912,8 +3914,7 @@ mpt_update_spi_config(struct mpt_softc *mpt, int tgt) mpt_lprt(mpt, MPT_PRT_NEGOTIATION, "mpt_update_spi_config[%d].page1: Requested Params 0x%08x\n", - tgt, - (unsigned)mpt->mpt_dev_page1[tgt].RequestedParameters); + tgt, mpt->mpt_dev_page1[tgt].RequestedParameters); tmp = mpt->mpt_dev_page1[tgt]; host2mpt_config_page_scsi_device_1(&tmp); rv = mpt_write_cur_cfg_page(mpt, tgt, @@ -3928,9 +3929,7 @@ mpt_update_spi_config(struct mpt_softc *mpt, int tgt) static void mpt_calc_geometry(struct ccb_calc_geometry *ccg, int extended) { -#if __FreeBSD_version >= 500000 cam_calc_geometry(ccg, extended); -#else uint32_t size_mb; uint32_t secs_per_cylinder; @@ -3949,7 +3948,6 @@ mpt_calc_geometry(struct ccb_calc_geometry *ccg, int extended) secs_per_cylinder = ccg->heads * ccg->secs_per_track; ccg->cylinders = ccg->volume_size / secs_per_cylinder; ccg->ccb_h.status = CAM_REQ_CMP; -#endif } /****************************** Timeout Recovery ******************************/ @@ -3976,7 +3974,7 @@ mpt_terminate_recovery_thread(struct mpt_softc *mpt) * Sleep on a slightly different location * for this interlock just for added safety. */ - mpt_sleep(mpt, &mpt->recovery_thread, PUSER, "thtrm", 0); + mpt_sleep(mpt, &mpt->recovery_thread, 0, "thtrm", 0); } static void @@ -3985,14 +3983,11 @@ mpt_recovery_thread(void *arg) struct mpt_softc *mpt; mpt = (struct mpt_softc *)arg; - - get_mplock(); MPT_LOCK(mpt); - for (;;) { if (TAILQ_EMPTY(&mpt->request_timeout_list) != 0) { if (mpt->shutdwn_recovery == 0) { - mpt_sleep(mpt, mpt, PUSER, "idle", 0); + mpt_sleep(mpt, mpt, 0, "idle", 0); } } if (mpt->shutdwn_recovery != 0) { @@ -4003,7 +3998,7 @@ mpt_recovery_thread(void *arg) mpt->recovery_thread = NULL; wakeup(&mpt->recovery_thread); MPT_UNLOCK(mpt); - rel_mplock(); + mpt_kthread_exit(0); } static int @@ -4045,10 +4040,8 @@ mpt_scsi_send_tmf(struct mpt_softc *mpt, u_int type, u_int flags, tmf_req->TaskMsgContext = abort_ctx; mpt_lprt(mpt, MPT_PRT_DEBUG, - "Issuing TMF %p:%u with MsgContext of 0x%x\n", - mpt->tmf_req, - (unsigned)mpt->tmf_req->serno, - (unsigned)tmf_req->MsgContext); + "Issuing TMF %p:%u with MsgContext of 0x%x\n", mpt->tmf_req, + mpt->tmf_req->serno, tmf_req->MsgContext); if (mpt->verbose > MPT_PRT_DEBUG) { mpt_print_request(tmf_req); } @@ -4221,7 +4214,7 @@ mpt_fc_post_els(struct mpt_softc *mpt, request_t *req, int ioindex) /* * Okay, set up ELS buffer pointers. ELS buffer pointers * consist of a TE SGL element (with details length of zero) - * followe by a SIMPLE SGL element which holds the address + * followed by a SIMPLE SGL element which holds the address * of the buffer. */ @@ -4555,9 +4548,11 @@ mpt_target_start_io(struct mpt_softc *mpt, union ccb *ccb) if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) { int error; + crit_enter(); error = bus_dmamap_load(mpt->buffer_dmat, req->dmap, csio->data_ptr, csio->dxfer_len, cb, req, 0); + crit_exit(); if (error == EINPROGRESS) { xpt_freeze_simq(mpt->sim, 1); ccb->ccb_h.status |= CAM_RELEASE_SIMQ; @@ -5019,15 +5014,6 @@ mpt_scsi_tgt_atio(struct mpt_softc *mpt, request_t *req, uint32_t reply_desc) uint8_t *cdbp; /* - * First, DMA sync the received command- - * which is in the *request* * phys area. - * - * XXX: We could optimize this for a range - */ - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); - - /* * Stash info for the current command where we can get at it later. */ vbuf = req->req_vbuf; @@ -5269,7 +5255,7 @@ mpt_scsi_tgt_atio(struct mpt_softc *mpt, request_t *req, uint32_t reply_desc) (i == (atiop->cdb_len - 1))? '>' : ' '); } mpt_prtc(mpt, " itag %x tag %x rdesc %x dl=%u\n", - itag, atiop->tag_id, tgt->reply_desc, tgt->resid); + itag, atiop->tag_id, tgt->reply_desc, tgt->resid); } MPTLOCK_2_CAMLOCK(mpt); diff --git a/sys/dev/disk/mpt/mpt_cam.h b/sys/dev/disk/mpt/mpt_cam.h index d8c7a4b..2b5e246 100644 --- a/sys/dev/disk/mpt/mpt_cam.h +++ b/sys/dev/disk/mpt/mpt_cam.h @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/mpt/mpt_cam.h,v 1.6 2007/05/05 20:18:24 mjacob Exp $ */ +/* $FreeBSD: src/sys/dev/mpt/mpt_cam.h,v 1.7 2010/01/28 08:41:30 mav Exp $ */ /*- * LSI MPT Host Adapter FreeBSD Wrapper Definitions (CAM version) * @@ -102,7 +102,6 @@ #include #include #include -#include #include #include #include @@ -144,16 +143,6 @@ mpt_wakeup_recovery_thread(struct mpt_softc *mpt) } /************************** Version Compatibility *************************/ -#ifdef __DragonFly__ -#define mpt_sim_alloc(a, b, c, mpt, e, f, g) \ - cam_sim_alloc(a, b, c, mpt, (mpt)->unit, &sim_mplock, e, f, g) -#else -#if __FreeBSD_version < 700031 -#define mpt_sim_alloc(a, b, c, mpt, e, f, g) \ - cam_sim_alloc(a, b, c, mpt, (mpt)->unit, e, f, g) -#else #define mpt_sim_alloc(a, b, c, mpt, e, f, g) \ cam_sim_alloc(a, b, c, mpt, (mpt)->unit, &(mpt)->mpt_lock, e, f, g) -#endif #endif /*_MPT_CAM_H_ */ -#endif diff --git a/sys/dev/disk/mpt/mpt_debug.c b/sys/dev/disk/mpt/mpt_debug.c index 8daa3ef..2e712d4 100644 --- a/sys/dev/disk/mpt/mpt_debug.c +++ b/sys/dev/disk/mpt/mpt_debug.c @@ -62,7 +62,7 @@ * Support from LSI-Logic has also gone a great deal toward making this a * workable subsystem and is gratefully acknowledged. * - * $FreeBSD: src/sys/dev/mpt/mpt_debug.c,v 1.18 2006/12/07 22:02:28 mjacob Exp $ + * $FreeBSD: src/sys/dev/mpt/mpt_debug.c,v 1.19 2011/04/22 09:59:16 marius Exp $ */ #include @@ -358,10 +358,10 @@ mpt_print_reply_hdr(MSG_DEFAULT_REPLY *msg) { kprintf("%s Reply @ %p\n", mpt_ioc_function(msg->Function), msg); kprintf("\tIOC Status %s\n", mpt_ioc_status(msg->IOCStatus)); - kprintf("\tIOCLogInfo 0x%08x\n", (unsigned)msg->IOCLogInfo); + kprintf("\tIOCLogInfo 0x%08x\n", msg->IOCLogInfo); kprintf("\tMsgLength 0x%02x\n", msg->MsgLength); kprintf("\tMsgFlags 0x%02x\n", msg->MsgFlags); - kprintf("\tMsgContext 0x%08x\n", (unsigned)msg->MsgContext); + kprintf("\tMsgContext 0x%08x\n", msg->MsgContext); } static void @@ -384,19 +384,18 @@ mpt_print_ioc_facts(MSG_IOC_FACTS_REPLY *msg) kprintf("\tFlags %d\n", msg->Flags); kprintf("\tReplyQueueDepth %d\n", msg->ReplyQueueDepth); kprintf("\tReqFrameSize 0x%04x\n", msg->RequestFrameSize); - kprintf("\tFW Version 0x%08x\n", (unsigned)msg->FWVersion.Word); + kprintf("\tFW Version 0x%08x\n", msg->FWVersion.Word); kprintf("\tProduct ID 0x%04x\n", msg->ProductID); kprintf("\tCredits 0x%04x\n", msg->GlobalCredits); kprintf("\tPorts %d\n", msg->NumberOfPorts); kprintf("\tEventState 0x%02x\n", msg->EventState); - kprintf("\tHostMFA_HA 0x%08x\n", - (unsigned)msg->CurrentHostMfaHighAddr); + kprintf("\tHostMFA_HA 0x%08x\n", msg->CurrentHostMfaHighAddr); kprintf("\tSenseBuf_HA 0x%08x\n", - (unsigned)msg->CurrentSenseBufferHighAddr); + msg->CurrentSenseBufferHighAddr); kprintf("\tRepFrameSize 0x%04x\n", msg->CurReplyFrameSize); kprintf("\tMaxDevices 0x%02x\n", msg->MaxDevices); kprintf("\tMaxBuses 0x%02x\n", msg->MaxBuses); - kprintf("\tFWImageSize 0x%04x\n", (unsigned)msg->FWImageSize); + kprintf("\tFWImageSize 0x%04x\n", msg->FWImageSize); } static void @@ -415,9 +414,9 @@ mpt_print_scsi_io_reply(MSG_SCSI_IO_REPLY *msg) kprintf("\tCDBLength %d\n", msg->CDBLength); kprintf("\tSCSI Status: %s\n", mpt_scsi_status(msg->SCSIStatus)); kprintf("\tSCSI State: %s\n", mpt_scsi_state(msg->SCSIState)); - kprintf("\tTransferCnt 0x%04x\n", (unsigned)msg->TransferCount); - kprintf("\tSenseCnt 0x%04x\n", (unsigned)msg->SenseCount); - kprintf("\tResponseInfo 0x%08x\n", (unsigned)msg->ResponseInfo); + kprintf("\tTransferCnt 0x%04x\n", msg->TransferCount); + kprintf("\tSenseCnt 0x%04x\n", msg->SenseCount); + kprintf("\tResponseInfo 0x%08x\n", msg->ResponseInfo); } @@ -427,51 +426,50 @@ mpt_print_event_notice(MSG_EVENT_NOTIFY_REPLY *msg) { mpt_print_reply_hdr((MSG_DEFAULT_REPLY *)msg); kprintf("\tEvent: %s\n", mpt_ioc_event(msg->Event)); - kprintf("\tEventContext 0x%04x\n", (unsigned)msg->EventContext); + kprintf("\tEventContext 0x%04x\n", msg->EventContext); kprintf("\tAckRequired %d\n", msg->AckRequired); kprintf("\tEventDataLength %d\n", msg->EventDataLength); kprintf("\tContinuation %d\n", msg->MsgFlags & 0x80); switch(msg->Event) { case MPI_EVENT_LOG_DATA: - kprintf("\tEvtLogData: 0x%04x\n", - (unsigned)msg->Data[0]); + kprintf("\tEvtLogData: 0x%04x\n", msg->Data[0]); break; case MPI_EVENT_UNIT_ATTENTION: kprintf("\tTargetID: 0x%04x\n", - (unsigned)msg->Data[0] & 0xff); + msg->Data[0] & 0xff); kprintf("\tBus: 0x%04x\n", - (unsigned)(msg->Data[0] >> 8) & 0xff); + (msg->Data[0] >> 8) & 0xff); break; case MPI_EVENT_IOC_BUS_RESET: case MPI_EVENT_EXT_BUS_RESET: case MPI_EVENT_RESCAN: - kprintf("\tPort: %u\n", + kprintf("\tPort: %d\n", (msg->Data[0] >> 8) & 0xff); break; case MPI_EVENT_LINK_STATUS_CHANGE: - kprintf("\tLinkState: %u\n", + kprintf("\tLinkState: %d\n", msg->Data[0] & 0xff); - kprintf("\tPort: %u\n", + kprintf("\tPort: %d\n", (msg->Data[1] >> 8) & 0xff); break; case MPI_EVENT_LOOP_STATE_CHANGE: - kprintf("\tType: %u\n", + kprintf("\tType: %d\n", (msg->Data[0] >> 16) & 0xff); kprintf("\tChar3: 0x%02x\n", (msg->Data[0] >> 8) & 0xff); kprintf("\tChar4: 0x%02x\n", (msg->Data[0] ) & 0xff); - kprintf("\tPort: %u\n", + kprintf("\tPort: %d\n", (msg->Data[1] >> 8) & 0xff); break; case MPI_EVENT_LOGOUT: kprintf("\tN_PortId: 0x%04x\n", msg->Data[0]); - kprintf("\tPort: %u\n", + kprintf("\tPort: %d\n", (msg->Data[1] >> 8) & 0xff); break; } @@ -514,8 +512,8 @@ mpt_print_request_hdr(MSG_REQUEST_HEADER *req) { kprintf("%s @ %p\n", mpt_ioc_function(req->Function), req); kprintf("\tChain Offset 0x%02x\n", req->ChainOffset); - kprintf("\tMsgFlags 0x%02x\n", (unsigned)req->MsgFlags); - kprintf("\tMsgContext 0x%08x\n", (unsigned)req->MsgContext); + kprintf("\tMsgFlags 0x%02x\n", req->MsgFlags); + kprintf("\tMsgContext 0x%08x\n", req->MsgContext); } void @@ -530,7 +528,7 @@ mpt_print_scsi_io_request(MSG_SCSI_IO_REQUEST *orig_msg) kprintf("\tTargetID %d\n", msg->TargetID); kprintf("\tSenseBufferLength %d\n", msg->SenseBufferLength); kprintf("\tLUN: 0x%0x\n", msg->LUN[1]); - kprintf("\tControl 0x%08x ", (unsigned)msg->Control); + kprintf("\tControl 0x%08x ", msg->Control); #define MPI_PRINT_FIELD(x) \ case MPI_SCSIIO_CONTROL_ ## x : \ kprintf(" " #x " "); \ @@ -559,8 +557,8 @@ mpt_print_scsi_io_request(MSG_SCSI_IO_REQUEST *orig_msg) kprintf("\n"); #undef MPI_PRINT_FIELD - kprintf("\tDataLength\t0x%08x\n", (unsigned)msg->DataLength); - kprintf("\tSenseBufAddr\t0x%08x\n", (unsigned)msg->SenseBufferLowAddr); + kprintf("\tDataLength\t0x%08x\n", msg->DataLength); + kprintf("\tSenseBufAddr\t0x%08x\n", msg->SenseBufferLowAddr); kprintf("\tCDB[0:%d]\t", msg->CDBLength); for (i = 0; i < msg->CDBLength; i++) kprintf("%02x ", msg->CDB[i]); @@ -579,7 +577,7 @@ mpt_print_scsi_tmf_request(MSG_SCSI_TASK_MGMT *msg) mpt_print_request_hdr((MSG_REQUEST_HEADER *)msg); kprintf("\tLun 0x%02x\n", msg->LUN[1]); kprintf("\tTaskType %s\n", mpt_scsi_tm_type(msg->TaskType)); - kprintf("\tTaskMsgContext 0x%08x\n", (unsigned)msg->TaskMsgContext); + kprintf("\tTaskMsgContext 0x%08x\n", msg->TaskMsgContext); } @@ -590,10 +588,10 @@ mpt_print_scsi_target_assist_request(PTR_MSG_TARGET_ASSIST_REQUEST msg) kprintf("\tStatusCode 0x%02x\n", msg->StatusCode); kprintf("\tTargetAssist 0x%02x\n", msg->TargetAssistFlags); kprintf("\tQueueTag 0x%04x\n", msg->QueueTag); - kprintf("\tReplyWord 0x%08x\n", (unsigned)msg->ReplyWord); + kprintf("\tReplyWord 0x%08x\n", msg->ReplyWord); kprintf("\tLun 0x%02x\n", msg->LUN[1]); - kprintf("\tRelativeOff 0x%08x\n", (unsigned)msg->RelativeOffset); - kprintf("\tDataLength 0x%08x\n", (unsigned)msg->DataLength); + kprintf("\tRelativeOff 0x%08x\n", msg->RelativeOffset); + kprintf("\tDataLength 0x%08x\n", msg->DataLength); mpt_dump_sgl(msg->SGL, 0); } @@ -605,7 +603,7 @@ mpt_print_scsi_target_status_send_request(MSG_TARGET_STATUS_SEND_REQUEST *msg) kprintf("\tStatusCode 0x%02x\n", msg->StatusCode); kprintf("\tStatusFlags 0x%02x\n", msg->StatusFlags); kprintf("\tQueueTag 0x%04x\n", msg->QueueTag); - kprintf("\tReplyWord 0x%08x\n", (unsigned)msg->ReplyWord); + kprintf("\tReplyWord 0x%08x\n", msg->ReplyWord); kprintf("\tLun 0x%02x\n", msg->LUN[1]); x.u.Simple = msg->StatusDataSGE; mpt_dump_sgl(&x, 0); @@ -744,16 +742,12 @@ mpt_dump_sgl(SGE_IO_UNION *su, int offset) if (flags & MPI_SGE_FLAGS_64_BIT_ADDRESSING) { SGE_SIMPLE64 *se64 = (SGE_SIMPLE64 *)se; kprintf("SE64 %p: Addr=0x%08x%08x FlagsLength" - "=0x%0x\n", se64, - (unsigned)se64->Address.High, - (unsigned)se64->Address.Low, - (unsigned)se64->FlagsLength); + "=0x%0x\n", se64, se64->Address.High, + se64->Address.Low, se64->FlagsLength); nxtaddr = se64 + 1; } else { kprintf("SE32 %p: Addr=0x%0x FlagsLength=0x%0x" - "\n", se, - (unsigned)se->Address, - (unsigned)se->FlagsLength); + "\n", se, se->Address, se->FlagsLength); } kprintf(" "); break; @@ -762,20 +756,15 @@ mpt_dump_sgl(SGE_IO_UNION *su, int offset) SGE_CHAIN64 *ce64 = (SGE_CHAIN64 *) se; kprintf("CE64 %p: Addr=0x%08x%08x NxtChnO=0x%x " "Flgs=0x%x Len=0x%0x\n", ce64, - (unsigned)ce64->Address.High, - (unsigned)ce64->Address.Low, + ce64->Address.High, ce64->Address.Low, ce64->NextChainOffset, - (unsigned)ce64->Flags, - (unsigned)ce64->Length); + ce64->Flags, ce64->Length); nxtaddr = ce64 + 1; } else { SGE_CHAIN32 *ce = (SGE_CHAIN32 *) se; kprintf("CE32 %p: Addr=0x%0x NxtChnO=0x%x " - " Flgs=0x%x Len=0x%0x\n", ce, - (unsigned)ce->Address, - ce->NextChainOffset, - ce->Flags, - ce->Length); + " Flgs=0x%x Len=0x%0x\n", ce, ce->Address, + ce->NextChainOffset, ce->Flags, ce->Length); } flags = 0; break; @@ -830,13 +819,8 @@ mpt_dump_request(struct mpt_softc *mpt, request_t *req) { uint32_t *pReq = req->req_vbuf; int o; -#if __FreeBSD_version >= 500000 mpt_prt(mpt, "Send Request %d (%jx):", req->index, (uintmax_t) req->req_pbuf); -#else - mpt_prt(mpt, "Send Request %d (%llx):", - req->index, (unsigned long long) req->req_pbuf); -#endif for (o = 0; o < mpt->ioc_facts.RequestFrameSize; o++) { if ((o & 0x7) == 0) { mpt_prtc(mpt, "\n"); @@ -847,31 +831,6 @@ mpt_dump_request(struct mpt_softc *mpt, request_t *req) mpt_prtc(mpt, "\n"); } -#if __FreeBSD_version < 500000 -void -mpt_lprt(struct mpt_softc *mpt, int level, const char *fmt, ...) -{ - __va_list ap; - if (level <= mpt->verbose) { - kprintf("%s: ", device_get_nameunit(mpt->dev)); - __va_start(ap, fmt); - kvprintf(fmt, ap); - __va_end(ap); - } -} - -void -mpt_lprtc(struct mpt_softc *mpt, int level, const char *fmt, ...) -{ - __va_list ap; - if (level <= mpt->verbose) { - __va_start(ap, fmt); - kvprintf(fmt, ap); - __va_end(ap); - } -} -#endif - void mpt_prt(struct mpt_softc *mpt, const char *fmt, ...) { diff --git a/sys/dev/disk/mpt/mpt_pci.c b/sys/dev/disk/mpt/mpt_pci.c index 3ffbdcc..1af5ec4 100644 --- a/sys/dev/disk/mpt/mpt_pci.c +++ b/sys/dev/disk/mpt/mpt_pci.c @@ -97,21 +97,13 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/mpt/mpt_pci.c,v 1.54 2009/07/10 08:18:08 scottl Exp $ + * $FreeBSD: src/sys/dev/mpt/mpt_pci.c,v 1.61 2011/04/22 09:59:16 marius Exp $ */ #include #include #include -#if __FreeBSD_version < 700000 -#define pci_msix_count(x) 0 -#define pci_msi_count(x) 0 -#define pci_alloc_msi(x, y) 1 -#define pci_alloc_msix(x, y) 1 -#define pci_release_msi(x) do { ; } while (0) -#endif - #ifndef PCI_VENDOR_LSI #define PCI_VENDOR_LSI 0x1000 #endif @@ -193,8 +185,6 @@ #endif -#define MPT_IO_BAR 0 -#define MPT_MEM_BAR 1 static int mpt_pci_probe(device_t); static int mpt_pci_attach(device_t); @@ -279,7 +269,6 @@ mpt_pci_probe(device_t dev) return (0); } -#if __FreeBSD_version < 500000 static void mpt_set_options(struct mpt_softc *mpt) { @@ -340,38 +329,6 @@ mpt_set_options(struct mpt_softc *mpt) } mpt->msi_enable = 0; } -#else -static void -mpt_set_options(struct mpt_softc *mpt) -{ - int tval; - - tval = 0; - if (resource_int_value(device_get_name(mpt->dev), - device_get_unit(mpt->dev), "disable", &tval) == 0 && tval != 0) { - mpt->disabled = 1; - } - tval = 0; - if (resource_int_value(device_get_name(mpt->dev), - device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) { - mpt->verbose = tval; - } - tval = -1; - if (resource_int_value(device_get_name(mpt->dev), - device_get_unit(mpt->dev), "role", &tval) == 0 && tval >= 0 && - tval <= 3) { - mpt->cfg_role = tval; - mpt->do_cfg_role = 1; - } - - tval = 0; - mpt->msi_enable = 0; - if (resource_int_value(device_get_name(mpt->dev), - device_get_unit(mpt->dev), "msi_enable", &tval) == 0 && tval == 1) { - mpt->msi_enable = 1; - } -} -#endif static void @@ -419,6 +376,7 @@ mpt_pci_attach(device_t dev) struct mpt_softc *mpt; int iqd; uint32_t data, cmd; + int mpt_io_bar, mpt_mem_bar; /* Allocate the softc structure */ mpt = (struct mpt_softc*)device_get_softc(dev); @@ -459,6 +417,7 @@ mpt_pci_attach(device_t dev) mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT; mpt->verbose = MPT_PRT_NONE; mpt->role = MPT_ROLE_NONE; + mpt->mpt_ini_id = MPT_INI_ID_NONE; mpt_set_options(mpt); if (mpt->verbose == MPT_PRT_NONE) { mpt->verbose = MPT_PRT_WARN; @@ -484,7 +443,7 @@ mpt_pci_attach(device_t dev) * Make sure we've disabled the ROM. */ data = pci_read_config(dev, PCIR_BIOS, 4); - data &= ~1; + data &= ~PCIM_BIOS_ENABLE; pci_write_config(dev, PCIR_BIOS, data, 4); /* @@ -499,13 +458,27 @@ mpt_pci_attach(device_t dev) } /* + * Figure out which are the I/O and MEM Bars + */ + data = pci_read_config(dev, PCIR_BAR(0), 4); + if (PCI_BAR_IO(data)) { + /* BAR0 is IO, BAR1 is memory */ + mpt_io_bar = 0; + mpt_mem_bar = 1; + } else { + /* BAR0 is memory, BAR1 is IO */ + mpt_mem_bar = 0; + mpt_io_bar = 1; + } + + /* * Set up register access. PIO mode is required for * certain reset operations (but must be disabled for * some cards otherwise). */ - mpt->pci_pio_rid = PCIR_BAR(MPT_IO_BAR); - mpt->pci_pio_reg = bus_alloc_resource(dev, SYS_RES_IOPORT, - &mpt->pci_pio_rid, 0, ~0, 0, RF_ACTIVE); + mpt->pci_pio_rid = PCIR_BAR(mpt_io_bar); + mpt->pci_pio_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, + &mpt->pci_pio_rid, RF_ACTIVE); if (mpt->pci_pio_reg == NULL) { device_printf(dev, "unable to map registers in PIO mode\n"); goto bad; @@ -514,9 +487,9 @@ mpt_pci_attach(device_t dev) mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg); /* Allocate kernel virtual memory for the 9x9's Mem0 region */ - mpt->pci_mem_rid = PCIR_BAR(MPT_MEM_BAR); - mpt->pci_reg = bus_alloc_resource(dev, SYS_RES_MEMORY, - &mpt->pci_mem_rid, 0, ~0, 0, RF_ACTIVE); + mpt->pci_mem_rid = PCIR_BAR(mpt_mem_bar); + mpt->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &mpt->pci_mem_rid, RF_ACTIVE); if (mpt->pci_reg == NULL) { device_printf(dev, "Unable to memory map registers.\n"); if (mpt->is_sas) { @@ -568,14 +541,14 @@ mpt_pci_attach(device_t dev) mpt_disable_ints(mpt); /* Register the interrupt handler */ - if (mpt_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr, + if (mpt_setup_intr(dev, mpt->pci_irq, 0, NULL, mpt_pci_intr, mpt, &mpt->ih)) { device_printf(dev, "could not setup interrupt\n"); goto bad; } /* Allocate dma memory */ - /* XXX JGibbs -Should really be done based on IOCFacts. */ +/* XXX JGibbs -Should really be done based on IOCFacts. */ if (mpt_dma_mem_alloc(mpt)) { mpt_prt(mpt, "Could not allocate DMA memory\n"); goto bad; @@ -587,7 +560,7 @@ mpt_pci_attach(device_t dev) * Hard resets are known to screw up the BAR for diagnostic * memory accesses (Mem1). * - * Using Mem1 is known to make the chip stop responding to + * Using Mem1 is known to make the chip stop responding to * configuration space transfers, so we need to save it now */ @@ -714,9 +687,6 @@ mpt_pci_shutdown(device_t dev) static int mpt_dma_mem_alloc(struct mpt_softc *mpt) { - int i, error, nsegs; - uint8_t *vptr; - uint32_t pptr, end; size_t len; struct mpt_map_info mi; @@ -726,20 +696,11 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt) } len = sizeof (request_t) * MPT_MAX_REQUESTS(mpt); -#ifdef RELENG_4 - mpt->request_pool = (request_t *)kmalloc(len, M_DEVBUF, M_WAITOK); - if (mpt->request_pool == NULL) { - mpt_prt(mpt, "cannot allocate request pool\n"); - return (1); - } - memset(mpt->request_pool, 0, len); -#else mpt->request_pool = (request_t *)kmalloc(len, M_DEVBUF, M_WAITOK|M_ZERO); if (mpt->request_pool == NULL) { mpt_prt(mpt, "cannot allocate request pool\n"); return (1); } -#endif /* * Create a parent dma tag for this device. @@ -747,12 +708,12 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt) * Align at byte boundaries, * Limit to 32-bit addressing for request/reply queues. */ - if (mpt_dma_tag_create(mpt, /*parent*/bus_get_dma_tag(mpt->dev), + if (mpt_dma_tag_create(mpt, /*parent*/NULL, /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/BUS_SPACE_MAXSIZE_32BIT, - /*maxsegsz*/BUS_SPACE_UNRESTRICTED, /*flags*/0, + /*nsegments*/BUS_SPACE_UNRESTRICTED, + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, &mpt->parent_dmat) != 0) { mpt_prt(mpt, "cannot create parent dma tag\n"); return (1); @@ -767,7 +728,7 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt) return (1); } - /* Allocate some DMA accessable memory for replies */ + /* Allocate some DMA accessible memory for replies */ if (bus_dmamem_alloc(mpt->reply_dmat, (void **)&mpt->reply, BUS_DMA_NOWAIT, &mpt->reply_dmap) != 0) { mpt_prt(mpt, "cannot allocate %lu bytes of reply memory\n", @@ -789,107 +750,23 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt) } mpt->reply_phys = mi.phys; - /* Create a child tag for data buffers */ - - /* - * XXX: we should say that nsegs is 'unrestricted, but that - * XXX: tickles a horrible bug in the busdma code. Instead, - * XXX: we'll derive a reasonable segment limit from MPT_MAXPHYS - */ - nsegs = (MPT_MAXPHYS / PAGE_SIZE) + 1; - if (mpt_dma_tag_create(mpt, mpt->parent_dmat, 1, - 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, - NULL, NULL, MAXBSIZE, nsegs, BUS_SPACE_MAXSIZE_32BIT, 0, - &mpt->buffer_dmat) != 0) { - mpt_prt(mpt, "cannot create a dma tag for data buffers\n"); - return (1); - } - - /* Create a child tag for request buffers */ - if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, - NULL, NULL, MPT_REQ_MEM_SIZE(mpt), 1, BUS_SPACE_MAXSIZE_32BIT, 0, - &mpt->request_dmat) != 0) { - mpt_prt(mpt, "cannot create a dma tag for requests\n"); - return (1); - } - - /* Allocate some DMA accessable memory for requests */ - if (bus_dmamem_alloc(mpt->request_dmat, (void **)&mpt->request, - BUS_DMA_NOWAIT, &mpt->request_dmap) != 0) { - mpt_prt(mpt, "cannot allocate %d bytes of request memory\n", - MPT_REQ_MEM_SIZE(mpt)); - return (1); - } - - mi.mpt = mpt; - mi.error = 0; - - /* Load and lock it into "bus space" */ - bus_dmamap_load(mpt->request_dmat, mpt->request_dmap, mpt->request, - MPT_REQ_MEM_SIZE(mpt), mpt_map_rquest, &mi, 0); - - if (mi.error) { - mpt_prt(mpt, "error %d loading dma map for DMA request queue\n", - mi.error); - return (1); - } - mpt->request_phys = mi.phys; - - /* - * Now create per-request dma maps - */ - i = 0; - pptr = mpt->request_phys; - vptr = mpt->request; - end = pptr + MPT_REQ_MEM_SIZE(mpt); - while(pptr < end) { - request_t *req = &mpt->request_pool[i]; - req->index = i++; - - /* Store location of Request Data */ - req->req_pbuf = pptr; - req->req_vbuf = vptr; - - pptr += MPT_REQUEST_AREA; - vptr += MPT_REQUEST_AREA; - - req->sense_pbuf = (pptr - MPT_SENSE_SIZE); - req->sense_vbuf = (vptr - MPT_SENSE_SIZE); - - error = bus_dmamap_create(mpt->buffer_dmat, 0, &req->dmap); - if (error) { - mpt_prt(mpt, "error %d creating per-cmd DMA maps\n", - error); - return (1); - } - } - return (0); } -/* Deallocate memory that was allocated by mpt_dma_mem_alloc +/* Deallocate memory that was allocated by mpt_dma_mem_alloc */ static void mpt_dma_mem_free(struct mpt_softc *mpt) { - int i; /* Make sure we aren't double destroying */ if (mpt->reply_dmat == 0) { mpt_lprt(mpt, MPT_PRT_DEBUG, "already released dma memory\n"); return; } - - for (i = 0; i < MPT_MAX_REQUESTS(mpt); i++) { - bus_dmamap_destroy(mpt->buffer_dmat, mpt->request_pool[i].dmap); - } - bus_dmamap_unload(mpt->request_dmat, mpt->request_dmap); - bus_dmamem_free(mpt->request_dmat, mpt->request, mpt->request_dmap); - bus_dma_tag_destroy(mpt->request_dmat); - bus_dma_tag_destroy(mpt->buffer_dmat); + bus_dmamap_unload(mpt->reply_dmat, mpt->reply_dmap); bus_dmamem_free(mpt->reply_dmat, mpt->reply, mpt->reply_dmap); bus_dma_tag_destroy(mpt->reply_dmat); diff --git a/sys/dev/disk/mpt/mpt_raid.c b/sys/dev/disk/mpt/mpt_raid.c index 5af4bd0..a0662bb 100644 --- a/sys/dev/disk/mpt/mpt_raid.c +++ b/sys/dev/disk/mpt/mpt_raid.c @@ -39,7 +39,7 @@ * Support from LSI-Logic has also gone a great deal toward making this a * workable subsystem and is gratefully acknowledged. * - * $FreeBSD: src/sys/dev/mpt/mpt_raid.c,v 1.20 2009/05/21 12:36:40 jhb Exp $ + * $FreeBSD: src/sys/dev/mpt/mpt_raid.c,v 1.28 2011/01/12 19:53:56 mdf Exp $ */ #include @@ -51,13 +51,9 @@ #include #include #include -#include #include -#if __FreeBSD_version < 500000 #include -#define GIANT_REQUIRED -#endif #include #include @@ -119,11 +115,7 @@ static void mpt_enable_vol(struct mpt_softc *mpt, static void mpt_verify_mwce(struct mpt_softc *, struct mpt_raid_volume *); static void mpt_adjust_queue_depth(struct mpt_softc *, struct mpt_raid_volume *, struct cam_path *); -#if __FreeBSD_version < 500000 -#define mpt_raid_sysctl_attach(x) do { } while (0) -#else static void mpt_raid_sysctl_attach(struct mpt_softc *); -#endif static uint32_t raid_handler_id = MPT_HANDLER_ID_NONE; @@ -270,7 +262,7 @@ mpt_raid_attach(struct mpt_softc *mpt) mpt_handler_t handler; int error; - mpt_callout_init(&mpt->raid_timer); + mpt_callout_init(mpt, &mpt->raid_timer); error = mpt_spawn_raid_thread(mpt); if (error != 0) { @@ -320,9 +312,9 @@ mpt_raid_detach(struct mpt_softc *mpt) mpt_handler_t handler; callout_stop(&mpt->raid_timer); + MPT_LOCK(mpt); mpt_terminate_raid_thread(mpt); - handler.reply_handler = mpt_raid_reply_handler; mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler, raid_handler_id); @@ -450,9 +442,9 @@ mpt_raid_event(struct mpt_softc *mpt, request_t *req, if (print_event) { if (mpt_disk != NULL) { - mpt_disk_prt(mpt, mpt_disk, NULL); + mpt_disk_prt(mpt, mpt_disk, ""); } else if (mpt_vol != NULL) { - mpt_vol_prt(mpt, mpt_vol, NULL); + mpt_vol_prt(mpt, mpt_vol, ""); } else { mpt_prt(mpt, "Volume(%d:%d", raid_event->VolumeBus, raid_event->VolumeID); @@ -475,7 +467,7 @@ mpt_raid_event(struct mpt_softc *mpt, request_t *req, if (raid_event->ReasonCode == MPI_EVENT_RAID_RC_SMART_DATA) { /* XXX Use CAM's print sense for this... */ if (mpt_disk != NULL) - mpt_disk_prt(mpt, mpt_disk, NULL); + mpt_disk_prt(mpt, mpt_disk, ""); else mpt_prt(mpt, "Volume(%d:%d:%d: ", raid_event->VolumeBus, raid_event->VolumeID, @@ -646,20 +638,19 @@ mpt_terminate_raid_thread(struct mpt_softc *mpt) return; } mpt->shutdwn_raid = 1; - wakeup(mpt->raid_volumes); + wakeup(&mpt->raid_volumes); /* * Sleep on a slightly different location * for this interlock just for added safety. */ - mpt_sleep(mpt, &mpt->raid_thread, PUSER, "thtrm", 0); + mpt_sleep(mpt, &mpt->raid_thread, 0, "thtrm", 0); } static void mpt_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) { - - xpt_free_path(ccb->ccb_h.path); - xpt_free_ccb(ccb); + xpt_free_path(ccb->ccb_h.path); + kfree(ccb, M_TEMP); } static void @@ -670,14 +661,11 @@ mpt_raid_thread(void *arg) mpt = (struct mpt_softc *)arg; firstrun = 1; - - get_mplock(); MPT_LOCK(mpt); - while (mpt->shutdwn_raid == 0) { if (mpt->raid_wakeup == 0) { - mpt_sleep(mpt, &mpt->raid_volumes, PUSER, "idle", 0); + mpt_sleep(mpt, &mpt->raid_volumes, 0, "idle", 0); continue; } @@ -701,36 +689,37 @@ mpt_raid_thread(void *arg) if (mpt->raid_rescan != 0) { union ccb *ccb; - struct cam_path *path; int error; mpt->raid_rescan = 0; MPT_UNLOCK(mpt); - ccb = xpt_alloc_ccb(); + ccb = kmalloc(sizeof(union ccb), M_TEMP, + M_WAITOK | M_ZERO); MPT_LOCK(mpt); - error = xpt_create_path(&path, xpt_periph, + error = xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(mpt->phydisk_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); if (error != CAM_REQ_CMP) { - xpt_free_ccb(ccb); + kfree(ccb, M_TEMP); mpt_prt(mpt, "Unable to rescan RAID Bus!\n"); } else { - xpt_setup_ccb(&ccb->ccb_h, path, 5); + xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, + 5/*priority (low)*/); ccb->ccb_h.func_code = XPT_SCAN_BUS; ccb->ccb_h.cbfcnp = mpt_cam_rescan_callback; ccb->crcn.flags = CAM_FLAG_NONE; - MPTLOCK_2_CAMLOCK(mpt); xpt_action(ccb); - CAMLOCK_2_MPTLOCK(mpt); + + /* scan is now in progress */ } } } mpt->raid_thread = NULL; wakeup(&mpt->raid_thread); MPT_UNLOCK(mpt); - rel_mplock(); + mpt_kthread_exit(0); } #if 0 @@ -1064,6 +1053,7 @@ mpt_adjust_queue_depth(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol, xpt_setup_ccb(&crs.ccb_h, path, /*priority*/5); crs.ccb_h.func_code = XPT_REL_SIMQ; + crs.ccb_h.flags = CAM_DEV_QFREEZE; crs.release_flags = RELSIM_ADJUST_OPENINGS; crs.openings = mpt->raid_queue_depth; xpt_action((union ccb *)&crs); @@ -1190,10 +1180,10 @@ mpt_announce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk) disk_pg = &mpt_disk->config_page; mpt_disk_prt(mpt, mpt_disk, - "Physical (%s:%d:%d:0), Pass-thru (%s:%d:%jd:0)\n", + "Physical (%s:%d:%d:0), Pass-thru (%s:%d:%d:0)\n", device_get_nameunit(mpt->dev), rd_bus, disk_pg->PhysDiskID, device_get_nameunit(mpt->dev), - pt_bus, (intmax_t)(mpt_disk - mpt->raid_disks)); + pt_bus, mpt_disk - mpt->raid_disks); if (disk_pg->PhysDiskSettings.HotSparePool == 0) return; mpt_disk_prt(mpt, mpt_disk, "Member of Hot Spare Pool%s", @@ -1566,9 +1556,8 @@ mpt_raid_timer(void *arg) struct mpt_softc *mpt; mpt = (struct mpt_softc *)arg; - MPT_LOCK(mpt); + MPT_LOCK_ASSERT(mpt); mpt_raid_wakeup(mpt); - MPT_UNLOCK(mpt); } void @@ -1611,7 +1600,6 @@ mpt_raid_free_mem(struct mpt_softc *mpt) mpt->raid_max_disks = 0; } -#if __FreeBSD_version >= 500000 static int mpt_raid_set_vol_resync_rate(struct mpt_softc *mpt, u_int rate) { @@ -1743,8 +1731,6 @@ mpt_raid_sysctl_vol_member_wce(SYSCTL_HANDLER_ARGS) u_int size; u_int i; - GIANT_REQUIRED; - mpt = (struct mpt_softc *)arg1; str = mpt_vol_mwce_strs[mpt->raid_mwce_setting]; error = SYSCTL_OUT(req, str, strlen(str) + 1); @@ -1777,8 +1763,6 @@ mpt_raid_sysctl_vol_resync_rate(SYSCTL_HANDLER_ARGS) u_int raid_resync_rate; int error; - GIANT_REQUIRED; - mpt = (struct mpt_softc *)arg1; raid_resync_rate = mpt->raid_resync_rate; @@ -1797,8 +1781,6 @@ mpt_raid_sysctl_vol_queue_depth(SYSCTL_HANDLER_ARGS) u_int raid_queue_depth; int error; - GIANT_REQUIRED; - mpt = (struct mpt_softc *)arg1; raid_queue_depth = mpt->raid_queue_depth; @@ -1813,26 +1795,26 @@ mpt_raid_sysctl_vol_queue_depth(SYSCTL_HANDLER_ARGS) static void mpt_raid_sysctl_attach(struct mpt_softc *mpt) { - struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev); - struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev); - - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_PROC(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "vol_member_wce", CTLTYPE_STRING | CTLFLAG_RW, mpt, 0, mpt_raid_sysctl_vol_member_wce, "A", "volume member WCE(On,Off,On-During-Rebuild,NC)"); - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_PROC(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "vol_queue_depth", CTLTYPE_INT | CTLFLAG_RW, mpt, 0, mpt_raid_sysctl_vol_queue_depth, "I", "default volume queue depth"); - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_PROC(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "vol_resync_rate", CTLTYPE_INT | CTLFLAG_RW, mpt, 0, mpt_raid_sysctl_vol_resync_rate, "I", "volume resync priority (0 == NC, 1 - 255)"); - SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + SYSCTL_ADD_UINT(&mpt->mpt_sysctl_ctx, + SYSCTL_CHILDREN(mpt->mpt_sysctl_tree), OID_AUTO, "nonoptimal_volumes", CTLFLAG_RD, &mpt->raid_nonopt_volumes, 0, "number of nonoptimal volumes"); } -#endif diff --git a/sys/dev/disk/mpt/mpt_raid.h b/sys/dev/disk/mpt/mpt_raid.h index d16e127..24f18e4 100644 --- a/sys/dev/disk/mpt/mpt_raid.h +++ b/sys/dev/disk/mpt/mpt_raid.h @@ -56,10 +56,10 @@ typedef enum { const char *mpt_vol_type(struct mpt_raid_volume *); const char *mpt_vol_state(struct mpt_raid_volume *); const char *mpt_disk_state(struct mpt_raid_disk *); -void mpt_vol_prt(struct mpt_softc *, struct mpt_raid_volume *, - const char *, ...) __printf0like(3, 4); -void mpt_disk_prt(struct mpt_softc *, struct mpt_raid_disk *, - const char *, ...) __printf0like(3, 4); +void +mpt_vol_prt(struct mpt_softc *, struct mpt_raid_volume *, const char *fmt, ...); +void +mpt_disk_prt(struct mpt_softc *, struct mpt_raid_disk *, const char *, ...); int mpt_issue_raid_req(struct mpt_softc *, struct mpt_raid_volume *, diff --git a/sys/dev/disk/mpt/mpt_user.c b/sys/dev/disk/mpt/mpt_user.c index 5f72aa3..50d51af 100644 --- a/sys/dev/disk/mpt/mpt_user.c +++ b/sys/dev/disk/mpt/mpt_user.c @@ -29,14 +29,14 @@ * * LSI MPT-Fusion Host Adapter FreeBSD userland interface * - * $FreeBSD: src/sys/dev/mpt/mpt_user.c,v 1.4 2009/05/20 17:29:21 imp Exp $ + * $FreeBSD: src/sys/dev/mpt/mpt_user.c,v 1.5 2011/03/06 12:48:15 marius Exp $ */ #include #include +#include #include #include -#include #include #include @@ -77,11 +77,12 @@ DECLARE_MPT_PERSONALITY(mpt_user, SI_ORDER_SECOND); static mpt_reply_handler_t mpt_user_reply_handler; -static int mpt_open(struct dev_open_args *ap); -static int mpt_close(struct dev_close_args *ap); -static int mpt_ioctl(struct dev_ioctl_args *ap); +static d_open_t mpt_open; +static d_close_t mpt_close; +static d_ioctl_t mpt_ioctl; -static struct dev_ops mpt_cdevsw = { +static struct dev_ops mpt_ops = { + { "mpt", 0, 0 }, .d_open = mpt_open, .d_close = mpt_close, .d_ioctl = mpt_ioctl, @@ -115,7 +116,7 @@ mpt_user_attach(struct mpt_softc *mpt) return (error); } unit = device_get_unit(mpt->dev); - mpt->cdev = make_dev(&mpt_cdevsw, unit, UID_ROOT, GID_OPERATOR, 0640, + mpt->cdev = make_dev(&mpt_ops, unit, UID_ROOT, GID_OPERATOR, 0640, "mpt%d", unit); if (mpt->cdev == NULL) { MPT_LOCK(mpt); @@ -201,7 +202,7 @@ mpt_alloc_buffer(struct mpt_softc *mpt, struct mpt_page_memory *page_mem, if (error) return (error); error = bus_dmamem_alloc(page_mem->tag, &page_mem->vaddr, - BUS_DMA_NOWAIT, &page_mem->map); + BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &page_mem->map); if (error) { bus_dma_tag_destroy(page_mem->tag); return (error); @@ -299,6 +300,8 @@ mpt_user_read_cfg_page(struct mpt_softc *mpt, struct mpt_cfg_page_req *page_req, params.PageNumber = hdr->PageNumber; params.PageType = hdr->PageType & MPI_CONFIG_PAGETYPE_MASK; params.PageAddress = le32toh(page_req->page_address); + bus_dmamap_sync(mpt_page->tag, mpt_page->map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); error = mpt_issue_cfg_req(mpt, req, ¶ms, mpt_page->paddr, le32toh(page_req->len), TRUE, 5000); if (error != 0) { @@ -309,7 +312,7 @@ mpt_user_read_cfg_page(struct mpt_softc *mpt, struct mpt_cfg_page_req *page_req, page_req->ioc_status = htole16(req->IOCStatus); if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } @@ -387,6 +390,8 @@ mpt_user_read_extcfg_page(struct mpt_softc *mpt, params.PageAddress = le32toh(ext_page_req->page_address); params.ExtPageType = hdr->ExtPageType; params.ExtPageLength = hdr->ExtPageLength; + bus_dmamap_sync(mpt_page->tag, mpt_page->map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); error = mpt_issue_cfg_req(mpt, req, ¶ms, mpt_page->paddr, le32toh(ext_page_req->len), TRUE, 5000); if (error != 0) { @@ -397,7 +402,7 @@ mpt_user_read_extcfg_page(struct mpt_softc *mpt, ext_page_req->ioc_status = htole16(req->IOCStatus); if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } @@ -432,7 +437,8 @@ mpt_user_write_cfg_page(struct mpt_softc *mpt, if (req == NULL) return (ENOMEM); - bus_dmamap_sync(mpt_page->tag, mpt_page->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(mpt_page->tag, mpt_page->map, BUS_DMASYNC_PREREAD | + BUS_DMASYNC_PREWRITE); /* * There isn't any point in restoring stripped out attributes @@ -459,6 +465,8 @@ mpt_user_write_cfg_page(struct mpt_softc *mpt, } page_req->ioc_status = htole16(req->IOCStatus); + bus_dmamap_sync(mpt_page->tag, mpt_page->map, BUS_DMASYNC_POSTREAD | + BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } @@ -474,8 +482,6 @@ mpt_user_reply_handler(struct mpt_softc *mpt, request_t *req, return (TRUE); if (reply_frame != NULL) { - bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, - BUS_DMASYNC_POSTREAD); reply = (MSG_RAID_ACTION_REPLY *)reply_frame; req->IOCStatus = le16toh(reply->IOCStatus); res = (struct mpt_user_raid_action_result *) @@ -532,7 +538,7 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act, se = (SGE_SIMPLE32 *)&rap->ActionDataSGE; if (mpt_page->vaddr != NULL && raid_act->len != 0) { bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_PREWRITE); + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); se->Address = htole32(mpt_page->paddr); MPI_pSGE_SET_LENGTH(se, le32toh(raid_act->len)); MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | @@ -571,7 +577,7 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act, sizeof(res->action_data)); if (mpt_page->vaddr != NULL) bus_dmamap_sync(mpt_page->tag, mpt_page->map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); mpt_free_request(mpt, req); return (0); } @@ -584,6 +590,9 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act, static int mpt_ioctl(struct dev_ioctl_args *ap) { + cdev_t dev = ap->a_head.a_dev; + u_long cmd = ap->a_cmd; + caddr_t arg = ap->a_data; struct mpt_softc *mpt; struct mpt_cfg_page_req *page_req; struct mpt_ext_cfg_page_req *ext_page_req; @@ -597,12 +606,9 @@ mpt_ioctl(struct dev_ioctl_args *ap) struct mpt_raid_action32 *raid_act32; struct mpt_raid_action raid_act_swab; #endif - u_long cmd = ap->a_cmd; - caddr_t arg = ap->a_data; - struct cdev *kdev = ap->a_head.a_dev; int error; - mpt = kdev->si_drv1; + mpt = dev->si_drv1; page_req = (void *)arg; ext_page_req = (void *)arg; raid_act = (void *)arg; -- 1.7.4.4