diff options
author | mjacob <mjacob@FreeBSD.org> | 2002-09-23 19:41:10 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2002-09-23 19:41:10 +0000 |
commit | 7a5bb65c8f40e51112c6edafb46f0f02786fd23b (patch) | |
tree | eb4740a4dabcf359632c49b40b4da68cefcd2ebc /sys/dev/mpt | |
parent | ac315391ceb9f2631fcaa72a6ab3da6255a6598d (diff) | |
download | FreeBSD-src-7a5bb65c8f40e51112c6edafb46f0f02786fd23b.zip FreeBSD-src-7a5bb65c8f40e51112c6edafb46f0f02786fd23b.tar.gz |
Parameterize MPT_MAX_REQUESTS based upon device type (FC has Global Credits
of 1024- Ultra4 256). Rename 'requests' tag to 'request_pool' for clarity.
Make sure we do correct xpt_freeze_simq/CAM_RELEASE_SIMQ if we run out
of chip resources.
MFC after: 6 days
Diffstat (limited to 'sys/dev/mpt')
-rw-r--r-- | sys/dev/mpt/mpt.c | 17 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_freebsd.c | 117 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_freebsd.h | 10 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_pci.c | 37 |
4 files changed, 99 insertions, 82 deletions
diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c index 925fef6..628a107 100644 --- a/sys/dev/mpt/mpt.c +++ b/sys/dev/mpt/mpt.c @@ -227,7 +227,7 @@ mpt_reset(mpt_softc_t *mpt) void mpt_free_request(mpt_softc_t *mpt, request_t *req) { - if (req == NULL || req != &mpt->requests[req->index]) { + if (req == NULL || req != &mpt->request_pool[req->index]) { panic("mpt_free_request bad req ptr\n"); return; } @@ -244,7 +244,7 @@ mpt_get_request(mpt_softc_t *mpt) request_t *req; req = SLIST_FIRST(&mpt->request_free_list); if (req != NULL) { - if (req != &mpt->requests[req->index]) { + if (req != &mpt->request_pool[req->index]) { panic("mpt_get_request: corrupted request free list\n"); } if (req->ccb != NULL) { @@ -991,7 +991,7 @@ mpt_send_port_enable(mpt_softc_t *mpt, int port) do { DELAY(500); mpt_intr(mpt); - if (++count == 1000) { + if (++count == 100000) { device_printf(mpt->dev, "port enable timed out\n"); return (-1); } @@ -1064,8 +1064,8 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who) /* Put all request buffers (back) on the free list */ SLIST_INIT(&mpt->request_free_list); - for (val = 0; val < MPT_MAX_REQUESTS; val++) { - mpt_free_request(mpt, &mpt->requests[val]); + for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { + mpt_free_request(mpt, &mpt->request_pool[val]); } if (mpt->verbose > 1) { @@ -1111,7 +1111,7 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who) if (mpt->verbose > 1) { device_printf(mpt->dev, - "mpt_get_iocfacts: GlobalCredits=%d BlockSize=%u " + "IOCFACTS: GlobalCredits=%d BlockSize=%u " "Request Frame Size %u\n", facts.GlobalCredits, facts.BlockSize, facts.RequestFrameSize); } @@ -1125,8 +1125,9 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who) if (mpt->verbose > 1) { device_printf(mpt->dev, - "mpt_get_portfacts: Type %x PFlags %x IID %d\n", - pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID); + "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n", + pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID, + pfp.MaxDevices); } if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI && diff --git a/sys/dev/mpt/mpt_freebsd.c b/sys/dev/mpt/mpt_freebsd.c index f3ea82e..f3d8968 100644 --- a/sys/dev/mpt/mpt_freebsd.c +++ b/sys/dev/mpt/mpt_freebsd.c @@ -47,8 +47,8 @@ mpt_cam_attach(mpt_softc_t *mpt) int maxq; mpt->bus = 0; - maxq = (mpt->mpt_global_credits < MPT_MAX_REQUESTS)? - mpt->mpt_global_credits : MPT_MAX_REQUESTS; + maxq = (mpt->mpt_global_credits < MPT_MAX_REQUESTS(mpt))? + mpt->mpt_global_credits : MPT_MAX_REQUESTS(mpt); /* @@ -156,6 +156,7 @@ mpttimeout(void *arg) (void) timeout(mpttimeout2, (caddr_t)req, hz / 10); ccb->ccb_h.status = CAM_CMD_TIMEOUT; ccb->ccb_h.status |= CAM_RELEASE_SIMQ; + mpt->outofbeer = 0; MPTLOCK_2_CAMLOCK(mpt); xpt_done(ccb); CAMLOCK_2_MPTLOCK(mpt); @@ -213,7 +214,6 @@ mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) else ccb->ccb_h.status |= CAM_REQ_CMP_ERR; } - ccb->ccb_h.status |= CAM_RELEASE_SIMQ; ccb->ccb_h.status &= ~CAM_SIM_QUEUED; xpt_done(ccb); CAMLOCK_2_MPTLOCK(mpt); @@ -358,8 +358,6 @@ mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) CAMLOCK_2_MPTLOCK(mpt); mpt_free_request(mpt, req); MPTLOCK_2_CAMLOCK(mpt); - ccb->ccb_h.status |= CAM_RELEASE_SIMQ; - ccb->ccb_h.status &= ~CAM_SIM_QUEUED; xpt_done(ccb); return; } @@ -379,9 +377,7 @@ mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) MPTLOCK_2_CAMLOCK(mpt); } -/* Convert a CAM SCSI I/O ccb into a MPT request to pass the FC Chip */ -/* Including building a Scatter gather list of physical page to transfer */ -static int +static void mpt_start(union ccb *ccb) { request_t *req; @@ -396,8 +392,17 @@ mpt_start(union ccb *ccb) CAMLOCK_2_MPTLOCK(mpt); /* Get a request structure off the free list */ if ((req = mpt_get_request(mpt)) == NULL) { + if (mpt->outofbeer == 0) { + mpt->outofbeer = 1; + xpt_freeze_simq(mpt->sim, 1); + if (mpt->verbose > 1) { + device_printf(mpt->dev, "FREEZEQ\n"); + } + } MPTLOCK_2_CAMLOCK(mpt); - return (CAM_REQUEUE_REQ); + ccb->ccb_h.status = CAM_REQUEUE_REQ; + xpt_done(ccb); + return; } MPTLOCK_2_CAMLOCK(mpt); @@ -533,7 +538,6 @@ mpt_start(union ccb *ccb) } else { mpt_execute_req(req, NULL, 0, 0); } - return (CAM_REQ_INPROG); } static int @@ -602,11 +606,6 @@ mpt_ctlop(mpt_softc_t *mpt, void *vmsg, u_int32_t reply) mpt_event_notify_reply(mpt, vmsg); mpt_free_reply(mpt, (reply << 1)); } else if (dmsg->Function == MPI_FUNCTION_EVENT_ACK) { - MSG_EVENT_ACK_REPLY *evar = vmsg; - -device_printf(mpt->dev, "ack response reply context %x, status %x\n", -evar->MsgContext, evar->IOCStatus); - mpt_free_reply(mpt, (reply << 1)); } else if (dmsg->Function == MPI_FUNCTION_PORT_ENABLE) { MSG_PORT_ENABLE_REPLY *msg = vmsg; @@ -615,16 +614,16 @@ evar->MsgContext, evar->IOCStatus); device_printf(mpt->dev, "enable port reply idx %d\n", index); } - if (index >= 0 && index < MPT_MAX_REQUESTS) { - request_t *req = &mpt->requests[index]; + if (index >= 0 && index < MPT_MAX_REQUESTS(mpt)) { + request_t *req = &mpt->request_pool[index]; req->debug = REQ_DONE; } mpt_free_reply(mpt, (reply << 1)); } else if (dmsg->Function == MPI_FUNCTION_CONFIG) { MSG_CONFIG_REPLY *msg = vmsg; int index = msg->MsgContext & ~0x80000000; - if (index >= 0 && index < MPT_MAX_REQUESTS) { - request_t *req = &mpt->requests[index]; + if (index >= 0 && index < MPT_MAX_REQUESTS(mpt)) { + request_t *req = &mpt->request_pool[index]; req->debug = REQ_DONE; req->sequence = reply; } else { @@ -765,8 +764,6 @@ mpt_event_notify_reply(mpt_softc_t *mpt, MSG_EVENT_NOTIFY_REPLY *msg) if (msg->AckRequired) { MSG_EVENT_ACK *ackp; request_t *req; -device_printf(mpt->dev, "ack required for event %x context %x\n", -msg->Event, msg->EventContext); if ((req = mpt_get_request(mpt)) == NULL) { panic("unable to get request to acknowledge notify"); } @@ -775,7 +772,7 @@ msg->Event, msg->EventContext); ackp->Function = MPI_FUNCTION_EVENT_ACK; ackp->Event = msg->Event; ackp->EventContext = msg->EventContext; - ackp->MsgContext = req->index | 0x8000000; + ackp->MsgContext = req->index | 0x80000000; mpt_check_doorbell(mpt); mpt_send_cmd(mpt, req); } @@ -832,12 +829,12 @@ mpt_done(mpt_softc_t *mpt, u_int32_t reply) } /* Did we end up with a valid index into the table? */ - if (index < 0 || index >= MPT_MAX_REQUESTS) { + if (index < 0 || index >= MPT_MAX_REQUESTS(mpt)) { printf("mpt_done: invalid index (%x) in reply\n", index); return; } - req = &mpt->requests[index]; + req = &mpt->request_pool[index]; /* Make sure memory hasn't been trashed */ if (req->index != index) { @@ -907,6 +904,13 @@ mpt_done(mpt_softc_t *mpt, u_int32_t reply) ccb->ccb_h.status = CAM_REQ_CMP; ccb->csio.scsi_status = SCSI_STATUS_OK; ccb->ccb_h.status &= ~CAM_SIM_QUEUED; + if (mpt->outofbeer) { + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; + mpt->outofbeer = 0; + if (mpt->verbose > 1) { + device_printf(mpt->dev, "THAWQ\n"); + } + } MPTLOCK_2_CAMLOCK(mpt); xpt_done(ccb); CAMLOCK_2_MPTLOCK(mpt); @@ -1004,15 +1008,6 @@ device_printf(mpt->dev, "underrun, scsi status is %x\n", ccb->csio.scsi_status); ccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; } - /* - * I don't see the point of this - */ -#if 0 - if ((mpt_reply->MsgFlags & 0x80) == 0) { - ccb->ccb_h.status |= CAM_RELEASE_SIMQ; - } -#endif - if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { ccb->ccb_h.status |= CAM_DEV_QFRZN; @@ -1022,6 +1017,13 @@ device_printf(mpt->dev, "underrun, scsi status is %x\n", ccb->csio.scsi_status); ccb->ccb_h.status &= ~CAM_SIM_QUEUED; + if (mpt->outofbeer) { + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; + mpt->outofbeer = 0; + if (mpt->verbose > 1) { + device_printf(mpt->dev, "THAWQ\n"); + } + } MPTLOCK_2_CAMLOCK(mpt); xpt_done(ccb); CAMLOCK_2_MPTLOCK(mpt); @@ -1055,26 +1057,40 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) device_printf(mpt->dev, "XPT_RESET_BUS\n"); CAMLOCK_2_MPTLOCK(mpt); error = mpt_bus_reset(ccb); - MPTLOCK_2_CAMLOCK(mpt); switch (error) { case CAM_REQ_INPROG: - ccb->ccb_h.status |= CAM_SIM_QUEUED; + MPTLOCK_2_CAMLOCK(mpt); break; case CAM_REQUEUE_REQ: -device_printf(mpt->dev, "CAM_REQUEUE_REQ on bus reset"); - xpt_freeze_simq(sim, 1); + if (mpt->outofbeer == 0) { + mpt->outofbeer = 1; + xpt_freeze_simq(sim, 1); + if (mpt->verbose > 1) { + device_printf(mpt->dev, "FREEZEQ\n"); + } + } ccb->ccb_h.status = CAM_REQUEUE_REQ; + MPTLOCK_2_CAMLOCK(mpt); xpt_done(ccb); break; case CAM_REQ_CMP: ccb->ccb_h.status &= ~CAM_SIM_QUEUED; ccb->ccb_h.status |= CAM_REQ_CMP; + if (mpt->outofbeer) { + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; + mpt->outofbeer = 0; + if (mpt->verbose > 1) { + device_printf(mpt->dev, "THAWQ\n"); + } + } + MPTLOCK_2_CAMLOCK(mpt); xpt_done(ccb); break; default: ccb->ccb_h.status = CAM_REQ_CMP_ERR; + MPTLOCK_2_CAMLOCK(mpt); xpt_done(ccb); } break; @@ -1091,35 +1107,14 @@ device_printf(mpt->dev, "CAM_REQUEUE_REQ on bus reset"); } } /* Max supported CDB length is 16 bytes */ - if (ccb->csio.cdb_len > 16) { + if (ccb->csio.cdb_len > + sizeof (((PTR_MSG_SCSI_IO_REQUEST)0)->CDB)) { ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); return; } - ccb->csio.scsi_status = SCSI_STATUS_OK; - error = mpt_start(ccb); - switch (error) { - case CAM_REQ_INPROG: - ccb->ccb_h.status |= CAM_SIM_QUEUED; - break; - - case CAM_REQUEUE_REQ: -device_printf(mpt->dev, "CAM_REQUEUE_REQ on SCSI_IO"); - xpt_freeze_simq(sim, 1); - ccb->ccb_h.status = CAM_REQUEUE_REQ; - xpt_done(ccb); - break; - - case CAM_REQ_CMP: - ccb->ccb_h.status &= ~CAM_SIM_QUEUED; - xpt_done(ccb); - break; - - default: - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - xpt_done(ccb); - } + mpt_start(ccb); break; case XPT_ABORT: diff --git a/sys/dev/mpt/mpt_freebsd.h b/sys/dev/mpt/mpt_freebsd.h index 6e7cbb4..4afcfe8 100644 --- a/sys/dev/mpt/mpt_freebsd.h +++ b/sys/dev/mpt/mpt_freebsd.h @@ -122,12 +122,12 @@ /* Max MPT Reply we are willing to accept (must be power of 2) */ -#define MPT_REPLY_SIZE 128 +#define MPT_REPLY_SIZE 128 -#define MPT_MAX_REQUESTS 256 /* XXX: should be derived from GlobalCredits */ +#define MPT_MAX_REQUESTS(mpt) ((mpt)->is_fc? 1024 : 256) #define MPT_REQUEST_AREA 512 #define MPT_SENSE_SIZE 32 /* included in MPT_REQUEST_SIZE */ -#define MPT_REQ_MEM_SIZE (MPT_MAX_REQUESTS * MPT_REQUEST_AREA) +#define MPT_REQ_MEM_SIZE(mpt) (MPT_MAX_REQUESTS(mpt) * MPT_REQUEST_AREA) /* * We cannot tell prior to getting IOC facts how big the IOC's request @@ -208,7 +208,7 @@ typedef struct mpt_softc { u_int32_t : 16, unit : 8, verbose : 3, - : 1, + outofbeer : 1, mpt_locksetup : 1, disabled : 1, is_fc : 1, @@ -291,7 +291,7 @@ typedef struct mpt_softc { * CAM && Software Management */ - request_t requests[MPT_MAX_REQUESTS]; + request_t * request_pool; SLIST_HEAD(req_queue, req_entry) request_free_list; struct cam_sim * sim; diff --git a/sys/dev/mpt/mpt_pci.c b/sys/dev/mpt/mpt_pci.c index d9e3ab6..499dc85 100644 --- a/sys/dev/mpt/mpt_pci.c +++ b/sys/dev/mpt/mpt_pci.c @@ -468,12 +468,31 @@ mpt_dma_mem_alloc(mpt_softc_t *mpt) int i, error; u_char *vptr; u_int32_t pptr, end; + size_t len; struct imush im; device_t dev = mpt->dev; /* Check if we alreay have allocated the reply memory */ - if (mpt->reply_phys != NULL) + if (mpt->reply_phys != NULL) { return 0; + } + + len = sizeof (request_t *) * MPT_REQ_MEM_SIZE(mpt); +#ifdef RELENG_4 + mpt->request_pool = (request_t *) malloc(len, M_DEVBUF, M_WAITOK); + if (mpt->request_pool == NULL) { + device_printf(dev, "cannot allocate request pool\n"); + return (1); + } + bzero(mpt->request_pool, len); +#else + mpt->request_pool = (request_t *) + malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + if (mpt->request_pool == NULL) { + device_printf(dev, "cannot allocate request pool\n"); + return (1); + } +#endif /* * Create a dma tag for this device @@ -533,7 +552,7 @@ mpt_dma_mem_alloc(mpt_softc_t *mpt) /* Create a child tag for request buffers */ if (bus_dma_tag_create(mpt->parent_dmat, PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, - NULL, NULL, MPT_REQ_MEM_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0, + NULL, NULL, MPT_REQ_MEM_SIZE(mpt), 1, BUS_SPACE_MAXSIZE_32BIT, 0, &mpt->request_dmat) != 0) { device_printf(dev, "cannot create a dma tag for requests\n"); return (1); @@ -544,7 +563,7 @@ mpt_dma_mem_alloc(mpt_softc_t *mpt) BUS_DMA_NOWAIT, &mpt->request_dmap) != 0) { device_printf(dev, "cannot allocate %d bytes of request memory\n", - MPT_REQ_MEM_SIZE); + MPT_REQ_MEM_SIZE(mpt)); return (1); } @@ -553,7 +572,7 @@ mpt_dma_mem_alloc(mpt_softc_t *mpt) /* Load and lock it into "bus space" */ bus_dmamap_load(mpt->request_dmat, mpt->request_dmap, mpt->request, - MPT_REQ_MEM_SIZE, mpt_map_rquest, &im, 0); + MPT_REQ_MEM_SIZE(mpt), mpt_map_rquest, &im, 0); if (im.error) { device_printf(dev, @@ -566,9 +585,9 @@ mpt_dma_mem_alloc(mpt_softc_t *mpt) i = 0; pptr = mpt->request_phys; vptr = mpt->request; - end = pptr + MPT_REQ_MEM_SIZE; + end = pptr + MPT_REQ_MEM_SIZE(mpt); while(pptr < end) { - request_t *req = &mpt->requests[i]; + request_t *req = &mpt->request_pool[i]; req->index = i++; /* Store location of Request Data */ @@ -607,8 +626,8 @@ mpt_dma_mem_free(mpt_softc_t *mpt) return; } - for (i = 0; i < MPT_MAX_REQUESTS; i++) { - bus_dmamap_destroy(mpt->buffer_dmat, mpt->requests[i].dmap); + 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); @@ -619,6 +638,8 @@ mpt_dma_mem_free(mpt_softc_t *mpt) bus_dma_tag_destroy(mpt->reply_dmat); bus_dma_tag_destroy(mpt->parent_dmat); mpt->reply_dmat = 0; + free(mpt->request_pool, M_DEVBUF); + mpt->request_pool = 0; } |