Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / scsi / aic7xxx / aic79xx_pci.c
index 9139845..14850f3 100644 (file)
@@ -38,9 +38,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_pci.c#77 $
- *
- * $FreeBSD$
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#92 $
  */
 
 #ifdef __linux__
@@ -51,6 +49,8 @@
 #include <dev/aic7xxx/aic79xx_inline.h>
 #endif
 
+#include "aic79xx_pci.h"
+
 static __inline uint64_t
 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
 {
@@ -64,34 +64,12 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
        return (id);
 }
 
-#define ID_ALL_MASK                    0xFFFFFFFFFFFFFFFFull
-#define ID_ALL_IROC_MASK               0xFFFFFF7FFFFFFFFFull
-#define ID_DEV_VENDOR_MASK             0xFFFFFFFF00000000ull
-#define ID_9005_GENERIC_MASK           0xFFF0FFFF00000000ull
-#define ID_9005_GENERIC_IROC_MASK      0xFFF0FF7F00000000ull
-
-#define ID_AIC7901                     0x800F9005FFFF9005ull
-#define ID_AHA_29320A                  0x8000900500609005ull
-#define ID_AHA_29320ALP                        0x8017900500449005ull
-
-#define ID_AIC7901A                    0x801E9005FFFF9005ull
-#define ID_AHA_29320                   0x8012900500429005ull
-#define ID_AHA_29320B                  0x8013900500439005ull
-#define ID_AHA_29320LP                 0x8014900500449005ull
-
-#define ID_AIC7902                     0x801F9005FFFF9005ull
-#define ID_AIC7902_B                   0x801D9005FFFF9005ull
-#define ID_AHA_39320                   0x8010900500409005ull
-#define ID_AHA_39320_B                 0x8015900500409005ull
-#define ID_AHA_39320A                  0x8016900500409005ull
-#define ID_AHA_39320D                  0x8011900500419005ull
-#define ID_AHA_39320D_B                        0x801C900500419005ull
-#define ID_AHA_39320D_HP               0x8011900500AC0E11ull
-#define ID_AHA_39320D_B_HP             0x801C900500AC0E11ull
 #define ID_AIC7902_PCI_REV_A4          0x3
 #define ID_AIC7902_PCI_REV_B0          0x10
 #define SUBID_HP                       0x0E11
 
+#define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
+
 #define DEVID_9005_TYPE(id) ((id) & 0xF)
 #define                DEVID_9005_TYPE_HBA             0x0     /* Standard Card */
 #define                DEVID_9005_TYPE_HBA_2EXT        0x1     /* 2 External Ports */
@@ -136,24 +114,24 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
        },
        /* aic7901A based controllers */
        {
-               ID_AHA_29320,
+               ID_AHA_29320LP,
                ID_ALL_MASK,
-               "Adaptec 29320 Ultra320 SCSI adapter",
+               "Adaptec 29320LP Ultra320 SCSI adapter",
                ahd_aic7901A_setup
        },
+       /* aic7902 based controllers */ 
        {
-               ID_AHA_29320B,
+               ID_AHA_29320,
                ID_ALL_MASK,
-               "Adaptec 29320B Ultra320 SCSI adapter",
-               ahd_aic7901A_setup
+               "Adaptec 29320 Ultra320 SCSI adapter",
+               ahd_aic7902_setup
        },
        {
-               ID_AHA_29320LP,
+               ID_AHA_29320B,
                ID_ALL_MASK,
-               "Adaptec 29320LP Ultra320 SCSI adapter",
-               ahd_aic7901A_setup
+               "Adaptec 29320B Ultra320 SCSI adapter",
+               ahd_aic7902_setup
        },
-       /* aic7902 based controllers */ 
        {
                ID_AHA_39320,
                ID_ALL_MASK,
@@ -166,6 +144,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
                "Adaptec 39320 Ultra320 SCSI adapter",
                ahd_aic7902_setup
        },
