[SCSI] aic7xxx: fix the BIOS limits setting routines
authorJames Bottomley <James.Bottomley@steeleye.com>
Tue, 14 Jun 2005 01:58:56 +0000 (20:58 -0500)
committerJames Bottomley <jejb@mulgrave.(none)>
Tue, 14 Jun 2005 02:37:27 +0000 (21:37 -0500)
Following the go around over the SONY DVD that needs artificial limits,
this should be the correct code for all cases (minus the debugging
prints).

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/aic7xxx/aic7xxx_osm.c

index 55e0b2875f99d96ae92b98e639bb556322a302b9..e3892585d7e68380a09d4f0a6322e9ecc4cd1f83 100644 (file)
@@ -621,20 +621,35 @@ ahc_linux_target_alloc(struct scsi_target *starget)
        memset(targ, 0, sizeof(*targ));
 
        if (sc) {
+               int maxsync = AHC_SYNCRATE_DT;
+               int ultra = 0;
+               int flags = sc->device_flags[target_offset];
+
+               if (ahc->flags & AHC_NEWEEPROM_FMT) {
+                   if (flags & CFSYNCHISULTRA)
+                       ultra = 1;
+               } else if (flags & CFULTRAEN)
+                       ultra = 1;
+               /* AIC nutcase; 10MHz appears as ultra = 1, CFXFER = 0x04
+                * change it to ultra=0, CFXFER = 0 */
+               if(ultra && (flags & CFXFER) == 0x04) {
+                       ultra = 0;
+                       flags &= ~CFXFER;
+               }
+           
                if ((ahc->features & AHC_ULTRA2) != 0) {
-                       scsirate = sc->device_flags[target_offset] & CFXFER;
+                       scsirate = (flags & CFXFER) | (ultra ? 0x8 : 0);
                } else {
-                       scsirate = (sc->device_flags[target_offset] & CFXFER) << 4;
-                       if (sc->device_flags[target_offset] & CFSYNCH)
-                               scsirate |= SOFS;
+                       scsirate = (flags & CFXFER) << 4;
+                       maxsync = ultra ? AHC_SYNCRATE_ULTRA : 
+                               AHC_SYNCRATE_FAST;
                }
-               if (sc->device_flags[target_offset] & CFWIDEB) {
-                       scsirate |= WIDEXFER;
-                       spi_max_width(starget) = 1;
-               } else
-                       spi_max_width(starget) = 0;
+               spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
+               if (!(flags & CFSYNCH))
+                       spi_max_offset(starget) = 0;
                spi_min_period(starget) = 
-                       ahc_find_period(ahc, scsirate, AHC_SYNCRATE_DT);
+                       ahc_find_period(ahc, scsirate, maxsync);
+
                tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id,
                                            starget->id, &tstate);
        }