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/pci/ahc_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 /*
    2  * Product specific probe and attach routines for:
    3  *      3940, 2940, aic7895, aic7890, aic7880,
    4  *      aic7870, aic7860 and aic7850 SCSI controllers
    5  *
    6  * Copyright (c) 1995, 1996, 1997, 1998 Justin T. Gibbs
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions, and the following disclaimer,
   14  *    without modification, immediately at the beginning of the file.
   15  * 2. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * Where this Software is combined with software released under the terms of 
   19  * the GNU Public License ("GPL") and the terms of the GPL would require the 
   20  * combined work to also be released under the terms of the GPL, the terms
   21  * and conditions of this License will apply in addition to those of the
   22  * GPL with the exception of any terms or conditions of this License that
   23  * conflict with, or are expressly prohibited by, the GPL.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   29  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  * $FreeBSD$
   38  */
   39 
   40 #include <pci.h>
   41 #if NPCI > 0
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 
   46 #include <pci/pcireg.h>
   47 #include <pci/pcivar.h>
   48 
   49 #include <machine/bus_memio.h>
   50 #include <machine/bus_pio.h>
   51 #include <machine/bus.h>
   52 #include <machine/clock.h>
   53 
   54 #include <cam/cam.h>
   55 #include <cam/cam_ccb.h>
   56 #include <cam/cam_sim.h>
   57 #include <cam/cam_xpt_sim.h>
   58 
   59 #include <cam/scsi/scsi_all.h>
   60 
   61 #include <dev/aic7xxx/aic7xxx.h>
   62 #include <dev/aic7xxx/93cx6.h>
   63 
   64 #include <aic7xxx_reg.h>
   65 
   66 #define AHC_PCI_IOADDR  PCIR_MAPS               /* I/O Address */
   67 #define AHC_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */
   68 
   69 static __inline u_int64_t
   70 ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
   71 {
   72         u_int64_t id;
   73 
   74         id = subvendor
   75            | (subdevice << 16)
   76            | ((u_int64_t)vendor << 32)
   77            | ((u_int64_t)device << 48);
   78 
   79         return (id);
   80 }
   81 
   82 #define ID_ALL_MASK             0xFFFFFFFFFFFFFFFFull
   83 #define ID_DEV_VENDOR_MASK      0xFFFFFFFF00000000ull
   84 #define ID_AIC7850              0x5078900400000000ull
   85 #define ID_AHA_2910_15_20_30C   0x5078900478509004ull
   86 #define ID_AIC7855              0x5578900400000000ull
   87 #define ID_AIC7859              0x3860900400000000ull
   88 #define ID_AHA_2930CU           0x3860900438699004ull
   89 #define ID_AIC7860              0x6078900400000000ull
   90 #define ID_AIC7860C             0x6078900478609004ull
   91 #define ID_AHA_2940AU_0         0x6178900400000000ull
   92 #define ID_AHA_2940AU_1         0x6178900478619004ull
   93 #define ID_AHA_2940AU_CN        0x2178900478219004ull
   94 #define ID_AHA_2930C_VAR        0x6038900438689004ull
   95 
   96 #define ID_AIC7870              0x7078900400000000ull
   97 #define ID_AHA_2940             0x7178900400000000ull
   98 #define ID_AHA_3940             0x7278900400000000ull
   99 #define ID_AHA_398X             0x7378900400000000ull
  100 #define ID_AHA_2944             0x7478900400000000ull
  101 #define ID_AHA_3944             0x7578900400000000ull
  102 
  103 #define ID_AIC7880              0x8078900400000000ull
  104 #define ID_AIC7880_B            0x8078900478809004ull
  105 #define ID_AHA_2940U            0x8178900400000000ull
  106 #define ID_AHA_3940U            0x8278900400000000ull
  107 #define ID_AHA_2944U            0x8478900400000000ull
  108 #define ID_AHA_3944U            0x8578900400000000ull
  109 #define ID_AHA_398XU            0x8378900400000000ull
  110 #define ID_AHA_4944U            0x8678900400000000ull
  111 #define ID_AHA_2940UB           0x8178900478819004ull
  112 #define ID_AHA_2930U            0x8878900478889004ull
  113 #define ID_AHA_2940U_PRO        0x8778900478879004ull
  114 #define ID_AHA_2940U_CN         0x0078900478009004ull
  115 
  116 #define ID_AIC7895              0x7895900478959004ull
  117 #define ID_AIC7895_RAID_PORT    0x7893900478939004ull
  118 #define ID_AHA_2940U_DUAL       0x7895900478919004ull
  119 #define ID_AHA_3940AU           0x7895900478929004ull
  120 #define ID_AHA_3944AU           0x7895900478949004ull
  121 
  122 #define ID_AIC7890              0x001F9005000F9005ull
  123 #define ID_AHA_2930U2           0x0011900501819005ull
  124 #define ID_AHA_2940U2B          0x00109005A1009005ull
  125 #define ID_AHA_2940U2_OEM       0x0010900521809005ull
  126 #define ID_AHA_2940U2           0x00109005A1809005ull
  127 #define ID_AHA_2950U2B          0x00109005E1009005ull
  128 
  129 #define ID_AIC7896              0x005F9005FFFF9005ull
  130 #define ID_AHA_3950U2B_0        0x00509005FFFF9005ull
  131 #define ID_AHA_3950U2B_1        0x00509005F5009005ull
  132 #define ID_AHA_3950U2D_0        0x00519005FFFF9005ull
  133 #define ID_AHA_3950U2D_1        0x00519005B5009005ull
  134 
  135 #define ID_AIC7810              0x1078900400000000ull
  136 #define ID_AIC7815              0x1578900400000000ull
  137 
  138 typedef int (ahc_device_setup_t)(pcici_t, char *, ahc_chip *,
  139                                  ahc_feature *, ahc_flag *);
  140 
  141 static ahc_device_setup_t ahc_aic7850_setup;
  142 static ahc_device_setup_t ahc_aic7855_setup;
  143 static ahc_device_setup_t ahc_aic7859_setup;
  144 static ahc_device_setup_t ahc_aic7860_setup;
  145 static ahc_device_setup_t ahc_aic7870_setup;
  146 static ahc_device_setup_t ahc_aha394X_setup;
  147 static ahc_device_setup_t ahc_aha398X_setup;
  148 static ahc_device_setup_t ahc_aic7880_setup;
  149 static ahc_device_setup_t ahc_aha394XU_setup;
  150 static ahc_device_setup_t ahc_aha398XU_setup;
  151 static ahc_device_setup_t ahc_aic7890_setup;
  152 static ahc_device_setup_t ahc_aic7895_setup;
  153 static ahc_device_setup_t ahc_aic7896_setup;
  154 static ahc_device_setup_t ahc_raid_setup;
  155 static ahc_device_setup_t ahc_aha394XX_setup;
  156 static ahc_device_setup_t ahc_aha398XX_setup;
  157 
  158 struct ahc_pci_identity {
  159         u_int64_t                full_id;
  160         u_int64_t                id_mask;
  161         char                    *name;
  162         ahc_device_setup_t      *setup;
  163 };
  164 
  165 struct ahc_pci_identity ahc_pci_ident_table [] =
  166 {
  167         /* aic7850 based controllers */
  168         {
  169                 ID_AHA_2910_15_20_30C,
  170                 ID_ALL_MASK,
  171                 "Adaptec 2910/15/20/30C SCSI adapter",
  172                 ahc_aic7850_setup
  173         },
  174         /* aic7859 based controllers */
  175         {
  176                 ID_AHA_2930CU,
  177                 ID_ALL_MASK,
  178                 "Adaptec 2930CU SCSI adapter",
  179                 ahc_aic7859_setup
  180         },
  181         /* aic7860 based controllers */
  182         {
  183                 ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK,
  184                 ID_DEV_VENDOR_MASK,
  185                 "Adaptec 2940A Ultra SCSI adapter",
  186                 ahc_aic7860_setup
  187         },
  188         {
  189                 ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK,
  190                 ID_DEV_VENDOR_MASK,
  191                 "Adaptec 2940A/CN Ultra SCSI adapter",
  192                 ahc_aic7860_setup
  193         },
  194         {
  195                 ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK,
  196                 ID_DEV_VENDOR_MASK,
  197                 "Adaptec 2930C SCSI adapter (VAR)",
  198                 ahc_aic7860_setup
  199         },
  200         /* aic7870 based controllers */
  201         {
  202                 ID_AHA_2940,
  203                 ID_ALL_MASK,
  204                 "Adaptec 2940 SCSI adapter",
  205                 ahc_aic7870_setup
  206         },
  207         {
  208                 ID_AHA_3940,
  209                 ID_ALL_MASK,
  210                 "Adaptec 3940 SCSI adapter",
  211                 ahc_aha394X_setup
  212         },
  213         {
  214                 ID_AHA_398X,
  215                 ID_ALL_MASK,
  216                 "Adaptec 398X SCSI RAID adapter",
  217                 ahc_aha398X_setup
  218         },
  219         {
  220                 ID_AHA_2944,
  221                 ID_ALL_MASK,
  222                 "Adaptec 2944 SCSI adapter",
  223                 ahc_aic7870_setup
  224         },
  225         {
  226                 ID_AHA_3944,
  227                 ID_ALL_MASK,
  228                 "Adaptec 3944 SCSI adapter",
  229                 ahc_aha394X_setup
  230         },
  231         /* aic7880 based controllers */
  232         {
  233                 ID_AHA_2940U & ID_DEV_VENDOR_MASK,
  234                 ID_DEV_VENDOR_MASK,
  235                 "Adaptec 2940 Ultra SCSI adapter",
  236                 ahc_aic7880_setup
  237         },
  238         {
  239                 ID_AHA_3940U & ID_DEV_VENDOR_MASK,
  240                 ID_DEV_VENDOR_MASK,
  241                 "Adaptec 3940 Ultra SCSI adapter",
  242                 ahc_aha394XU_setup
  243         },
  244         {
  245                 ID_AHA_2944U & ID_DEV_VENDOR_MASK,
  246                 ID_DEV_VENDOR_MASK,
  247                 "Adaptec 2944 Ultra SCSI adapter",
  248                 ahc_aic7880_setup
  249         },
  250         {
  251                 ID_AHA_3944U & ID_DEV_VENDOR_MASK,
  252                 ID_DEV_VENDOR_MASK,
  253                 "Adaptec 3944 Ultra SCSI adapter",
  254                 ahc_aha394XU_setup
  255         },
  256         {
  257                 ID_AHA_398XU & ID_DEV_VENDOR_MASK,
  258                 ID_DEV_VENDOR_MASK,
  259                 "Adaptec 398X Ultra SCSI RAID adapter",
  260                 ahc_aha398XU_setup
  261         },
  262         {
  263                 /* XXX Don't know the slot numbers so can't identify channels */
  264                 ID_AHA_4944U & ID_DEV_VENDOR_MASK,
  265                 ID_DEV_VENDOR_MASK,
  266                 "Adaptec 4944 Ultra SCSI adapter",
  267                 ahc_aic7880_setup
  268         },
  269         {
  270                 ID_AHA_2930U & ID_DEV_VENDOR_MASK,
  271                 ID_DEV_VENDOR_MASK,
  272                 "Adaptec 2930 Ultra SCSI adapter",
  273                 ahc_aic7880_setup
  274         },
  275         {
  276                 ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK,
  277                 ID_DEV_VENDOR_MASK,
  278                 "Adaptec 2940 Pro Ultra SCSI adapter",
  279                 ahc_aic7880_setup
  280         },
  281         {
  282                 ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK,
  283                 ID_DEV_VENDOR_MASK,
  284                 "Adaptec 2940/CN Ultra SCSI adapter",
  285                 ahc_aic7880_setup
  286         },
  287         /* aic7890 based controllers */
  288         {
  289                 ID_AHA_2930U2,
  290                 ID_ALL_MASK,
  291                 "Adaptec 2930 Ultra2 SCSI adapter",
  292                 ahc_aic7890_setup
  293         },
  294         {
  295                 ID_AHA_2940U2B,
  296                 ID_ALL_MASK,
  297                 "Adaptec 2940B Ultra2 SCSI adapter",
  298                 ahc_aic7890_setup
  299         },
  300         {
  301                 ID_AHA_2940U2_OEM,
  302                 ID_ALL_MASK,
  303                 "Adaptec 2940 Ultra2 SCSI adapter (OEM)",
  304                 ahc_aic7890_setup
  305         },
  306         {
  307                 ID_AHA_2940U2,
  308                 ID_ALL_MASK,
  309                 "Adaptec 2940 Ultra2 SCSI adapter",
  310                 ahc_aic7890_setup
  311         },
  312         {
  313                 ID_AHA_2950U2B,
  314                 ID_ALL_MASK,
  315                 "Adaptec 2950 Ultra2 SCSI adapter",
  316                 ahc_aic7890_setup
  317         },
  318         /* aic7895 based controllers */ 
  319         {
  320                 ID_AHA_2940U_DUAL,
  321                 ID_ALL_MASK,
  322                 "Adaptec 2940/DUAL Ultra SCSI adapter",
  323                 ahc_aic7895_setup
  324         },
  325         {
  326                 ID_AHA_3940AU,
  327                 ID_ALL_MASK,
  328                 "Adaptec 3940A Ultra SCSI adapter",
  329                 ahc_aic7895_setup
  330         },
  331         {
  332                 ID_AHA_3944AU,
  333                 ID_ALL_MASK,
  334                 "Adaptec 3944A Ultra SCSI adapter",
  335                 ahc_aic7895_setup
  336         },
  337         /* aic7896/97 based controllers */      
  338         {
  339                 ID_AHA_3950U2B_0,
  340                 ID_ALL_MASK,
  341                 "Adaptec 3950B Ultra2 SCSI adapter",
  342                 ahc_aic7896_setup
  343         },
  344         {
  345                 ID_AHA_3950U2B_1,
  346                 ID_ALL_MASK,
  347                 "Adaptec 3950B Ultra2 SCSI adapter",
  348                 ahc_aic7896_setup
  349         },
  350         {
  351                 ID_AHA_3950U2D_0,
  352                 ID_ALL_MASK,
  353                 "Adaptec 3950D Ultra2 SCSI adapter",
  354                 ahc_aic7896_setup
  355         },
  356         {
  357                 ID_AHA_3950U2D_1,
  358                 ID_ALL_MASK,
  359                 "Adaptec 3950D Ultra2 SCSI adapter",
  360                 ahc_aic7896_setup
  361         },
  362         /* Generic chip probes for devices we don't know 'exactly' */
  363         {
  364                 ID_AIC7850 & ID_DEV_VENDOR_MASK,
  365                 ID_DEV_VENDOR_MASK,
  366                 "Adaptec aic7850 SCSI adapter",
  367                 ahc_aic7850_setup
  368         },
  369         {
  370                 ID_AIC7855 & ID_DEV_VENDOR_MASK,
  371                 ID_DEV_VENDOR_MASK,
  372                 "Adaptec aic7855 SCSI adapter",
  373                 ahc_aic7855_setup
  374         },
  375         {
  376                 ID_AIC7859 & ID_DEV_VENDOR_MASK,
  377                 ID_DEV_VENDOR_MASK,
  378                 "Adaptec aic7859 SCSI adapter",
  379                 ahc_aic7859_setup
  380         },
  381         {
  382                 ID_AIC7860 & ID_DEV_VENDOR_MASK,
  383                 ID_DEV_VENDOR_MASK,
  384                 "Adaptec aic7860 SCSI adapter",
  385                 ahc_aic7860_setup
  386         },
  387         {
  388                 ID_AIC7870 & ID_DEV_VENDOR_MASK,
  389                 ID_DEV_VENDOR_MASK,
  390                 "Adaptec aic7870 SCSI adapter",
  391                 ahc_aic7870_setup
  392         },
  393         {
  394                 ID_AIC7880 & ID_DEV_VENDOR_MASK,
  395                 ID_DEV_VENDOR_MASK,
  396                 "Adaptec aic7880 Ultra SCSI adapter",
  397                 ahc_aic7880_setup
  398         },
  399         {
  400                 ID_AIC7890 & ID_DEV_VENDOR_MASK,
  401                 ID_DEV_VENDOR_MASK,
  402                 "Adaptec aic7890/91 Ultra2 SCSI adapter",
  403                 ahc_aic7890_setup
  404         },
  405         {
  406                 ID_AIC7895 & ID_DEV_VENDOR_MASK,
  407                 ID_DEV_VENDOR_MASK,
  408                 "Adaptec aic7895 Ultra SCSI adapter",
  409                 ahc_aic7895_setup
  410         },
  411         {
  412                 ID_AIC7895_RAID_PORT & ID_DEV_VENDOR_MASK,
  413                 ID_DEV_VENDOR_MASK,
  414                 "Adaptec aic7895 Ultra SCSI adapter (RAID PORT)",
  415                 ahc_aic7895_setup
  416         },
  417         {
  418                 ID_AIC7896 & ID_DEV_VENDOR_MASK,
  419                 ID_DEV_VENDOR_MASK,
  420                 "Adaptec aic7896/97 Ultra2 SCSI adapter",
  421                 ahc_aic7896_setup
  422         },
  423         {
  424                 ID_AIC7810 & ID_DEV_VENDOR_MASK,
  425                 ID_DEV_VENDOR_MASK,
  426                 "Adaptec aic7810 RAID memory controller",
  427                 ahc_raid_setup
  428         },
  429         {
  430                 ID_AIC7815 & ID_DEV_VENDOR_MASK,
  431                 ID_DEV_VENDOR_MASK,
  432                 "Adaptec aic7815 RAID memory controller",
  433                 ahc_raid_setup
  434         }
  435 };
  436 
  437 static const int ahc_num_pci_devs =
  438         sizeof(ahc_pci_ident_table) / sizeof(*ahc_pci_ident_table);
  439                 
  440 #define AHC_394X_SLOT_CHANNEL_A 4
  441 #define AHC_394X_SLOT_CHANNEL_B 5
  442 
  443 #define AHC_398X_SLOT_CHANNEL_A 4
  444 #define AHC_398X_SLOT_CHANNEL_B 8
  445 #define AHC_398X_SLOT_CHANNEL_C 12
  446 
  447 #define DEVCONFIG               0x40
  448 #define         SCBSIZE32       0x00010000ul    /* aic789X only */
  449 #define         MPORTMODE       0x00000400ul    /* aic7870 only */
  450 #define         RAMPSM          0x00000200ul    /* aic7870 only */
  451 #define         VOLSENSE        0x00000100ul
  452 #define         SCBRAMSEL       0x00000080ul
  453 #define         MRDCEN          0x00000040ul
  454 #define         EXTSCBTIME      0x00000020ul    /* aic7870 only */
  455 #define         EXTSCBPEN       0x00000010ul    /* aic7870 only */
  456 #define         BERREN          0x00000008ul
  457 #define         DACEN           0x00000004ul
  458 #define         STPWLEVEL       0x00000002ul
  459 #define         DIFACTNEGEN     0x00000001ul    /* aic7870 only */
  460 
  461 #define CSIZE_LATTIME           0x0c
  462 #define         CACHESIZE       0x0000003ful    /* only 5 bits */
  463 #define         LATTIME         0x0000ff00ul
  464 
  465 static struct ahc_pci_identity *ahc_find_pci_device(pcici_t tag);
  466 static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1);
  467 static void configure_termination(struct ahc_softc *ahc,
  468                                   struct seeprom_descriptor *sd,
  469                                   u_int adapter_control,
  470                                   u_int *sxfrctl1);
  471 
  472 static void ahc_ultra2_term_detect(struct ahc_softc *ahc,
  473                                    int *enableSEC_low,
  474                                    int *enableSEC_high,
  475                                    int *enablePRI_low,
  476                                    int *enablePRI_high,
  477                                    int *eeprom_present);
  478 static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
  479                                  int *internal68_present,
  480                                  int *externalcable_present,
  481                                  int *eeprom_present);
  482 static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
  483                                  int *externalcable_present,
  484                                  int *eeprom_present);
  485 static int acquire_seeprom(struct ahc_softc *ahc,
  486                            struct seeprom_descriptor *sd);
  487 static void release_seeprom(struct seeprom_descriptor *sd);
  488 static void write_brdctl(struct ahc_softc *ahc, u_int8_t value);
  489 static u_int8_t read_brdctl(struct ahc_softc *ahc);
  490 
  491 static struct ahc_softc *first_398X;
  492 
  493 static const char* ahc_pci_probe(pcici_t tag, pcidi_t type);
  494 static void ahc_pci_attach(pcici_t config_id, int unit);
  495 
  496 /* Exported for use in the ahc_intr routine */
  497 void ahc_pci_intr(struct ahc_softc *ahc);
  498 
  499 static struct   pci_device ahc_pci_driver = {
  500         "ahc",
  501         ahc_pci_probe,
  502         ahc_pci_attach,
  503         &ahc_unit,
  504         NULL
  505 }; 
  506 
  507 DATA_SET (pcidevice_set, ahc_pci_driver);
  508 
  509 static struct ahc_pci_identity *
  510 ahc_find_pci_device(pcici_t tag)
  511 {
  512         u_int64_t  full_id;
  513         struct     ahc_pci_identity *entry;
  514         u_int      deviceid;
  515         u_int      vendorid;
  516         u_int      subdeviceid;
  517         u_int      subvendorid;
  518         u_int      i;
  519 
  520         deviceid = pci_cfgread(tag, PCIR_DEVICE, /*bytes*/2);
  521         vendorid = pci_cfgread(tag, PCIR_VENDOR, /*bytes*/2);
  522         subdeviceid = pci_cfgread(tag, PCIR_SUBDEV_0, /*bytes*/2);
  523         subvendorid = pci_cfgread(tag, PCIR_SUBVEND_0, /*bytes*/2);
  524         full_id = ahc_compose_id(deviceid,
  525                                  vendorid,
  526                                  subdeviceid,
  527                                  subvendorid);
  528 
  529         for (i = 0; i < ahc_num_pci_devs; i++) {
  530                 entry = &ahc_pci_ident_table[i];
  531                 if (entry->full_id == (full_id & entry->id_mask))
  532                         return (entry);
  533         }
  534         return (NULL);
  535 }
  536 
  537 static const char*
  538 ahc_pci_probe(pcici_t tag, pcidi_t type)
  539 {
  540         struct     ahc_pci_identity *entry;
  541 
  542         entry = ahc_find_pci_device(tag);
  543         if (entry != NULL)
  544                 return (entry->name);
  545         return (NULL);
  546 }
  547 
  548 static void
  549 ahc_pci_attach(pcici_t config_id, int unit)
  550 {
  551         pci_port_t         io_port;
  552         bus_dma_tag_t      parent_dmat;
  553         struct             ahc_softc *ahc;
  554         struct             ahc_pci_identity *entry;
  555         vm_offset_t        vaddr;
  556 #ifdef AHC_ALLOW_MEMIO
  557         vm_offset_t        paddr;
  558 #endif
  559         u_int              command;
  560         struct scb_data   *shared_scb_data;
  561         ahc_chip           ahc_t = AHC_NONE;
  562         ahc_feature        ahc_fe = AHC_FENONE;
  563         ahc_flag           ahc_f = AHC_FNONE;
  564         u_int              our_id = 0;
  565         u_int              sxfrctl1;
  566         u_int              scsiseq;
  567         int                error;
  568         int                opri;
  569         char               channel;
  570 
  571         shared_scb_data = NULL;
  572         command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1);
  573         entry = ahc_find_pci_device(config_id);
  574         if (entry == NULL)
  575                 return;
  576 
  577         error = entry->setup(config_id, &channel, &ahc_t, &ahc_fe, &ahc_f);
  578         if (error != 0)
  579                 return;
  580 
  581         vaddr = NULL;
  582 #ifdef AHC_ALLOW_MEMIO
  583         if ((command & PCI_COMMAND_MEM_ENABLE) == 0
  584          || (pci_map_mem(config_id, AHC_PCI_MEMADDR, &vaddr, &paddr)) == 0)
  585 #endif
  586                 if ((command & PCI_COMMAND_IO_ENABLE) == 0
  587                  || (pci_map_port(config_id, AHC_PCI_IOADDR, &io_port)) == 0)
  588                         return;
  589 
  590         /* Ensure busmastering is enabled */
  591         command |= PCIM_CMD_BUSMASTEREN;
  592         pci_cfgwrite(config_id, PCIR_COMMAND, command, /*bytes*/1);
  593 
  594         /* Allocate a dmatag for our SCB DMA maps */
  595         /* XXX Should be a child of the PCI bus dma tag */
  596         error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/0,
  597                                    /*boundary*/0,
  598                                    /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
  599                                    /*highaddr*/BUS_SPACE_MAXADDR,
  600                                    /*filter*/NULL, /*filterarg*/NULL,
  601                                    /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG,
  602                                    /*maxsegsz*/AHC_MAXTRANSFER_SIZE,
  603                                    /*flags*/BUS_DMA_ALLOCNOW, &parent_dmat);
  604 
  605         if (error != 0) {
  606                 printf("ahc_pci_attach: Could not allocate DMA tag "
  607                        "- error %d\n", error);
  608                 return;
  609         }
  610 
  611         /* On all PCI adapters, we allow SCB paging */
  612         ahc_f |= AHC_PAGESCBS;
  613         if ((ahc = ahc_alloc(unit, io_port, vaddr, parent_dmat,
  614                              ahc_t|AHC_PCI, ahc_fe, ahc_f,
  615                              shared_scb_data)) == NULL)
  616                 return;
  617 
  618         ahc->channel = channel;
  619 
  620         /* Store our PCI bus information for use in our PCI error handler */
  621         ahc->pci_config_id = config_id;
  622         
  623         /* Remeber how the card was setup in case there is no SEEPROM */
  624         ahc_outb(ahc, HCNTRL, ahc->pause);
  625         if ((ahc->features & AHC_ULTRA2) != 0) {
  626                 our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
  627         } else
  628                 our_id = ahc_inb(ahc, SCSIID) & OID;
  629         sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
  630         scsiseq = ahc_inb(ahc, SCSISEQ);
  631 
  632         if (ahc_reset(ahc) != 0) {
  633                 /* Failed */
  634                 ahc_free(ahc);
  635                 return;
  636         }
  637 
  638         /*
  639          * Take a look to see if we have external SRAM.
  640          * We currently do not attempt to use SRAM that is
  641          * shared among multiple controllers.
  642          */
  643         if ((ahc->features & AHC_ULTRA2) != 0) {
  644                 u_int dscommand0;
  645 
  646                 dscommand0 = ahc_inb(ahc, DSCOMMAND0);
  647                 if ((dscommand0 & RAMPS) != 0) {
  648                         u_int32_t devconfig;
  649 
  650                         devconfig = pci_cfgread(config_id, DEVCONFIG,
  651                                                 /*bytes*/4);
  652                         if ((devconfig & MPORTMODE) != 0) {
  653                                 /* Single user mode */
  654 
  655                                 /*
  656                                  * XXX Assume 9bit SRAM and enable
  657                                  * parity checking
  658                                  */
  659                                 devconfig |= EXTSCBPEN;
  660                                 pci_cfgwrite(config_id, DEVCONFIG,
  661                                              devconfig, /*bytes*/4);
  662 
  663                                 /*
  664                                  * Set the bank select apropriately.
  665                                  */
  666                                 if (ahc->channel == 'B')
  667                                         ahc_outb(ahc, SCBBADDR, 1);
  668                                 else
  669                                         ahc_outb(ahc, SCBBADDR, 0);
  670                                 
  671                                 /* Select external SCB SRAM */
  672                                 dscommand0 &= ~INTSCBRAMSEL;
  673                                 ahc_outb(ahc, DSCOMMAND0, dscommand0);
  674 
  675                                 if (ahc_probe_scbs(ahc) == 0) {
  676                                         /* External ram isn't really there */
  677                                         dscommand0 |= INTSCBRAMSEL;
  678                                         ahc_outb(ahc, DSCOMMAND0, dscommand0);
  679                                 } else if (bootverbose)
  680                                         printf("%s: External SRAM bank%d\n",
  681                                                ahc_name(ahc),
  682                                                ahc->channel == 'B' ? 1 : 0);
  683                         }
  684 
  685                 }
  686         } else if ((ahc->chip & AHC_CHIPID_MASK) >= AHC_AIC7870) {
  687                 u_int32_t devconfig;
  688 
  689                 devconfig = pci_cfgread(config_id, DEVCONFIG, /*bytes*/4);
  690                 if ((devconfig & RAMPSM) != 0
  691                  && (devconfig & MPORTMODE) != 0) {
  692 
  693                         /* XXX Assume 9bit SRAM and enable parity checking */
  694                         devconfig |= EXTSCBPEN;
  695 
  696                         /* XXX Assume fast SRAM */
  697                         devconfig &= ~EXTSCBTIME;
  698 
  699                         /*
  700                          * Set the bank select apropriately.
  701                          */
  702                         if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
  703                                 if (ahc->channel == 'B')
  704                                         ahc_outb(ahc, SCBBADDR, 1);
  705                                 else
  706                                         ahc_outb(ahc, SCBBADDR, 0);
  707                         }
  708 
  709                         /* Select external SRAM */
  710                         devconfig &= ~SCBRAMSEL;
  711                         pci_cfgwrite(config_id, DEVCONFIG,
  712                                      devconfig, /*bytes*/4);
  713 
  714                         if (ahc_probe_scbs(ahc) == 0) {
  715                                 /* External ram isn't really there */
  716                                 devconfig |= SCBRAMSEL;
  717                                 pci_cfgwrite(config_id, DEVCONFIG,
  718                                              devconfig, /*bytes*/4);
  719                         } else if (bootverbose)
  720                                 printf("%s: External SRAM bank%d\n",
  721                                        ahc_name(ahc),
  722                                        ahc->channel == 'B' ? 1 : 0);
  723                 }
  724         }
  725 
  726         if (!(pci_map_int(config_id, ahc_intr, (void *)ahc, &cam_imask))) {
  727                 ahc_free(ahc);
  728                 return;
  729         }
  730 
  731         /*
  732          * Protect ourself from spurrious interrupts during
  733          * intialization.
  734          */
  735         opri = splcam();
  736 
  737         /*
  738          * Do aic7880/aic7870/aic7860/aic7850 specific initialization
  739          */
  740         {
  741                 u_int8_t sblkctl;
  742                 char     *id_string;
  743 
  744                 switch(ahc_t) {
  745                 case AHC_AIC7896:
  746                 {
  747                         u_int dscommand0;
  748 
  749                         /*
  750                          * DPARCKEN doesn't work correctly on
  751                          * some MBs so don't use it.
  752                          */
  753                         id_string = "aic7896/97 ";
  754                         dscommand0 = ahc_inb(ahc, DSCOMMAND0);
  755                         dscommand0 &= ~(USCBSIZE32|DPARCKEN);
  756                         dscommand0 |= CACHETHEN|MPARCKEN;
  757                         ahc_outb(ahc, DSCOMMAND0, dscommand0);
  758                         break;
  759                 }
  760                 case AHC_AIC7890:
  761                 {
  762                         u_int dscommand0;
  763 
  764                         /*
  765                          * DPARCKEN doesn't work correctly on
  766                          * some MBs so don't use it.
  767                          */
  768                         id_string = "aic7890/91 ";
  769                         dscommand0 = ahc_inb(ahc, DSCOMMAND0);
  770                         dscommand0 &= ~(USCBSIZE32|DPARCKEN);
  771                         dscommand0 |= CACHETHEN|MPARCKEN;
  772                         ahc_outb(ahc, DSCOMMAND0, dscommand0);
  773                         break;
  774                 }
  775                 case AHC_AIC7895:
  776                         id_string = "aic7895 ";
  777                         break;
  778                 case AHC_AIC7880:
  779                         id_string = "aic7880 ";
  780                         break;
  781                 case AHC_AIC7870:
  782                         id_string = "aic7870 ";
  783                         break;
  784                 case AHC_AIC7860:
  785                         id_string = "aic7860 ";
  786                         break;
  787                 case AHC_AIC7859:
  788                         id_string = "aic7859 ";
  789                         break;
  790                 case AHC_AIC7855:
  791                         id_string = "aic7855 ";
  792                         break;
  793                 case AHC_AIC7850:
  794                         id_string = "aic7850 ";
  795                         break;
  796                 default:
  797                         printf("ahc: Unknown controller type.  Ignoring.\n");
  798                         ahc_free(ahc);
  799                         splx(opri);
  800                         return;
  801                 }
  802 
  803                 /* See if we have an SEEPROM and perform auto-term */
  804                 check_extport(ahc, &sxfrctl1);
  805 
  806                 /*
  807                  * Take the LED out of diagnostic mode
  808                  */
  809                 sblkctl = ahc_inb(ahc, SBLKCTL);
  810                 ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
  811 
  812                 /*
  813                  * I don't know where this is set in the SEEPROM or by the
  814                  * BIOS, so we default to 100% on Ultra or slower controllers
  815                  * and 75% on ULTRA2 controllers.
  816                  */
  817                 if ((ahc->features & AHC_ULTRA2) != 0) {
  818                         ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX);
  819                 } else {
  820                         ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
  821                 }
  822 
  823                 if (ahc->flags & AHC_USEDEFAULTS) {
  824                         /*
  825                          * PCI Adapter default setup
  826                          * Should only be used if the adapter does not have
  827                          * an SEEPROM.
  828                          */
  829                         /* See if someone else set us up already */
  830                         if (scsiseq != 0) {
  831                                 printf("%s: Using left over BIOS settings\n",
  832                                         ahc_name(ahc));
  833                                 ahc->flags &= ~AHC_USEDEFAULTS;
  834                         } else {
  835                                 /*
  836                                  * Assume only one connector and always turn
  837                                  * on termination.
  838                                  */
  839                                 our_id = 0x07;
  840                                 sxfrctl1 = STPWEN;
  841                         }
  842                         ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
  843 
  844                         ahc->our_id = our_id;
  845                 }
  846 
  847                 printf("%s: %s", ahc_name(ahc), id_string);
  848         }
  849 
  850         /*
  851          * Record our termination setting for the
  852          * generic initialization routine.
  853          */
  854         if ((sxfrctl1 & STPWEN) != 0)
  855                 ahc->flags |= AHC_TERM_ENB_A;
  856 
  857         if (ahc_init(ahc)) {
  858                 ahc_free(ahc);
  859                 splx(opri);
  860                 return;
  861         }
  862 
  863         /* XXX Crude hack - fix sometime */
  864         if (ahc->flags & AHC_SHARED_SRAM) {
  865                 /* Only set this once we've successfully probed */
  866                 if (shared_scb_data == NULL)
  867                         first_398X = ahc;
  868         }
  869 
  870         splx(opri);
  871 
  872         ahc_attach(ahc);
  873 }
  874 
  875 /*
  876  * Check the external port logic for a serial eeprom
  877  * and termination/cable detection contrls.
  878  */
  879 static void
  880 check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
  881 {
  882         struct    seeprom_descriptor sd;
  883         struct    seeprom_config sc;
  884         u_int     scsi_conf;
  885         u_int     adapter_control;
  886         int       have_seeprom;
  887         int       have_autoterm;
  888 
  889         sd.sd_tag = ahc->tag;
  890         sd.sd_bsh = ahc->bsh;
  891         sd.sd_control_offset = SEECTL;          
  892         sd.sd_status_offset = SEECTL;           
  893         sd.sd_dataout_offset = SEECTL;          
  894 
  895         /*
  896          * For some multi-channel devices, the c46 is simply too
  897          * small to work.  For the other controller types, we can
  898          * get our information from either SEEPROM type.  Set the
  899          * type to start our probe with accordingly.
  900          */
  901         if (ahc->flags & AHC_LARGE_SEEPROM)
  902                 sd.sd_chip = C56_66;
  903         else
  904                 sd.sd_chip = C46;
  905 
  906         sd.sd_MS = SEEMS;
  907         sd.sd_RDY = SEERDY;
  908         sd.sd_CS = SEECS;
  909         sd.sd_CK = SEECK;
  910         sd.sd_DO = SEEDO;
  911         sd.sd_DI = SEEDI;
  912 
  913         have_seeprom = acquire_seeprom(ahc, &sd);
  914         if (have_seeprom) {
  915 
  916                 if (bootverbose) 
  917                         printf("%s: Reading SEEPROM...", ahc_name(ahc));
  918 
  919                 for (;;) {
  920                         bus_size_t start_addr;
  921 
  922                         start_addr = 32 * (ahc->channel - 'A');
  923 
  924                         have_seeprom = read_seeprom(&sd, (u_int16_t *)&sc,
  925                                                     start_addr, sizeof(sc)/2);
  926 
  927                         if (have_seeprom) {
  928                                 /* Check checksum */
  929                                 int i;
  930                                 int maxaddr;
  931                                 u_int32_t checksum;
  932                                 u_int16_t *scarray;
  933 
  934                                 maxaddr = (sizeof(sc)/2) - 1;
  935                                 checksum = 0;
  936                                 scarray = (u_int16_t *)&sc;
  937 
  938                                 for (i = 0; i < maxaddr; i++)
  939                                         checksum = checksum + scarray[i];
  940                                 if (checksum == 0
  941                                  || (checksum & 0xFFFF) != sc.checksum) {
  942                                         if (bootverbose && sd.sd_chip == C56_66)
  943                                                 printf ("checksum error\n");
  944                                         have_seeprom = 0;
  945                                 } else {
  946                                         if (bootverbose)
  947                                                 printf("done.\n");
  948                                         break;
  949                                 }
  950                         }
  951 
  952                         if (sd.sd_chip == C56_66)
  953                                 break;
  954                         sd.sd_chip = C56_66;
  955                 }
  956         }
  957 
  958         if (!have_seeprom) {
  959                 if (bootverbose)
  960                         printf("%s: No SEEPROM available.\n", ahc_name(ahc));
  961                 ahc->flags |= AHC_USEDEFAULTS;
  962         } else {
  963                 /*
  964                  * Put the data we've collected down into SRAM
  965                  * where ahc_init will find it.
  966                  */
  967                 int i;
  968                 int max_targ = sc.max_targets & CFMAXTARG;
  969                 u_int16_t discenable;
  970                 u_int16_t ultraenb;
  971 
  972                 discenable = 0;
  973                 ultraenb = 0;
  974                 if ((sc.adapter_control & CFULTRAEN) != 0) {
  975                         /*
  976                          * Determine if this adapter has a "newstyle"
  977                          * SEEPROM format.
  978                          */
  979                         for (i = 0; i < max_targ; i++) {
  980                                 if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0){
  981                                         ahc->flags |= AHC_NEWEEPROM_FMT;
  982                                         break;
  983                                 }
  984                         }
  985                 }
  986 
  987                 for (i = 0; i < max_targ; i++) {
  988                         u_int     scsirate;
  989                         u_int16_t target_mask;
  990 
  991                         target_mask = 0x01 << i;
  992                         if (sc.device_flags[i] & CFDISC)
  993                                 discenable |= target_mask;
  994                         if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) {
  995                                 if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0)
  996                                         ultraenb |= target_mask;
  997                         } else if ((sc.adapter_control & CFULTRAEN) != 0) {
  998                                 ultraenb |= target_mask;
  999                         }
 1000                         if ((sc.device_flags[i] & CFXFER) == 0x04
 1001                          && (ultraenb & target_mask) != 0) {
 1002                                 /* Treat 10MHz as a non-ultra speed */
 1003                                 sc.device_flags[i] &= ~CFXFER;
 1004                                 ultraenb &= ~target_mask;
 1005                         }
 1006                         if ((ahc->features & AHC_ULTRA2) != 0) {
 1007                                 u_int offset;
 1008 
 1009                                 if (sc.device_flags[i] & CFSYNCH)
 1010                                         offset = MAX_OFFSET_ULTRA2;
 1011                                 else 
 1012                                         offset = 0;
 1013                                 ahc_outb(ahc, TARG_OFFSET + i, offset);
 1014 
 1015                                 scsirate = (sc.device_flags[i] & CFXFER)
 1016                                          | ((ultraenb & target_mask)
 1017                                             ? 0x18 : 0x10);
 1018                                 if (sc.device_flags[i] & CFWIDEB)
 1019                                         scsirate |= WIDEXFER;
 1020                         } else {
 1021                                 scsirate = (sc.device_flags[i] & CFXFER) << 4;
 1022                                 if (sc.device_flags[i] & CFSYNCH)
 1023                                         scsirate |= SOFS;
 1024                                 if (sc.device_flags[i] & CFWIDEB)
 1025                                         scsirate |= WIDEXFER;
 1026                         }
 1027                         ahc_outb(ahc, TARG_SCSIRATE + i, scsirate);
 1028                 }
 1029                 ahc->our_id = sc.brtime_id & CFSCSIID;
 1030 
 1031                 scsi_conf = (ahc->our_id & 0x7);
 1032                 if (sc.adapter_control & CFSPARITY)
 1033                         scsi_conf |= ENSPCHK;
 1034                 if (sc.adapter_control & CFRESETB)
 1035                         scsi_conf |= RESET_SCSI;
 1036 
 1037                 if (sc.bios_control & CFEXTEND)
 1038                         ahc->flags |= AHC_EXTENDED_TRANS_A;
 1039                 if (ahc->features & AHC_ULTRA
 1040                  && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) {
 1041                         /* Should we enable Ultra mode? */
 1042                         if (!(sc.adapter_control & CFULTRAEN))
 1043                                 /* Treat us as a non-ultra card */
 1044                                 ultraenb = 0;
 1045                 }
 1046                 /* Set SCSICONF info */
 1047                 ahc_outb(ahc, SCSICONF, scsi_conf);
 1048                 ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
 1049                 ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
 1050                 ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff);
 1051                 ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);
 1052         }
 1053 
 1054         /*
 1055          * Cards that have the external logic necessary to talk to
 1056          * a SEEPROM, are almost certain to have the remaining logic
 1057          * necessary for auto-termination control.  This assumption
 1058          * hasn't failed yet...
 1059          */
 1060         have_autoterm = have_seeprom;
 1061         if (have_seeprom)
 1062                 adapter_control = sc.adapter_control;
 1063         else
 1064                 adapter_control = CFAUTOTERM;
 1065 
 1066         /*
 1067          * Some low-cost chips have SEEPROM and auto-term control built
 1068          * in, instead of using a GAL.  They can tell us directly
 1069          * if the termination logic is enabled.
 1070          */
 1071         if ((ahc->features & AHC_SPIOCAP) != 0) {
 1072                 if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) != 0)
 1073                         have_autoterm = TRUE;
 1074                 else
 1075                         have_autoterm = FALSE;
 1076         }
 1077 
 1078         if (have_autoterm)
 1079                 configure_termination(ahc, &sd, adapter_control, sxfrctl1);
 1080 
 1081         release_seeprom(&sd);
 1082 }
 1083 
 1084 static void
 1085 configure_termination(struct ahc_softc *ahc,
 1086                       struct seeprom_descriptor *sd,
 1087                       u_int adapter_control,
 1088                       u_int *sxfrctl1)
 1089 {
 1090         u_int8_t brddat;
 1091         
 1092         brddat = 0;
 1093 
 1094         /*
 1095          * Update the settings in sxfrctl1 to match the
 1096          *termination settings 
 1097          */
 1098         *sxfrctl1 = 0;
 1099         
 1100         /*
 1101          * SEECS must be on for the GALS to latch
 1102          * the data properly.  Be sure to leave MS
 1103          * on or we will release the seeprom.
 1104          */
 1105         SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS);
 1106         if ((adapter_control & CFAUTOTERM) != 0
 1107          || (ahc->features & AHC_ULTRA2) != 0) {
 1108                 int internal50_present;
 1109                 int internal68_present;
 1110                 int externalcable_present;
 1111                 int eeprom_present;
 1112                 int enableSEC_low;
 1113                 int enableSEC_high;
 1114                 int enablePRI_low;
 1115                 int enablePRI_high;
 1116 
 1117                 enableSEC_low = 0;
 1118                 enableSEC_high = 0;
 1119                 enablePRI_low = 0;
 1120                 enablePRI_high = 0;
 1121                 if (ahc->features & AHC_ULTRA2) {
 1122                         ahc_ultra2_term_detect(ahc, &enableSEC_low,
 1123                                                &enableSEC_high,
 1124                                                &enablePRI_low,
 1125                                                &enablePRI_high,
 1126                                                &eeprom_present);
 1127                         if ((adapter_control & CFSEAUTOTERM) == 0) {
 1128                                 if (bootverbose)
 1129                                         printf("%s: Manual SE Termination\n",
 1130                                                ahc_name(ahc));
 1131                                 enableSEC_low = (adapter_control & CFSTERM);
 1132                                 enableSEC_high = (adapter_control & CFWSTERM);
 1133                         }
 1134                         if ((adapter_control & CFAUTOTERM) == 0) {
 1135                                 if (bootverbose)
 1136                                         printf("%s: Manual LVD Termination\n",
 1137                                                ahc_name(ahc));
 1138                                 enablePRI_low = enablePRI_high =
 1139                                     (adapter_control & CFLVDSTERM);
 1140                         }
 1141                         /* Make the table calculations below happy */
 1142                         internal50_present = 0;
 1143                         internal68_present = 1;
 1144                         externalcable_present = 1;
 1145                 } else if ((ahc->features & AHC_SPIOCAP) != 0) {
 1146                         aic785X_cable_detect(ahc, &internal50_present,
 1147                                              &externalcable_present,
 1148                                              &eeprom_present);
 1149                 } else {
 1150                         aic787X_cable_detect(ahc, &internal50_present,
 1151                                              &internal68_present,
 1152                                              &externalcable_present,
 1153                                              &eeprom_present);
 1154                 }
 1155 
 1156                 if ((ahc->features & AHC_WIDE) == 0)
 1157                         internal68_present = 0;
 1158 
 1159                 if (bootverbose) {
 1160                         if ((ahc->features & AHC_ULTRA2) == 0) {
 1161                                 printf("%s: internal 50 cable %s present, "
 1162                                        "internal 68 cable %s present\n",
 1163                                        ahc_name(ahc),
 1164                                        internal50_present ? "is":"not",
 1165                                        internal68_present ? "is":"not");
 1166 
 1167                                 printf("%s: external cable %s present\n",
 1168                                        ahc_name(ahc),
 1169                                        externalcable_present ? "is":"not");
 1170                         }
 1171                         printf("%s: BIOS eeprom %s present\n",
 1172                                ahc_name(ahc), eeprom_present ? "is" : "not");
 1173 
 1174                 }
 1175 
 1176                 /*
 1177                  * Now set the termination based on what
 1178                  * we found.
 1179                  * Flash Enable = BRDDAT7
 1180                  * Secondary High Term Enable = BRDDAT6
 1181                  * Secondary Low Term Enable = BRDDAT5 (7890)
 1182                  * Primary High Term Enable = BRDDAT4 (7890)
 1183                  */
 1184                 if ((ahc->features & AHC_ULTRA2) == 0
 1185                     && (internal50_present != 0)
 1186                     && (internal68_present != 0)
 1187                     && (externalcable_present != 0)) {
 1188                         printf("%s: Illegal cable configuration!!. "
 1189                                "Only two connectors on the "
 1190                                "adapter may be used at a "
 1191                                "time!\n", ahc_name(ahc));
 1192                 }
 1193 
 1194                 if ((ahc->features & AHC_WIDE) != 0
 1195                  && ((externalcable_present == 0)
 1196                   || (internal68_present == 0)
 1197                   || (enableSEC_high != 0))) {
 1198                         brddat |= BRDDAT6;
 1199                         if (bootverbose)
 1200                                 printf("%s: %sHigh byte termination Enabled\n",
 1201                                        ahc_name(ahc),
 1202                                        enableSEC_high ? "Secondary " : "");
 1203                 }
 1204 
 1205                 if (((internal50_present ? 1 : 0)
 1206                    + (internal68_present ? 1 : 0)
 1207                    + (externalcable_present ? 1 : 0)) <= 1
 1208                  || (enableSEC_low != 0)) {
 1209                         if ((ahc->features & AHC_ULTRA2) != 0)
 1210                                 brddat |= BRDDAT5;
 1211                         else
 1212                                 *sxfrctl1 |= STPWEN;
 1213                         if (bootverbose)
 1214                                 printf("%s: %sLow byte termination Enabled\n",
 1215                                        ahc_name(ahc),
 1216                                        enableSEC_low ? "Secondary " : "");
 1217                 }
 1218 
 1219                 if (enablePRI_low != 0) {
 1220                         *sxfrctl1 |= STPWEN;
 1221                         if (bootverbose)
 1222                                 printf("%s: Primary Low Byte termination "
 1223                                        "Enabled\n", ahc_name(ahc));
 1224                 }
 1225 
 1226                 if (enablePRI_high != 0) {
 1227                         brddat |= BRDDAT4;
 1228                         if (bootverbose)
 1229                                 printf("%s: Primary High Byte "
 1230                                        "termination Enabled\n",
 1231                                        ahc_name(ahc));
 1232                 }
 1233                 
 1234                 write_brdctl(ahc, brddat);
 1235 
 1236         } else {
 1237                 if ((adapter_control & CFSTERM) != 0) {
 1238                         *sxfrctl1 |= STPWEN;
 1239 
 1240                         if (bootverbose)
 1241                                 printf("%s: %sLow byte termination Enabled\n",
 1242                                        ahc_name(ahc),
 1243                                        (ahc->features & AHC_ULTRA2) ? "Primary "
 1244                                                                     : "");
 1245                 }
 1246 
 1247                 if ((adapter_control & CFWSTERM) != 0) {
 1248                         brddat |= BRDDAT6;
 1249                         if (bootverbose)
 1250                                 printf("%s: %sHigh byte termination Enabled\n",
 1251                                        ahc_name(ahc),
 1252                                        (ahc->features & AHC_ULTRA2)
 1253                                      ? "Secondary " : "");
 1254                 }
 1255 
 1256                 write_brdctl(ahc, brddat);
 1257         }
 1258         SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */
 1259 }
 1260 
 1261 static void
 1262 ahc_ultra2_term_detect(struct ahc_softc *ahc, int *enableSEC_low,
 1263                       int *enableSEC_high, int *enablePRI_low,
 1264                       int *enablePRI_high, int *eeprom_present)
 1265 {
 1266         u_int8_t brdctl;
 1267 
 1268         /*
 1269          * BRDDAT7 = Eeprom
 1270          * BRDDAT6 = Enable Secondary High Byte termination
 1271          * BRDDAT5 = Enable Secondary Low Byte termination
 1272          * BRDDAT4 = Enable Primary high byte termination
 1273          * BRDDAT3 = Enable Primary low byte termination
 1274          */
 1275         brdctl = read_brdctl(ahc);
 1276         *eeprom_present = brdctl & BRDDAT7;
 1277         *enableSEC_high = (brdctl & BRDDAT6);
 1278         *enableSEC_low = (brdctl & BRDDAT5);
 1279         *enablePRI_high = (brdctl & BRDDAT4);
 1280         *enablePRI_low = (brdctl & BRDDAT3);
 1281 }
 1282 
 1283 static void
 1284 aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
 1285                      int *internal68_present, int *externalcable_present,
 1286                      int *eeprom_present)
 1287 {
 1288         u_int8_t brdctl;
 1289 
 1290         /*
 1291          * First read the status of our cables.
 1292          * Set the rom bank to 0 since the
 1293          * bank setting serves as a multiplexor
 1294          * for the cable detection logic.
 1295          * BRDDAT5 controls the bank switch.
 1296          */
 1297         write_brdctl(ahc, 0);
 1298 
 1299         /*
 1300          * Now read the state of the internal
 1301          * connectors.  BRDDAT6 is INT50 and
 1302          * BRDDAT7 is INT68.
 1303          */
 1304         brdctl = read_brdctl(ahc);
 1305         *internal50_present = !(brdctl & BRDDAT6);
 1306         *internal68_present = !(brdctl & BRDDAT7);
 1307 
 1308         /*
 1309          * Set the rom bank to 1 and determine
 1310          * the other signals.
 1311          */
 1312         write_brdctl(ahc, BRDDAT5);
 1313 
 1314         /*
 1315          * Now read the state of the external
 1316          * connectors.  BRDDAT6 is EXT68 and
 1317          * BRDDAT7 is EPROMPS.
 1318          */
 1319         brdctl = read_brdctl(ahc);
 1320         *externalcable_present = !(brdctl & BRDDAT6);
 1321         *eeprom_present = brdctl & BRDDAT7;
 1322 }
 1323 
 1324 static void
 1325 aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
 1326                      int *externalcable_present, int *eeprom_present)
 1327 {
 1328         u_int8_t brdctl;
 1329 
 1330         ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
 1331         ahc_outb(ahc, BRDCTL, 0);
 1332         brdctl = ahc_inb(ahc, BRDCTL);
 1333         *internal50_present = !(brdctl & BRDDAT5);
 1334         *externalcable_present = !(brdctl & BRDDAT6);
 1335 
 1336         *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) != 0;
 1337 }
 1338         
 1339 static int
 1340 acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd)
 1341 {
 1342         int wait;
 1343 
 1344         if ((ahc->features & AHC_SPIOCAP) != 0
 1345          && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0)
 1346                 return (0);
 1347 
 1348         /*
 1349          * Request access of the memory port.  When access is
 1350          * granted, SEERDY will go high.  We use a 1 second
 1351          * timeout which should be near 1 second more than
 1352          * is needed.  Reason: after the chip reset, there
 1353          * should be no contention.
 1354          */
 1355         SEEPROM_OUTB(sd, sd->sd_MS);
 1356         wait = 1000;  /* 1 second timeout in msec */
 1357         while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) {
 1358                 DELAY(1000);  /* delay 1 msec */
 1359         }
 1360         if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) {
 1361                 SEEPROM_OUTB(sd, 0); 
 1362                 return (0);
 1363         }
 1364         return(1);
 1365 }
 1366 
 1367 static void
 1368 release_seeprom(sd)
 1369         struct seeprom_descriptor *sd;
 1370 {
 1371         /* Release access to the memory port and the serial EEPROM. */
 1372         SEEPROM_OUTB(sd, 0);
 1373 }
 1374 
 1375 static void
 1376 write_brdctl(ahc, value)
 1377         struct  ahc_softc *ahc;
 1378         u_int8_t value;
 1379 {
 1380         u_int8_t brdctl;
 1381 
 1382         if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
 1383                 brdctl = BRDSTB;
 1384                 if (ahc->channel == 'B')
 1385                         brdctl |= BRDCS;
 1386         } else if ((ahc->features & AHC_ULTRA2) != 0) {
 1387                 brdctl = 0;
 1388         } else {
 1389                 brdctl = BRDSTB|BRDCS;
 1390         }
 1391         ahc_outb(ahc, BRDCTL, brdctl);
 1392         brdctl |= value;
 1393         ahc_outb(ahc, BRDCTL, brdctl);
 1394         if ((ahc->features & AHC_ULTRA2) != 0)
 1395                 brdctl |= BRDSTB_ULTRA2;
 1396         else
 1397                 brdctl &= ~BRDSTB;
 1398         ahc_outb(ahc, BRDCTL, brdctl);
 1399         if ((ahc->features & AHC_ULTRA2) != 0)
 1400                 brdctl = 0;
 1401         else
 1402                 brdctl &= ~BRDCS;
 1403         ahc_outb(ahc, BRDCTL, brdctl);
 1404 }
 1405 
 1406 static u_int8_t
 1407 read_brdctl(ahc)
 1408         struct  ahc_softc *ahc;
 1409 {
 1410         u_int8_t brdctl;
 1411         u_int8_t value;
 1412 
 1413         if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
 1414                 brdctl = BRDRW;
 1415                 if (ahc->channel == 'B')
 1416                         brdctl |= BRDCS;
 1417         } else if ((ahc->features & AHC_ULTRA2) != 0) {
 1418                 brdctl = BRDRW_ULTRA2;
 1419         } else {
 1420                 brdctl = BRDRW|BRDCS;
 1421         }
 1422         ahc_outb(ahc, BRDCTL, brdctl);
 1423         value = ahc_inb(ahc, BRDCTL);
 1424         ahc_outb(ahc, BRDCTL, 0);
 1425         return (value);
 1426 }
 1427 
 1428 #define DPE     0x80
 1429 #define SSE     0x40
 1430 #define RMA     0x20
 1431 #define RTA     0x10
 1432 #define STA     0x08
 1433 #define DPR     0x01
 1434 
 1435 void
 1436 ahc_pci_intr(struct ahc_softc *ahc)
 1437 {
 1438         u_int8_t status1;
 1439 
 1440         status1 = pci_cfgread(ahc->pci_config_id, PCIR_STATUS + 1, /*bytes*/1);
 1441 
 1442         if (status1 & DPE) {
 1443                 printf("%s: Data Parity Error Detected during address "
 1444                        "or write data phase\n", ahc_name(ahc));
 1445         }
 1446         if (status1 & SSE) {
 1447                 printf("%s: Signal System Error Detected\n", ahc_name(ahc));
 1448         }
 1449         if (status1 & RMA) {
 1450                 printf("%s: Received a Master Abort\n", ahc_name(ahc));
 1451         }
 1452         if (status1 & RTA) {
 1453                 printf("%s: Received a Target Abort\n", ahc_name(ahc));
 1454         }
 1455         if (status1 & STA) {
 1456                 printf("%s: Signaled a Target Abort\n", ahc_name(ahc));
 1457         }
 1458         if (status1 & DPR) {
 1459                 printf("%s: Data Parity Error has been reported via PERR#\n",
 1460                        ahc_name(ahc));
 1461         }
 1462         if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
 1463                 printf("%s: Latched PCIERR interrupt with "
 1464                        "no status bits set\n", ahc_name(ahc)); 
 1465         }
 1466         pci_cfgwrite(ahc->pci_config_id, PCIR_STATUS + 1, status1, /*bytes*/1);
 1467 
 1468         if (status1 & (DPR|RMA|RTA)) {
 1469                 ahc_outb(ahc, CLRINT, CLRPARERR);
 1470         }
 1471 }
 1472 
 1473 static int
 1474 ahc_aic7850_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1475                   ahc_feature *features, ahc_flag *flags)
 1476 {
 1477         *channel = 'A';
 1478         *chip = AHC_AIC7850;
 1479         *features = AHC_AIC7850_FE;
 1480         return (0);
 1481 }
 1482 
 1483 static int
 1484 ahc_aic7855_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1485                   ahc_feature *features, ahc_flag *flags)
 1486 {
 1487         *channel = 'A';
 1488         *chip = AHC_AIC7855;
 1489         *features = AHC_AIC7855_FE;
 1490         return (0);
 1491 }
 1492 
 1493 static int
 1494 ahc_aic7859_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1495                   ahc_feature *features, ahc_flag *flags)
 1496 {
 1497         *channel = 'A';
 1498         *chip = AHC_AIC7859;
 1499         *features = AHC_AIC7859_FE;
 1500         return (0);
 1501 }
 1502 
 1503 static int
 1504 ahc_aic7860_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1505                   ahc_feature *features, ahc_flag *flags)
 1506 {
 1507         *channel = 'A';
 1508         *chip = AHC_AIC7860;
 1509         *features = AHC_AIC7860_FE;
 1510         return (0);
 1511 }
 1512 
 1513 static int
 1514 ahc_aic7870_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1515                   ahc_feature *features, ahc_flag *flags)
 1516 {
 1517         *channel = 'A';
 1518         *chip = AHC_AIC7870;
 1519         *features = AHC_AIC7870_FE;
 1520         return (0);
 1521 }
 1522 
 1523 static int
 1524 ahc_aha394X_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1525                   ahc_feature *features, ahc_flag *flags)
 1526 {
 1527         int error;
 1528 
 1529         error = ahc_aic7870_setup(dev, channel, chip, features, flags);
 1530         if (error == 0)
 1531                 error = ahc_aha394XX_setup(dev, channel, chip, features, flags);
 1532         return (error);
 1533 }
 1534 
 1535 static int
 1536 ahc_aha398X_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1537                   ahc_feature *features, ahc_flag *flags)
 1538 {
 1539         int error;
 1540 
 1541         error = ahc_aic7870_setup(dev, channel, chip, features, flags);
 1542         if (error == 0)
 1543                 error = ahc_aha398XX_setup(dev, channel, chip, features, flags);
 1544         return (error);
 1545 }
 1546 
 1547 static int
 1548 ahc_aic7880_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1549                   ahc_feature *features, ahc_flag *flags)
 1550 {
 1551         *channel = 'A';
 1552         *chip = AHC_AIC7880;
 1553         *features = AHC_AIC7880_FE;
 1554         return (0);
 1555 }
 1556 
 1557 static int
 1558 ahc_aha394XU_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1559                    ahc_feature *features, ahc_flag *flags)
 1560 {
 1561         int error;
 1562 
 1563         error = ahc_aic7880_setup(dev, channel, chip, features, flags);
 1564         if (error == 0)
 1565                 error = ahc_aha394XX_setup(dev, channel, chip, features, flags);
 1566         return (error);
 1567 }
 1568 
 1569 static int
 1570 ahc_aha398XU_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1571                    ahc_feature *features, ahc_flag *flags)
 1572 {
 1573         int error;
 1574 
 1575         error = ahc_aic7880_setup(dev, channel, chip, features, flags);
 1576         if (error == 0)
 1577                 error = ahc_aha398XX_setup(dev, channel, chip, features, flags);
 1578         return (error);
 1579 }
 1580 
 1581 static int
 1582 ahc_aic7890_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1583                   ahc_feature *features, ahc_flag *flags)
 1584 {
 1585         *channel = 'A';
 1586         *chip = AHC_AIC7890;
 1587         *features = AHC_AIC7890_FE;
 1588         *flags |= AHC_NEWEEPROM_FMT;
 1589         return (0);
 1590 }
 1591 
 1592 static int
 1593 ahc_aic7895_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1594                   ahc_feature *features, ahc_flag *flags)
 1595 {
 1596         u_int32_t devconfig;
 1597         u_int8_t revid;
 1598 
 1599         *channel = dev->func == 1 ? 'B' : 'A';
 1600         *chip = AHC_AIC7895;
 1601         /* The 'C' revision of the aic7895 has a few additional features */
 1602         revid = pci_cfgread(dev, PCIR_REVID, /*bytes*/1);
 1603         if (revid >= 4)
 1604                 *features = AHC_AIC7895C_FE;
 1605         else
 1606                 *features = AHC_AIC7895_FE;
 1607         *flags |= AHC_NEWEEPROM_FMT;
 1608         devconfig = pci_cfgread(dev, DEVCONFIG, /*bytes*/4);
 1609         devconfig &= ~SCBSIZE32;
 1610         pci_cfgwrite(dev, DEVCONFIG, devconfig, /*bytes*/4);
 1611         return (0);
 1612 }
 1613 
 1614 static int
 1615 ahc_aic7896_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1616                   ahc_feature *features, ahc_flag *flags)
 1617 {
 1618         *channel = dev->func == 1 ? 'B' : 'A';
 1619         *chip = AHC_AIC7896;
 1620         *features = AHC_AIC7896_FE;
 1621         *flags |= AHC_NEWEEPROM_FMT;
 1622         return (0);
 1623 }
 1624 
 1625 static int
 1626 ahc_raid_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1627                ahc_feature *features, ahc_flag *flags)
 1628 {
 1629         printf("RAID functionality unsupported\n");
 1630         return (ENXIO);
 1631 }
 1632 
 1633 static int
 1634 ahc_aha394XX_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1635                    ahc_feature *features, ahc_flag *flags)
 1636 {
 1637         switch (dev->slot) {
 1638         case AHC_394X_SLOT_CHANNEL_A:
 1639                 *channel = 'A';
 1640                 break;
 1641         case AHC_394X_SLOT_CHANNEL_B:
 1642                 *channel = 'B';
 1643                 break;
 1644         default:
 1645                 printf("adapter at unexpected slot %d\n"
 1646                        "unable to map to a channel\n",
 1647                        dev->slot);
 1648                 *channel = 'A';
 1649         }
 1650         return (0);
 1651 }
 1652 
 1653 static int
 1654 ahc_aha398XX_setup(pcici_t dev, char *channel, ahc_chip *chip,
 1655                    ahc_feature *features, ahc_flag *flags)
 1656 {
 1657         switch (dev->slot) {
 1658         case AHC_398X_SLOT_CHANNEL_A:
 1659                 *channel = 'A';
 1660                 break;
 1661         case AHC_398X_SLOT_CHANNEL_B:
 1662                 *channel = 'B';
 1663                 break;
 1664         case AHC_398X_SLOT_CHANNEL_C:
 1665                 *channel = 'C';
 1666                 break;
 1667         default:
 1668                 printf("adapter at unexpected slot %d\n"
 1669                        "unable to map to a channel\n",
 1670                        dev->slot);
 1671                 *channel = 'A';
 1672         }
 1673         *flags |= AHC_LARGE_SEEPROM;
 1674         return (0);
 1675 }
 1676 
 1677 #endif /* NPCI > 0 */

Cache object: 75f9b054beee1346916d1f6e9481feda


[ 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.