]> git.hungrycats.org Git - linux/commitdiff
aic7xxx and aic79xx drivers Correct several DV issues:
authorJustin T. Gibbs <gibbs@overdrive.btc.adaptec.com>
Tue, 7 Jan 2003 12:40:37 +0000 (05:40 -0700)
committerJustin T. Gibbs <gibbs@overdrive.btc.adaptec.com>
Tue, 7 Jan 2003 12:40:37 +0000 (05:40 -0700)
 o Do not fallback to a wide speed if the device does not support
   wide transfers.

 o Don't bother allocating target instances for wide IDs on narrow
   controllers.

 o Add a few additional diagnostics to aid in tracking down DV bugs.

drivers/scsi/aic7xxx/aic79xx_core.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic79xx_osm.h
drivers/scsi/aic7xxx/aic7xxx_core.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.h

index a288ed9f9b3e5e985bc95afb25198b7348733af8..1cd5afa6ebcda6055d1ca20af0495259ad8e8064 100644 (file)
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#148 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#150 $
  *
  * $FreeBSD$
  */
@@ -2321,13 +2321,13 @@ ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
 
        /* Skip all PACED only entries if IU is not available */
        if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0
-        && maxsync < AHD_SYNCRATE_DT)
-               maxsync = AHD_SYNCRATE_DT;
+        && *period < AHD_SYNCRATE_DT)
+               *period = AHD_SYNCRATE_DT;
 
        /* Skip all DT only entries if DT is not available */
        if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
-        && maxsync < AHD_SYNCRATE_ULTRA2)
-               maxsync = AHD_SYNCRATE_ULTRA2;
+        && *period < AHD_SYNCRATE_ULTRA2)
+               *period = AHD_SYNCRATE_ULTRA2;
 }
 
 /*
@@ -5680,7 +5680,8 @@ ahd_init(struct ahd_softc *ahd)
                               /*lowaddr*/BUS_SPACE_MAXADDR,
                               /*highaddr*/BUS_SPACE_MAXADDR,
                               /*filter*/NULL, /*filterarg*/NULL,
