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#77 $
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_ALL_IROC_MASK 0xFF7FFFFFFFFFFFFFull
69 #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
70 #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
71 #define ID_9005_GENERIC_IROC_MASK 0xFF70FFFF00000000ull
73 #define ID_AIC7901 0x800F9005FFFF9005ull
74 #define ID_AHA_29320A 0x8000900500609005ull
75 #define ID_AHA_29320ALP 0x8017900500449005ull
77 #define ID_AIC7901A 0x801E9005FFFF9005ull
78 #define ID_AHA_29320 0x8012900500429005ull
79 #define ID_AHA_29320B 0x8013900500439005ull
80 #define ID_AHA_29320LP 0x8014900500449005ull
82 #define ID_AIC7902 0x801F9005FFFF9005ull
83 #define ID_AIC7902_B 0x801D9005FFFF9005ull
84 #define ID_AHA_39320 0x8010900500409005ull
85 #define ID_AHA_39320_B 0x8015900500409005ull
86 #define ID_AHA_39320A 0x8016900500409005ull
87 #define ID_AHA_39320D 0x8011900500419005ull
88 #define ID_AHA_39320D_B 0x801C900500419005ull
89 #define ID_AHA_39320D_HP 0x8011900500AC0E11ull
90 #define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull
91 #define ID_AIC7902_PCI_REV_A4 0x3
92 #define ID_AIC7902_PCI_REV_B0 0x10
93 #define SUBID_HP 0x0E11
95 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
97 #define DEVID_9005_TYPE(id) ((id) & 0xF)
98 #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
99 #define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */
100 #define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */
101 #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
103 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
105 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
107 #define SUBID_9005_TYPE(id) ((id) & 0xF)
108 #define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */
109 #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
111 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
113 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
115 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
116 #define SUBID_9005_SEEPTYPE_NONE 0x0
117 #define SUBID_9005_SEEPTYPE_4K 0x1
119 static ahd_device_setup_t ahd_aic7901_setup;
120 static ahd_device_setup_t ahd_aic7901A_setup;
121 static ahd_device_setup_t ahd_aic7902_setup;
122 static ahd_device_setup_t ahd_aic790X_setup;
124 struct ahd_pci_identity ahd_pci_ident_table [] =
126 /* aic7901 based controllers */
130 "Adaptec 29320A Ultra320 SCSI adapter",
136 "Adaptec 29320ALP Ultra320 SCSI adapter",
139 /* aic7902 based controllers */
143 "Adaptec 29320 Ultra320 SCSI adapter",
149 "Adaptec 29320B Ultra320 SCSI adapter",
155 "Adaptec 29320LP Ultra320 SCSI adapter",
161 "Adaptec 39320 Ultra320 SCSI adapter",
167 "Adaptec 39320 Ultra320 SCSI adapter",
173 "Adaptec 39320A Ultra320 SCSI adapter",
179 "Adaptec 39320D Ultra320 SCSI adapter",
185 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
191 "Adaptec 39320D Ultra320 SCSI adapter",
197 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
200 /* Generic chip probes for devices we don't know 'exactly' */
202 ID_AIC7901 & ID_9005_GENERIC_MASK,
203 ID_9005_GENERIC_MASK,
204 "Adaptec AIC7901 Ultra320 SCSI adapter",
208 ID_AIC7901A & ID_DEV_VENDOR_MASK,
210 "Adaptec AIC7901A Ultra320 SCSI adapter",
214 ID_AIC7902 & ID_9005_GENERIC_MASK,
215 ID_9005_GENERIC_MASK,
216 "Adaptec AIC7902 Ultra320 SCSI adapter",
221 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
223 #define DEVCONFIG 0x40
224 #define PCIXINITPAT 0x0000E000ul
225 #define PCIXINIT_PCI33_66 0x0000E000ul
226 #define PCIXINIT_PCIX50_66 0x0000C000ul
227 #define PCIXINIT_PCIX66_100 0x0000A000ul
228 #define PCIXINIT_PCIX100_133 0x00008000ul
229 #define PCI_BUS_MODES_INDEX(devconfig) \
230 (((devconfig) & PCIXINITPAT) >> 13)
231 static const char *pci_bus_modes[] =
233 "PCI bus mode unknown",
234 "PCI bus mode unknown",
235 "PCI bus mode unknown",
236 "PCI bus mode unknown",
243 #define TESTMODE 0x00000800ul
244 #define IRDY_RST 0x00000200ul
245 #define FRAME_RST 0x00000100ul
246 #define PCI64BIT 0x00000080ul
247 #define MRDCEN 0x00000040ul
248 #define ENDIANSEL 0x00000020ul
249 #define MIXQWENDIANEN 0x00000008ul
250 #define DACEN 0x00000004ul
251 #define STPWLEVEL 0x00000002ul
252 #define QWENDIANSEL 0x00000001ul
254 #define DEVCONFIG1 0x44
257 #define CSIZE_LATTIME 0x0c
258 #define CACHESIZE 0x000000fful
259 #define LATTIME 0x0000ff00ul
261 static int ahd_check_extport(struct ahd_softc *ahd);
262 static void ahd_configure_termination(struct ahd_softc *ahd,
263 u_int adapter_control);
264 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
266 struct ahd_pci_identity *
267 ahd_find_pci_device(ahd_dev_softc_t pci)
274 struct ahd_pci_identity *entry;
277 vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
278 device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
279 subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
280 subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
281 full_id = ahd_compose_id(device,
287 * Controllers, mask out the IROC/HostRAID bit
290 full_id &= ID_ALL_IROC_MASK;
292 for (i = 0; i < ahd_num_pci_devs; i++) {
293 entry = &ahd_pci_ident_table[i];
294 if (entry->full_id == (full_id & entry->id_mask)) {
295 /* Honor exclusion entries. */
296 if (entry->name == NULL)
305 ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
307 struct scb_data *shared_scb_data;
314 shared_scb_data = NULL;
315 ahd->description = entry->name;
317 * Record if this is an HP board.
319 subvendor = ahd_pci_read_config(ahd->dev_softc,
320 PCIR_SUBVEND_0, /*bytes*/2);
321 if (subvendor == SUBID_HP)
322 ahd->flags |= AHD_HP_BOARD;
324 error = entry->setup(ahd);
328 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
329 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
330 ahd->chip |= AHD_PCI;
331 /* Disable PCIX workarounds when running in PCI mode. */
332 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
334 ahd->chip |= AHD_PCIX;
336 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
338 ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
340 error = ahd_pci_map_registers(ahd);
345 * If we need to support high memory, enable dual
346 * address cycles. This bit must be set to enable
347 * high address bit generation even if we are on a
348 * 64bit bus (PCI64BIT set in devconfig).
350 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
354 printf("%s: Enabling 39Bit Addressing\n",
356 devconfig = ahd_pci_read_config(ahd->dev_softc,
357 DEVCONFIG, /*bytes*/4);
359 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
360 devconfig, /*bytes*/4);
363 /* Ensure busmastering is enabled */
364 command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
365 command |= PCIM_CMD_BUSMASTEREN;
366 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
368 error = ahd_softc_init(ahd);
372 ahd->bus_intr = ahd_pci_intr;
374 error = ahd_reset(ahd, /*reinit*/FALSE);
379 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
380 /*bytes*/1) & CACHESIZE;
381 ahd->pci_cachesize *= 4;
383 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
384 /* See if we have a SEEPROM and perform auto-term */
385 error = ahd_check_extport(ahd);
389 /* Core initialization */
390 error = ahd_init(ahd);
395 * Allow interrupts now that we are completely setup.
397 error = ahd_pci_map_int(ahd);
403 * Link this softc in with all other ahd instances.
405 ahd_softc_insert(ahd);
411 * Perform some simple tests that should catch situations where
412 * our registers are invalidly mapped.
415 ahd_pci_test_register_access(struct ahd_softc *ahd)
426 * Enable PCI error interrupt status, but suppress NMIs
427 * generated by SERR raised due to target aborts.
429 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
430 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
431 cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
434 * First a simple test to see if any
435 * registers can be read. Reading
436 * HCNTRL has no side effects and has
437 * at least one bit that is guaranteed to
438 * be zero so it is a good register to
441 hcntrl = ahd_inb(ahd, HCNTRL);
446 * Next create a situation where write combining
447 * or read prefetching could be initiated by the
448 * CPU or host bridge. Our device does not support
449 * either, so look for data corruption and/or flaged
450 * PCI errors. First pause without causing another
454 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
455 while (ahd_is_paused(ahd) == 0)
458 /* Clear any PCI errors that occurred before our driver attached. */
459 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
460 targpcistat = ahd_inb(ahd, TARGPCISTAT);
461 ahd_outb(ahd, TARGPCISTAT, targpcistat);
462 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
463 PCIR_STATUS + 1, /*bytes*/1);
464 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
465 pci_status1, /*bytes*/1);
466 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
467 ahd_outb(ahd, CLRINT, CLRPCIINT);
469 ahd_outb(ahd, SEQCTL0, PERRORDIS);
470 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
471 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
474 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
477 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
478 targpcistat = ahd_inb(ahd, TARGPCISTAT);
479 if ((targpcistat & STA) != 0)
486 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
488 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
489 targpcistat = ahd_inb(ahd, TARGPCISTAT);
491 /* Silently clear any latched errors. */
492 ahd_outb(ahd, TARGPCISTAT, targpcistat);
493 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
494 PCIR_STATUS + 1, /*bytes*/1);
495 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
496 pci_status1, /*bytes*/1);
497 ahd_outb(ahd, CLRINT, CLRPCIINT);
499 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
500 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
505 * Check the external port logic for a serial eeprom
506 * and termination/cable detection contrls.
509 ahd_check_extport(struct ahd_softc *ahd)
511 struct vpd_config vpd;
512 struct seeprom_config *sc;
513 u_int adapter_control;
517 sc = ahd->seep_config;
518 have_seeprom = ahd_acquire_seeprom(ahd);
523 * Fetch VPD for this function and parse it.
526 printf("%s: Reading VPD from SEEPROM...",
529 /* Address is always in units of 16bit words */
530 start_addr = ((2 * sizeof(*sc))
531 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
533 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
534 start_addr, sizeof(vpd)/2,
537 error = ahd_parse_vpddata(ahd, &vpd);
539 printf("%s: VPD parsing %s\n",
541 error == 0 ? "successful" : "failed");
544 printf("%s: Reading SEEPROM...", ahd_name(ahd));
546 /* Address is always in units of 16bit words */
547 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
549 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
550 start_addr, sizeof(*sc)/2,
551 /*bytestream*/FALSE);
554 printf("Unable to read SEEPROM\n");
557 have_seeprom = ahd_verify_cksum(sc);
560 if (have_seeprom == 0)
561 printf ("checksum error\n");
566 ahd_release_seeprom(ahd);
573 * Pull scratch ram settings and treat them as
574 * if they are the contents of an seeprom if
575 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
576 * in SCB 0xFF. We manually compose the data as 16bit
577 * values to avoid endian issues.
579 ahd_set_scbptr(ahd, 0xFF);
580 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
581 if (nvram_scb != 0xFF
582 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
583 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
584 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
585 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
586 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
587 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
588 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
589 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
590 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
591 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
592 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
593 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
597 ahd_set_scbptr(ahd, nvram_scb);
598 sc_data = (uint16_t *)sc;
599 for (i = 0; i < 64; i += 2)
600 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
601 have_seeprom = ahd_verify_cksum(sc);
603 ahd->flags |= AHD_SCB_CONFIG_USED;
608 if (have_seeprom != 0
609 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
613 printf("%s: Seeprom Contents:", ahd_name(ahd));
614 sc_data = (uint16_t *)sc;
615 for (i = 0; i < (sizeof(*sc)); i += 2)
616 printf("\n\t0x%.4x", sc_data[i]);
623 printf("%s: No SEEPROM available.\n", ahd_name(ahd));
624 ahd->flags |= AHD_USEDEFAULTS;
625 error = ahd_default_config(ahd);
626 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
627 free(ahd->seep_config, M_DEVBUF);
628 ahd->seep_config = NULL;
630 error = ahd_parse_cfgdata(ahd, sc);
631 adapter_control = sc->adapter_control;
636 ahd_configure_termination(ahd, adapter_control);
642 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
649 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
650 devconfig &= ~STPWLEVEL;
651 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
652 devconfig |= STPWLEVEL;
654 printf("%s: STPWLEVEL is %s\n",
655 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
656 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
658 /* Make sure current sensing is off. */
659 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
660 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
664 * Read to sense. Write to set.
666 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
667 if ((adapter_control & CFAUTOTERM) == 0) {
669 printf("%s: Manual Primary Termination\n",
671 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
672 if ((adapter_control & CFSTERM) != 0)
673 termctl |= FLX_TERMCTL_ENPRILOW;
674 if ((adapter_control & CFWSTERM) != 0)
675 termctl |= FLX_TERMCTL_ENPRIHIGH;
676 } else if (error != 0) {
677 printf("%s: Primary Auto-Term Sensing failed! "
678 "Using Defaults.\n", ahd_name(ahd));
679 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
682 if ((adapter_control & CFSEAUTOTERM) == 0) {
684 printf("%s: Manual Secondary Termination\n",
686 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
687 if ((adapter_control & CFSELOWTERM) != 0)
688 termctl |= FLX_TERMCTL_ENSECLOW;
689 if ((adapter_control & CFSEHIGHTERM) != 0)
690 termctl |= FLX_TERMCTL_ENSECHIGH;
691 } else if (error != 0) {
692 printf("%s: Secondary Auto-Term Sensing failed! "
693 "Using Defaults.\n", ahd_name(ahd));
694 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
698 * Now set the termination based on what we found.
700 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
701 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
702 ahd->flags |= AHD_TERM_ENB_A;
705 /* Must set the latch once in order to be effective. */
706 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
707 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
709 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
711 printf("%s: Unable to set termination settings!\n",
713 } else if (bootverbose) {
714 printf("%s: Primary High byte termination %sabled\n",
716 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
718 printf("%s: Primary Low byte termination %sabled\n",
720 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
722 printf("%s: Secondary High byte termination %sabled\n",
724 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
726 printf("%s: Secondary Low byte termination %sabled\n",
728 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
740 static const char *split_status_source[] =
748 static const char *pci_status_source[] =
760 static const char *split_status_strings[] =
762 "%s: Received split response in %s.\n",
763 "%s: Received split completion error message in %s\n",
764 "%s: Receive overrun in %s\n",
765 "%s: Count not complete in %s\n",
766 "%s: Split completion data bucket in %s\n",
767 "%s: Split completion address error in %s\n",
768 "%s: Split completion byte count error in %s\n",
769 "%s: Signaled Target-abort to early terminate a split in %s\n"
772 static const char *pci_status_strings[] =
774 "%s: Data Parity Error has been reported via PERR# in %s\n",
775 "%s: Target initial wait state error in %s\n",
776 "%s: Split completion read data parity error in %s\n",
777 "%s: Split completion address attribute parity error in %s\n",
778 "%s: Received a Target Abort in %s\n",
779 "%s: Received a Master Abort in %s\n",
780 "%s: Signal System Error Detected in %s\n",
781 "%s: Address or Write Phase Parity Error Detected in %s.\n"
785 ahd_pci_intr(struct ahd_softc *ahd)
787 uint8_t pci_status[8];
788 ahd_mode_state saved_modes;
794 intstat = ahd_inb(ahd, INTSTAT);
796 if ((intstat & SPLTINT) != 0)
797 ahd_pci_split_intr(ahd, intstat);
799 if ((intstat & PCIINT) == 0)
802 printf("%s: PCI error Interrupt\n", ahd_name(ahd));
803 saved_modes = ahd_save_modes(ahd);
804 ahd_dump_card_state(ahd);
805 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
806 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
810 pci_status[i] = ahd_inb(ahd, reg);
811 /* Clear latched errors. So our interrupt deasserts. */
812 ahd_outb(ahd, reg, pci_status[i]);
815 for (i = 0; i < 8; i++) {
821 for (bit = 0; bit < 8; bit++) {
823 if ((pci_status[i] & (0x1 << bit)) != 0) {
824 static const char *s;
826 s = pci_status_strings[bit];
827 if (i == 7/*TARG*/ && bit == 3)
828 s = "%s: Signaled Target Abort\n";
829 printf(s, ahd_name(ahd), pci_status_source[i]);
833 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
834 PCIR_STATUS + 1, /*bytes*/1);
835 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
836 pci_status1, /*bytes*/1);
837 ahd_restore_modes(ahd, saved_modes);
838 ahd_outb(ahd, CLRINT, CLRPCIINT);
843 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
845 uint8_t split_status[4];
846 uint8_t split_status1[4];
847 uint8_t sg_split_status[2];
848 uint8_t sg_split_status1[2];
849 ahd_mode_state saved_modes;
851 uint16_t pcix_status;
854 * Check for splits in all modes. Modes 0 and 1
855 * additionally have SG engine splits to look at.
857 pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
859 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
860 ahd_name(ahd), pcix_status);
861 saved_modes = ahd_save_modes(ahd);
862 for (i = 0; i < 4; i++) {
863 ahd_set_modes(ahd, i, i);
865 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
866 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
867 /* Clear latched errors. So our interrupt deasserts. */
868 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
869 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
872 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
873 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
874 /* Clear latched errors. So our interrupt deasserts. */
875 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
876 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
879 for (i = 0; i < 4; i++) {
882 for (bit = 0; bit < 8; bit++) {
884 if ((split_status[i] & (0x1 << bit)) != 0) {
885 static const char *s;
887 s = split_status_strings[bit];
888 printf(s, ahd_name(ahd),
889 split_status_source[i]);
895 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
896 static const char *s;
898 s = split_status_strings[bit];
899 printf(s, ahd_name(ahd), "SG");
904 * Clear PCI-X status bits.
906 ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
907 pcix_status, /*bytes*/2);
908 ahd_outb(ahd, CLRINT, CLRSPLTINT);
909 ahd_restore_modes(ahd, saved_modes);
913 ahd_aic7901_setup(struct ahd_softc *ahd)
916 ahd->chip = AHD_AIC7901;
917 ahd->features = AHD_AIC7901_FE;
918 return (ahd_aic790X_setup(ahd));
922 ahd_aic7901A_setup(struct ahd_softc *ahd)
925 ahd->chip = AHD_AIC7901A;
926 ahd->features = AHD_AIC7901A_FE;
927 return (ahd_aic790X_setup(ahd));
931 ahd_aic7902_setup(struct ahd_softc *ahd)
933 ahd->chip = AHD_AIC7902;
934 ahd->features = AHD_AIC7902_FE;
935 return (ahd_aic790X_setup(ahd));
939 ahd_aic790X_setup(struct ahd_softc *ahd)
944 pci = ahd->dev_softc;
945 rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
946 if (rev < ID_AIC7902_PCI_REV_A4) {
947 printf("%s: Unable to attach to unsupported chip revision %d\n",
949 ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
952 ahd->channel = ahd_get_pci_function(pci) + 'A';
953 if (rev < ID_AIC7902_PCI_REV_B0) {
955 * Enable A series workarounds.
957 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
958 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
959 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
960 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
961 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
962 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
963 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
964 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
965 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
966 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
970 * IO Cell paramter setup.
972 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
974 if ((ahd->flags & AHD_HP_BOARD) == 0)
975 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
979 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
980 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
981 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
984 * Some issues have been resolved in the 7901B.
986 if ((ahd->features & AHD_MULTI_FUNC) != 0)
987 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
990 * IO Cell paramter setup.
992 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
993 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
994 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
997 * Set the PREQDIS bit for H2B which disables some workaround
998 * that doesn't work on regular PCI busses.
999 * XXX - Find out exactly what this does from the hardware
1002 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
1003 ahd_pci_write_config(pci, DEVCONFIG1,
1004 devconfig1|PREQDIS, /*bytes*/1);
1005 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);