Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Product specific probe and attach routines for:
0003  *  aic7901 and aic7902 SCSI controllers
0004  *
0005  * Copyright (c) 1994-2001 Justin T. Gibbs.
0006  * Copyright (c) 2000-2002 Adaptec Inc.
0007  * All rights reserved.
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions, and the following disclaimer,
0014  *    without modification.
0015  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0016  *    substantially similar to the "NO WARRANTY" disclaimer below
0017  *    ("Disclaimer") and any redistribution must be conditioned upon
0018  *    including a substantially similar Disclaimer requirement for further
0019  *    binary redistribution.
0020  * 3. Neither the names of the above-listed copyright holders nor the names
0021  *    of any contributors may be used to endorse or promote products derived
0022  *    from this software without specific prior written permission.
0023  *
0024  * Alternatively, this software may be distributed under the terms of the
0025  * GNU General Public License ("GPL") version 2 as published by the Free
0026  * Software Foundation.
0027  *
0028  * NO WARRANTY
0029  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0030  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0031  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
0032  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0033  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
0037  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
0038  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0039  * POSSIBILITY OF SUCH DAMAGES.
0040  *
0041  * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#92 $
0042  */
0043 
0044 #include "aic79xx_osm.h"
0045 #include "aic79xx_inline.h"
0046 #include "aic79xx_pci.h"
0047 
0048 static inline uint64_t
0049 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
0050 {
0051     uint64_t id;
0052 
0053     id = subvendor
0054        | (subdevice << 16)
0055        | ((uint64_t)vendor << 32)
0056        | ((uint64_t)device << 48);
0057 
0058     return (id);
0059 }
0060 
0061 #define ID_AIC7902_PCI_REV_A4       0x3
0062 #define ID_AIC7902_PCI_REV_B0       0x10
0063 #define SUBID_HP            0x0E11
0064 
0065 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
0066 
0067 #define DEVID_9005_TYPE(id) ((id) & 0xF)
0068 #define     DEVID_9005_TYPE_HBA     0x0 /* Standard Card */
0069 #define     DEVID_9005_TYPE_HBA_2EXT    0x1 /* 2 External Ports */
0070 #define     DEVID_9005_TYPE_IROC        0x8 /* Raid(0,1,10) Card */
0071 #define     DEVID_9005_TYPE_MB      0xF /* On Motherboard */
0072 
0073 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
0074 
0075 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
0076 
0077 #define SUBID_9005_TYPE(id) ((id) & 0xF)
0078 #define     SUBID_9005_TYPE_HBA     0x0 /* Standard Card */
0079 #define     SUBID_9005_TYPE_MB      0xF /* On Motherboard */
0080 
0081 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
0082 
0083 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
0084 
0085 #define SUBID_9005_SEEPTYPE(id) (((id) & 0x0C0) >> 6)
0086 #define     SUBID_9005_SEEPTYPE_NONE    0x0
0087 #define     SUBID_9005_SEEPTYPE_4K      0x1
0088 
0089 static ahd_device_setup_t ahd_aic7901_setup;
0090 static ahd_device_setup_t ahd_aic7901A_setup;
0091 static ahd_device_setup_t ahd_aic7902_setup;
0092 static ahd_device_setup_t ahd_aic790X_setup;
0093 
0094 static const struct ahd_pci_identity ahd_pci_ident_table[] =
0095 {
0096     /* aic7901 based controllers */
0097     {
0098         ID_AHA_29320A,
0099         ID_ALL_MASK,
0100         "Adaptec 29320A Ultra320 SCSI adapter",
0101         ahd_aic7901_setup
0102     },
0103     {
0104         ID_AHA_29320ALP,
0105         ID_ALL_MASK,
0106         "Adaptec 29320ALP PCIx Ultra320 SCSI adapter",
0107         ahd_aic7901_setup
0108     },
0109     {
0110         ID_AHA_29320LPE,
0111         ID_ALL_MASK,
0112         "Adaptec 29320LPE PCIe Ultra320 SCSI adapter",
0113         ahd_aic7901_setup
0114     },
0115     /* aic7901A based controllers */
0116     {
0117         ID_AHA_29320LP,
0118         ID_ALL_MASK,
0119         "Adaptec 29320LP Ultra320 SCSI adapter",
0120         ahd_aic7901A_setup
0121     },
0122     /* aic7902 based controllers */ 
0123     {
0124         ID_AHA_29320,
0125         ID_ALL_MASK,
0126         "Adaptec 29320 Ultra320 SCSI adapter",
0127         ahd_aic7902_setup
0128     },
0129     {
0130         ID_AHA_29320B,
0131         ID_ALL_MASK,
0132         "Adaptec 29320B Ultra320 SCSI adapter",
0133         ahd_aic7902_setup
0134     },
0135     {
0136         ID_AHA_39320,
0137         ID_ALL_MASK,
0138         "Adaptec 39320 Ultra320 SCSI adapter",
0139         ahd_aic7902_setup
0140     },
0141     {
0142         ID_AHA_39320_B,
0143         ID_ALL_MASK,
0144         "Adaptec 39320 Ultra320 SCSI adapter",
0145         ahd_aic7902_setup
0146     },
0147     {
0148         ID_AHA_39320_B_DELL,
0149         ID_ALL_MASK,
0150         "Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",
0151         ahd_aic7902_setup
0152     },
0153     {
0154         ID_AHA_39320A,
0155         ID_ALL_MASK,
0156         "Adaptec 39320A Ultra320 SCSI adapter",
0157         ahd_aic7902_setup
0158     },
0159     {
0160         ID_AHA_39320D,
0161         ID_ALL_MASK,
0162         "Adaptec 39320D Ultra320 SCSI adapter",
0163         ahd_aic7902_setup
0164     },
0165     {
0166         ID_AHA_39320D_HP,
0167         ID_ALL_MASK,
0168         "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
0169         ahd_aic7902_setup
0170     },
0171     {
0172         ID_AHA_39320D_B,
0173         ID_ALL_MASK,
0174         "Adaptec 39320D Ultra320 SCSI adapter",
0175         ahd_aic7902_setup
0176     },
0177     {
0178         ID_AHA_39320D_B_HP,
0179         ID_ALL_MASK,
0180         "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
0181         ahd_aic7902_setup
0182     },
0183     /* Generic chip probes for devices we don't know 'exactly' */
0184     {
0185         ID_AIC7901 & ID_9005_GENERIC_MASK,
0186         ID_9005_GENERIC_MASK,
0187         "Adaptec AIC7901 Ultra320 SCSI adapter",
0188         ahd_aic7901_setup
0189     },
0190     {
0191         ID_AIC7901A & ID_DEV_VENDOR_MASK,
0192         ID_DEV_VENDOR_MASK,
0193         "Adaptec AIC7901A Ultra320 SCSI adapter",
0194         ahd_aic7901A_setup
0195     },
0196     {
0197         ID_AIC7902 & ID_9005_GENERIC_MASK,
0198         ID_9005_GENERIC_MASK,
0199         "Adaptec AIC7902 Ultra320 SCSI adapter",
0200         ahd_aic7902_setup
0201     }
0202 };
0203 
0204 static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
0205         
0206 #define DEVCONFIG       0x40
0207 #define     PCIXINITPAT 0x0000E000ul
0208 #define         PCIXINIT_PCI33_66   0x0000E000ul
0209 #define         PCIXINIT_PCIX50_66  0x0000C000ul
0210 #define         PCIXINIT_PCIX66_100 0x0000A000ul
0211 #define         PCIXINIT_PCIX100_133    0x00008000ul
0212 #define PCI_BUS_MODES_INDEX(devconfig)  \
0213     (((devconfig) & PCIXINITPAT) >> 13)
0214 static const char *pci_bus_modes[] =
0215 {
0216     "PCI bus mode unknown",
0217     "PCI bus mode unknown",
0218     "PCI bus mode unknown",
0219     "PCI bus mode unknown",
0220     "PCI-X 101-133MHz",
0221     "PCI-X 67-100MHz",
0222     "PCI-X 50-66MHz",
0223     "PCI 33 or 66MHz"
0224 };
0225 
0226 #define     TESTMODE    0x00000800ul
0227 #define     IRDY_RST    0x00000200ul
0228 #define     FRAME_RST   0x00000100ul
0229 #define     PCI64BIT    0x00000080ul
0230 #define     MRDCEN      0x00000040ul
0231 #define     ENDIANSEL   0x00000020ul
0232 #define     MIXQWENDIANEN   0x00000008ul
0233 #define     DACEN       0x00000004ul
0234 #define     STPWLEVEL   0x00000002ul
0235 #define     QWENDIANSEL 0x00000001ul
0236 
0237 #define DEVCONFIG1      0x44
0238 #define     PREQDIS     0x01
0239 
0240 #define CSIZE_LATTIME       0x0c
0241 #define     CACHESIZE   0x000000fful
0242 #define     LATTIME     0x0000ff00ul
0243 
0244 static int  ahd_check_extport(struct ahd_softc *ahd);
0245 static void ahd_configure_termination(struct ahd_softc *ahd,
0246                       u_int adapter_control);
0247 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
0248 static void ahd_pci_intr(struct ahd_softc *ahd);
0249 
0250 const struct ahd_pci_identity *
0251 ahd_find_pci_device(ahd_dev_softc_t pci)
0252 {
0253     uint64_t  full_id;
0254     uint16_t  device;
0255     uint16_t  vendor;
0256     uint16_t  subdevice;
0257     uint16_t  subvendor;
0258     const struct ahd_pci_identity *entry;
0259     u_int     i;
0260 
0261     vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
0262     device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
0263     subvendor = ahd_pci_read_config(pci, PCI_SUBSYSTEM_VENDOR_ID, /*bytes*/2);
0264     subdevice = ahd_pci_read_config(pci, PCI_SUBSYSTEM_ID, /*bytes*/2);
0265     full_id = ahd_compose_id(device,
0266                  vendor,
0267                  subdevice,
0268                  subvendor);
0269 
0270     /*
0271      * Controllers, mask out the IROC/HostRAID bit
0272      */
0273     
0274     full_id &= ID_ALL_IROC_MASK;
0275 
0276     for (i = 0; i < ahd_num_pci_devs; i++) {
0277         entry = &ahd_pci_ident_table[i];
0278         if (entry->full_id == (full_id & entry->id_mask)) {
0279             /* Honor exclusion entries. */
0280             if (entry->name == NULL)
0281                 return (NULL);
0282             return (entry);
0283         }
0284     }
0285     return (NULL);
0286 }
0287 
0288 int
0289 ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
0290 {
0291     u_int        command;
0292     uint32_t     devconfig;
0293     uint16_t     subvendor; 
0294     int      error;
0295 
0296     ahd->description = entry->name;
0297     /*
0298      * Record if this is an HP board.
0299      */
0300     subvendor = ahd_pci_read_config(ahd->dev_softc,
0301                     PCI_SUBSYSTEM_VENDOR_ID, /*bytes*/2);
0302     if (subvendor == SUBID_HP)
0303         ahd->flags |= AHD_HP_BOARD;
0304 
0305     error = entry->setup(ahd);
0306     if (error != 0)
0307         return (error);
0308     
0309     devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
0310     if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
0311         ahd->chip |= AHD_PCI;
0312         /* Disable PCIX workarounds when running in PCI mode. */
0313         ahd->bugs &= ~AHD_PCIX_BUG_MASK;
0314     } else {
0315         ahd->chip |= AHD_PCIX;
0316     }
0317     ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
0318 
0319     ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
0320 
0321     error = ahd_pci_map_registers(ahd);
0322     if (error != 0)
0323         return (error);
0324 
0325     /*
0326      * If we need to support high memory, enable dual
0327      * address cycles.  This bit must be set to enable
0328      * high address bit generation even if we are on a
0329      * 64bit bus (PCI64BIT set in devconfig).
0330      */
0331     if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
0332         if (bootverbose)
0333             printk("%s: Enabling 39Bit Addressing\n",
0334                    ahd_name(ahd));
0335         devconfig = ahd_pci_read_config(ahd->dev_softc,
0336                         DEVCONFIG, /*bytes*/4);
0337         devconfig |= DACEN;
0338         ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
0339                      devconfig, /*bytes*/4);
0340     }
0341     
0342     /* Ensure busmastering is enabled */
0343     command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
0344     command |= PCIM_CMD_BUSMASTEREN;
0345     ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
0346 
0347     error = ahd_softc_init(ahd);
0348     if (error != 0)
0349         return (error);
0350 
0351     ahd->bus_intr = ahd_pci_intr;
0352 
0353     error = ahd_reset(ahd, /*reinit*/FALSE);
0354     if (error != 0)
0355         return (ENXIO);
0356 
0357     ahd->pci_cachesize =
0358         ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
0359                 /*bytes*/1) & CACHESIZE;
0360     ahd->pci_cachesize *= 4;
0361 
0362     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
0363     /* See if we have a SEEPROM and perform auto-term */
0364     error = ahd_check_extport(ahd);
0365     if (error != 0)
0366         return (error);
0367 
0368     /* Core initialization */
0369     error = ahd_init(ahd);
0370     if (error != 0)
0371         return (error);
0372     ahd->init_level++;
0373 
0374     /*
0375      * Allow interrupts now that we are completely setup.
0376      */
0377     return ahd_pci_map_int(ahd);
0378 }
0379 
0380 void __maybe_unused
0381 ahd_pci_suspend(struct ahd_softc *ahd)
0382 {
0383     /*
0384      * Save chip register configuration data for chip resets
0385      * that occur during runtime and resume events.
0386      */
0387     ahd->suspend_state.pci_state.devconfig =
0388         ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
0389     ahd->suspend_state.pci_state.command =
0390         ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1);
0391     ahd->suspend_state.pci_state.csize_lattime =
0392         ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, /*bytes*/1);
0393 
0394 }
0395 
0396 void __maybe_unused
0397 ahd_pci_resume(struct ahd_softc *ahd)
0398 {
0399     ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
0400                  ahd->suspend_state.pci_state.devconfig, /*bytes*/4);
0401     ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
0402                  ahd->suspend_state.pci_state.command, /*bytes*/1);
0403     ahd_pci_write_config(ahd->dev_softc, CSIZE_LATTIME,
0404                  ahd->suspend_state.pci_state.csize_lattime, /*bytes*/1);
0405 }
0406 
0407 /*
0408  * Perform some simple tests that should catch situations where
0409  * our registers are invalidly mapped.
0410  */
0411 int
0412 ahd_pci_test_register_access(struct ahd_softc *ahd)
0413 {
0414     uint32_t cmd;
0415     u_int    targpcistat;
0416     u_int    pci_status1;
0417     int  error;
0418     uint8_t  hcntrl;
0419 
0420     error = EIO;
0421 
0422     /*
0423      * Enable PCI error interrupt status, but suppress NMIs
0424      * generated by SERR raised due to target aborts.
0425      */
0426     cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
0427     ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
0428                  cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
0429 
0430     /*
0431      * First a simple test to see if any
0432      * registers can be read.  Reading
0433      * HCNTRL has no side effects and has
0434      * at least one bit that is guaranteed to
0435      * be zero so it is a good register to
0436      * use for this test.
0437      */
0438     hcntrl = ahd_inb(ahd, HCNTRL);
0439     if (hcntrl == 0xFF)
0440         goto fail;
0441 
0442     /*
0443      * Next create a situation where write combining
0444      * or read prefetching could be initiated by the
0445      * CPU or host bridge.  Our device does not support
0446      * either, so look for data corruption and/or flaged
0447      * PCI errors.  First pause without causing another
0448      * chip reset.
0449      */
0450     hcntrl &= ~CHIPRST;
0451     ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
0452     while (ahd_is_paused(ahd) == 0)
0453         ;
0454 
0455     /* Clear any PCI errors that occurred before our driver attached. */
0456     ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0457     targpcistat = ahd_inb(ahd, TARGPCISTAT);
0458     ahd_outb(ahd, TARGPCISTAT, targpcistat);
0459     pci_status1 = ahd_pci_read_config(ahd->dev_softc,
0460                       PCIR_STATUS + 1, /*bytes*/1);
0461     ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
0462                  pci_status1, /*bytes*/1);
0463     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
0464     ahd_outb(ahd, CLRINT, CLRPCIINT);
0465 
0466     ahd_outb(ahd, SEQCTL0, PERRORDIS);
0467     ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
0468     if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
0469         goto fail;
0470 
0471     if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
0472         ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0473         targpcistat = ahd_inb(ahd, TARGPCISTAT);
0474         if ((targpcistat & STA) != 0)
0475             goto fail;
0476     }
0477 
0478     error = 0;
0479 
0480 fail:
0481     if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
0482 
0483         ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0484         targpcistat = ahd_inb(ahd, TARGPCISTAT);
0485 
0486         /* Silently clear any latched errors. */
0487         ahd_outb(ahd, TARGPCISTAT, targpcistat);
0488         pci_status1 = ahd_pci_read_config(ahd->dev_softc,
0489                           PCIR_STATUS + 1, /*bytes*/1);
0490         ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
0491                      pci_status1, /*bytes*/1);
0492         ahd_outb(ahd, CLRINT, CLRPCIINT);
0493     }
0494     ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
0495     ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
0496     return (error);
0497 }
0498 
0499 /*
0500  * Check the external port logic for a serial eeprom
0501  * and termination/cable detection contrls.
0502  */
0503 static int
0504 ahd_check_extport(struct ahd_softc *ahd)
0505 {
0506     struct  vpd_config vpd;
0507     struct  seeprom_config *sc;
0508     u_int   adapter_control;
0509     int have_seeprom;
0510     int error;
0511 
0512     sc = ahd->seep_config;
0513     have_seeprom = ahd_acquire_seeprom(ahd);
0514     if (have_seeprom) {
0515         u_int start_addr;
0516 
0517         /*
0518          * Fetch VPD for this function and parse it.
0519          */
0520         if (bootverbose) 
0521             printk("%s: Reading VPD from SEEPROM...",
0522                    ahd_name(ahd));
0523 
0524         /* Address is always in units of 16bit words */
0525         start_addr = ((2 * sizeof(*sc))
0526                 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
0527 
0528         error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
0529                      start_addr, sizeof(vpd)/2,
0530                      /*bytestream*/TRUE);
0531         if (error == 0)
0532             error = ahd_parse_vpddata(ahd, &vpd);
0533         if (bootverbose) 
0534             printk("%s: VPD parsing %s\n",
0535                    ahd_name(ahd),
0536                    error == 0 ? "successful" : "failed");
0537 
0538         if (bootverbose) 
0539             printk("%s: Reading SEEPROM...", ahd_name(ahd));
0540 
0541         /* Address is always in units of 16bit words */
0542         start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
0543 
0544         error = ahd_read_seeprom(ahd, (uint16_t *)sc,
0545                      start_addr, sizeof(*sc)/2,
0546                      /*bytestream*/FALSE);
0547 
0548         if (error != 0) {
0549             printk("Unable to read SEEPROM\n");
0550             have_seeprom = 0;
0551         } else {
0552             have_seeprom = ahd_verify_cksum(sc);
0553 
0554             if (bootverbose) {
0555                 if (have_seeprom == 0)
0556                     printk ("checksum error\n");
0557                 else
0558                     printk ("done.\n");
0559             }
0560         }
0561         ahd_release_seeprom(ahd);
0562     }
0563 
0564     if (!have_seeprom) {
0565         u_int     nvram_scb;
0566 
0567         /*
0568          * Pull scratch ram settings and treat them as
0569          * if they are the contents of an seeprom if
0570          * the 'ADPT', 'BIOS', or 'ASPI' signature is found
0571          * in SCB 0xFF.  We manually compose the data as 16bit
0572          * values to avoid endian issues.
0573          */
0574         ahd_set_scbptr(ahd, 0xFF);
0575         nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
0576         if (nvram_scb != 0xFF
0577          && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
0578            && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
0579            && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
0580            && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
0581           || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
0582            && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
0583            && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
0584            && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
0585           || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
0586            && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
0587            && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
0588            && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
0589             uint16_t *sc_data;
0590             int   i;
0591 
0592             ahd_set_scbptr(ahd, nvram_scb);
0593             sc_data = (uint16_t *)sc;
0594             for (i = 0; i < 64; i += 2)
0595                 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
0596             have_seeprom = ahd_verify_cksum(sc);
0597             if (have_seeprom)
0598                 ahd->flags |= AHD_SCB_CONFIG_USED;
0599         }
0600     }
0601 
0602 #ifdef AHD_DEBUG
0603     if (have_seeprom != 0
0604      && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
0605         uint16_t *sc_data;
0606         int   i;
0607 
0608         printk("%s: Seeprom Contents:", ahd_name(ahd));
0609         sc_data = (uint16_t *)sc;
0610         for (i = 0; i < (sizeof(*sc)); i += 2)
0611             printk("\n\t0x%.4x", sc_data[i]);
0612         printk("\n");
0613     }
0614 #endif
0615 
0616     if (!have_seeprom) {
0617         if (bootverbose)
0618             printk("%s: No SEEPROM available.\n", ahd_name(ahd));
0619         ahd->flags |= AHD_USEDEFAULTS;
0620         error = ahd_default_config(ahd);
0621         adapter_control = CFAUTOTERM|CFSEAUTOTERM;
0622         kfree(ahd->seep_config);
0623         ahd->seep_config = NULL;
0624     } else {
0625         error = ahd_parse_cfgdata(ahd, sc);
0626         adapter_control = sc->adapter_control;
0627     }
0628     if (error != 0)
0629         return (error);
0630 
0631     ahd_configure_termination(ahd, adapter_control);
0632 
0633     return (0);
0634 }
0635 
0636 static void
0637 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
0638 {
0639     int  error;
0640     u_int    sxfrctl1;
0641     uint8_t  termctl;
0642     uint32_t devconfig;
0643 
0644     devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
0645     devconfig &= ~STPWLEVEL;
0646     if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
0647         devconfig |= STPWLEVEL;
0648     if (bootverbose)
0649         printk("%s: STPWLEVEL is %s\n",
0650                ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
0651     ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
0652  
0653     /* Make sure current sensing is off. */
0654     if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
0655         (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
0656     }
0657 
0658     /*
0659      * Read to sense.  Write to set.
0660      */
0661     error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
0662     if ((adapter_control & CFAUTOTERM) == 0) {
0663         if (bootverbose)
0664             printk("%s: Manual Primary Termination\n",
0665                    ahd_name(ahd));
0666         termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
0667         if ((adapter_control & CFSTERM) != 0)
0668             termctl |= FLX_TERMCTL_ENPRILOW;
0669         if ((adapter_control & CFWSTERM) != 0)
0670             termctl |= FLX_TERMCTL_ENPRIHIGH;
0671     } else if (error != 0) {
0672         printk("%s: Primary Auto-Term Sensing failed! "
0673                "Using Defaults.\n", ahd_name(ahd));
0674         termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
0675     }
0676 
0677     if ((adapter_control & CFSEAUTOTERM) == 0) {
0678         if (bootverbose)
0679             printk("%s: Manual Secondary Termination\n",
0680                    ahd_name(ahd));
0681         termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
0682         if ((adapter_control & CFSELOWTERM) != 0)
0683             termctl |= FLX_TERMCTL_ENSECLOW;
0684         if ((adapter_control & CFSEHIGHTERM) != 0)
0685             termctl |= FLX_TERMCTL_ENSECHIGH;
0686     } else if (error != 0) {
0687         printk("%s: Secondary Auto-Term Sensing failed! "
0688                "Using Defaults.\n", ahd_name(ahd));
0689         termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
0690     }
0691 
0692     /*
0693      * Now set the termination based on what we found.
0694      */
0695     sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
0696     ahd->flags &= ~AHD_TERM_ENB_A;
0697     if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
0698         ahd->flags |= AHD_TERM_ENB_A;
0699         sxfrctl1 |= STPWEN;
0700     }
0701     /* Must set the latch once in order to be effective. */
0702     ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
0703     ahd_outb(ahd, SXFRCTL1, sxfrctl1);
0704 
0705     error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
0706     if (error != 0) {
0707         printk("%s: Unable to set termination settings!\n",
0708                ahd_name(ahd));
0709     } else if (bootverbose) {
0710         printk("%s: Primary High byte termination %sabled\n",
0711                ahd_name(ahd),
0712                (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
0713 
0714         printk("%s: Primary Low byte termination %sabled\n",
0715                ahd_name(ahd),
0716                (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
0717 
0718         printk("%s: Secondary High byte termination %sabled\n",
0719                ahd_name(ahd),
0720                (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
0721 
0722         printk("%s: Secondary Low byte termination %sabled\n",
0723                ahd_name(ahd),
0724                (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
0725     }
0726     return;
0727 }
0728 
0729 #define DPE 0x80
0730 #define SSE 0x40
0731 #define RMA 0x20
0732 #define RTA 0x10
0733 #define STA 0x08
0734 #define DPR 0x01
0735 
0736 static const char *split_status_source[] =
0737 {
0738     "DFF0",
0739     "DFF1",
0740     "OVLY",
0741     "CMC",
0742 };
0743 
0744 static const char *pci_status_source[] =
0745 {
0746     "DFF0",
0747     "DFF1",
0748     "SG",
0749     "CMC",
0750     "OVLY",
0751     "NONE",
0752     "MSI",
0753     "TARG"
0754 };
0755 
0756 static const char *split_status_strings[] =
0757 {
0758     "%s: Received split response in %s.\n",
0759     "%s: Received split completion error message in %s\n",
0760     "%s: Receive overrun in %s\n",
0761     "%s: Count not complete in %s\n",
0762     "%s: Split completion data bucket in %s\n",
0763     "%s: Split completion address error in %s\n",
0764     "%s: Split completion byte count error in %s\n",
0765     "%s: Signaled Target-abort to early terminate a split in %s\n"
0766 };
0767 
0768 static const char *pci_status_strings[] =
0769 {
0770     "%s: Data Parity Error has been reported via PERR# in %s\n",
0771     "%s: Target initial wait state error in %s\n",
0772     "%s: Split completion read data parity error in %s\n",
0773     "%s: Split completion address attribute parity error in %s\n",
0774     "%s: Received a Target Abort in %s\n",
0775     "%s: Received a Master Abort in %s\n",
0776     "%s: Signal System Error Detected in %s\n",
0777     "%s: Address or Write Phase Parity Error Detected in %s.\n"
0778 };
0779 
0780 static void
0781 ahd_pci_intr(struct ahd_softc *ahd)
0782 {
0783     uint8_t     pci_status[8];
0784     ahd_mode_state  saved_modes;
0785     u_int       pci_status1;
0786     u_int       intstat;
0787     u_int       i;
0788     u_int       reg;
0789     
0790     intstat = ahd_inb(ahd, INTSTAT);
0791 
0792     if ((intstat & SPLTINT) != 0)
0793         ahd_pci_split_intr(ahd, intstat);
0794 
0795     if ((intstat & PCIINT) == 0)
0796         return;
0797 
0798     printk("%s: PCI error Interrupt\n", ahd_name(ahd));
0799     saved_modes = ahd_save_modes(ahd);
0800     ahd_dump_card_state(ahd);
0801     ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0802     for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
0803 
0804         if (i == 5)
0805             continue;
0806         pci_status[i] = ahd_inb(ahd, reg);
0807         /* Clear latched errors.  So our interrupt deasserts. */
0808         ahd_outb(ahd, reg, pci_status[i]);
0809     }
0810 
0811     for (i = 0; i < 8; i++) {
0812         u_int bit;
0813     
0814         if (i == 5)
0815             continue;
0816 
0817         for (bit = 0; bit < 8; bit++) {
0818 
0819             if ((pci_status[i] & (0x1 << bit)) != 0) {
0820                 const char *s;
0821 
0822                 s = pci_status_strings[bit];
0823                 if (i == 7/*TARG*/ && bit == 3)
0824                     s = "%s: Signaled Target Abort\n";
0825                 printk(s, ahd_name(ahd), pci_status_source[i]);
0826             }
0827         }   
0828     }
0829     pci_status1 = ahd_pci_read_config(ahd->dev_softc,
0830                       PCIR_STATUS + 1, /*bytes*/1);
0831     ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
0832                  pci_status1, /*bytes*/1);
0833     ahd_restore_modes(ahd, saved_modes);
0834     ahd_outb(ahd, CLRINT, CLRPCIINT);
0835     ahd_unpause(ahd);
0836 }
0837 
0838 static void
0839 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
0840 {
0841     uint8_t     split_status[4];
0842     uint8_t     split_status1[4];
0843     uint8_t     sg_split_status[2];
0844     uint8_t     sg_split_status1[2];
0845     ahd_mode_state  saved_modes;
0846     u_int       i;
0847     uint16_t    pcix_status;
0848 
0849     /*
0850      * Check for splits in all modes.  Modes 0 and 1
0851      * additionally have SG engine splits to look at.
0852      */
0853     pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
0854                       /*bytes*/2);
0855     printk("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
0856            ahd_name(ahd), pcix_status);
0857     saved_modes = ahd_save_modes(ahd);
0858     for (i = 0; i < 4; i++) {
0859         ahd_set_modes(ahd, i, i);
0860 
0861         split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
0862         split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
0863         /* Clear latched errors.  So our interrupt deasserts. */
0864         ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
0865         ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
0866         if (i > 1)
0867             continue;
0868         sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
0869         sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
0870         /* Clear latched errors.  So our interrupt deasserts. */
0871         ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
0872         ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
0873     }
0874 
0875     for (i = 0; i < 4; i++) {
0876         u_int bit;
0877 
0878         for (bit = 0; bit < 8; bit++) {
0879 
0880             if ((split_status[i] & (0x1 << bit)) != 0)
0881                 printk(split_status_strings[bit], ahd_name(ahd),
0882                        split_status_source[i]);
0883 
0884             if (i > 1)
0885                 continue;
0886 
0887             if ((sg_split_status[i] & (0x1 << bit)) != 0)
0888                 printk(split_status_strings[bit], ahd_name(ahd), "SG");
0889         }
0890     }
0891     /*
0892      * Clear PCI-X status bits.
0893      */
0894     ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
0895                  pcix_status, /*bytes*/2);
0896     ahd_outb(ahd, CLRINT, CLRSPLTINT);
0897     ahd_restore_modes(ahd, saved_modes);
0898 }
0899 
0900 static int
0901 ahd_aic7901_setup(struct ahd_softc *ahd)
0902 {
0903 
0904     ahd->chip = AHD_AIC7901;
0905     ahd->features = AHD_AIC7901_FE;
0906     return (ahd_aic790X_setup(ahd));
0907 }
0908 
0909 static int
0910 ahd_aic7901A_setup(struct ahd_softc *ahd)
0911 {
0912 
0913     ahd->chip = AHD_AIC7901A;
0914     ahd->features = AHD_AIC7901A_FE;
0915     return (ahd_aic790X_setup(ahd));
0916 }
0917 
0918 static int
0919 ahd_aic7902_setup(struct ahd_softc *ahd)
0920 {
0921     ahd->chip = AHD_AIC7902;
0922     ahd->features = AHD_AIC7902_FE;
0923     return (ahd_aic790X_setup(ahd));
0924 }
0925 
0926 static int
0927 ahd_aic790X_setup(struct ahd_softc *ahd)
0928 {
0929     ahd_dev_softc_t pci;
0930     u_int rev;
0931 
0932     pci = ahd->dev_softc;
0933     rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
0934     if (rev < ID_AIC7902_PCI_REV_A4) {
0935         printk("%s: Unable to attach to unsupported chip revision %d\n",
0936                ahd_name(ahd), rev);
0937         ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
0938         return (ENXIO);
0939     }
0940     ahd->channel = ahd_get_pci_function(pci) + 'A';
0941     if (rev < ID_AIC7902_PCI_REV_B0) {
0942         /*
0943          * Enable A series workarounds.
0944          */
0945         ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
0946               |  AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
0947               |  AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
0948               |  AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
0949               |  AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
0950               |  AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
0951               |  AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
0952               |  AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
0953               |  AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
0954               |  AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
0955               |  AHD_FAINT_LED_BUG;
0956 
0957         /*
0958          * IO Cell parameter setup.
0959          */
0960         AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
0961 
0962         if ((ahd->flags & AHD_HP_BOARD) == 0)
0963             AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
0964     } else {
0965         /* This is revision B and newer. */
0966         extern uint32_t aic79xx_slowcrc;
0967         u_int devconfig1;
0968 
0969         ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
0970                   |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY
0971                   |  AHD_BUSFREEREV_BUG;
0972         ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
0973 
0974         /* If the user requested that the SLOWCRC bit to be set. */
0975         if (aic79xx_slowcrc)
0976             ahd->features |= AHD_AIC79XXB_SLOWCRC;
0977 
0978         /*
0979          * Some issues have been resolved in the 7901B.
0980          */
0981         if ((ahd->features & AHD_MULTI_FUNC) != 0)
0982             ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
0983 
0984         /*
0985          * IO Cell parameter setup.
0986          */
0987         AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
0988         AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
0989         AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
0990 
0991         /*
0992          * Set the PREQDIS bit for H2B which disables some workaround
0993          * that doesn't work on regular PCI busses.
0994          * XXX - Find out exactly what this does from the hardware
0995          *   folks!
0996          */
0997         devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
0998         ahd_pci_write_config(pci, DEVCONFIG1,
0999                      devconfig1|PREQDIS, /*bytes*/1);
1000         devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
1001     }
1002 
1003     return (0);
1004 }