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