root/dev/pci/ahd_pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ahd_compose_id
  2. ahd_find_pci_device
  3. ahd_pci_probe
  4. ahd_pci_attach
  5. ahd_pci_test_register_access
  6. ahd_check_extport
  7. ahd_configure_termination
  8. ahd_pci_intr
  9. ahd_pci_split_intr
  10. ahd_aic7901_setup
  11. ahd_aic7901A_setup
  12. ahd_aic7902_setup
  13. ahd_aic790X_setup

    1 /*      $OpenBSD: ahd_pci.c,v 1.15 2006/10/19 10:55:56 tom Exp $        */
    2 
    3 /*
    4  * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
   20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  */
   29 
   30 /*
   31  * Product specific probe and attach routines for:
   32  *      aic7901 and aic7902 SCSI controllers
   33  *
   34  * Copyright (c) 1994-2001 Justin T. Gibbs.
   35  * Copyright (c) 2000-2002 Adaptec Inc.
   36  * All rights reserved.
   37  *
   38  * Redistribution and use in source and binary forms, with or without
   39  * modification, are permitted provided that the following conditions
   40  * are met:
   41  * 1. Redistributions of source code must retain the above copyright
   42  *    notice, this list of conditions, and the following disclaimer,
   43  *    without modification.
   44  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   45  *    substantially similar to the "NO WARRANTY" disclaimer below
   46  *    ("Disclaimer") and any redistribution must be conditioned upon
   47  *    including a substantially similar Disclaimer requirement for further
   48  *    binary redistribution.
   49  * 3. Neither the names of the above-listed copyright holders nor the names
   50  *    of any contributors may be used to endorse or promote products derived
   51  *    from this software without specific prior written permission.
   52  *
   53  * Alternatively, this software may be distributed under the terms of the
   54  * GNU General Public License ("GPL") version 2 as published by the Free
   55  * Software Foundation.
   56  *
   57  * NO WARRANTY
   58  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   59  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   60  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   61  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   62  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   66  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   67  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   68  * POSSIBILITY OF SUCH DAMAGES.
   69  *
   70  */
   71 
   72 #include <sys/cdefs.h>
   73 /*
   74 __FBSDID("$FreeBSD: src/sys/dev/aic7xxx/aic79xx_pci.c,v 1.18 2004/02/04 16:38:38 gibbs Exp $");
   75 */
   76 
   77 #include <dev/ic/aic79xx_openbsd.h>
   78 #include <dev/ic/aic79xx_inline.h>
   79 #include <dev/ic/aic79xx.h>
   80 
   81 #include <dev/pci/pcivar.h>
   82 
   83 __inline uint64_t ahd_compose_id(u_int, u_int, u_int, u_int);
   84 __inline uint64_t
   85 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
   86 {
   87         uint64_t id;
   88 
   89         id = subvendor
   90            | (subdevice << 16)
   91            | ((uint64_t)vendor << 32)
   92            | ((uint64_t)device << 48);
   93 
   94         return (id);
   95 }
   96 
   97 #define ID_ALL_MASK                     0xFFFFFFFFFFFFFFFFull
   98 #define ID_ALL_IROC_MASK                0xFF7FFFFFFFFFFFFFull
   99 #define ID_DEV_VENDOR_MASK              0xFFFFFFFF00000000ull
  100 #define ID_9005_GENERIC_MASK            0xFFF0FFFF00000000ull
  101 #define ID_9005_GENERIC_IROC_MASK       0xFF70FFFF00000000ull
  102 
  103 #define ID_AIC7901                      0x800F9005FFFF9005ull
  104 #define ID_AHA_29320A                   0x8000900500609005ull
  105 #define ID_AHA_29320ALP                 0x8017900500449005ull
  106 
  107 #define ID_AIC7901A                     0x801E9005FFFF9005ull
  108 #define ID_AHA_29320LP                  0x8014900500449005ull
  109 
  110 #define ID_AIC7902                      0x801F9005FFFF9005ull
  111 #define ID_AIC7902_B                    0x801D9005FFFF9005ull
  112 #define ID_AHA_39320                    0x8010900500409005ull
  113 #define ID_AHA_29320                    0x8012900500429005ull
  114 #define ID_AHA_29320B                   0x8013900500439005ull
  115 #define ID_AHA_39320_B                  0x8015900500409005ull
  116 #define ID_AHA_39320_B_DELL             0x8015900501681028ull
  117 #define ID_AHA_39320A                   0x8016900500409005ull
  118 #define ID_AHA_39320D                   0x8011900500419005ull
  119 #define ID_AHA_39320D_B                 0x801C900500419005ull
  120 #define ID_AHA_39320D_HP                0x8011900500AC0E11ull
  121 #define ID_AHA_39320D_B_HP              0x801C900500AC0E11ull
  122 #define ID_AIC7902_PCI_REV_A4           0x3
  123 #define ID_AIC7902_PCI_REV_B0           0x10
  124 #define SUBID_HP                        0x0E11
  125 
  126 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
  127 
  128 #define DEVID_9005_TYPE(id) ((id) & 0xF)
  129 #define         DEVID_9005_TYPE_HBA             0x0     /* Standard Card */
  130 #define         DEVID_9005_TYPE_HBA_2EXT        0x1     /* 2 External Ports */
  131 #define         DEVID_9005_TYPE_MB              0xF     /* On Motherboard */
  132 
  133 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
  134 
  135 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
  136 
  137 #define SUBID_9005_TYPE(id) ((id) & 0xF)
  138 #define         SUBID_9005_TYPE_HBA             0x0     /* Standard Card */
  139 #define         SUBID_9005_TYPE_MB              0xF     /* On Motherboard */
  140 
  141 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
  142 
  143 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
  144 
  145 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
  146 #define         SUBID_9005_SEEPTYPE_NONE        0x0
  147 #define         SUBID_9005_SEEPTYPE_4K          0x1
  148 
  149 ahd_device_setup_t ahd_aic7901_setup;
  150 ahd_device_setup_t ahd_aic7901A_setup;
  151 ahd_device_setup_t ahd_aic7902_setup;
  152 ahd_device_setup_t ahd_aic790X_setup;
  153 
  154 struct ahd_pci_identity ahd_pci_ident_table [] =
  155 {
  156         /* aic7901 based controllers */
  157         {
  158                 ID_AHA_29320A,
  159                 ID_ALL_MASK,
  160                 ahd_aic7901_setup
  161         },
  162         {
  163                 ID_AHA_29320ALP,
  164                 ID_ALL_MASK,
  165                 ahd_aic7901_setup
  166         },
  167         /* aic7901A based controllers */
  168         {
  169                 ID_AHA_29320LP,
  170                 ID_ALL_MASK,
  171                 ahd_aic7901A_setup
  172         },
  173         /* aic7902 based controllers */ 
  174         {
  175                 ID_AHA_29320,
  176                 ID_ALL_MASK,
  177                 ahd_aic7902_setup
  178         },
  179         {
  180                 ID_AHA_29320B,
  181                 ID_ALL_MASK,
  182                 ahd_aic7902_setup
  183         },
  184         {
  185                 ID_AHA_39320,
  186                 ID_ALL_MASK,
  187                 ahd_aic7902_setup
  188         },
  189         {
  190                 ID_AHA_39320_B,
  191                 ID_ALL_MASK,
  192                 ahd_aic7902_setup
  193         },
  194         {
  195                 ID_AHA_39320_B_DELL,
  196                 ID_ALL_MASK,
  197                 ahd_aic7902_setup
  198         },
  199         {
  200                 ID_AHA_39320A,
  201                 ID_ALL_MASK,
  202                 ahd_aic7902_setup
  203         },
  204         {
  205                 ID_AHA_39320D,
  206                 ID_ALL_MASK,
  207                 ahd_aic7902_setup
  208         },
  209         {
  210                 ID_AHA_39320D_HP,
  211                 ID_ALL_MASK,
  212                 ahd_aic7902_setup
  213         },
  214         {
  215                 ID_AHA_39320D_B,
  216                 ID_ALL_MASK,
  217                 ahd_aic7902_setup
  218         },
  219         {
  220                 ID_AHA_39320D_B_HP,
  221                 ID_ALL_MASK,
  222                 ahd_aic7902_setup
  223         },
  224         /* Generic chip probes for devices we don't know 'exactly' */
  225         {
  226                 ID_AIC7901 & ID_9005_GENERIC_MASK,
  227                 ID_9005_GENERIC_MASK,
  228                 ahd_aic7901_setup
  229         },
  230         {
  231                 ID_AIC7901A & ID_DEV_VENDOR_MASK,
  232                 ID_DEV_VENDOR_MASK,
  233                 ahd_aic7901A_setup
  234         },
  235         {
  236                 ID_AIC7902 & ID_9005_GENERIC_MASK,
  237                 ID_9005_GENERIC_MASK,
  238                 ahd_aic7902_setup
  239         }
  240 };
  241 
  242 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
  243                 
  244 #define                 DEVCONFIG               0x40
  245 #define                 PCIXINITPAT             0x0000E000ul
  246 #define                 PCIXINIT_PCI33_66       0x0000E000ul
  247 #define                 PCIXINIT_PCIX50_66      0x0000C000ul
  248 #define                 PCIXINIT_PCIX66_100     0x0000A000ul
  249 #define                 PCIXINIT_PCIX100_133    0x00008000ul
  250 #define PCI_BUS_MODES_INDEX(devconfig)  \
  251         (((devconfig) & PCIXINITPAT) >> 13)
  252 
  253 static const char *pci_bus_modes[] =
  254 {
  255         "PCI bus mode unknown",
  256         "PCI bus mode unknown",
  257         "PCI bus mode unknown",
  258         "PCI bus mode unknown",
  259         "PCI-X 101-133MHz",
  260         "PCI-X 67-100MHz",
  261         "PCI-X 50-66MHz",
  262         "PCI 33 or 66MHz"
  263 };
  264 
  265 #define         TESTMODE        0x00000800ul
  266 #define         IRDY_RST        0x00000200ul
  267 #define         FRAME_RST       0x00000100ul
  268 #define         PCI64BIT        0x00000080ul
  269 #define         MRDCEN          0x00000040ul
  270 #define         ENDIANSEL       0x00000020ul
  271 #define         MIXQWENDIANEN   0x00000008ul
  272 #define         DACEN           0x00000004ul
  273 #define         STPWLEVEL       0x00000002ul
  274 #define         QWENDIANSEL     0x00000001ul
  275 
  276 #define DEVCONFIG1              0x44
  277 #define         PREQDIS         0x01
  278 
  279 #define CSIZE_LATTIME           0x0c
  280 #define         CACHESIZE       0x000000fful
  281 #define         LATTIME         0x0000ff00ul
  282 
  283 int     ahd_pci_probe(struct device *, void *, void *);
  284 void    ahd_pci_attach(struct device *, struct device *, void *);
  285 
  286 struct cfattach ahd_pci_ca = {
  287                 sizeof(struct ahd_softc), ahd_pci_probe, ahd_pci_attach
  288 };
  289 
  290 int     ahd_check_extport(struct ahd_softc *ahd);
  291 void    ahd_configure_termination(struct ahd_softc *ahd,
  292                                           u_int adapter_control);
  293 void    ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
  294 
  295 const struct ahd_pci_identity *
  296 ahd_find_pci_device(pcireg_t id, pcireg_t subid)
  297 {
  298         const struct ahd_pci_identity *entry;
  299         u_int64_t full_id;
  300         u_int i;
  301 
  302         full_id = ahd_compose_id(PCI_PRODUCT(id), PCI_VENDOR(id),
  303             PCI_PRODUCT(subid), PCI_VENDOR(subid));
  304 
  305         /*
  306          * If we are configured to attach to HostRAID
  307          * controllers, mask out the IROC/HostRAID bit
  308          * in the
  309          */
  310         if (ahd_attach_to_HostRAID_controllers)
  311                 full_id &= ID_ALL_IROC_MASK;
  312 
  313         for (i = 0; i < ahd_num_pci_devs; i++) {
  314                 entry = &ahd_pci_ident_table[i];
  315                 if (entry->full_id == (full_id & entry->id_mask)) {
  316                         return (entry);
  317                 }
  318         }
  319         return (NULL);
  320 }
  321 
  322 int
  323 ahd_pci_probe(struct device *parent, void *match, void *aux)
  324 {
  325         const struct ahd_pci_identity *entry;
  326         struct pci_attach_args *pa = aux;
  327         pcireg_t subid;
  328 
  329         subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
  330         entry = ahd_find_pci_device(pa->pa_id, subid);
  331         return entry != NULL ? 1 : 0;
  332 }
  333 
  334 void
  335 ahd_pci_attach(struct device *parent, struct device *self, void *aux)
  336 {
  337         const struct ahd_pci_identity *entry;
  338         struct pci_attach_args *pa = aux;
  339         struct ahd_softc *ahd = (void *)self;
  340         pci_intr_handle_t ih;
  341         const char *intrstr;
  342         pcireg_t devconfig, memtype, reg, subid;
  343         uint16_t device, subvendor; 
  344         int error, ioh_valid, ioh2_valid, l, memh_valid, offset;
  345 
  346         ahd->dev_softc = pa;
  347         ahd->parent_dmat = pa->pa_dmat;
  348 
  349         if (ahd_alloc(ahd, ahd->sc_dev.dv_xname) == NULL)
  350                 return;
  351 
  352         subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
  353         entry = ahd_find_pci_device(pa->pa_id, subid);
  354         if (entry == NULL)
  355                 return;
  356 
  357         /*
  358          * Record if this is a HostRAID board.
  359          */
  360         device = PCI_PRODUCT(pa->pa_id);
  361         if (DEVID_9005_HOSTRAID(device))
  362                 ahd->flags |= AHD_HOSTRAID_BOARD;
  363 
  364         /*
  365          * Record if this is an HP board.
  366          */
  367         subvendor = PCI_VENDOR(subid);
  368         if (subvendor == SUBID_HP)
  369                 ahd->flags |= AHD_HP_BOARD;
  370 
  371         error = entry->setup(ahd, pa);
  372         if (error != 0)
  373                 return;
  374         
  375         /* XXX ahc on sparc64 needs this twice */
  376         devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
  377         
  378         if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
  379                 ahd->chip |= AHD_PCI;
  380                 /* Disable PCIX workarounds when running in PCI mode. */
  381                 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
  382         } else {
  383                 ahd->chip |= AHD_PCIX;
  384         }
  385         ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
  386 
  387         memh_valid = ioh_valid = ioh2_valid = 0;
  388 
  389         if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
  390             &ahd->pcix_off, NULL)) {
  391                 if (ahd->chip & AHD_PCIX)
  392                         printf("%s: warning: can't find PCI-X capability\n",
  393                             ahd_name(ahd));
  394                 ahd->chip &= ~AHD_PCIX;
  395                 ahd->chip |= AHD_PCI;
  396                 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
  397         }
  398 
  399         /*
  400          * Map PCI registers
  401          */
  402         if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) {
  403                 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
  404                     AHD_PCI_MEMADDR);
  405                 switch (memtype) {
  406                 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
  407                 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
  408                         memh_valid = (pci_mapreg_map(pa, AHD_PCI_MEMADDR,
  409                             memtype, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
  410                             NULL, 0) == 0);
  411                         if (memh_valid) {
  412                                 ahd->tags[1] = ahd->tags[0];
  413                                 bus_space_subregion(ahd->tags[0], ahd->bshs[0],
  414                                     /*offset*/0x100, /*size*/0x100,
  415                                     &ahd->bshs[1]);
  416                                 if (ahd_pci_test_register_access(ahd) != 0)
  417                                         memh_valid = 0;
  418                         }
  419                         break;
  420                 default:
  421                         memh_valid = 0;
  422                         printf("%s: unknown memory type: 0x%x\n",
  423                         ahd_name(ahd), memtype);
  424                         break;
  425                 }
  426 
  427 #ifdef AHD_DEBUG
  428                 printf("%s: doing memory mapping tag0 0x%x, tag1 0x%x, shs0 "
  429                     "0x%lx, shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0],
  430                     ahd->tags[1], ahd->bshs[0], ahd->bshs[1]);
  431 #endif
  432         }
  433 
  434         if (!memh_valid) {
  435                 /* First BAR */
  436                 ioh_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR,
  437                     PCI_MAPREG_TYPE_IO, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
  438                     NULL, 0) == 0);
  439 
  440                 /* 2nd BAR */
  441                 ioh2_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR1,
  442                     PCI_MAPREG_TYPE_IO, 0, &ahd->tags[1], &ahd->bshs[1], NULL,
  443                     NULL, 0) == 0);
  444 
  445 #ifdef AHD_DEBUG
  446                 printf("%s: doing io mapping tag0 0x%x, tag1 0x%x, shs0 0x%lx, "
  447                     "shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0], ahd->tags[1],
  448                     ahd->bshs[0], ahd->bshs[1]);
  449 #endif
  450         }
  451 
  452         if (memh_valid == 0 && (ioh_valid == 0 || ioh2_valid == 0)) {
  453                 printf("%s: unable to map registers\n", ahd_name(ahd));
  454                 return;
  455         }
  456 
  457         /*
  458          * Set Power State D0.
  459          */
  460         if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT, &offset,
  461             NULL)) {
  462                 /* Increment offset from cap register to csr register. */
  463                 offset += 4;
  464                 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, offset);
  465                 if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
  466                         pci_conf_write(pa->pa_pc, pa->pa_tag, offset,
  467                             (reg & ~PCI_PMCSR_STATE_MASK) | PCI_PMCSR_STATE_D0);
  468                 }
  469         }
  470 
  471         /*
  472          * Should we bother disabling 39Bit addressing
  473          * based on installed memory?
  474          */
  475         if (sizeof(bus_addr_t) > 4)
  476                 ahd->flags |= AHD_39BIT_ADDRESSING;
  477 
  478         /*
  479          * If we need to support high memory, enable dual
  480          * address cycles.  This bit must be set to enable
  481          * high address bit generation even if we are on a
  482          * 64bit bus (PCI64BIT set in devconfig).
  483          */
  484         if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
  485                 pcireg_t devconfig;
  486 
  487                 if (bootverbose)
  488                         printf("%s: Enabling 39Bit Addressing\n",
  489                                ahd_name(ahd));
  490                 devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
  491                 devconfig |= DACEN;
  492                 pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, devconfig);
  493         }
  494         
  495         ahd_softc_init(ahd);
  496 
  497         /*
  498          * Map the interrupts routines
  499          */
  500         ahd->bus_intr = ahd_pci_intr;
  501 
  502         error = ahd_reset(ahd, /*reinit*/FALSE);
  503         if (error != 0) {
  504                 ahd_free(ahd);
  505                 return;
  506         }
  507 
  508         if (pci_intr_map(pa, &ih)) {
  509                 printf("%s: couldn't map interrupt\n", ahd_name(ahd));
  510                 ahd_free(ahd);
  511                 return;
  512         }
  513         intrstr = pci_intr_string(pa->pa_pc, ih);
  514         ahd->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
  515         ahd_platform_intr, ahd, ahd->sc_dev.dv_xname);
  516         if (ahd->ih == NULL) {
  517                 printf("%s: couldn't establish interrupt", ahd_name(ahd));
  518                 if (intrstr != NULL)
  519                         printf(" at %s", intrstr);
  520                 printf("\n");
  521                 ahd_free(ahd);
  522                 return;
  523         }
  524         if (intrstr != NULL)
  525                 printf(": %s\n", intrstr);
  526         
  527         /* Get the size of the cache */
  528         ahd->pci_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
  529         ahd->pci_cachesize *= 4;
  530 
  531         ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
  532         /* See if we have a SEEPROM and perform auto-term */
  533         error = ahd_check_extport(ahd);
  534         if (error != 0)
  535                 return;
  536 
  537         /* Core initialization */
  538         error = ahd_init(ahd);
  539         if (error != 0)
  540                 return;
  541 
  542         ahd_list_lock(&l);
  543         /*
  544          * Link this softc in with all other ahd instances.
  545          */
  546         ahd_softc_insert(ahd);
  547         ahd_list_unlock(&l);
  548 
  549         /* complete the attach */
  550         ahd_attach(ahd);
  551 }
  552 
  553 /*
  554  * Perform some simple tests that should catch situations where
  555  * our registers are invalidly mapped.
  556  */
  557 int
  558 ahd_pci_test_register_access(struct ahd_softc *ahd)
  559 {
  560         const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
  561         const pcitag_t tag = ahd->dev_softc->pa_tag;
  562         pcireg_t cmd;
  563         u_int    targpcistat;
  564         pcireg_t pci_status1;
  565         int      error;
  566         uint8_t  hcntrl;
  567 
  568         error = EIO;
  569 
  570         /*
  571          * Enable PCI error interrupt status, but suppress NMIs
  572          * generated by SERR raised due to target aborts.
  573          */
  574         cmd = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
  575         pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
  576             cmd & ~PCI_COMMAND_SERR_ENABLE);
  577 
  578         /*
  579          * First a simple test to see if any
  580          * registers can be read.  Reading
  581          * HCNTRL has no side effects and has
  582          * at least one bit that is guaranteed to
  583          * be zero so it is a good register to
  584          * use for this test.
  585          */
  586         hcntrl = ahd_inb(ahd, HCNTRL);
  587         if (hcntrl == 0xFF)
  588                 goto fail;
  589 
  590         /*
  591          * Next create a situation where write combining
  592          * or read prefetching could be initiated by the
  593          * CPU or host bridge.  Our device does not support
  594          * either, so look for data corruption and/or flaged
  595          * PCI errors.  First pause without causing another
  596          * chip reset.
  597          */
  598         hcntrl &= ~CHIPRST;
  599         ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
  600         while (ahd_is_paused(ahd) == 0)
  601                 ;
  602 
  603         /* Clear any PCI errors that occurred before our driver attached. */
  604         ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
  605         targpcistat = ahd_inb(ahd, TARGPCISTAT);
  606         ahd_outb(ahd, TARGPCISTAT, targpcistat);
  607         pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
  608         pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
  609         ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
  610         ahd_outb(ahd, CLRINT, CLRPCIINT);
  611 
  612         ahd_outb(ahd, SEQCTL0, PERRORDIS);
  613         ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
  614         if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
  615                 goto fail;
  616 
  617         if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
  618                 u_int targpcistat;
  619 
  620                 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
  621                 targpcistat = ahd_inb(ahd, TARGPCISTAT);
  622                 if ((targpcistat & STA) != 0)
  623                         goto fail;
  624         }
  625 
  626         error = 0;
  627 
  628 fail:
  629         if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
  630 
  631                 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
  632                 targpcistat = ahd_inb(ahd, TARGPCISTAT);
  633 
  634                 /* Silently clear any latched errors. */
  635                 ahd_outb(ahd, TARGPCISTAT, targpcistat);
  636                 pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
  637                 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
  638                 ahd_outb(ahd, CLRINT, CLRPCIINT);
  639         }
  640         ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
  641         pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmd);
  642         return (error);
  643 }
  644 
  645 /*
  646  * Check the external port logic for a serial eeprom
  647  * and termination/cable detection contrls.
  648  */
  649 int
  650 ahd_check_extport(struct ahd_softc *ahd)
  651 {
  652         struct  vpd_config vpd;
  653         struct  seeprom_config *sc;
  654         u_int   adapter_control;
  655         int     have_seeprom;
  656         int     error;
  657 
  658         sc = ahd->seep_config;
  659         have_seeprom = ahd_acquire_seeprom(ahd);
  660         if (have_seeprom) {
  661                 u_int start_addr;
  662 
  663                 /*
  664                  * Fetch VPD for this function and parse it.
  665                  */
  666                 if (bootverbose) 
  667                         printf("%s: Reading VPD from SEEPROM...",
  668                                ahd_name(ahd));
  669 
  670                 /* Address is always in units of 16bit words */
  671                 start_addr = ((2 * sizeof(*sc))
  672                             + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
  673 
  674                 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
  675                                          start_addr, sizeof(vpd)/2,
  676                                          /*bytestream*/TRUE);
  677                 if (error == 0)
  678                         error = ahd_parse_vpddata(ahd, &vpd);
  679                 if (bootverbose) 
  680                         printf("%s: VPD parsing %s\n",
  681                                ahd_name(ahd),
  682                                error == 0 ? "successful" : "failed");
  683 
  684                 if (bootverbose) 
  685                         printf("%s: Reading SEEPROM...", ahd_name(ahd));
  686 
  687                 /* Address is always in units of 16bit words */
  688                 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
  689 
  690                 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
  691                                          start_addr, sizeof(*sc)/2,
  692                                          /*bytestream*/FALSE);
  693 
  694                 if (error != 0) {
  695                         printf("Unable to read SEEPROM\n");
  696                         have_seeprom = 0;
  697                 } else {
  698                         have_seeprom = ahd_verify_cksum(sc);
  699 
  700                         if (bootverbose) {
  701                                 if (have_seeprom == 0)
  702                                         printf ("checksum error\n");
  703                                 else
  704                                         printf ("done.\n");
  705                         }
  706                 }
  707                 ahd_release_seeprom(ahd);
  708         }
  709 
  710         if (!have_seeprom) {
  711                 u_int     nvram_scb;
  712 
  713                 /*
  714                  * Pull scratch ram settings and treat them as
  715                  * if they are the contents of an seeprom if
  716                  * the 'ADPT', 'BIOS', or 'ASPI' signature is found
  717                  * in SCB 0xFF.  We manually compose the data as 16bit
  718                  * values to avoid endian issues.
  719                  */
  720                 ahd_set_scbptr(ahd, 0xFF);
  721                 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
  722                 if (nvram_scb != 0xFF
  723                  && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
  724                    && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
  725                    && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
  726                    && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
  727                   || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
  728                    && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
  729                    && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
  730                    && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
  731                   || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
  732                    && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
  733                    && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
  734                    && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
  735                         uint16_t *sc_data;
  736                         int       i;
  737 
  738                         ahd_set_scbptr(ahd, nvram_scb);
  739                         sc_data = (uint16_t *)sc;
  740                         for (i = 0; i < 64; i += 2)
  741                                 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
  742                         have_seeprom = ahd_verify_cksum(sc);
  743                         if (have_seeprom)
  744                                 ahd->flags |= AHD_SCB_CONFIG_USED;
  745                 }
  746         }
  747 
  748 #ifdef AHD_DEBUG
  749         if (have_seeprom != 0
  750          && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
  751                 uint16_t *sc_data;
  752                 int       i;
  753 
  754                 printf("%s: Seeprom Contents:", ahd_name(ahd));
  755                 sc_data = (uint16_t *)sc;
  756                 for (i = 0; i < (sizeof(*sc)); i += 2)
  757                         printf("\n\t0x%.4x", sc_data[i]);
  758                 printf("\n");
  759         }
  760 #endif
  761 
  762         if (!have_seeprom) {
  763                 if (bootverbose)
  764                         printf("%s: No SEEPROM available.\n", ahd_name(ahd));
  765                 ahd->flags |= AHD_USEDEFAULTS;
  766                 error = ahd_default_config(ahd);
  767                 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
  768                 free(ahd->seep_config, M_DEVBUF);
  769                 ahd->seep_config = NULL;
  770         } else {
  771                 error = ahd_parse_cfgdata(ahd, sc);
  772                 adapter_control = sc->adapter_control;
  773         }
  774         if (error != 0)
  775                 return (error);
  776 
  777         ahd_configure_termination(ahd, adapter_control);
  778 
  779         return (0);
  780 }
  781 
  782 void
  783 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
  784 {
  785         const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
  786         const pcitag_t tag = ahd->dev_softc->pa_tag;
  787         int      error;
  788         u_int    sxfrctl1;
  789         uint8_t  termctl;
  790         pcireg_t devconfig;
  791 
  792         devconfig = pci_conf_read(pc, tag, DEVCONFIG);
  793         devconfig &= ~STPWLEVEL;
  794         if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
  795                 devconfig |= STPWLEVEL;
  796         if (bootverbose)
  797                 printf("%s: STPWLEVEL is %s\n",
  798                        ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
  799         pci_conf_write(pc, tag, DEVCONFIG, devconfig);
  800 
  801         /* Make sure current sensing is off. */
  802         if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
  803                 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
  804         }
  805 
  806         /*
  807          * Read to sense.  Write to set.
  808          */
  809         error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
  810         if ((adapter_control & CFAUTOTERM) == 0) {
  811                 if (bootverbose)
  812                         printf("%s: Manual Primary Termination\n",
  813                                ahd_name(ahd));
  814                 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
  815                 if ((adapter_control & CFSTERM) != 0)
  816                         termctl |= FLX_TERMCTL_ENPRILOW;
  817                 if ((adapter_control & CFWSTERM) != 0)
  818                         termctl |= FLX_TERMCTL_ENPRIHIGH;
  819         } else if (error != 0) {
  820                 printf("%s: Primary Auto-Term Sensing failed! "
  821                        "Using Defaults.\n", ahd_name(ahd));
  822                 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
  823         }
  824 
  825         if ((adapter_control & CFSEAUTOTERM) == 0) {
  826                 if (bootverbose)
  827                         printf("%s: Manual Secondary Termination\n",
  828                                ahd_name(ahd));
  829                 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
  830                 if ((adapter_control & CFSELOWTERM) != 0)
  831                         termctl |= FLX_TERMCTL_ENSECLOW;
  832                 if ((adapter_control & CFSEHIGHTERM) != 0)
  833                         termctl |= FLX_TERMCTL_ENSECHIGH;
  834         } else if (error != 0) {
  835                 printf("%s: Secondary Auto-Term Sensing failed! "
  836                        "Using Defaults.\n", ahd_name(ahd));
  837                 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
  838         }
  839 
  840         /*
  841          * Now set the termination based on what we found.
  842          */
  843         sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
  844         ahd->flags &= ~AHD_TERM_ENB_A;
  845         if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
  846                 ahd->flags |= AHD_TERM_ENB_A;
  847                 sxfrctl1 |= STPWEN;
  848         }
  849         /* Must set the latch once in order to be effective. */
  850         ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
  851         ahd_outb(ahd, SXFRCTL1, sxfrctl1);
  852 
  853         error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
  854         if (error != 0) {
  855                 printf("%s: Unable to set termination settings!\n",
  856                        ahd_name(ahd));
  857         } else if (bootverbose) {
  858                 printf("%s: Primary High byte termination %sabled\n",
  859                        ahd_name(ahd),
  860                        (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
  861 
  862                 printf("%s: Primary Low byte termination %sabled\n",
  863                        ahd_name(ahd),
  864                        (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
  865 
  866                 printf("%s: Secondary High byte termination %sabled\n",
  867                        ahd_name(ahd),
  868                        (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
  869 
  870                 printf("%s: Secondary Low byte termination %sabled\n",
  871                        ahd_name(ahd),
  872                        (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
  873         }
  874         return;
  875 }
  876 
  877 #define DPE     0x80
  878 #define SSE     0x40
  879 #define RMA     0x20
  880 #define RTA     0x10
  881 #define STA     0x08
  882 #define DPR     0x01
  883 
  884 static const char *split_status_source[] =
  885 {
  886         "DFF0",
  887         "DFF1",
  888         "OVLY",
  889         "CMC",
  890 };
  891 
  892 static const char *pci_status_source[] =
  893 {
  894         "DFF0",
  895         "DFF1",
  896         "SG",
  897         "CMC",
  898         "OVLY",
  899         "NONE",
  900         "MSI",
  901         "TARG"
  902 };
  903 
  904 static const char *split_status_strings[] =
  905 {
  906         "%s: Received split response in %s.\n",
  907         "%s: Received split completion error message in %s\n",
  908         "%s: Receive overrun in %s\n",
  909         "%s: Count not complete in %s\n",
  910         "%s: Split completion data bucket in %s\n",
  911         "%s: Split completion address error in %s\n",
  912         "%s: Split completion byte count error in %s\n",
  913         "%s: Signaled Target-abort to early terminate a split in %s\n"
  914 };
  915 
  916 static const char *pci_status_strings[] =
  917 {
  918         "%s: Data Parity Error has been reported via PERR# in %s\n",
  919         "%s: Target initial wait state error in %s\n",
  920         "%s: Split completion read data parity error in %s\n",
  921         "%s: Split completion address attribute parity error in %s\n",
  922         "%s: Received a Target Abort in %s\n",
  923         "%s: Received a Master Abort in %s\n",
  924         "%s: Signal System Error Detected in %s\n",
  925         "%s: Address or Write Phase Parity Error Detected in %s.\n"
  926 };
  927 
  928 void
  929 ahd_pci_intr(struct ahd_softc *ahd)
  930 {
  931         const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
  932         const pcitag_t tag = ahd->dev_softc->pa_tag;
  933         uint8_t         pci_status[8];
  934         ahd_mode_state  saved_modes;
  935         pcireg_t        pci_status1;
  936         u_int           intstat;
  937         u_int           i;
  938         u_int           reg;
  939         
  940         intstat = ahd_inb(ahd, INTSTAT);
  941 
  942         if ((intstat & SPLTINT) != 0)
  943                 ahd_pci_split_intr(ahd, intstat);
  944 
  945         if ((intstat & PCIINT) == 0)
  946                 return;
  947 
  948         printf("%s: PCI error Interrupt\n", ahd_name(ahd));
  949         saved_modes = ahd_save_modes(ahd);
  950         ahd_dump_card_state(ahd);
  951         ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
  952         for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
  953 
  954                 if (i == 5)
  955                         continue;
  956                 pci_status[i] = ahd_inb(ahd, reg);
  957                 /* Clear latched errors.  So our interrupt deasserts. */
  958                 ahd_outb(ahd, reg, pci_status[i]);
  959         }
  960 
  961         for (i = 0; i < 8; i++) {
  962                 u_int bit;
  963         
  964                 if (i == 5)
  965                         continue;
  966 
  967                 for (bit = 0; bit < 8; bit++) {
  968 
  969                         if ((pci_status[i] & (0x1 << bit)) != 0) {
  970                                 static const char *s;
  971 
  972                                 s = pci_status_strings[bit];
  973                                 if (i == 7/*TARG*/ && bit == 3)
  974                                         s = "%s: Signaled Target Abort\n";
  975                                 printf(s, ahd_name(ahd), pci_status_source[i]);
  976                         }
  977                 }       
  978         }
  979         pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
  980         pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG , pci_status1);
  981 
  982         ahd_restore_modes(ahd, saved_modes);
  983         ahd_outb(ahd, CLRINT, CLRPCIINT);
  984         ahd_unpause(ahd);
  985 
  986         return;
  987 }
  988 
  989 void
  990 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
  991 {
  992         const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
  993         const pcitag_t tag = ahd->dev_softc->pa_tag;
  994         uint8_t         split_status[4];
  995         uint8_t         split_status1[4];
  996         uint8_t         sg_split_status[2];
  997         uint8_t         sg_split_status1[2];
  998         ahd_mode_state  saved_modes;
  999         u_int           i;
 1000         pcireg_t        pcix_status;
 1001 
 1002         /*
 1003          * Check for splits in all modes.  Modes 0 and 1
 1004          * additionally have SG engine splits to look at.
 1005          */
 1006         pcix_status = pci_conf_read(pc, tag, ahd->pcix_off + 0x04);
 1007         printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
 1008                ahd_name(ahd), pcix_status);
 1009 
 1010         saved_modes = ahd_save_modes(ahd);
 1011         for (i = 0; i < 4; i++) {
 1012                 ahd_set_modes(ahd, i, i);
 1013 
 1014                 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
 1015                 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
 1016                 /* Clear latched errors.  So our interrupt deasserts. */
 1017                 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
 1018                 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
 1019                 if (i > 1)
 1020                         continue;
 1021                 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
 1022                 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
 1023                 /* Clear latched errors.  So our interrupt deasserts. */
 1024                 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
 1025                 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
 1026         }
 1027 
 1028         for (i = 0; i < 4; i++) {
 1029                 u_int bit;
 1030 
 1031                 for (bit = 0; bit < 8; bit++) {
 1032 
 1033                         if ((split_status[i] & (0x1 << bit)) != 0) {
 1034                                 static const char *s;
 1035 
 1036                                 s = split_status_strings[bit];
 1037                                 printf(s, ahd_name(ahd),
 1038                                        split_status_source[i]);
 1039                         }
 1040 
 1041                         if (i > 1)
 1042                                 continue;
 1043 
 1044                         if ((sg_split_status[i] & (0x1 << bit)) != 0) {
 1045                                 static const char *s;
 1046 
 1047                                 s = split_status_strings[bit];
 1048                                 printf(s, ahd_name(ahd), "SG");
 1049                         }
 1050                 }
 1051         }
 1052         /*
 1053          * Clear PCI-X status bits.
 1054          */
 1055         pci_conf_write(pc, tag, ahd->pcix_off + 0x04, pcix_status);
 1056         ahd_outb(ahd, CLRINT, CLRSPLTINT);
 1057         ahd_restore_modes(ahd, saved_modes);
 1058 }
 1059 
 1060 int
 1061 ahd_aic7901_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
 1062 {
 1063 
 1064         ahd->chip = AHD_AIC7901;
 1065         ahd->features = AHD_AIC7901_FE;
 1066         return (ahd_aic790X_setup(ahd, pa));
 1067 }
 1068 
 1069 int
 1070 ahd_aic7901A_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
 1071 {
 1072 
 1073         ahd->chip = AHD_AIC7901A;
 1074         ahd->features = AHD_AIC7901A_FE;
 1075         return (ahd_aic790X_setup(ahd, pa));
 1076 }
 1077 
 1078 int
 1079 ahd_aic7902_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
 1080 {
 1081         ahd->chip = AHD_AIC7902;
 1082         ahd->features = AHD_AIC7902_FE;
 1083         return (ahd_aic790X_setup(ahd, pa));
 1084 }
 1085 
 1086 int
 1087 ahd_aic790X_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
 1088 {
 1089         u_int rev;
 1090 
 1091         rev = PCI_REVISION(pa->pa_class);
 1092 #ifdef AHD_DEBUG
 1093         printf("\n%s: aic7902 chip revision 0x%x\n", ahd_name(ahd), rev);
 1094 #endif
 1095         if (rev < ID_AIC7902_PCI_REV_A4) {
 1096                 printf("%s: Unable to attach to unsupported chip revision %d\n",
 1097                        ahd_name(ahd), rev);
 1098                 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 0);
 1099                 return (ENXIO);
 1100         }
 1101 
 1102         ahd->channel = (pa->pa_function == 1) ? 'B' : 'A';
 1103         if (rev < ID_AIC7902_PCI_REV_B0) {
 1104                 /*
 1105                  * Enable A series workarounds.
 1106                  */
 1107                 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
 1108                           |  AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
 1109                           |  AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
 1110                           |  AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
 1111                           |  AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
 1112                           |  AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
 1113                           |  AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
 1114                           |  AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
 1115                           |  AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
 1116                           |  AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
 1117                           |  AHD_FAINT_LED_BUG;
 1118 
 1119                 /*
 1120                  * IO Cell parameter setup.
 1121                  */
 1122                 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
 1123 
 1124                 if ((ahd->flags & AHD_HP_BOARD) == 0)
 1125                         AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
 1126         } else {
 1127                 pcireg_t devconfig1;
 1128 
 1129                 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
 1130                               |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
 1131                 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG
 1132                           |  AHD_BUSFREEREV_BUG;
 1133 
 1134                 /*
 1135                  * Some issues have been resolved in the 7901B.
 1136                  */
 1137                 if ((ahd->features & AHD_MULTI_FUNC) != 0)
 1138                         ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
 1139 
 1140                 /*
 1141                  * IO Cell parameter setup.
 1142                  */
 1143                 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
 1144                 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
 1145                 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
 1146 
 1147                 /*
 1148                  * Set the PREQDIS bit for H2B which disables some workaround
 1149                  * that doesn't work on regular PCI busses.
 1150                  * XXX - Find out exactly what this does from the hardware
 1151                  *       folks!
 1152                  */
 1153                 devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
 1154                 pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG1, devconfig1|PREQDIS);
 1155                 devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
 1156         }
 1157 
 1158         return (0);
 1159 }

/* [<][>][^][v][top][bottom][index][help] */