fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / scsi / aic7xxx / aic7xxx_pci.c
index 01cfab0..09c8172 100644 (file)
@@ -39,9 +39,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_pci.c#69 $
- *
- * $FreeBSD$
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#79 $
  */
 
 #ifdef __linux__
@@ -54,8 +52,7 @@
 #include <dev/aic7xxx/aic7xxx_93cx6.h>
 #endif
 
-#define AHC_PCI_IOADDR PCIR_MAPS       /* I/O Address */
-#define AHC_PCI_MEMADDR        (PCIR_MAPS + 4) /* Mem I/O Address */
+#include "aic7xxx_pci.h"
 
 static __inline uint64_t
 ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
@@ -70,84 +67,8 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
        return (id);
 }
 
-#define ID_ALL_MASK                    0xFFFFFFFFFFFFFFFFull
-#define ID_DEV_VENDOR_MASK             0xFFFFFFFF00000000ull
-#define ID_9005_GENERIC_MASK           0xFFF0FFFF00000000ull
-#define ID_9005_SISL_MASK              0x000FFFFF00000000ull
-#define ID_9005_SISL_ID                        0x0005900500000000ull
-#define ID_AIC7850                     0x5078900400000000ull
-#define ID_AHA_2902_04_10_15_20C_30C   0x5078900478509004ull
-#define ID_AIC7855                     0x5578900400000000ull
-#define ID_AIC7859                     0x3860900400000000ull
-#define ID_AHA_2930CU                  0x3860900438699004ull
-#define ID_AIC7860                     0x6078900400000000ull
-#define ID_AIC7860C                    0x6078900478609004ull
-#define ID_AHA_1480A                   0x6075900400000000ull
-#define ID_AHA_2940AU_0                        0x6178900400000000ull
-#define ID_AHA_2940AU_1                        0x6178900478619004ull
-#define ID_AHA_2940AU_CN               0x2178900478219004ull
-#define ID_AHA_2930C_VAR               0x6038900438689004ull
-
-#define ID_AIC7870                     0x7078900400000000ull
-#define ID_AHA_2940                    0x7178900400000000ull
-#define ID_AHA_3940                    0x7278900400000000ull
-#define ID_AHA_398X                    0x7378900400000000ull
-#define ID_AHA_2944                    0x7478900400000000ull
-#define ID_AHA_3944                    0x7578900400000000ull
-#define ID_AHA_4944                    0x7678900400000000ull
-
-#define ID_AIC7880                     0x8078900400000000ull
-#define ID_AIC7880_B                   0x8078900478809004ull
-#define ID_AHA_2940U                   0x8178900400000000ull
-#define ID_AHA_3940U                   0x8278900400000000ull
-#define ID_AHA_2944U                   0x8478900400000000ull
-#define ID_AHA_3944U                   0x8578900400000000ull
-#define ID_AHA_398XU                   0x8378900400000000ull
-#define ID_AHA_4944U                   0x8678900400000000ull
-#define ID_AHA_2940UB                  0x8178900478819004ull
-#define ID_AHA_2930U                   0x8878900478889004ull
-#define ID_AHA_2940U_PRO               0x8778900478879004ull
-#define ID_AHA_2940U_CN                        0x0078900478009004ull
-
-#define ID_AIC7895                     0x7895900478959004ull
-#define ID_AIC7895_ARO                 0x7890900478939004ull
-#define ID_AIC7895_ARO_MASK            0xFFF0FFFFFFFFFFFFull
-#define ID_AHA_2940U_DUAL              0x7895900478919004ull
-#define ID_AHA_3940AU                  0x7895900478929004ull
-#define ID_AHA_3944AU                  0x7895900478949004ull
-
-#define ID_AIC7890                     0x001F9005000F9005ull
-#define ID_AIC7890_ARO                 0x00139005000F9005ull
-#define ID_AAA_131U2                   0x0013900500039005ull
-#define ID_AHA_2930U2                  0x0011900501819005ull
-#define ID_AHA_2940U2B                 0x00109005A1009005ull
-#define ID_AHA_2940U2_OEM              0x0010900521809005ull
-#define ID_AHA_2940U2                  0x00109005A1809005ull
-#define ID_AHA_2950U2B                 0x00109005E1009005ull
-
-#define ID_AIC7892                     0x008F9005FFFF9005ull
-#define ID_AIC7892_ARO                 0x00839005FFFF9005ull
-#define ID_AHA_29160                   0x00809005E2A09005ull
-#define ID_AHA_29160_CPQ               0x00809005E2A00E11ull
-#define ID_AHA_29160N                  0x0080900562A09005ull
-#define ID_AHA_29160C                  0x0080900562209005ull
-#define ID_AHA_29160B                  0x00809005E2209005ull
-#define ID_AHA_19160B                  0x0081900562A19005ull
-
-#define ID_AIC7896                     0x005F9005FFFF9005ull
-#define ID_AIC7896_ARO                 0x00539005FFFF9005ull
-#define ID_AHA_3950U2B_0               0x00509005FFFF9005ull
-#define ID_AHA_3950U2B_1               0x00509005F5009005ull
-#define ID_AHA_3950U2D_0               0x00519005FFFF9005ull
-#define ID_AHA_3950U2D_1               0x00519005B5009005ull
-
-#define ID_AIC7899                     0x00CF9005FFFF9005ull
-#define ID_AIC7899_ARO                 0x00C39005FFFF9005ull
-#define ID_AHA_3960D                   0x00C09005F6209005ull
-#define ID_AHA_3960D_CPQ               0x00C09005F6200E11ull
-
-#define ID_AIC7810                     0x1078900400000000ull
-#define ID_AIC7815                     0x7815900400000000ull
+#define AHC_PCI_IOADDR PCIR_MAPS       /* I/O Address */
+#define AHC_PCI_MEMADDR        (PCIR_MAPS + 4) /* Mem I/O Address */
 
 #define DEVID_9005_TYPE(id) ((id) & 0xF)
 #define                DEVID_9005_TYPE_HBA             0x0     /* Standard Card */
