summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>1998-09-17 21:11:21 +0000
committermjacob <mjacob@FreeBSD.org>1998-09-17 21:11:21 +0000
commit2b203e82ec863b8db570bd9c6f4d5695db6b9a2e (patch)
tree0b024c4aab7471ee06017e317141e4adf057884a /sys/dev/isp
parent45723eb95751314770578c8bf21f7ddf8b633ae8 (diff)
downloadFreeBSD-src-2b203e82ec863b8db570bd9c6f4d5695db6b9a2e.zip
FreeBSD-src-2b203e82ec863b8db570bd9c6f4d5695db6b9a2e.tar.gz
A major amount of cleaning up:
+ Change some messages about CCB memory allocation + Turn a failure to DMA map all of a transaction due to lack of ISP queue entries into a requeue operation (instead of the case where it had been treated the same as a DMA too big operation). + put back splsoftvm around bus_dmamap_load calls. + cleanup (and fix a glaring bug) in the and of the dma setup routine. Also, the dma setup routines either return CMD_QUEUED (for success) or CMD_COMPLETE (for failure) or CMD_EAGAIN (for requeuing for resource shortage reasons).
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp_pci.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 909bea5..f0d7a75 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1,5 +1,4 @@
/* $FreeBSD$ */
-/* $Id: isp_pci.c,v 1.4 1998/09/15 10:06:22 gibbs Exp $ */
/*
* PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
* FreeBSD Version.
@@ -477,7 +476,8 @@ isp_pci_mbxdma(isp)
}
if (bus_dmamem_alloc(pci->cntrol_dmat, (void **)&base,
BUS_DMA_NOWAIT, &pci->cntrol_dmap) != 0) {
- printf("%s: cannot allocate CCB memory\n", isp->isp_name);
+ printf("%s: cannot allocate %d bytes of CCB memory\n",
+ isp->isp_name, len);
return (1);
}
@@ -503,7 +503,7 @@ isp_pci_mbxdma(isp)
for (i = 0; i < MAXISPREQUEST; i++) {
error = bus_dmamap_create(pci->parent_dmat, 0, &pci->dmaps[i]);
if (error) {
- printf("%s: error %d creating data DMA maps\n",
+ printf("%s: error %d creating mailbox DMA maps\n",
isp->isp_name, error);
return (1);
}
@@ -521,6 +521,8 @@ typedef struct {
u_int error;
} mush_t;
+#define MUSHERR_NOQENTRIES -2
+
static void
dma2(arg, dm_segs, nseg, error)
void *arg;
@@ -611,15 +613,14 @@ dma2(arg, dm_segs, nseg, error)
dm_segs++;
}
- if (datalen == 0)
- return;
-
while (datalen > 0 && dm_segs != eseg) {
crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
- *iptrp = (*iptrp + 1) & (RQUEST_QUEUE_LEN - 1);
+ *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN);
if (*iptrp == optr) {
- printf("%s: Request Queue Overflow+\n", isp->isp_name);
- mp->error = EFBIG;
+#if 0
+ printf("%s: Request Queue Overflow++\n", isp->isp_name);
+#endif
+ mp->error = MUSHERR_NOQENTRIES;
return;
}
rq->req_header.rqs_entry_count++;
@@ -666,13 +667,13 @@ isp_pci_dmasetup(isp, ccb, rq, iptrp, optr)
if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE) {
rq->req_seg_count = 1;
- return (0);
+ return (CMD_QUEUED);
}
dp = &pci->dmaps[rq->req_handle - 1];
/*
* Do a virtual grapevine step to collect info for
- * a callback method we really didn't want.
+ * the callback dma allocation that we have to use...
*/
mp = &mush;
mp->isp = isp;
@@ -684,34 +685,20 @@ isp_pci_dmasetup(isp, ccb, rq, iptrp, optr)
if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) {
if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
- int error;
- /*
- * spls are spls, locks are locks.
- * it isn't clear whether splsoftvm, if s spl,
- * is a RAISE over splcam, or not.
- */
-#if 0
- int s;
+ int error, s;
+
s = splsoftvm();
-#endif
error = bus_dmamap_load(pci->parent_dmat, *dp,
csio->data_ptr, csio->dxfer_len, dma2, mp, 0);
-#if 0
- splx(s);
-#endif
if (error == EINPROGRESS) {
- /*
- * We simply aren't going to support
- * this at this time. This mechanism
- * is too rigid for my taste.
- */
- printf("%s: sorry, we're not doing bounceio\n",
- isp->isp_name);
bus_dmamap_unload(pci->parent_dmat, *dp);
mp->error = EINVAL;
+ printf("%s: deferred dma allocation not "
+ "supported\n", isp->isp_name);
} else if (error && mp->error == 0) {
mp->error = error;
}
+ splx(s);
} else {
/* Pointer to physical buffer */
struct bus_dma_segment seg;
@@ -726,7 +713,7 @@ isp_pci_dmasetup(isp, ccb, rq, iptrp, optr)
printf("%s: Physical segment pointers unsupported",
isp->isp_name);
mp->error = EINVAL;
- } else if ((ccb_h->flags&CAM_SG_LIST_PHYS) == 0) {
+ } else if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) {
printf("%s: Virtual segment addresses unsupported",
isp->isp_name);
mp->error = EINVAL;
@@ -737,20 +724,21 @@ isp_pci_dmasetup(isp, ccb, rq, iptrp, optr)
}
}
if (mp->error) {
- if (mp->error != EFBIG) {
- printf("%s: Unexepected error 0x%x returned from "
- "bus_dmamap_load\n", isp->isp_name, mp->error);
- ccb_h->status = CAM_REQ_TOO_BIG;
+ int retval = CMD_COMPLETE;
+ if (mp->error == MUSHERR_NOQENTRIES) {
+ retval = CMD_EAGAIN;
+ ccb_h->status = CAM_UNREC_HBA_ERROR;
+ } else if (mp->error == EFBIG) {
+ ccb_h->status = CAM_REQ_TOO_BIG;
} else if (mp->error == EINVAL) {
ccb_h->status = CAM_REQ_INVALID;
} else {
ccb_h->status = CAM_UNREC_HBA_ERROR;
}
- ccb_h->status |= CAM_DEV_QFRZN;
- printf("%s:isp_pci_dmasetup->xpt_freeze_devq\n", isp->isp_name);
- xpt_freeze_devq(ccb_h->path, 1);
+ return (retval);
+ } else {
+ return (CMD_QUEUED);
}
- return (mp->error);
}
static void
@@ -835,7 +823,7 @@ isp_pci_dmasetup(isp, xs, rq, iptrp, optr)
if (xs->datalen == 0) {
rq->req_seg_count = 1;
- return (0);
+ return (CMD_QUEUED);
}
if (xs->flags & SCSI_DATA_IN) {
@@ -902,16 +890,16 @@ isp_pci_dmasetup(isp, xs, rq, iptrp, optr)
if (datalen == 0)
- return (0);
+ return (CMD_QUEUED);
paddr = vtophys(vaddr);
while (datalen > 0) {
crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
- *iptrp = (*iptrp + 1) & (RQUEST_QUEUE_LEN - 1);
+ *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN);
if (*iptrp == optr) {
printf("%s: Request Queue Overflow\n", isp->isp_name);
XS_SETERR(xs, HBA_BOTCH);
- return (EFBIG);
+ return (CMD_EAGAIN);
}
rq->req_header.rqs_entry_count++;
bzero((void *)crq, sizeof (*crq));
@@ -945,7 +933,7 @@ isp_pci_dmasetup(isp, xs, rq, iptrp, optr)
}
}
- return (0);
+ return (CMD_QUEUED);
}
#endif
OpenPOWER on IntegriCloud