The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pci/ahd_pci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 507eca960489ee20f7e8bec5e5afc14b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.