@@ -223,16 +144,22 @@ static ahc_device_setup_t ahc_aic785X_setup;
 static ahc_device_setup_t ahc_aic7860_setup;
 static ahc_device_setup_t ahc_apa1480_setup;
 static ahc_device_setup_t ahc_aic7870_setup;
+static ahc_device_setup_t ahc_aic7870h_setup;
 static ahc_device_setup_t ahc_aha394X_setup;
+static ahc_device_setup_t ahc_aha394Xh_setup;
 static ahc_device_setup_t ahc_aha494X_setup;
+static ahc_device_setup_t ahc_aha494Xh_setup;
 static ahc_device_setup_t ahc_aha398X_setup;
 static ahc_device_setup_t ahc_aic7880_setup;
+static ahc_device_setup_t ahc_aic7880h_setup;
 static ahc_device_setup_t ahc_aha2940Pro_setup;
 static ahc_device_setup_t ahc_aha394XU_setup;
+static ahc_device_setup_t ahc_aha394XUh_setup;
 static ahc_device_setup_t ahc_aha398XU_setup;
 static ahc_device_setup_t ahc_aic7890_setup;
 static ahc_device_setup_t ahc_aic7892_setup;
 static ahc_device_setup_t ahc_aic7895_setup;
+static ahc_device_setup_t ahc_aic7895h_setup;
 static ahc_device_setup_t ahc_aic7896_setup;
 static ahc_device_setup_t ahc_aic7899_setup;
 static ahc_device_setup_t ahc_aha29160C_setup;
@@ -241,7 +168,7 @@ static ahc_device_setup_t ahc_aha394XX_setup;
 static ahc_device_setup_t ahc_aha494XX_setup;
 static ahc_device_setup_t ahc_aha398XX_setup;
 
