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