summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpt
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2002-09-23 19:41:10 +0000
committermjacob <mjacob@FreeBSD.org>2002-09-23 19:41:10 +0000
commit7a5bb65c8f40e51112c6edafb46f0f02786fd23b (patch)
treeeb4740a4dabcf359632c49b40b4da68cefcd2ebc /sys/dev/mpt
parentac315391ceb9f2631fcaa72a6ab3da6255a6598d (diff)
downloadFreeBSD-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.c17
-rw-r--r--sys/dev/mpt/mpt_freebsd.c117
-rw-r--r--sys/dev/mpt/mpt_freebsd.h10
-rw-r--r--sys/dev/mpt/mpt_pci.c37
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;
}
OpenPOWER on IntegriCloud