-struct ahc_pci_identity ahc_pci_ident_table [] =
+static struct ahc_pci_identity ahc_pci_ident_table [] =
 {
        /* aic7850 based controllers */
        {
@@ -304,19 +231,19 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
                ID_AHA_2944,
                ID_ALL_MASK,
                "Adaptec 2944 SCSI adapter",
-               ahc_aic7870_setup
+               ahc_aic7870h_setup
        },
        {
                ID_AHA_3944,
                ID_ALL_MASK,
                "Adaptec 3944 SCSI adapter",
-               ahc_aha394X_setup
+               ahc_aha394Xh_setup
        },
        {
                ID_AHA_4944,
                ID_ALL_MASK,
                "Adaptec 4944 SCSI adapter",
-               ahc_aha494X_setup
+               ahc_aha494Xh_setup
        },
        /* aic7880 based controllers */
        {
@@ -335,13 +262,13 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
                ID_AHA_2944U & ID_DEV_VENDOR_MASK,
                ID_DEV_VENDOR_MASK,
                "Adaptec 2944 Ultra SCSI adapter",
-               ahc_aic7880_setup
+               ahc_aic7880h_setup
        },
        {
                ID_AHA_3944U & ID_DEV_VENDOR_MASK,
                ID_DEV_VENDOR_MASK,
                "Adaptec 3944 Ultra SCSI adapter",
-               ahc_aha394XU_setup
+               ahc_aha394XUh_setup
        },
        {
                ID_AHA_398XU & ID_DEV_VENDOR_MASK,
@@ -357,7 +284,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
                ID_AHA_4944U & ID_DEV_VENDOR_MASK,
                ID_DEV_VENDOR_MASK,
                "Adaptec 4944 Ultra SCSI adapter",
-               ahc_aic7880_setup
+               ahc_aic7880h_setup
        },
        {
                ID_AHA_2930U & ID_DEV_VENDOR_MASK,
@@ -470,6 +397,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
                "Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
                ahc_aic7892_setup
        },
+       {
+               ID_AHA_2915_30LP,
+               ID_ALL_MASK,
+               "Adaptec 2915/30LP Ultra160 SCSI adapter",
+               ahc_aic7892_setup
+       },
        /* aic7895 based controllers */ 
        {
                ID_AHA_2940U_DUAL,
@@ -487,7 +420,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
                ID_AHA_3944AU,
                ID_ALL_MASK,
                "Adaptec 3944A Ultra SCSI adapter",
-               ahc_aic7895_setup
+               ahc_aic7895h_setup
        },
        {
                ID_AIC7895_ARO,
@@ -626,7 +559,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
        }
 };
 
-const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table);
+static const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table);
                
 #define AHC_394X_SLOT_CHANNEL_A        4
 #define AHC_394X_SLOT_CHANNEL_B        5
@@ -781,7 +714,6 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
 int
 ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
 {
-       u_long   l;
        u_int    command;
        u_int    our_id;
        u_int    sxfrctl1;
@@ -798,7 +730,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
        ahc->chip |= AHC_PCI;
        ahc->description = entry->name;
 
-       ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+       pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
 
        error = ahc_pci_map_registers(ahc);
        if (error != 0)
@@ -1041,12 +973,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
        if (error != 0)
                return (error);
 
-       ahc_list_lock(&l);
-       /*
-        * Link this softc in with all other ahc instances.
-        */
-       ahc_softc_insert(ahc);
-       ahc_list_unlock(&l);
+       ahc->init_level++;
        return (0);
 }
 
@@ -1276,16 +1203,28 @@ ahc_pci_test_register_access(struct ahc_softc *ahc)
         * use for this test.
         */
        hcntrl = ahc_inb(ahc, HCNTRL);
+
        if (hcntrl == 0xFF)
                goto fail;
 
+       if ((hcntrl & CHIPRST) != 0) {
+               /*
+                * The chip has not been initialized since
+                * PCI/EISA/VLB bus reset.  Don't trust
+                * "left over BIOS data".
+                */
+               ahc->flags |= AHC_NO_BIOS_INIT;
+       }
+
        /*
         * Next create a situation where write combining
         * 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 flagged
-        * PCI errors.
+        * PCI errors.  First pause without causing another
+        * chip reset.
         */
+       hcntrl &= ~CHIPRST;
        ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
        while (ahc_is_paused(ahc) == 0)
                ;
