Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Change adw_isr_callback() status handler
details: https://anonhg.NetBSD.org/src/rev/7f240e8a7f47
branches: trunk
changeset: 486001:7f240e8a7f47
user: dante <dante%NetBSD.org@localhost>
date: Wed May 10 21:22:34 2000 +0000
description:
Change adw_isr_callback() status handler
Add a catch for DMA Error which show up on Intel 82443BX Host Bridge/Controller (rev. 0x03). This doesn't fix the problem, but reset the SCSI bus and reinitialize the host adapter
Minor cosmetical changes
Thanks a lot to Greg Oster and Andan Lauber
diffstat:
sys/dev/ic/adw.c | 122 +++++++++++++++++++++----------------
sys/dev/ic/adw.h | 23 +++---
sys/dev/ic/adwlib.c | 101 +++++++++++++++++--------------
sys/dev/ic/adwlib.h | 168 ++++++++++++++++++---------------------------------
4 files changed, 196 insertions(+), 218 deletions(-)
diffs (truncated from 774 to 300 lines):
diff -r 3efffc4a2843 -r 7f240e8a7f47 sys/dev/ic/adw.c
--- a/sys/dev/ic/adw.c Wed May 10 20:35:35 2000 +0000
+++ b/sys/dev/ic/adw.c Wed May 10 21:22:34 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: adw.c,v 1.19 2000/05/08 17:21:33 dante Exp $ */
+/* $NetBSD: adw.c,v 1.20 2000/05/10 21:22:34 dante Exp $ */
/*
* Generic driver for the Advanced Systems Inc. SCSI controllers
@@ -231,10 +231,10 @@
for(i=0; i < ADW_MAX_CARRIER; i++) {
carr = (ADW_CARRIER *)(((u_int8_t *)sc->sc_control->carriers) +
(sizeof(ADW_CARRIER) * i));
- carr->carr_pa = ADW_CARRIER_BADDR(sc, carr);
+ carr->carr_ba = ADW_CARRIER_BADDR(sc, carr);
carr->carr_id = i;
- carr->next_vpa = carr_next;
- carr_next = carr->carr_pa;
+ carr->next_ba = carr_next;
+ carr_next = carr->carr_ba;
}
sc->carr_freelist = carr;
return (i);
@@ -1015,15 +1015,12 @@
s = splbio();
- /*
- * If it has been through before, then previous aborts failed,
- * don't try abort again, reset the bus instead.
- */
if (ccb->flags & CCB_ABORTED) {
/*
* Abort Timed Out
*
- * No more opportunities. Lets try resetting the bus!
+ * No more opportunities. Lets try resetting the bus and
+ * reinitialize the host adapter.
*/
callout_stop(&xs->xs_callout);
@@ -1041,7 +1038,7 @@
return;
} else if (ccb->flags & CCB_ABORTING) {
/*
- * Abort the operation that has timed out
+ * Abort the operation that has timed out.
*
* Second opportunity.
*/
@@ -1070,12 +1067,11 @@
* by hand so the next time a timeout event will occour
* we will reset the bus.
*/
- callout_stop(&xs->xs_callout);
callout_reset(&xs->xs_callout,
(ccb->timeout * hz) / 1000, adw_timeout, ccb);
} else {
/*
- * Abort the operation that has timed out
+ * Abort the operation that has timed out.
*
* First opportunity.
*/
@@ -1101,10 +1097,9 @@
#endif
/*
* waiting for multishot callout_reset() let's restart it
- * by hand so the next time a timeout event will occour
- * we will reset the bus.
+ * by hand so to give a second opportunity to the command
+ * which timed-out.
*/
- callout_stop(&xs->xs_callout);
callout_reset(&xs->xs_callout,
(ccb->timeout * hz) / 1000, adw_timeout, ccb);
}
@@ -1127,7 +1122,11 @@
bus_space_handle_t ioh = sc->sc_ioh;
u_int16_t wdtr_able, wdtr_done, wdtr;
u_int16_t sdtr_able, sdtr_done, sdtr, period;
- int wdtr_reneg = 0, sdtr_reneg = 0;
+ static int wdtr_reneg = 0, sdtr_reneg = 0;
+
+ if (tid == 0){
+ wdtr_reneg = sdtr_reneg = 0;
+ }
printf("%s: target %d ", sc->sc_dev.dv_xname, tid);
@@ -1226,37 +1225,32 @@
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(dmat, ccb->dmamap_xfer);
}
+
if ((ccb->flags & CCB_ALLOC) == 0) {
printf("%s: exiting ccb not allocated!\n", sc->sc_dev.dv_xname);
Debugger();
return;
}
- /*
- * Check for an underrun condition.
- */
- /*
- * if (xs->request_bufflen != 0 && scsiqp->data_cnt != 0) {
- * ASC_DBG1(1, "adw_isr_callback: underrun condition %lu bytes\n",
- * scsiqp->data_cnt); underrun = ASC_TRUE; }
- */
+
/*
* 'done_status' contains the command's ending status.
+ * 'host_status' conatins the host adapter status.
+ * 'scsi_status' contains the scsi peripheral status.
*/
switch (scsiq->done_status) {
case QD_NO_ERROR:
- switch (scsiq->host_status) {
- case QHSTA_NO_ERROR:
- xs->error = XS_NOERROR;
- xs->resid = 0;
- if (scsiq->cdb[0] == INQUIRY &&
- scsiq->target_lun == 0) {
- adw_print_info(sc, scsiq->target_id);
- }
- break;
- default:
- /* QHSTA error occurred. */
- xs->error = XS_DRIVER_STUFFUP;
- break;
+ xs->error = XS_NOERROR;
+ xs->resid = scsiq->data_cnt;
+#ifdef ADW_DEBUG
+ /* Check for an underrun condition. */
+ if ((xs->datalen != 0) && (scsiq->data_cnt != 0) &&
+ (scsiq->data_cnt <= xs->datalen)) {
+ printf("%s: underrun condition %d bytes\n",
+ sc->sc_dev.dv_xname, scsiq->data_cnt);
+ }
+#endif
+ if ((scsiq->cdb[0] == INQUIRY) && (scsiq->target_lun == 0)) {
+ adw_print_info(sc, scsiq->target_id);
}
break;
@@ -1265,44 +1259,66 @@
case QHSTA_NO_ERROR:
switch(scsiq->scsi_status) {
case SS_CHK_CONDITION:
- case SS_CMD_TERMINATED:
s1 = &ccb->scsi_sense;
s2 = &xs->sense.scsi_sense;
*s2 = *s1;
xs->error = XS_SENSE;
break;
- case SS_TARGET_BUSY:
- case SS_RSERV_CONFLICT:
- case SS_QUEUE_FULL:
+
+ default:
xs->error = XS_DRIVER_STUFFUP;
- break;
- case SS_CONDITION_MET:
- case SS_INTERMID:
- case SS_INTERMID_COND_MET:
- xs->error = XS_DRIVER_STUFFUP;
- break;
- case SS_GOOD:
+#ifdef ADW_DEBUG
+ printf("%s: Command %d completed with error."
+ " SCSI Status = %d\n",
+ sc->sc_dev.dv_xname, scsiq->cdb[0],
+ scsiq->scsi_status);
+#endif
break;
}
break;
- case QHSTA_M_SEL_TIMEOUT:
- xs->error = XS_DRIVER_STUFFUP;
- break;
+ case QHSTA_M_SXFR_SDMA_ERR:
+ /*
+ * SCSI DMA Error. This should *NEVER* happen!
+ *
+ * Lets try resetting the bus and reinitialize
+ * the host adapter.
+ */
+ AdvResetSCSIBus(sc);
+ while((ccb = TAILQ_LAST(&sc->sc_pending_ccb,
+ adw_pending_ccb)) != NULL) {
+ callout_stop(&ccb->xs->xs_callout);
+ TAILQ_REMOVE(&sc->sc_pending_ccb, ccb, chain);
+ TAILQ_INSERT_HEAD(&sc->sc_waiting_ccb, ccb, chain);
+ }
+ adw_queue_ccb(sc, TAILQ_FIRST(&sc->sc_waiting_ccb), 1);
+ return;
default:
- /* Some other QHSTA error occurred. */
xs->error = XS_DRIVER_STUFFUP;
+#ifdef ADW_DEBUG
+ printf("%s: Command %d completed with error."
+ " Host Status = %d\n",
+ sc->sc_dev.dv_xname, scsiq->cdb[0],
+ scsiq->host_status);
+#endif
break;
}
break;
case QD_ABORTED_BY_HOST:
xs->error = XS_DRIVER_STUFFUP;
+ printf("%s: Command aborted by host.\n", sc->sc_dev.dv_xname);
break;
default:
xs->error = XS_DRIVER_STUFFUP;
+#ifdef ADW_DEBUG
+ printf("%s: Command %d completed with error."
+ " Done Status = %d\n",
+ sc->sc_dev.dv_xname, scsiq->cdb[0],
+ scsiq->done_status);
+#endif
break;
}
@@ -1334,6 +1350,8 @@
* Handle RDMA failure by resetting the SCSI Bus and
* possibly the chip if it is unresponsive.
*/
+ printf("%s: RDMA failure. Resetting the SCSI Bus and"
+ " the adapter\n", sc->sc_dev.dv_xname);
AdvResetSCSIBus(sc);
break;
diff -r 3efffc4a2843 -r 7f240e8a7f47 sys/dev/ic/adw.h
--- a/sys/dev/ic/adw.h Wed May 10 20:35:35 2000 +0000
+++ b/sys/dev/ic/adw.h Wed May 10 21:22:34 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: adw.h,v 1.7 2000/05/08 17:21:34 dante Exp $ */
+/* $NetBSD: adw.h,v 1.8 2000/05/10 21:22:34 dante Exp $ */
/*
* Generic driver definitions and exported functions for the Advanced
@@ -54,31 +54,32 @@
struct adw_carrier {
/* ---------- the microcode wants the field below ---------- */
u_int32_t carr_id; /* Carrier ID */
- u_int32_t carr_pa; /* Carrier Physical Address */
- u_int32_t areq_vpa; /* ADW_SCSI_REQ_Q Physical Address */
+ u_int32_t carr_ba; /* Carrier Bus Address */
+ u_int32_t areq_ba; /* ADW_SCSI_REQ_Q Bus Address */
/*
* next_vpa [31:4] Carrier Physical Next Pointer
*
* next_vpa [3:1] Reserved Bits
* next_vpa [0] Done Flag set in Response Queue.
*/
- u_int32_t next_vpa;
+ u_int32_t next_ba; /* see next_ba flags below */
/* ---------- ---------- */
};
typedef struct adw_carrier ADW_CARRIER;
+/*
+ * next_ba flags
+ */
+#define ASC_RQ_DONE 0x00000001
+#define ASC_RQ_GOOD 0x00000002
+#define ASC_CQ_STOPPER 0x00000000
/*
* Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
*/
-#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
-
-#define ASC_RQ_DONE 0x00000001
-#define ASC_RQ_GOOD 0x00000002
-#define ASC_CQ_STOPPER 0x00000000
-
-#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
+#define ASC_NEXT_BA_MASK 0xFFFFFFF0
+#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_BA_MASK)
/*
diff -r 3efffc4a2843 -r 7f240e8a7f47 sys/dev/ic/adwlib.c
--- a/sys/dev/ic/adwlib.c Wed May 10 20:35:35 2000 +0000
+++ b/sys/dev/ic/adwlib.c Wed May 10 21:22:34 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: adwlib.c,v 1.11 2000/05/08 17:21:34 dante Exp $ */
+/* $NetBSD: adwlib.c,v 1.12 2000/05/10 21:22:34 dante Exp $ */
/*
* Low level routines for the Advanced Systems Inc. SCSI controllers chips
@@ -684,17 +684,17 @@
return ASC_IERR_NO_CARRIER;
}
sc->carr_freelist = adw_carrier_phys_kv(sc,
Home |
Main Index |
Thread Index |
Old Index