2 * Product specific probe and attach routines for:
3 * aic7901 and aic7902 SCSI controllers
5 * Copyright (c) 1994-2001 Justin T. Gibbs.
6 * Copyright (c) 2000-2002 Adaptec Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * substantially similar to the "NO WARRANTY" disclaimer below
17 * ("Disclaimer") and any redistribution must be conditioned upon
18 * including a substantially similar Disclaimer requirement for further
19 * binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES.
41 * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#44 $
47 #include "aic79xx_osm.h"
48 #include "aic79xx_inline.h"
50 #include <dev/aic7xxx/aic79xx_osm.h>
51 #include <dev/aic7xxx/aic79xx_inline.h>
54 static __inline uint64_t
55 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
61 | ((uint64_t)vendor << 32)
62 | ((uint64_t)device << 48);
67 #define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
68 #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
69 #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
71 #define ID_AIC7901 0x800F9005FFFF9005ull
72 #define ID_AIC7901_IROC 0x80089005FFFF9005ull
73 #define ID_AIC7901A 0x801E9005FFFF9005ull
74 #define ID_AHA_29320A 0x8000900500609005ull
76 #define ID_AIC7902 0x801F9005FFFF9005ull
77 #define ID_AIC7902_IROC 0x80189005FFFF9005ull
78 #define ID_AHA_39320 0x8010900500409005ull
79 #define ID_AHA_39320D 0x8011900500419005ull
80 #define ID_AHA_39320D_CPQ 0x8011900500AC0E11ull
81 #define ID_AHA_29320 0x8012900500429005ull
82 #define ID_AHA_29320B 0x8013900500439005ull
83 #define ID_AHA_29320LP 0x8014900500449005ull
84 #define ID_AIC7902_PCI_REV_A4 0x3
85 #define ID_AIC7902_PCI_REV_B0 0x10
86 #define SUBID_CPQ 0x0E11
88 #define DEVID_9005_TYPE(id) ((id) & 0xF)
89 #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
90 #define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */
91 #define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */
92 #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
94 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
96 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
98 #define SUBID_9005_TYPE(id) ((id) & 0xF)
99 #define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */
100 #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
102 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
104 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
106 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
107 #define SUBID_9005_SEEPTYPE_NONE 0x0
108 #define SUBID_9005_SEEPTYPE_4K 0x1
110 static ahd_device_setup_t ahd_aic7901_setup;
111 static ahd_device_setup_t ahd_aic7902_setup;
112 static ahd_device_setup_t ahd_aic7901A_setup;
114 struct ahd_pci_identity ahd_pci_ident_table [] =
116 /* aic7901 based controllers */
120 "Adaptec 29320A Ultra320 SCSI adapter",
123 /* aic7902 based controllers */
127 "Adaptec 39320 Ultra320 SCSI adapter",
133 "Adaptec 39320D Ultra320 SCSI adapter",
139 "Adaptec (Compaq OEM) 39320D Ultra320 SCSI adapter",
145 "Adaptec 29320 Ultra320 SCSI adapter",
151 "Adaptec 29320B Ultra320 SCSI adapter",
157 "Adaptec 29320LP Ultra320 SCSI adapter",
161 ID_AIC7901A & ID_9005_GENERIC_MASK,
162 ID_9005_GENERIC_MASK,
163 "Adaptec 7901A Ultra320 SCSI adapter",
166 /* Generic chip probes for devices we don't know 'exactly' */
168 ID_AIC7901 & ID_9005_GENERIC_MASK,
169 ID_9005_GENERIC_MASK,
170 "Adaptec aic7901 Ultra320 SCSI adapter",
174 ID_AIC7902 & ID_9005_GENERIC_MASK,
175 ID_9005_GENERIC_MASK,
176 "Adaptec aic7902 Ultra320 SCSI adapter",
181 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
183 #define DEVCONFIG 0x40
184 #define PCIXINITPAT 0x0000E000ul
185 #define PCIXINIT_PCI33_66 0x0000E000ul
186 #define PCIXINIT_PCIX50_66 0x0000C000ul
187 #define PCIXINIT_PCIX66_100 0x0000A000ul
188 #define PCIXINIT_PCIX100_133 0x00008000ul
189 #define PCI_BUS_MODES_INDEX(devconfig) \
190 (((devconfig) & PCIXINITPAT) >> 13)
191 static const char *pci_bus_modes[] =
193 "PCI bus mode unknown",
194 "PCI bus mode unknown",
195 "PCI bus mode unknown",
196 "PCI bus mode unknown",
203 #define TESTMODE 0x00000800ul
204 #define IRDY_RST 0x00000200ul
205 #define FRAME_RST 0x00000100ul
206 #define PCI64BIT 0x00000080ul
207 #define MRDCEN 0x00000040ul
208 #define ENDIANSEL 0x00000020ul
209 #define MIXQWENDIANEN 0x00000008ul
210 #define DACEN 0x00000004ul
211 #define STPWLEVEL 0x00000002ul
212 #define QWENDIANSEL 0x00000001ul
214 #define DEVCONFIG1 0x44
217 #define CSIZE_LATTIME 0x0c
218 #define CACHESIZE 0x000000fful
219 #define LATTIME 0x0000ff00ul
221 static int ahd_check_extport(struct ahd_softc *ahd);
222 static void ahd_configure_termination(struct ahd_softc *ahd,
223 u_int adapter_control);
224 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
226 struct ahd_pci_identity *
227 ahd_find_pci_device(ahd_dev_softc_t pci)
234 struct ahd_pci_identity *entry;
237 vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
238 device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
239 subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
240 subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
241 full_id = ahd_compose_id(device,
246 for (i = 0; i < ahd_num_pci_devs; i++) {
247 entry = &ahd_pci_ident_table[i];
248 if (entry->full_id == (full_id & entry->id_mask)) {
249 /* Honor exclusion entries. */
250 if (entry->name == NULL)
259 ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
261 struct scb_data *shared_scb_data;
268 shared_scb_data = NULL;
269 error = entry->setup(ahd);
273 ahd->description = entry->name;
274 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
275 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
276 ahd->chip |= AHD_PCI;
277 /* Disable PCIX workarounds when running in PCI mode. */
278 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
280 ahd->chip |= AHD_PCIX;
282 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
285 * Record if this is a Compaq board.
287 subvendor = ahd_pci_read_config(ahd->dev_softc,
288 PCIR_SUBVEND_0, /*bytes*/2);
289 if (subvendor == SUBID_CPQ)
290 ahd->flags |= AHD_CPQ_BOARD;
292 ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
294 error = ahd_pci_map_registers(ahd);
299 * If we need to support high memory, enable dual
300 * address cycles. This bit must be set to enable
301 * high address bit generation even if we are on a
302 * 64bit bus (PCI64BIT set in devconfig).
304 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
308 printf("%s: Enabling 39Bit Addressing\n",
310 devconfig = ahd_pci_read_config(ahd->dev_softc,
311 DEVCONFIG, /*bytes*/4);
313 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
314 devconfig, /*bytes*/4);
317 /* Ensure busmastering is enabled */
318 command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1);
319 command |= PCIM_CMD_BUSMASTEREN;
320 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
322 error = ahd_softc_init(ahd);
326 ahd->bus_intr = ahd_pci_intr;
328 error = ahd_reset(ahd);
333 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
334 /*bytes*/1) & CACHESIZE;
335 ahd->pci_cachesize *= 4;
337 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
338 /* See if we have a SEEPROM and perform auto-term */
339 error = ahd_check_extport(ahd);
343 /* Core initialization */
344 error = ahd_init(ahd);
349 * Allow interrupts now that we are completely setup.
351 error = ahd_pci_map_int(ahd);
357 * Link this softc in with all other ahd instances.
359 ahd_softc_insert(ahd);
365 * Check the external port logic for a serial eeprom
366 * and termination/cable detection contrls.
369 ahd_check_extport(struct ahd_softc *ahd)
371 struct seeprom_config *sc;
372 u_int adapter_control;
376 sc = ahd->seep_config;
377 have_seeprom = ahd_acquire_seeprom(ahd);
382 printf("%s: Reading SEEPROM...", ahd_name(ahd));
384 /* Address is always in units of 16bit words */
385 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
387 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
388 start_addr, sizeof(*sc)/2);
391 printf("Unable to read SEEPROM\n");
394 have_seeprom = ahd_verify_cksum(sc);
397 if (have_seeprom == 0)
398 printf ("checksum error\n");
403 ahd_release_seeprom(ahd);
410 * Pull scratch ram settings and treat them as
411 * if they are the contents of an seeprom if
412 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
413 * in SCB 0xFF. We manually compose the data as 16bit
414 * values to avoid endian issues.
416 ahd_set_scbptr(ahd, 0xFF);
417 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
418 if (nvram_scb != 0xFF
419 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
420 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
421 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
422 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
423 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
424 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
425 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
426 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
427 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
428 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
429 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
430 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
434 ahd_set_scbptr(ahd, nvram_scb);
435 sc_data = (uint16_t *)sc;
436 for (i = 0; i < 64; i += 2)
437 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
438 have_seeprom = ahd_verify_cksum(sc);
440 ahd->flags |= AHD_SCB_CONFIG_USED;
445 if (have_seeprom != 0
446 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
450 printf("%s: Seeprom Contents:", ahd_name(ahd));
451 sc_data = (uint8_t *)sc;
452 for (i = 0; i < (sizeof(*sc)); i += 2)
454 sc_data[i] | (sc_data[i+1] << 8));
461 printf("%s: No SEEPROM available.\n", ahd_name(ahd));
462 ahd->flags |= AHD_USEDEFAULTS;
463 error = ahd_default_config(ahd);
464 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
465 free(ahd->seep_config, M_DEVBUF);
466 ahd->seep_config = NULL;
468 error = ahd_parse_cfgdata(ahd, sc);
469 adapter_control = sc->adapter_control;
474 ahd_configure_termination(ahd, adapter_control);
480 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
487 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
488 devconfig &= ~STPWLEVEL;
489 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
490 devconfig |= STPWLEVEL;
492 printf("%s: STPWLEVEL is %s\n",
493 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
494 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
496 /* Make sure current sensing is off. */
497 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
498 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
502 * Read to sense. Write to set.
504 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
505 if ((adapter_control & CFAUTOTERM) == 0) {
507 printf("%s: Manual Primary Termination\n",
509 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
510 if ((adapter_control & CFSTERM) != 0)
511 termctl |= FLX_TERMCTL_ENPRILOW;
512 if ((adapter_control & CFWSTERM) != 0)
513 termctl |= FLX_TERMCTL_ENPRIHIGH;
514 } else if (error != 0) {
515 printf("%s: Primary Auto-Term Sensing failed! "
516 "Using Defaults.\n", ahd_name(ahd));
517 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
520 if ((adapter_control & CFSEAUTOTERM) == 0) {
522 printf("%s: Manual Secondary Termination\n",
524 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
525 if ((adapter_control & CFSELOWTERM) != 0)
526 termctl |= FLX_TERMCTL_ENSECLOW;
527 if ((adapter_control & CFSEHIGHTERM) != 0)
528 termctl |= FLX_TERMCTL_ENSECHIGH;
529 } else if (error != 0) {
530 printf("%s: Secondary Auto-Term Sensing failed! "
531 "Using Defaults.\n", ahd_name(ahd));
532 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
536 * Now set the termination based on what we found.
538 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
539 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
540 ahd->flags |= AHD_TERM_ENB_A;
543 /* Must set the latch once in order to be effective. */
544 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
545 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
547 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
549 printf("%s: Unable to set termination settings!\n",
551 } else if (bootverbose) {
552 printf("%s: Primary High byte termination %sabled\n",
554 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
556 printf("%s: Primary Low byte termination %sabled\n",
558 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
560 printf("%s: Secondary High byte termination %sabled\n",
562 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
564 printf("%s: Secondary Low byte termination %sabled\n",
566 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
578 static const char *split_status_source[] =
586 static const char *pci_status_source[] =
598 static const char *split_status_strings[] =
600 "%s: Received split response in %s.\n"
601 "%s: Received split completion error message in %s\n",
602 "%s: Receive overrun in %s\n",
603 "%s: Count not complete in %s\n",
604 "%s: Split completion data bucket in %s\n",
605 "%s: Split completion address error in %s\n",
606 "%s: Split completion byte count error in %s\n",
607 "%s: Signaled Target-abort to early terminate a split in %s\n",
610 static const char *pci_status_strings[] =
612 "%s: Data Parity Error has been reported via PERR# in %s\n",
613 "%s: Target initial wait state error in %s\n",
614 "%s: Split completion read data parity error in %s\n",
615 "%s: Split completion address attribute parity error in %s\n",
616 "%s: Received a Target Abort in %s\n",
617 "%s: Received a Master Abort in %s\n",
618 "%s: Signal System Error Detected in %s\n",
619 "%s: Address or Write Phase Parity Error Detected in %s.\n"
623 ahd_pci_intr(struct ahd_softc *ahd)
625 uint8_t pci_status[8];
626 ahd_mode_state saved_modes;
632 intstat = ahd_inb(ahd, INTSTAT);
634 if ((intstat & SPLTINT) != 0)
635 ahd_pci_split_intr(ahd, intstat);
637 if ((intstat & PCIINT) == 0)
640 printf("%s: PCI error Interrupt\n", ahd_name(ahd));
641 saved_modes = ahd_save_modes(ahd);
642 ahd_dump_card_state(ahd);
643 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
644 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
648 pci_status[i] = ahd_inb(ahd, reg);
649 /* Clear latched errors. So our interupt deasserts. */
650 ahd_outb(ahd, reg, pci_status[i]);
653 for (i = 0; i < 8; i++) {
659 for (bit = 0; bit < 8; bit++) {
661 if ((pci_status[i] & (0x1 << bit)) != 0) {
662 static const char *s;
664 s = pci_status_strings[bit];
665 if (i == 7/*TARG*/ && bit == 3)
666 s = "%s: Signal Target Abort\n";
667 printf(s, ahd_name(ahd), pci_status_source[i]);
671 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
672 PCIR_STATUS + 1, /*bytes*/1);
673 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
674 pci_status1, /*bytes*/1);
675 ahd_restore_modes(ahd, saved_modes);
680 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
682 uint8_t split_status[4];
683 uint8_t split_status1[4];
684 uint8_t sg_split_status[2];
685 uint8_t sg_split_status1[2];
686 ahd_mode_state saved_modes;
688 uint16_t pcix_status;
691 * Check for splits in all modes. Modes 0 and 1
692 * additionally have SG engine splits to look at.
694 pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
696 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
697 ahd_name(ahd), pcix_status);
698 saved_modes = ahd_save_modes(ahd);
699 for (i = 0; i < 4; i++) {
700 ahd_set_modes(ahd, i, i);
702 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
703 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
704 /* Clear latched errors. So our interupt deasserts. */
705 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
706 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
709 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
710 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
711 /* Clear latched errors. So our interupt deasserts. */
712 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
713 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
716 for (i = 0; i < 4; i++) {
719 for (bit = 0; bit < 8; bit++) {
721 if ((split_status[i] & (0x1 << bit)) != 0) {
722 static const char *s;
724 s = split_status_strings[bit];
725 printf(s, ahd_name(ahd),
726 split_status_source[i]);
732 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
733 static const char *s;
735 s = split_status_strings[bit];
736 printf(s, ahd_name(ahd), "SG");
741 * Clear PCI-X status bits.
743 ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
744 pcix_status, /*bytes*/2);
745 ahd_restore_modes(ahd, saved_modes);
749 ahd_aic7901_setup(struct ahd_softc *ahd)
753 pci = ahd->dev_softc;
755 ahd->chip = AHD_AIC7901;
756 ahd->features = AHD_AIC7901_FE;
761 ahd_aic7902_setup(struct ahd_softc *ahd)
767 pci = ahd->dev_softc;
768 rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
769 if (rev < ID_AIC7902_PCI_REV_A4) {
770 printf("%s: Unable to attach to unsupported chip revision %d\n",
772 ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/1);
775 if (rev < ID_AIC7902_PCI_REV_B0) {
777 * Pending request assertion does not work on the A if we have
778 * DMA requests outstanding on both channels. See H2A3 Razors
781 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
782 ahd_pci_write_config(pci, DEVCONFIG1,
783 devconfig1|PREQDIS, /*bytes*/1);
784 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
786 * Enable A series workarounds.
788 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
789 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
790 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
791 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
792 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
793 | AHD_PCIX_CHIPRST_BUG|AHD_PKTIZED_STATUS_BUG
794 | AHD_PKT_LUN_BUG|AHD_MDFF_WSCBPTR_BUG
795 | AHD_REG_SLOW_SETTLE_BUG|AHD_SET_MODE_BUG
796 | AHD_BUSFREEREV_BUG;
799 ahd->channel = ahd_get_pci_function(pci) + 'A';
800 ahd->chip = AHD_AIC7902;
801 ahd->features = AHD_AIC7902_FE;
806 ahd_aic7901A_setup(struct ahd_softc *ahd)
810 error = ahd_aic7902_setup(ahd);
813 ahd->chip = AHD_AIC7901A;