@@ -1388,6 +1327,10 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
                        sd.sd_chip = C56_66;
                }
                ahc_release_seeprom(&sd);
+
+               /* Remember the SEEPROM type for later */
+               if (sd.sd_chip == C56_66)
+                       ahc->flags |= AHC_LARGE_SEEPROM;
        }
 
        if (!have_seeprom) {
@@ -2091,7 +2034,7 @@ static int
 ahc_pci_resume(struct ahc_softc *ahc)
 {
 
-       ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+       pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
 
        /*
         * We assume that the OS has restored our register
@@ -2099,12 +2042,12 @@ ahc_pci_resume(struct ahc_softc *ahc)
         * that the OS doesn't know about and rely on our chip
         * reset handler to handle the rest.
         */
-       ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
-                            ahc->bus_softc.pci_softc.devconfig);
-       ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
-                            ahc->bus_softc.pci_softc.command);
-       ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
-                            ahc->bus_softc.pci_softc.csize_lattime);
+       ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
+                            ahc->bus_softc.pci_softc.devconfig, /*bytes*/4);
+       ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
+                            ahc->bus_softc.pci_softc.command, /*bytes*/1);
+       ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
+                            ahc->bus_softc.pci_softc.csize_lattime, /*bytes*/1);
        if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
                struct  seeprom_descriptor sd;
                u_int   sxfrctl1;
@@ -2183,6 +2126,16 @@ ahc_aic7870_setup(struct ahc_softc *ahc)
        return (0);
 }
 
+static int
+ahc_aic7870h_setup(struct ahc_softc *ahc)
+{
+       int error = ahc_aic7870_setup(ahc);
+
+       ahc->features |= AHC_HVD;
+
+       return error;
+}
+
 static int
 ahc_aha394X_setup(struct ahc_softc *ahc)
 {
@@ -2194,6 +2147,16 @@ ahc_aha394X_setup(struct ahc_softc *ahc)
        return (error);
 }
 
+static int
+ahc_aha394Xh_setup(struct ahc_softc *ahc)
+{
+       int error = ahc_aha394X_setup(ahc);
+
+       ahc->features |= AHC_HVD;
+
+       return error;
+}
+
 static int
 ahc_aha398X_setup(struct ahc_softc *ahc)
 {
@@ -2216,6 +2179,16 @@ ahc_aha494X_setup(struct ahc_softc *ahc)
        return (error);
 }
 
+static int
+ahc_aha494Xh_setup(struct ahc_softc *ahc)
+{
+       int error = ahc_aha494X_setup(ahc);
+
+       ahc->features |= AHC_HVD;
+
+       return error;
+}
+
 static int
 ahc_aic7880_setup(struct ahc_softc *ahc)
 {
@@ -2237,6 +2210,17 @@ ahc_aic7880_setup(struct ahc_softc *ahc)
        return (0);
 }
 
+static int
+ahc_aic7880h_setup(struct ahc_softc *ahc)
+{
+       int error = ahc_aic7880_setup(ahc);
+
+       ahc->features |= AHC_HVD;
+
+       return error;
+}
+
+
 static int
 ahc_aha2940Pro_setup(struct ahc_softc *ahc)
 {
@@ -2256,6 +2240,16 @@ ahc_aha394XU_setup(struct ahc_softc *ahc)
        return (error);
 }
 
+static int
+ahc_aha394XUh_setup(struct ahc_softc *ahc)
+{
+       int error = ahc_aha394XU_setup(ahc);
+
+       ahc->features |= AHC_HVD;
+
+       return error;
+}
+
 static int
 ahc_aha398XU_setup(struct ahc_softc *ahc)
 {
@@ -2354,6 +2348,16 @@ ahc_aic7895_setup(struct ahc_softc *ahc)
        return (0);
 }
 
+static int
+ahc_aic7895h_setup(struct ahc_softc *ahc)
+{
+       int error = ahc_aic7895_setup(ahc);
+
+       ahc->features |= AHC_HVD;
+
+       return error;
+}
+
 static int
 ahc_aic7896_setup(struct ahc_softc *ahc)
 {