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#88 $
45 #include "aic79xx_osm.h"
46 #include "aic79xx_inline.h"
48 #include <sys/cdefs.h>
49 __FBSDID("$FreeBSD$");
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_29320LP 0x8014900500449005ull
80 #define ID_AIC7902 0x801F9005FFFF9005ull
81 #define ID_AIC7902_B 0x801D9005FFFF9005ull
82 #define ID_AHA_39320 0x8010900500409005ull
83 #define ID_AHA_29320 0x8012900500429005ull
84 #define ID_AHA_29320B 0x8013900500439005ull
85 #define ID_AHA_39320_B 0x8015900500409005ull
86 #define ID_AHA_39320_B_DELL 0x8015900501681028ull
87 #define ID_AHA_39320A 0x8016900500409005ull
88 #define ID_AHA_39320D 0x8011900500419005ull
89 #define ID_AHA_39320D_B 0x801C900500419005ull
90 #define ID_AHA_39320D_HP 0x8011900500AC0E11ull
91 #define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull
92 #define ID_AIC7902_PCI_REV_A4 0x3
93 #define ID_AIC7902_PCI_REV_B0 0x10
94 #define SUBID_HP 0x0E11
96 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
98 #define DEVID_9005_TYPE(id) ((id) & 0xF)
99 #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
100 #define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */
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 /* aic7901A based controllers */
143 "Adaptec 29320LP Ultra320 SCSI adapter",
146 /* aic7902 based controllers */
150 "Adaptec 29320 Ultra320 SCSI adapter",
156 "Adaptec 29320B Ultra320 SCSI adapter",
162 "Adaptec 39320 Ultra320 SCSI adapter",
168 "Adaptec 39320 Ultra320 SCSI adapter",
174 "Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",
180 "Adaptec 39320A Ultra320 SCSI adapter",
186 "Adaptec 39320D Ultra320 SCSI adapter",
192 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
198 "Adaptec 39320D Ultra320 SCSI adapter",
204 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
207 /* Generic chip probes for devices we don't know 'exactly' */
209 ID_AIC7901 & ID_9005_GENERIC_MASK,
210 ID_9005_GENERIC_MASK,
211 "Adaptec AIC7901 Ultra320 SCSI adapter",
215 ID_AIC7901A & ID_DEV_VENDOR_MASK,
217 "Adaptec AIC7901A Ultra320 SCSI adapter",
221 ID_AIC7902 & ID_9005_GENERIC_MASK,
222 ID_9005_GENERIC_MASK,
223 "Adaptec AIC7902 Ultra320 SCSI adapter",
228 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
230 #define DEVCONFIG 0x40
231 #define PCIXINITPAT 0x0000E000ul
232 #define PCIXINIT_PCI33_66 0x0000E000ul
233 #define PCIXINIT_PCIX50_66 0x0000C000ul
234 #define PCIXINIT_PCIX66_100 0x0000A000ul
235 #define PCIXINIT_PCIX100_133 0x00008000ul
236 #define PCI_BUS_MODES_INDEX(devconfig) \
237 (((devconfig) & PCIXINITPAT) >> 13)
238 static const char *pci_bus_modes[] =
240 "PCI bus mode unknown",
241 "PCI bus mode unknown",
242 "PCI bus mode unknown",
243 "PCI bus mode unknown",
250 #define TESTMODE 0x00000800ul
251 #define IRDY_RST 0x00000200ul
252 #define FRAME_RST 0x00000100ul
253 #define PCI64BIT 0x00000080ul
254 #define MRDCEN 0x00000040ul
255 #define ENDIANSEL 0x00000020ul
256 #define MIXQWENDIANEN 0x00000008ul
257 #define DACEN 0x00000004ul
258 #define STPWLEVEL 0x00000002ul
259 #define QWENDIANSEL 0x00000001ul
261 #define DEVCONFIG1 0x44
264 #define CSIZE_LATTIME 0x0c
265 #define CACHESIZE 0x000000fful
266 #define LATTIME 0x0000ff00ul
268 static int ahd_check_extport(struct ahd_softc *ahd);
269 static void ahd_configure_termination(struct ahd_softc *ahd,
270 u_int adapter_control);
271 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
273 struct ahd_pci_identity *
274 ahd_find_pci_device(aic_dev_softc_t pci)
281 struct ahd_pci_identity *entry;
284 vendor = aic_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
285 device = aic_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
286 subvendor = aic_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
287 subdevice = aic_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
288 full_id = ahd_compose_id(device,
294 * If we are configured to attach to HostRAID
295 * controllers, mask out the IROC/HostRAID bit
298 if (ahd_attach_to_HostRAID_controllers)
299 full_id &= ID_ALL_IROC_MASK;
301 for (i = 0; i < ahd_num_pci_devs; i++) {
302 entry = &ahd_pci_ident_table[i];
303 if (entry->full_id == (full_id & entry->id_mask)) {
304 /* Honor exclusion entries. */
305 if (entry->name == NULL)
314 ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
316 struct scb_data *shared_scb_data;
323 shared_scb_data = NULL;
324 ahd->description = entry->name;
326 * Record if this is a HostRAID board.
328 device = aic_pci_read_config(ahd->dev_softc,
329 PCIR_DEVICE, /*bytes*/2);
330 if (DEVID_9005_HOSTRAID(device))
331 ahd->flags |= AHD_HOSTRAID_BOARD;
334 * Record if this is an HP board.
336 subvendor = aic_pci_read_config(ahd->dev_softc,
337 PCIR_SUBVEND_0, /*bytes*/2);
338 if (subvendor == SUBID_HP)
339 ahd->flags |= AHD_HP_BOARD;
341 error = entry->setup(ahd);
346 * Find the PCI-X cap pointer. If we don't find it,
347 * pcix_ptr will be 0.
349 pci_find_extcap(ahd->dev_softc, PCIY_PCIX, &ahd->pcix_ptr);
350 devconfig = aic_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
351 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
352 ahd->chip |= AHD_PCI;
353 /* Disable PCIX workarounds when running in PCI mode. */
354 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
356 ahd->chip |= AHD_PCIX;
357 if (ahd->pcix_ptr == 0)
360 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
362 aic_power_state_change(ahd, AIC_POWER_STATE_D0);
364 error = ahd_pci_map_registers(ahd);
369 * If we need to support high memory, enable dual
370 * address cycles. This bit must be set to enable
371 * high address bit generation even if we are on a
372 * 64bit bus (PCI64BIT set in devconfig).
374 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
378 printf("%s: Enabling 39Bit Addressing\n",
380 devconfig = aic_pci_read_config(ahd->dev_softc,
381 DEVCONFIG, /*bytes*/4);
383 aic_pci_write_config(ahd->dev_softc, DEVCONFIG,
384 devconfig, /*bytes*/4);
387 /* Ensure busmastering is enabled */
388 command = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
389 command |= PCIM_CMD_BUSMASTEREN;
390 aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
392 error = ahd_softc_init(ahd);
396 ahd->bus_intr = ahd_pci_intr;
398 error = ahd_reset(ahd, /*reinit*/FALSE);
403 aic_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
404 /*bytes*/1) & CACHESIZE;
405 ahd->pci_cachesize *= 4;
407 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
408 /* See if we have a SEEPROM and perform auto-term */
409 error = ahd_check_extport(ahd);
413 /* Core initialization */
414 error = ahd_init(ahd);
419 * Allow interrupts now that we are completely setup.
421 error = ahd_pci_map_int(ahd);
427 * Link this softc in with all other ahd instances.
429 ahd_softc_insert(ahd);
435 * Perform some simple tests that should catch situations where
436 * our registers are invalidly mapped.
439 ahd_pci_test_register_access(struct ahd_softc *ahd)
450 * Enable PCI error interrupt status, but suppress NMIs
451 * generated by SERR raised due to target aborts.
453 cmd = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
454 aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
455 cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
458 * First a simple test to see if any
459 * registers can be read. Reading
460 * HCNTRL has no side effects and has
461 * at least one bit that is guaranteed to
462 * be zero so it is a good register to
465 hcntrl = ahd_inb(ahd, HCNTRL);
470 * Next create a situation where write combining
471 * or read prefetching could be initiated by the
472 * CPU or host bridge. Our device does not support
473 * either, so look for data corruption and/or flaged
474 * PCI errors. First pause without causing another
478 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
479 while (ahd_is_paused(ahd) == 0)
482 /* Clear any PCI errors that occurred before our driver attached. */
483 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
484 targpcistat = ahd_inb(ahd, TARGPCISTAT);
485 ahd_outb(ahd, TARGPCISTAT, targpcistat);
486 pci_status1 = aic_pci_read_config(ahd->dev_softc,
487 PCIR_STATUS + 1, /*bytes*/1);
488 aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
489 pci_status1, /*bytes*/1);
490 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
491 ahd_outb(ahd, CLRINT, CLRPCIINT);
493 ahd_outb(ahd, SEQCTL0, PERRORDIS);
494 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
495 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
498 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
501 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
502 targpcistat = ahd_inb(ahd, TARGPCISTAT);
503 if ((targpcistat & STA) != 0)
510 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
512 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
513 targpcistat = ahd_inb(ahd, TARGPCISTAT);
515 /* Silently clear any latched errors. */
516 ahd_outb(ahd, TARGPCISTAT, targpcistat);
517 pci_status1 = aic_pci_read_config(ahd->dev_softc,
518 PCIR_STATUS + 1, /*bytes*/1);
519 aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
520 pci_status1, /*bytes*/1);
521 ahd_outb(ahd, CLRINT, CLRPCIINT);
523 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
524 aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
529 * Check the external port logic for a serial eeprom
530 * and termination/cable detection contrls.
533 ahd_check_extport(struct ahd_softc *ahd)
535 struct vpd_config vpd;
536 struct seeprom_config *sc;
537 u_int adapter_control;
541 sc = ahd->seep_config;
542 have_seeprom = ahd_acquire_seeprom(ahd);
547 * Fetch VPD for this function and parse it.
550 printf("%s: Reading VPD from SEEPROM...",
553 /* Address is always in units of 16bit words */
554 start_addr = ((2 * sizeof(*sc))
555 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
557 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
558 start_addr, sizeof(vpd)/2,
561 error = ahd_parse_vpddata(ahd, &vpd);
563 printf("%s: VPD parsing %s\n",
565 error == 0 ? "successful" : "failed");
568 printf("%s: Reading SEEPROM...", ahd_name(ahd));
570 /* Address is always in units of 16bit words */
571 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
573 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
574 start_addr, sizeof(*sc)/2,
575 /*bytestream*/FALSE);
578 printf("Unable to read SEEPROM\n");
581 have_seeprom = ahd_verify_cksum(sc);
584 if (have_seeprom == 0)
585 printf ("checksum error\n");
590 ahd_release_seeprom(ahd);
597 * Pull scratch ram settings and treat them as
598 * if they are the contents of an seeprom if
599 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
600 * in SCB 0xFF. We manually compose the data as 16bit
601 * values to avoid endian issues.
603 ahd_set_scbptr(ahd, 0xFF);
604 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
605 if (nvram_scb != 0xFF
606 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
607 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
608 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
609 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
610 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
611 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
612 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
613 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
614 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
615 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
616 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
617 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
621 ahd_set_scbptr(ahd, nvram_scb);
622 sc_data = (uint16_t *)sc;
623 for (i = 0; i < 64; i += 2)
624 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
625 have_seeprom = ahd_verify_cksum(sc);
627 ahd->flags |= AHD_SCB_CONFIG_USED;
632 if (have_seeprom != 0
633 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
637 printf("%s: Seeprom Contents:", ahd_name(ahd));
638 sc_data = (uint16_t *)sc;
639 for (i = 0; i < (sizeof(*sc)); i += 2)
640 printf("\n\t0x%.4x", sc_data[i]);
647 printf("%s: No SEEPROM available.\n", ahd_name(ahd));
648 ahd->flags |= AHD_USEDEFAULTS;
649 error = ahd_default_config(ahd);
650 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
651 free(ahd->seep_config, M_DEVBUF);
652 ahd->seep_config = NULL;
654 error = ahd_parse_cfgdata(ahd, sc);
655 adapter_control = sc->adapter_control;
660 ahd_configure_termination(ahd, adapter_control);
666 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
673 devconfig = aic_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
674 devconfig &= ~STPWLEVEL;
675 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
676 devconfig |= STPWLEVEL;
678 printf("%s: STPWLEVEL is %s\n",
679 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
680 aic_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
682 /* Make sure current sensing is off. */
683 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
684 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
688 * Read to sense. Write to set.
690 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
691 if ((adapter_control & CFAUTOTERM) == 0) {
693 printf("%s: Manual Primary Termination\n",
695 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
696 if ((adapter_control & CFSTERM) != 0)
697 termctl |= FLX_TERMCTL_ENPRILOW;
698 if ((adapter_control & CFWSTERM) != 0)
699 termctl |= FLX_TERMCTL_ENPRIHIGH;
700 } else if (error != 0) {
701 printf("%s: Primary Auto-Term Sensing failed! "
702 "Using Defaults.\n", ahd_name(ahd));
703 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
706 if ((adapter_control & CFSEAUTOTERM) == 0) {
708 printf("%s: Manual Secondary Termination\n",
710 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
711 if ((adapter_control & CFSELOWTERM) != 0)
712 termctl |= FLX_TERMCTL_ENSECLOW;
713 if ((adapter_control & CFSEHIGHTERM) != 0)
714 termctl |= FLX_TERMCTL_ENSECHIGH;
715 } else if (error != 0) {
716 printf("%s: Secondary Auto-Term Sensing failed! "
717 "Using Defaults.\n", ahd_name(ahd));
718 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
722 * Now set the termination based on what we found.
724 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
725 ahd->flags &= ~AHD_TERM_ENB_A;
726 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
727 ahd->flags |= AHD_TERM_ENB_A;
730 /* Must set the latch once in order to be effective. */
731 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
732 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
734 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
736 printf("%s: Unable to set termination settings!\n",
738 } else if (bootverbose) {
739 printf("%s: Primary High byte termination %sabled\n",
741 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
743 printf("%s: Primary Low byte termination %sabled\n",
745 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
747 printf("%s: Secondary High byte termination %sabled\n",
749 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
751 printf("%s: Secondary Low byte termination %sabled\n",
753 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
765 static const char *split_status_source[] =
773 static const char *pci_status_source[] =
785 static const char *split_status_strings[] =
787 "%s: Received split response in %s.\n",
788 "%s: Received split completion error message in %s\n",
789 "%s: Receive overrun in %s\n",
790 "%s: Count not complete in %s\n",
791 "%s: Split completion data bucket in %s\n",
792 "%s: Split completion address error in %s\n",
793 "%s: Split completion byte count error in %s\n",
794 "%s: Signaled Target-abort to early terminate a split in %s\n"
797 static const char *pci_status_strings[] =
799 "%s: Data Parity Error has been reported via PERR# in %s\n",
800 "%s: Target initial wait state error in %s\n",
801 "%s: Split completion read data parity error in %s\n",
802 "%s: Split completion address attribute parity error in %s\n",
803 "%s: Received a Target Abort in %s\n",
804 "%s: Received a Master Abort in %s\n",
805 "%s: Signal System Error Detected in %s\n",
806 "%s: Address or Write Phase Parity Error Detected in %s.\n"
810 ahd_pci_intr(struct ahd_softc *ahd)
812 uint8_t pci_status[8];
813 ahd_mode_state saved_modes;
819 intstat = ahd_inb(ahd, INTSTAT);
821 if ((intstat & SPLTINT) != 0)
822 ahd_pci_split_intr(ahd, intstat);
824 if ((intstat & PCIINT) == 0)
827 printf("%s: PCI error Interrupt\n", ahd_name(ahd));
828 saved_modes = ahd_save_modes(ahd);
829 ahd_dump_card_state(ahd);
830 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
831 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
835 pci_status[i] = ahd_inb(ahd, reg);
836 /* Clear latched errors. So our interrupt deasserts. */
837 ahd_outb(ahd, reg, pci_status[i]);
840 for (i = 0; i < 8; i++) {
846 for (bit = 0; bit < 8; bit++) {
848 if ((pci_status[i] & (0x1 << bit)) != 0) {
849 static const char *s;
851 s = pci_status_strings[bit];
852 if (i == 7/*TARG*/ && bit == 3)
853 s = "%s: Signaled Target Abort\n";
854 printf(s, ahd_name(ahd), pci_status_source[i]);
858 pci_status1 = aic_pci_read_config(ahd->dev_softc,
859 PCIR_STATUS + 1, /*bytes*/1);
860 aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
861 pci_status1, /*bytes*/1);
862 ahd_restore_modes(ahd, saved_modes);
863 ahd_outb(ahd, CLRINT, CLRPCIINT);
868 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
870 uint8_t split_status[4];
871 uint8_t split_status1[4];
872 uint8_t sg_split_status[2];
873 uint8_t sg_split_status1[2];
874 ahd_mode_state saved_modes;
876 uint32_t pcix_status;
879 * Check for splits in all modes. Modes 0 and 1
880 * additionally have SG engine splits to look at.
882 pcix_status = aic_pci_read_config(ahd->dev_softc,
883 ahd->pcix_ptr + PCIXR_STATUS, /*bytes*/ 4);
884 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
885 ahd_name(ahd), pcix_status >> 16);
886 saved_modes = ahd_save_modes(ahd);
887 for (i = 0; i < 4; i++) {
888 ahd_set_modes(ahd, i, i);
890 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
891 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
892 /* Clear latched errors. So our interrupt deasserts. */
893 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
894 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
897 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
898 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
899 /* Clear latched errors. So our interrupt deasserts. */
900 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
901 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
904 for (i = 0; i < 4; i++) {
907 for (bit = 0; bit < 8; bit++) {
909 if ((split_status[i] & (0x1 << bit)) != 0) {
910 static const char *s;
912 s = split_status_strings[bit];
913 printf(s, ahd_name(ahd),
914 split_status_source[i]);
920 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
921 static const char *s;
923 s = split_status_strings[bit];
924 printf(s, ahd_name(ahd), "SG");
929 * Clear PCI-X status bits.
931 aic_pci_write_config(ahd->dev_softc, ahd->pcix_ptr + PCIXR_STATUS,
932 pcix_status, /*bytes*/4);
933 ahd_outb(ahd, CLRINT, CLRSPLTINT);
934 ahd_restore_modes(ahd, saved_modes);
938 ahd_aic7901_setup(struct ahd_softc *ahd)
941 ahd->chip = AHD_AIC7901;
942 ahd->features = AHD_AIC7901_FE;
943 return (ahd_aic790X_setup(ahd));
947 ahd_aic7901A_setup(struct ahd_softc *ahd)
950 ahd->chip = AHD_AIC7901A;
951 ahd->features = AHD_AIC7901A_FE;
952 return (ahd_aic790X_setup(ahd));
956 ahd_aic7902_setup(struct ahd_softc *ahd)
958 ahd->chip = AHD_AIC7902;
959 ahd->features = AHD_AIC7902_FE;
960 return (ahd_aic790X_setup(ahd));
964 ahd_aic790X_setup(struct ahd_softc *ahd)
969 pci = ahd->dev_softc;
970 rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
971 if (rev < ID_AIC7902_PCI_REV_A4) {
972 printf("%s: Unable to attach to unsupported chip revision %d\n",
974 aic_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
977 ahd->channel = aic_get_pci_function(pci) + 'A';
978 if (rev < ID_AIC7902_PCI_REV_B0) {
980 * Enable A series workarounds.
982 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
983 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
984 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
985 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
986 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
987 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
988 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
989 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
990 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
991 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
995 * IO Cell paramter setup.
997 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
999 if ((ahd->flags & AHD_HP_BOARD) == 0)
1000 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
1004 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
1005 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
1006 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
1009 * Some issues have been resolved in the 7901B.
1011 if ((ahd->features & AHD_MULTI_FUNC) != 0)
1012 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG
1013 | AHD_BUSFREEREV_BUG;
1016 * IO Cell paramter setup.
1018 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
1019 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
1020 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
1023 * Set the PREQDIS bit for H2B which disables some workaround
1024 * that doesn't work on regular PCI busses.
1025 * XXX - Find out exactly what this does from the hardware
1028 devconfig1 = aic_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
1029 aic_pci_write_config(pci, DEVCONFIG1,
1030 devconfig1|PREQDIS, /*bytes*/1);
1031 devconfig1 = aic_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);