Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci fix issues when reading variable block sized tapes.
details: https://anonhg.NetBSD.org/src/rev/15f15b1cac75
branches: trunk
changeset: 789161:15f15b1cac75
user: kardel <kardel%NetBSD.org@localhost>
date: Fri Aug 09 19:51:29 2013 +0000
description:
fix issues when reading variable block sized tapes.
symptoms:
generic HBA error on console when reading
with a larger blocksize. blocks read
are padded to requested block size with
a 5a... a5... pattern.
problems fixed:
- controller scsi_status values did not match
the ones used by the spsipi layer.
a mapping function was introduced.
- when experiencing an underrun (read 64k and
get a 63k block) the controller posted
not a SUCCESS status but CHECK status. handle
that like SUCCESS adjusting xs->resid and set
XS_SENSE.
now the correct data amount is returned and
nothing is 'added' and no 'generic HBA error'
occurs.
- make decisions using variables and constants
from the controller domain.
diffstat:
sys/dev/pci/mpii.c | 112 +++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 88 insertions(+), 24 deletions(-)
diffs (162 lines):
diff -r 1bde6d22f5f5 -r 15f15b1cac75 sys/dev/pci/mpii.c
--- a/sys/dev/pci/mpii.c Fri Aug 09 15:35:54 2013 +0000
+++ b/sys/dev/pci/mpii.c Fri Aug 09 19:51:29 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mpii.c,v 1.2 2013/08/08 07:06:13 kardel Exp $ */
+/* $NetBSD: mpii.c,v 1.3 2013/08/09 19:51:29 kardel Exp $ */
/* OpenBSD: mpii.c,v 1.51 2012/04/11 13:29:14 naddy Exp */
/*
* Copyright (c) 2010 Mike Belopuhov <mkb%crypt.org.ru@localhost>
@@ -20,7 +20,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.2 2013/08/08 07:06:13 kardel Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.3 2013/08/09 19:51:29 kardel Exp $");
#include "bio.h"
@@ -790,18 +790,18 @@
u_int16_t reserved3;
u_int8_t scsi_status;
- /* XXX JPG validate this */
-#if notyet
-#define MPII_SCSIIO_ERR_STATUS_SUCCESS
-#define MPII_SCSIIO_ERR_STATUS_CHECK_COND
-#define MPII_SCSIIO_ERR_STATUS_BUSY
-#define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE
-#define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET
-#define MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT
-#define MPII_SCSIIO_ERR_STATUS_CMD_TERM
-#define MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL
-#define MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE
-#endif
+
+#define MPII_SCSIIO_ERR_STATUS_SUCCESS (0x00)
+#define MPII_SCSIIO_ERR_STATUS_CHECK_COND (0x02)
+#define MPII_SCSIIO_ERR_STATUS_BUSY (0x04)
+#define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE (0x08)
+#define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET (0x10)
+#define MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT (0x14)
+#define MPII_SCSIIO_ERR_STATUS_CMD_TERM (0x22)
+#define MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL (0x28)
+#define MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE (0x30)
+#define MPII_SCSIIO_ERR_STATUS_TASK_ABORTED (0x40)
+
u_int8_t scsi_state;
#define MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID (1<<0)
#define MPII_SCSIIO_ERR_STATE_AUTOSENSE_FAILED (1<<1)
@@ -4682,6 +4682,58 @@
mpii_put_ccb(tccb->ccb_sc, tccb);
}
+static u_int8_t
+map_scsi_status(u_int8_t mpii_scsi_status)
+{
+ u_int8_t scsi_status;
+
+ switch (mpii_scsi_status)
+ {
+ case MPII_SCSIIO_ERR_STATUS_SUCCESS:
+ scsi_status = SCSI_OK;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_CHECK_COND:
+ scsi_status = SCSI_CHECK;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_BUSY:
+ scsi_status = SCSI_BUSY;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_INTERMEDIATE:
+ scsi_status = SCSI_INTERM;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET:
+ scsi_status = SCSI_INTERM;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT:
+ scsi_status = SCSI_RESV_CONFLICT;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_CMD_TERM:
+ case MPII_SCSIIO_ERR_STATUS_TASK_ABORTED:
+ scsi_status = SCSI_TERMINATED;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL:
+ scsi_status = SCSI_QUEUE_FULL;
+ break;
+
+ case MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE:
+ scsi_status = SCSI_ACA_ACTIVE;
+ break;
+
+ default:
+ /* XXX: for the lack of anything better and other than OK */
+ scsi_status = 0xFF;
+ break;
+ }
+
+ return scsi_status;
+}
static void
mpii_scsi_cmd_done(struct mpii_ccb *ccb)
@@ -4745,31 +4797,43 @@
DNPRINTF(MPII_D_CMD, "%s: bidirectional_transfer_count: 0x%08x\n",
DEVNAME(sc), le32toh(sie->bidirectional_transfer_count));
- xs->status = sie->scsi_status;
+ xs->status = map_scsi_status(sie->scsi_status);
+
switch (le16toh(sie->ioc_status) & MPII_IOCSTATUS_MASK) {
case MPII_IOCSTATUS_SCSI_DATA_UNDERRUN:
- switch (xs->status) {
- case SCSI_OK:
+ switch (sie->scsi_status) {
+ case MPII_SCSIIO_ERR_STATUS_CHECK_COND:
+ xs->error = XS_SENSE;
+ /*FALLTHROUGH*/
+ case MPII_SCSIIO_ERR_STATUS_SUCCESS:
xs->resid = xs->datalen - le32toh(sie->transfer_count);
break;
+
default:
xs->error = XS_DRIVER_STUFFUP;
break;
}
break;
+
case MPII_IOCSTATUS_SUCCESS:
case MPII_IOCSTATUS_SCSI_RECOVERED_ERROR:
- switch (xs->status) {
- case SCSI_OK:
- xs->resid = 0;
+ switch (sie->scsi_status) {
+ case MPII_SCSIIO_ERR_STATUS_SUCCESS:
+ /*
+ * xs->resid = 0; - already set above
+ *
+ * XXX: check whether UNDERUN strategy
+ * would be appropriate here too.
+ * that would allow joining these cases.
+ */
break;
- case SCSI_CHECK:
+ case MPII_SCSIIO_ERR_STATUS_CHECK_COND:
xs->error = XS_SENSE;
break;
-
- case SCSI_BUSY:
- case SCSI_QUEUE_FULL:
+
+ case MPII_SCSIIO_ERR_STATUS_BUSY:
+ case MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL:
xs->error = XS_BUSY;
break;
Home |
Main Index |
Thread Index |
Old Index