+       {
+               ID_AHA_39320_B_DELL,
+               ID_ALL_MASK,
+               "Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",
+               ahd_aic7902_setup
+       },
        {
                ID_AHA_39320A,
                ID_ALL_MASK,
@@ -196,22 +180,10 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
                "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
                ahd_aic7902_setup
        },
-       {
-               ID_AHA_29320,
-               ID_ALL_MASK,
-               "Adaptec 29320 Ultra320 SCSI adapter",
-               ahd_aic7902_setup
-       },
-       {
-               ID_AHA_29320B,
-               ID_ALL_MASK,
-               "Adaptec 29320B Ultra320 SCSI adapter",
-               ahd_aic7902_setup
-       },
        /* Generic chip probes for devices we don't know 'exactly' */
        {
-               ID_AIC7901 & ID_DEV_VENDOR_MASK,
-               ID_DEV_VENDOR_MASK,
+               ID_AIC7901 & ID_9005_GENERIC_MASK,
+               ID_9005_GENERIC_MASK,
                "Adaptec AIC7901 Ultra320 SCSI adapter",
                ahd_aic7901_setup
        },
@@ -229,7 +201,7 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
        }
 };
 
-const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
+const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
                
 #define        DEVCONFIG               0x40
 #define                PCIXINITPAT     0x0000E000ul
@@ -294,6 +266,12 @@ ahd_find_pci_device(ahd_dev_softc_t pci)
                                 subdevice,
                                 subvendor);
 
+       /*
+        * Controllers, mask out the IROC/HostRAID bit
+        */
+       
+       full_id &= ID_ALL_IROC_MASK;
+
        for (i = 0; i < ahd_num_pci_devs; i++) {
                entry = &ahd_pci_ident_table[i];
                if (entry->full_id == (full_id & entry->id_mask)) {
@@ -310,7 +288,6 @@ int
 ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
 {
        struct scb_data *shared_scb_data;
-       u_long           l;
        u_int            command;
        uint32_t         devconfig;
        uint16_t         subvendor; 
@@ -400,16 +377,9 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
         * Allow interrupts now that we are completely setup.
         */
        error = ahd_pci_map_int(ahd);
-       if (error != 0)
-               return (error);
-
-       ahd_list_lock(&l);
-       /*
-        * Link this softc in with all other ahd instances.
-        */
-       ahd_softc_insert(ahd);
-       ahd_list_unlock(&l);
-       return (0);
+       if (!error)
+               ahd->init_level++;
+       return error;
 }
 
 /*
@@ -452,8 +422,10 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
         * or read prefetching could be initiated by the
         * CPU or host bridge.  Our device does not support
         * either, so look for data corruption and/or flaged
-        * PCI errors.
+        * PCI errors.  First pause without causing another
+        * chip reset.
         */
+       hcntrl &= ~CHIPRST;
        ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
        while (ahd_is_paused(ahd) == 0)
                ;
@@ -607,7 +579,7 @@ ahd_check_extport(struct ahd_softc *ahd)
                }
        }
 
-#if AHD_DEBUG
+#ifdef AHD_DEBUG
        if (have_seeprom != 0
         && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
                uint16_t *sc_data;
@@ -701,6 +673,7 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
         * Now set the termination based on what we found.
         */
        sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
+       ahd->flags &= ~AHD_TERM_ENB_A;
        if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
                ahd->flags |= AHD_TERM_ENB_A;
                sxfrctl1 |= STPWEN;
@@ -977,12 +950,19 @@ ahd_aic790X_setup(struct ahd_softc *ahd)
                if ((ahd->flags & AHD_HP_BOARD) == 0)
                        AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
        } else {
+               /* This is revision B and newer. */
+               extern uint32_t aic79xx_slowcrc;
                u_int devconfig1;
 
                ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
-                             |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
+                             |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY
+                             |  AHD_BUSFREEREV_BUG;
                ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
 
+               /* If the user requested the the SLOWCRC bit to be set. */
+               if (aic79xx_slowcrc)
+                       ahd->features |= AHD_AIC79XXB_SLOWCRC;
+
                /*
                 * Some issues have been resolved in the 7901B.
                 */