-                              /*maxsize*/MAXBSIZE, /*nsegments*/AHD_NSEG,
+                              /*maxsize*/(AHD_NSEG - 1) * PAGE_SIZE,
+                              /*nsegments*/AHD_NSEG,
                               /*maxsegsz*/AHD_MAXTRANSFER_SIZE,
                               /*flags*/BUS_DMA_ALLOCNOW,
                               &ahd->buffer_dmat) != 0) {
@@ -7856,7 +7857,8 @@ ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
 #ifdef AHD_DEBUG
        if ((ahd_debug & AHD_SHOW_MISC) != 0) {
                ahd_print_path(ahd, scb);
-               printf("Handled Residual of %d bytes\n", resid);
+               printf("Handled %sResidual of %d bytes\n",
+                      (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
        }
 #endif
 }
index 02a7612a7efd9675c715c4b01eb21c57260b3899..05edbed59319c1901a5ad86868c20fdf62eed251 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Adaptec AIC79xx device driver for Linux.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#103 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#104 $
  *
  * --------------------------------------------------------------------------
  * Copyright (c) 1994-2000 Justin T. Gibbs.
@@ -2058,7 +2058,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
         * negotiation will occur for the first command, and DV
         * will comence should that first command be successful.
         */
-       for (target = 0; target < AHD_NUM_TARGETS; target++)
+       for (target = 0; target < host->max_id; target++)
                ahd_linux_alloc_target(ahd, 0, target);
        ahd_intr_enable(ahd, TRUE);
        ahd_linux_start_dv(ahd);
@@ -2883,6 +2883,23 @@ ahd_linux_dv_transition(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
                                break;
                        }
 
+#ifdef AHD_DEBUG
+                       if (ahd_debug & AHD_SHOW_DV) {
+                               int i;
+
+                               ahd_print_devinfo(ahd, devinfo);
+                               printf("Inquiry buffer mismatch:");
+                               for (i = 0; i < AHD_LINUX_DV_INQ_LEN; i++) {
+                                       if ((i & 0xF) == 0)
+                                               printf("\n        ");
+                                       printf("0x%x:0x0%x ",
+                                              ((uint8_t *)targ->inq_data)[i], 
+                                              targ->dv_buffer[i]);
+                               }
+                               printf("\n");
+                       }
+#endif
+
                        if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
                                AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
                                break;
@@ -3525,6 +3542,8 @@ ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                targ->dv_next_narrow_period = MAX(period, AHD_SYNCRATE_ULTRA2);
        if (targ->dv_next_wide_period == 0)
                targ->dv_next_wide_period = period;
+       if (targ->dv_max_width == 0)
+               targ->dv_max_width = width;
        if (targ->dv_max_ppr_options == 0)
                targ->dv_max_ppr_options = ppr_options;
        if (targ->dv_last_ppr_options == 0)
@@ -3619,7 +3638,7 @@ ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                                period++;
                        }
                } else if ((ahd->features & AHD_WIDE) != 0
-                       && tinfo->user.width != 0
+                       && targ->dv_max_width != 0
                        && wide_speed >= fallback_speed
                        && (targ->dv_next_wide_period <= AHD_ASYNC_XFER_PERIOD
                         || period >= AHD_ASYNC_XFER_PERIOD)) {
index a3377dcc6f50efa6a98c7e5276c51447522ea043..2afe38447ae5e2b5c4bc50d608340a8e6de20562 100644 (file)
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#99 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#100 $
  *
  */
 #ifndef _AIC79XX_LINUX_H_
@@ -458,10 +458,11 @@ struct ahd_linux_target {
        /*
         * The next "fallback" period to use for narrow/wide transfers.
         */
-       u_int                     dv_next_narrow_period;
-       u_int                     dv_next_wide_period;
-       u_int                     dv_max_ppr_options;
-       u_int                     dv_last_ppr_options;
+       uint8_t                   dv_next_narrow_period;
+       uint8_t                   dv_next_wide_period;
+       uint8_t                   dv_max_width;
+       uint8_t                   dv_max_ppr_options;
+       uint8_t                   dv_last_ppr_options;
        u_int                     dv_echo_size;
        ahd_dv_state              dv_state;
        u_int                     dv_state_retry;
index a69c1194203ef37acffe85b434655bbf39f94420..b7ec61e7f3a8468106354f23d6cf0915df169432 100644 (file)
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#105 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#107 $
  *
  * $FreeBSD$
  */
@@ -4602,7 +4602,8 @@ ahc_init(struct ahc_softc *ahc)
                               /*lowaddr*/BUS_SPACE_MAXADDR,
                               /*highaddr*/BUS_SPACE_MAXADDR,
                               /*filter*/NULL, /*filterarg*/NULL,
-                              /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG,
+                              /*maxsize*/(AHC_NSEG - 1) * PAGE_SIZE,
+                              /*nsegments*/AHC_NSEG,
                               /*maxsegsz*/AHC_MAXTRANSFER_SIZE,
                               /*flags*/BUS_DMA_ALLOCNOW,
                               &ahc->buffer_dmat) != 0) {
@@ -6275,7 +6276,8 @@ ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
 #ifdef AHC_DEBUG
        if ((ahc_debug & AHC_SHOW_MISC) != 0) {
                ahc_print_path(ahc, scb);
-               printf("Handled Residual of %d bytes\n", resid);
+               printf("Handled %sResidual of %d bytes\n",
+                      (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
        }
 #endif
 }
index e8e2a4e915276a5f6d1e802faea503d5c4fe50f9..750b4998c1b567c676e91baa23b9cc97d78a32b7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Adaptec AIC7xxx device driver for Linux.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#166 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#167 $
  *
  * Copyright (c) 1994 John Aycock
  *   The University of Calgary Department of Computer Science.
@@ -1297,6 +1297,7 @@ Scsi_Host_Template aic7xxx_driver_template = {
         */
        .max_sectors            = 8192,
 #endif
+#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
 /* Assume RedHat Distribution with its different HIGHIO conventions. */
        .can_dma_32             = 1,
@@ -1304,6 +1305,7 @@ Scsi_Host_Template aic7xxx_driver_template = {
 #else
        .highmem_io             = 1,
 #endif
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        .name                   = "aic7xxx",
        .slave_alloc            = ahc_linux_slave_alloc,
@@ -1888,7 +1890,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
         * negotiation will occur for the first command, and DV
         * will comence should that first command be successful.
         */
-       for (target = 0; target < AHC_NUM_TARGETS; target++) {
+       for (target = 0; target < host->max_id; target++) {
                u_int channel;
 
                channel = 0;
@@ -2732,6 +2734,22 @@ ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
                                AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
                                break;
                        }
+#ifdef AHC_DEBUG
+                       if (ahc_debug & AHC_SHOW_DV) {
+                               int i;
+
+                               ahc_print_devinfo(ahc, devinfo);
+                               printf("Inquiry buffer mismatch:");
+                               for (i = 0; i < AHC_LINUX_DV_INQ_LEN; i++) {
+                                       if ((i & 0xF) == 0)
+                                               printf("\n        ");
+                                       printf("0x%x:0x0%x ",
+                                              ((uint8_t *)targ->inq_data)[i], 
+                                              targ->dv_buffer[i]);
+                               }
+                               printf("\n");
+                       }
+#endif
 
                        if (ahc_linux_fallback(ahc, devinfo) != 0) {
                                AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
@@ -3365,6 +3383,8 @@ ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
                targ->dv_next_narrow_period = MAX(period, AHC_SYNCRATE_ULTRA2);
        if (targ->dv_next_wide_period == 0)
                targ->dv_next_wide_period = period;
+       if (targ->dv_max_width == 0)
+               targ->dv_max_width = width;
        if (targ->dv_max_ppr_options == 0)
                targ->dv_max_ppr_options = ppr_options;
        if (targ->dv_last_ppr_options == 0)
@@ -3459,7 +3479,7 @@ ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
                                period++;
                        }
                } else if ((ahc->features & AHC_WIDE) != 0
-                       && tinfo->user.width != 0
+                       && targ->dv_max_width != 0
                        && wide_speed >= fallback_speed
                        && (targ->dv_next_wide_period <= AHC_ASYNC_XFER_PERIOD
                         || period >= AHC_ASYNC_XFER_PERIOD)) {
index 3b4b602f969fea6e400c62a939e6a60edf0bea66..0fe7bdde7f4198798684cc25e891e8b4d888264b 100644 (file)
@@ -53,7 +53,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#114 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#115 $
  *
  */
 #ifndef _AIC7XXX_LINUX_H_
@@ -72,7 +72,6 @@
 #endif
 #include <linux/module.h>
 #include <asm/byteorder.h>
-#include <asm/io.h>
 
 #ifndef KERNEL_VERSION
 #define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
@@ -472,10 +471,11 @@ struct ahc_linux_target {
        /*
         * The next "fallback" period to use for narrow/wide transfers.
         */
-       u_int                     dv_next_narrow_period;
-       u_int                     dv_next_wide_period;
-       u_int                     dv_max_ppr_options;
-       u_int                     dv_last_ppr_options;
+       uint8_t                   dv_next_narrow_period;
+       uint8_t                   dv_next_wide_period;
+       uint8_t                   dv_max_width;
+       uint8_t                   dv_max_ppr_options;
+       uint8_t                   dv_last_ppr_options;
        u_int                     dv_echo_size;
        ahc_dv_state              dv_state;
        u_int                     dv_state_retry;