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#86 $
43 * $FreeBSD: src/sys/dev/aic7xxx/aic79xx_pci.c,v 1.18 2004/02/04 16:38:38 gibbs Exp $
44 * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_pci.c,v 1.10 2007/07/06 00:56:38 pavalos Exp $
48 #include "aic79xx_osm.h"
49 #include "aic79xx_inline.h"
51 #include "aic79xx_osm.h"
52 #include "aic79xx_inline.h"
55 static __inline uint64_t
56 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
62 | ((uint64_t)vendor << 32)
63 | ((uint64_t)device << 48);
68 #define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
69 #define ID_ALL_IROC_MASK 0xFF7FFFFFFFFFFFFFull
70 #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
71 #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
72 #define ID_9005_GENERIC_IROC_MASK 0xFF70FFFF00000000ull
74 #define ID_AIC7901 0x800F9005FFFF9005ull
75 #define ID_AHA_29320A 0x8000900500609005ull
76 #define ID_AHA_29320ALP 0x8017900500449005ull
78 #define ID_AIC7901A 0x801E9005FFFF9005ull
79 #define ID_AHA_29320LP 0x8014900500449005ull
81 #define ID_AIC7902 0x801F9005FFFF9005ull
82 #define ID_AIC7902_B 0x801D9005FFFF9005ull
83 #define ID_AHA_39320 0x8010900500409005ull
84 #define ID_AHA_29320 0x8012900500429005ull
85 #define ID_AHA_29320B 0x8013900500439005ull
86 #define ID_AHA_39320_B 0x8015900500409005ull
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 39320A Ultra320 SCSI adapter",
180 "Adaptec 39320D Ultra320 SCSI adapter",
186 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
192 "Adaptec 39320D Ultra320 SCSI adapter",
198 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
201 /* Generic chip probes for devices we don't know 'exactly' */
203 ID_AIC7901 & ID_9005_GENERIC_MASK,
205 "Adaptec AIC7901 Ultra320 SCSI adapter",
209 ID_AIC7901A & ID_DEV_VENDOR_MASK,
211 "Adaptec AIC7901A Ultra320 SCSI adapter",
215 ID_AIC7902 & ID_9005_GENERIC_MASK,
216 ID_9005_GENERIC_MASK,
217 "Adaptec AIC7902 Ultra320 SCSI adapter",
222 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
224 #define DEVCONFIG 0x40
225 #define PCIXINITPAT 0x0000E000ul
226 #define PCIXINIT_PCI33_66 0x0000E000ul
227 #define PCIXINIT_PCIX50_66 0x0000C000ul
228 #define PCIXINIT_PCIX66_100 0x0000A000ul
229 #define PCIXINIT_PCIX100_133 0x00008000ul
230 #define PCI_BUS_MODES_INDEX(devconfig) \
231 (((devconfig) & PCIXINITPAT) >> 13)
232 static const char *pci_bus_modes[] =
234 "PCI bus mode unknown",
235 "PCI bus mode unknown",
236 "PCI bus mode unknown",
237 "PCI bus mode unknown",
244 #define TESTMODE 0x00000800ul
245 #define IRDY_RST 0x00000200ul
246 #define FRAME_RST 0x00000100ul
247 #define PCI64BIT 0x00000080ul
248 #define MRDCEN 0x00000040ul
249 #define ENDIANSEL 0x00000020ul
250 #define MIXQWENDIANEN 0x00000008ul
251 #define DACEN 0x00000004ul
252 #define STPWLEVEL 0x00000002ul
253 #define QWENDIANSEL 0x00000001ul
255 #define DEVCONFIG1 0x44
258 #define CSIZE_LATTIME 0x0c
259 #define CACHESIZE 0x000000fful
260 #define LATTIME 0x0000ff00ul
262 static int ahd_check_extport(struct ahd_softc *ahd);
263 static void ahd_configure_termination(struct ahd_softc *ahd,
264 u_int adapter_control);
265 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
267 struct ahd_pci_identity *
268 ahd_find_pci_device(aic_dev_softc_t pci)
275 struct ahd_pci_identity *entry;
278 vendor = aic_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
279 device = aic_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
280 subvendor = aic_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
281 subdevice = aic_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
282 full_id = ahd_compose_id(device,
288 * If we are configured to attach to HostRAID
289 * controllers, mask out the IROC/HostRAID bit
292 if (ahd_attach_to_HostRAID_controllers)
293 full_id &= ID_ALL_IROC_MASK;
295 for (i = 0; i < ahd_num_pci_devs; i++) {
296 entry = &ahd_pci_ident_table[i];
297 if (entry->full_id == (full_id & entry->id_mask)) {
298 /* Honor exclusion entries. */
299 if (entry->name == NULL)
308 ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
310 struct scb_data *shared_scb_data;
317 shared_scb_data = NULL;
318 ahd->description = entry->name;
320 * Record if this is a HostRAID board.
322 device = aic_pci_read_config(ahd->dev_softc,
323 PCIR_DEVICE, /*bytes*/2);
324 if (DEVID_9005_HOSTRAID(device))
325 ahd->flags |= AHD_HOSTRAID_BOARD;
328 * Record if this is an HP board.
330 subvendor = aic_pci_read_config(ahd->dev_softc,
331 PCIR_SUBVEND_0, /*bytes*/2);
332 if (subvendor == SUBID_HP)
333 ahd->flags |= AHD_HP_BOARD;
335 error = entry->setup(ahd);
339 devconfig = aic_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
340 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
341 ahd->chip |= AHD_PCI;
342 /* Disable PCIX workarounds when running in PCI mode. */
343 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
345 ahd->chip |= AHD_PCIX;
347 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
349 aic_power_state_change(ahd, AIC_POWER_STATE_D0);
351 error = ahd_pci_map_registers(ahd);
356 * If we need to support high memory, enable dual
357 * address cycles. This bit must be set to enable
358 * high address bit generation even if we are on a
359 * 64bit bus (PCI64BIT set in devconfig).
361 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
365 kprintf("%s: Enabling 39Bit Addressing\n",
367 devconfig = aic_pci_read_config(ahd->dev_softc,
368 DEVCONFIG, /*bytes*/4);
370 aic_pci_write_config(ahd->dev_softc, DEVCONFIG,
371 devconfig, /*bytes*/4);
374 /* Ensure busmastering is enabled */
375 command = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
376 command |= PCIM_CMD_BUSMASTEREN;
377 aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
379 error = ahd_softc_init(ahd);
383 ahd->bus_intr = ahd_pci_intr;
385 error = ahd_reset(ahd, /*reinit*/FALSE);
390 aic_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
391 /*bytes*/1) & CACHESIZE;
392 ahd->pci_cachesize *= 4;
394 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
395 /* See if we have a SEEPROM and perform auto-term */
396 error = ahd_check_extport(ahd);
400 /* Core initialization */
401 error = ahd_init(ahd);
406 * Allow interrupts now that we are completely setup.
408 error = ahd_pci_map_int(ahd);
413 * Link this softc in with all other ahd instances.
415 ahd_softc_insert(ahd);
420 * Perform some simple tests that should catch situations where
421 * our registers are invalidly mapped.
424 ahd_pci_test_register_access(struct ahd_softc *ahd)
435 * Enable PCI error interrupt status, but suppress NMIs
436 * generated by SERR raised due to target aborts.
438 cmd = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
439 aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
440 cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
443 * First a simple test to see if any
444 * registers can be read. Reading
445 * HCNTRL has no side effects and has
446 * at least one bit that is guaranteed to
447 * be zero so it is a good register to
450 hcntrl = ahd_inb(ahd, HCNTRL);
455 * Next create a situation where write combining
456 * or read prefetching could be initiated by the
457 * CPU or host bridge. Our device does not support
458 * either, so look for data corruption and/or flaged
459 * PCI errors. First pause without causing another
463 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
464 while (ahd_is_paused(ahd) == 0)
467 /* Clear any PCI errors that occurred before our driver attached. */
468 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
469 targpcistat = ahd_inb(ahd, TARGPCISTAT);
470 ahd_outb(ahd, TARGPCISTAT, targpcistat);
471 pci_status1 = aic_pci_read_config(ahd->dev_softc,
472 PCIR_STATUS + 1, /*bytes*/1);
473 aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
474 pci_status1, /*bytes*/1);
475 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
476 ahd_outb(ahd, CLRINT, CLRPCIINT);
478 ahd_outb(ahd, SEQCTL0, PERRORDIS);
479 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
480 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
483 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
486 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
487 targpcistat = ahd_inb(ahd, TARGPCISTAT);
488 if ((targpcistat & STA) != 0)
495 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
497 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
498 targpcistat = ahd_inb(ahd, TARGPCISTAT);
500 /* Silently clear any latched errors. */
501 ahd_outb(ahd, TARGPCISTAT, targpcistat);
502 pci_status1 = aic_pci_read_config(ahd->dev_softc,
503 PCIR_STATUS + 1, /*bytes*/1);
504 aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
505 pci_status1, /*bytes*/1);
506 ahd_outb(ahd, CLRINT, CLRPCIINT);
508 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
509 aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
514 * Check the external port logic for a serial eeprom
515 * and termination/cable detection contrls.
518 ahd_check_extport(struct ahd_softc *ahd)
520 struct vpd_config vpd;
521 struct seeprom_config *sc;
522 u_int adapter_control;
526 sc = ahd->seep_config;
527 have_seeprom = ahd_acquire_seeprom(ahd);
532 * Fetch VPD for this function and parse it.
535 kprintf("%s: Reading VPD from SEEPROM...",
538 /* Address is always in units of 16bit words */
539 start_addr = ((2 * sizeof(*sc))
540 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
542 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
543 start_addr, sizeof(vpd)/2,
546 error = ahd_parse_vpddata(ahd, &vpd);
548 kprintf("%s: VPD parsing %s\n",
550 error == 0 ? "successful" : "failed");
553 kprintf("%s: Reading SEEPROM...", ahd_name(ahd));
555 /* Address is always in units of 16bit words */
556 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
558 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
559 start_addr, sizeof(*sc)/2,
560 /*bytestream*/FALSE);
563 kprintf("Unable to read SEEPROM\n");
566 have_seeprom = ahd_verify_cksum(sc);
569 if (have_seeprom == 0)
570 kprintf ("checksum error\n");
575 ahd_release_seeprom(ahd);
582 * Pull scratch ram settings and treat them as
583 * if they are the contents of an seeprom if
584 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
585 * in SCB 0xFF. We manually compose the data as 16bit
586 * values to avoid endian issues.
588 ahd_set_scbptr(ahd, 0xFF);
589 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
590 if (nvram_scb != 0xFF
591 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
592 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
593 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
594 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
595 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
596 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
597 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
598 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
599 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
600 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
601 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
602 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
606 ahd_set_scbptr(ahd, nvram_scb);
607 sc_data = (uint16_t *)sc;
608 for (i = 0; i < 64; i += 2)
609 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
610 have_seeprom = ahd_verify_cksum(sc);
612 ahd->flags |= AHD_SCB_CONFIG_USED;
617 if (have_seeprom != 0
618 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
622 kprintf("%s: Seeprom Contents:", ahd_name(ahd));
623 sc_data = (uint16_t *)sc;
624 for (i = 0; i < (sizeof(*sc)); i += 2)
625 kprintf("\n\t0x%.4x", sc_data[i]);
632 kprintf("%s: No SEEPROM available.\n", ahd_name(ahd));
633 ahd->flags |= AHD_USEDEFAULTS;
634 error = ahd_default_config(ahd);
635 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
636 kfree(ahd->seep_config, M_DEVBUF);
637 ahd->seep_config = NULL;
639 error = ahd_parse_cfgdata(ahd, sc);
640 adapter_control = sc->adapter_control;
645 ahd_configure_termination(ahd, adapter_control);
651 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
658 devconfig = aic_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
659 devconfig &= ~STPWLEVEL;
660 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
661 devconfig |= STPWLEVEL;
663 kprintf("%s: STPWLEVEL is %s\n",
664 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
665 aic_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
667 /* Make sure current sensing is off. */
668 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
669 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
673 * Read to sense. Write to set.
675 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
676 if ((adapter_control & CFAUTOTERM) == 0) {
678 kprintf("%s: Manual Primary Termination\n",
680 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
681 if ((adapter_control & CFSTERM) != 0)
682 termctl |= FLX_TERMCTL_ENPRILOW;
683 if ((adapter_control & CFWSTERM) != 0)
684 termctl |= FLX_TERMCTL_ENPRIHIGH;
685 } else if (error != 0) {
686 kprintf("%s: Primary Auto-Term Sensing failed! "
687 "Using Defaults.\n", ahd_name(ahd));
688 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
691 if ((adapter_control & CFSEAUTOTERM) == 0) {
693 kprintf("%s: Manual Secondary Termination\n",
695 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
696 if ((adapter_control & CFSELOWTERM) != 0)
697 termctl |= FLX_TERMCTL_ENSECLOW;
698 if ((adapter_control & CFSEHIGHTERM) != 0)
699 termctl |= FLX_TERMCTL_ENSECHIGH;
700 } else if (error != 0) {
701 kprintf("%s: Secondary Auto-Term Sensing failed! "
702 "Using Defaults.\n", ahd_name(ahd));
703 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
707 * Now set the termination based on what we found.
709 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
710 ahd->flags &= ~AHD_TERM_ENB_A;
711 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
712 ahd->flags |= AHD_TERM_ENB_A;
715 /* Must set the latch once in order to be effective. */
716 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
717 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
719 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
721 kprintf("%s: Unable to set termination settings!\n",
723 } else if (bootverbose) {
724 kprintf("%s: Primary High byte termination %sabled\n",
726 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
728 kprintf("%s: Primary Low byte termination %sabled\n",
730 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
732 kprintf("%s: Secondary High byte termination %sabled\n",
734 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
736 kprintf("%s: Secondary Low byte termination %sabled\n",
738 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
750 static const char *split_status_source[] =
758 static const char *pci_status_source[] =
770 static const char *split_status_strings[] =
772 "%s: Received split response in %s.\n",
773 "%s: Received split completion error message in %s\n",
774 "%s: Receive overrun in %s\n",
775 "%s: Count not complete in %s\n",
776 "%s: Split completion data bucket in %s\n",
777 "%s: Split completion address error in %s\n",
778 "%s: Split completion byte count error in %s\n",
779 "%s: Signaled Target-abort to early terminate a split in %s\n"
782 static const char *pci_status_strings[] =
784 "%s: Data Parity Error has been reported via PERR# in %s\n",
785 "%s: Target initial wait state error in %s\n",
786 "%s: Split completion read data parity error in %s\n",
787 "%s: Split completion address attribute parity error in %s\n",
788 "%s: Received a Target Abort in %s\n",
789 "%s: Received a Master Abort in %s\n",
790 "%s: Signal System Error Detected in %s\n",
791 "%s: Address or Write Phase Parity Error Detected in %s.\n"
795 ahd_pci_intr(struct ahd_softc *ahd)
797 uint8_t pci_status[8];
798 ahd_mode_state saved_modes;
804 intstat = ahd_inb(ahd, INTSTAT);
806 if ((intstat & SPLTINT) != 0)
807 ahd_pci_split_intr(ahd, intstat);
809 if ((intstat & PCIINT) == 0)
812 kprintf("%s: PCI error Interrupt\n", ahd_name(ahd));
813 saved_modes = ahd_save_modes(ahd);
814 ahd_dump_card_state(ahd);
815 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
816 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
820 pci_status[i] = ahd_inb(ahd, reg);
821 /* Clear latched errors. So our interrupt deasserts. */
822 ahd_outb(ahd, reg, pci_status[i]);
825 for (i = 0; i < 8; i++) {
831 for (bit = 0; bit < 8; bit++) {
833 if ((pci_status[i] & (0x1 << bit)) != 0) {
834 static const char *s;
836 s = pci_status_strings[bit];
837 if (i == 7/*TARG*/ && bit == 3)
838 s = "%s: Signaled Target Abort\n";
839 kprintf(s, ahd_name(ahd), pci_status_source[i]);
843 pci_status1 = aic_pci_read_config(ahd->dev_softc,
844 PCIR_STATUS + 1, /*bytes*/1);
845 aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
846 pci_status1, /*bytes*/1);
847 ahd_restore_modes(ahd, saved_modes);
848 ahd_outb(ahd, CLRINT, CLRPCIINT);
853 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
855 uint8_t split_status[4];
856 uint8_t split_status1[4];
857 uint8_t sg_split_status[2];
858 uint8_t sg_split_status1[2];
859 ahd_mode_state saved_modes;
861 uint16_t pcix_status;
864 * Check for splits in all modes. Modes 0 and 1
865 * additionally have SG engine splits to look at.
867 pcix_status = aic_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
869 kprintf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
870 ahd_name(ahd), pcix_status);
871 saved_modes = ahd_save_modes(ahd);
872 for (i = 0; i < 4; i++) {
873 ahd_set_modes(ahd, i, i);
875 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
876 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
877 /* Clear latched errors. So our interrupt deasserts. */
878 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
879 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
882 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
883 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
884 /* Clear latched errors. So our interrupt deasserts. */
885 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
886 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
889 for (i = 0; i < 4; i++) {
892 for (bit = 0; bit < 8; bit++) {
894 if ((split_status[i] & (0x1 << bit)) != 0) {
895 static const char *s;
897 s = split_status_strings[bit];
898 kprintf(s, ahd_name(ahd),
899 split_status_source[i]);
905 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
906 static const char *s;
908 s = split_status_strings[bit];
909 kprintf(s, ahd_name(ahd), "SG");
914 * Clear PCI-X status bits.
916 aic_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
917 pcix_status, /*bytes*/2);
918 ahd_outb(ahd, CLRINT, CLRSPLTINT);
919 ahd_restore_modes(ahd, saved_modes);
923 ahd_aic7901_setup(struct ahd_softc *ahd)
926 ahd->chip = AHD_AIC7901;
927 ahd->features = AHD_AIC7901_FE;
928 return (ahd_aic790X_setup(ahd));
932 ahd_aic7901A_setup(struct ahd_softc *ahd)
935 ahd->chip = AHD_AIC7901A;
936 ahd->features = AHD_AIC7901A_FE;
937 return (ahd_aic790X_setup(ahd));
941 ahd_aic7902_setup(struct ahd_softc *ahd)
943 ahd->chip = AHD_AIC7902;
944 ahd->features = AHD_AIC7902_FE;
945 return (ahd_aic790X_setup(ahd));
949 ahd_aic790X_setup(struct ahd_softc *ahd)
954 pci = ahd->dev_softc;
955 rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
956 if (rev < ID_AIC7902_PCI_REV_A4) {
957 kprintf("%s: Unable to attach to unsupported chip revision %d\n",
959 aic_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
962 ahd->channel = aic_get_pci_function(pci) + 'A';
963 if (rev < ID_AIC7902_PCI_REV_B0) {
965 * Enable A series workarounds.
967 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
968 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
969 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
970 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
971 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
972 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
973 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
974 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
975 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
976 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
980 * IO Cell paramter setup.
982 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
984 if ((ahd->flags & AHD_HP_BOARD) == 0)
985 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
989 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
990 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
991 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
994 * Some issues have been resolved in the 7901B.
996 if ((ahd->features & AHD_MULTI_FUNC) != 0)
997 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
1000 * IO Cell paramter setup.
1002 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
1003 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
1004 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
1007 * Set the PREQDIS bit for H2B which disables some workaround
1008 * that doesn't work on regular PCI busses.
1009 * XXX - Find out exactly what this does from the hardware
1012 devconfig1 = aic_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
1013 aic_pci_write_config(pci, DEVCONFIG1,
1014 devconfig1|PREQDIS, /*bytes*/1);
1015 devconfig1 = aic_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);