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 0xFFFFFF7FFFFFFFFFull
69 #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
70 #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
71 #define ID_9005_GENERIC_IROC_MASK 0xFFF0FF7F00000000ull
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_TYPE(id) ((id) & 0xF)
96 #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
97 #define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */
98 #define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */
99 #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
101 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
103 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
105 #define SUBID_9005_TYPE(id) ((id) & 0xF)
106 #define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */
107 #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
109 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
111 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
113 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
114 #define SUBID_9005_SEEPTYPE_NONE 0x0
115 #define SUBID_9005_SEEPTYPE_4K 0x1
117 static ahd_device_setup_t ahd_aic7901_setup;
118 static ahd_device_setup_t ahd_aic7901A_setup;
119 static ahd_device_setup_t ahd_aic7902_setup;
120 static ahd_device_setup_t ahd_aic790X_setup;
122 struct ahd_pci_identity ahd_pci_ident_table [] =
124 /* aic7901 based controllers */
128 "Adaptec 29320A Ultra320 SCSI adapter",
134 "Adaptec 29320ALP Ultra320 SCSI adapter",
137 /* aic7901A based controllers */
141 "Adaptec 29320 Ultra320 SCSI adapter",
147 "Adaptec 29320B Ultra320 SCSI adapter",
153 "Adaptec 29320LP Ultra320 SCSI adapter",
156 /* aic7902 based controllers */
160 "Adaptec 39320 Ultra320 SCSI adapter",
166 "Adaptec 39320 Ultra320 SCSI adapter",
172 "Adaptec 39320A Ultra320 SCSI adapter",
178 "Adaptec 39320D Ultra320 SCSI adapter",
184 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
190 "Adaptec 39320D Ultra320 SCSI adapter",
196 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
202 "Adaptec 29320 Ultra320 SCSI adapter",
208 "Adaptec 29320B Ultra320 SCSI adapter",
211 /* Generic chip probes for devices we don't know 'exactly' */
213 ID_AIC7901 & ID_DEV_VENDOR_MASK,
215 "Adaptec AIC7901 Ultra320 SCSI adapter",
219 ID_AIC7901A & ID_DEV_VENDOR_MASK,
221 "Adaptec AIC7901A Ultra320 SCSI adapter",
225 ID_AIC7902 & ID_9005_GENERIC_MASK,
226 ID_9005_GENERIC_MASK,
227 "Adaptec AIC7902 Ultra320 SCSI adapter",
232 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
234 #define DEVCONFIG 0x40
235 #define PCIXINITPAT 0x0000E000ul
236 #define PCIXINIT_PCI33_66 0x0000E000ul
237 #define PCIXINIT_PCIX50_66 0x0000C000ul
238 #define PCIXINIT_PCIX66_100 0x0000A000ul
239 #define PCIXINIT_PCIX100_133 0x00008000ul
240 #define PCI_BUS_MODES_INDEX(devconfig) \
241 (((devconfig) & PCIXINITPAT) >> 13)
242 static const char *pci_bus_modes[] =
244 "PCI bus mode unknown",
245 "PCI bus mode unknown",
246 "PCI bus mode unknown",
247 "PCI bus mode unknown",
254 #define TESTMODE 0x00000800ul
255 #define IRDY_RST 0x00000200ul
256 #define FRAME_RST 0x00000100ul
257 #define PCI64BIT 0x00000080ul
258 #define MRDCEN 0x00000040ul
259 #define ENDIANSEL 0x00000020ul
260 #define MIXQWENDIANEN 0x00000008ul
261 #define DACEN 0x00000004ul
262 #define STPWLEVEL 0x00000002ul
263 #define QWENDIANSEL 0x00000001ul
265 #define DEVCONFIG1 0x44
268 #define CSIZE_LATTIME 0x0c
269 #define CACHESIZE 0x000000fful
270 #define LATTIME 0x0000ff00ul
272 static int ahd_check_extport(struct ahd_softc *ahd);
273 static void ahd_configure_termination(struct ahd_softc *ahd,
274 u_int adapter_control);
275 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
277 struct ahd_pci_identity *
278 ahd_find_pci_device(ahd_dev_softc_t pci)
285 struct ahd_pci_identity *entry;
288 vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
289 device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
290 subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
291 subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
292 full_id = ahd_compose_id(device,
297 for (i = 0; i < ahd_num_pci_devs; i++) {
298 entry = &ahd_pci_ident_table[i];
299 if (entry->full_id == (full_id & entry->id_mask)) {
300 /* Honor exclusion entries. */
301 if (entry->name == NULL)
310 ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
312 struct scb_data *shared_scb_data;
319 shared_scb_data = NULL;
320 ahd->description = entry->name;
322 * Record if this is an HP board.
324 subvendor = ahd_pci_read_config(ahd->dev_softc,
325 PCIR_SUBVEND_0, /*bytes*/2);
326 if (subvendor == SUBID_HP)
327 ahd->flags |= AHD_HP_BOARD;
329 error = entry->setup(ahd);
333 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
334 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
335 ahd->chip |= AHD_PCI;
336 /* Disable PCIX workarounds when running in PCI mode. */
337 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
339 ahd->chip |= AHD_PCIX;
341 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
343 ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
345 error = ahd_pci_map_registers(ahd);
350 * If we need to support high memory, enable dual
351 * address cycles. This bit must be set to enable
352 * high address bit generation even if we are on a
353 * 64bit bus (PCI64BIT set in devconfig).
355 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
359 printf("%s: Enabling 39Bit Addressing\n",
361 devconfig = ahd_pci_read_config(ahd->dev_softc,
362 DEVCONFIG, /*bytes*/4);
364 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
365 devconfig, /*bytes*/4);
368 /* Ensure busmastering is enabled */
369 command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
370 command |= PCIM_CMD_BUSMASTEREN;
371 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
373 error = ahd_softc_init(ahd);
377 ahd->bus_intr = ahd_pci_intr;
379 error = ahd_reset(ahd, /*reinit*/FALSE);
384 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
385 /*bytes*/1) & CACHESIZE;
386 ahd->pci_cachesize *= 4;
388 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
389 /* See if we have a SEEPROM and perform auto-term */
390 error = ahd_check_extport(ahd);
394 /* Core initialization */
395 error = ahd_init(ahd);
400 * Allow interrupts now that we are completely setup.
402 error = ahd_pci_map_int(ahd);
408 * Link this softc in with all other ahd instances.
410 ahd_softc_insert(ahd);
416 * Perform some simple tests that should catch situations where
417 * our registers are invalidly mapped.
420 ahd_pci_test_register_access(struct ahd_softc *ahd)
431 * Enable PCI error interrupt status, but suppress NMIs
432 * generated by SERR raised due to target aborts.
434 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
435 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
436 cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
439 * First a simple test to see if any
440 * registers can be read. Reading
441 * HCNTRL has no side effects and has
442 * at least one bit that is guaranteed to
443 * be zero so it is a good register to
446 hcntrl = ahd_inb(ahd, HCNTRL);
451 * Next create a situation where write combining
452 * or read prefetching could be initiated by the
453 * CPU or host bridge. Our device does not support
454 * either, so look for data corruption and/or flaged
457 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
458 while (ahd_is_paused(ahd) == 0)
461 /* Clear any PCI errors that occurred before our driver attached. */
462 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
463 targpcistat = ahd_inb(ahd, TARGPCISTAT);
464 ahd_outb(ahd, TARGPCISTAT, targpcistat);
465 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
466 PCIR_STATUS + 1, /*bytes*/1);
467 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
468 pci_status1, /*bytes*/1);
469 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
470 ahd_outb(ahd, CLRINT, CLRPCIINT);
472 ahd_outb(ahd, SEQCTL0, PERRORDIS);
473 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
474 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
477 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
480 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
481 targpcistat = ahd_inb(ahd, TARGPCISTAT);
482 if ((targpcistat & STA) != 0)
489 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
491 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
492 targpcistat = ahd_inb(ahd, TARGPCISTAT);
494 /* Silently clear any latched errors. */
495 ahd_outb(ahd, TARGPCISTAT, targpcistat);
496 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
497 PCIR_STATUS + 1, /*bytes*/1);
498 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
499 pci_status1, /*bytes*/1);
500 ahd_outb(ahd, CLRINT, CLRPCIINT);
502 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
503 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
508 * Check the external port logic for a serial eeprom
509 * and termination/cable detection contrls.
512 ahd_check_extport(struct ahd_softc *ahd)
514 struct vpd_config vpd;
515 struct seeprom_config *sc;
516 u_int adapter_control;
520 sc = ahd->seep_config;
521 have_seeprom = ahd_acquire_seeprom(ahd);
526 * Fetch VPD for this function and parse it.
529 printf("%s: Reading VPD from SEEPROM...",
532 /* Address is always in units of 16bit words */
533 start_addr = ((2 * sizeof(*sc))
534 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
536 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
537 start_addr, sizeof(vpd)/2,
540 error = ahd_parse_vpddata(ahd, &vpd);
542 printf("%s: VPD parsing %s\n",
544 error == 0 ? "successful" : "failed");
547 printf("%s: Reading SEEPROM...", ahd_name(ahd));
549 /* Address is always in units of 16bit words */
550 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
552 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
553 start_addr, sizeof(*sc)/2,
554 /*bytestream*/FALSE);
557 printf("Unable to read SEEPROM\n");
560 have_seeprom = ahd_verify_cksum(sc);
563 if (have_seeprom == 0)
564 printf ("checksum error\n");
569 ahd_release_seeprom(ahd);
576 * Pull scratch ram settings and treat them as
577 * if they are the contents of an seeprom if
578 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
579 * in SCB 0xFF. We manually compose the data as 16bit
580 * values to avoid endian issues.
582 ahd_set_scbptr(ahd, 0xFF);
583 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
584 if (nvram_scb != 0xFF
585 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
586 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
587 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
588 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
589 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
590 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
591 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
592 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
593 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
594 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
595 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
596 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
600 ahd_set_scbptr(ahd, nvram_scb);
601 sc_data = (uint16_t *)sc;
602 for (i = 0; i < 64; i += 2)
603 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
604 have_seeprom = ahd_verify_cksum(sc);
606 ahd->flags |= AHD_SCB_CONFIG_USED;
611 if (have_seeprom != 0
612 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
616 printf("%s: Seeprom Contents:", ahd_name(ahd));
617 sc_data = (uint16_t *)sc;
618 for (i = 0; i < (sizeof(*sc)); i += 2)
619 printf("\n\t0x%.4x", sc_data[i]);
626 printf("%s: No SEEPROM available.\n", ahd_name(ahd));
627 ahd->flags |= AHD_USEDEFAULTS;
628 error = ahd_default_config(ahd);
629 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
630 free(ahd->seep_config, M_DEVBUF);
631 ahd->seep_config = NULL;
633 error = ahd_parse_cfgdata(ahd, sc);
634 adapter_control = sc->adapter_control;
639 ahd_configure_termination(ahd, adapter_control);
645 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
652 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
653 devconfig &= ~STPWLEVEL;
654 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
655 devconfig |= STPWLEVEL;
657 printf("%s: STPWLEVEL is %s\n",
658 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
659 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
661 /* Make sure current sensing is off. */
662 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
663 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
667 * Read to sense. Write to set.
669 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
670 if ((adapter_control & CFAUTOTERM) == 0) {
672 printf("%s: Manual Primary Termination\n",
674 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
675 if ((adapter_control & CFSTERM) != 0)
676 termctl |= FLX_TERMCTL_ENPRILOW;
677 if ((adapter_control & CFWSTERM) != 0)
678 termctl |= FLX_TERMCTL_ENPRIHIGH;
679 } else if (error != 0) {
680 printf("%s: Primary Auto-Term Sensing failed! "
681 "Using Defaults.\n", ahd_name(ahd));
682 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
685 if ((adapter_control & CFSEAUTOTERM) == 0) {
687 printf("%s: Manual Secondary Termination\n",
689 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
690 if ((adapter_control & CFSELOWTERM) != 0)
691 termctl |= FLX_TERMCTL_ENSECLOW;
692 if ((adapter_control & CFSEHIGHTERM) != 0)
693 termctl |= FLX_TERMCTL_ENSECHIGH;
694 } else if (error != 0) {
695 printf("%s: Secondary Auto-Term Sensing failed! "
696 "Using Defaults.\n", ahd_name(ahd));
697 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
701 * Now set the termination based on what we found.
703 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
704 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
705 ahd->flags |= AHD_TERM_ENB_A;
708 /* Must set the latch once in order to be effective. */
709 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
710 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
712 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
714 printf("%s: Unable to set termination settings!\n",
716 } else if (bootverbose) {
717 printf("%s: Primary High byte termination %sabled\n",
719 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
721 printf("%s: Primary Low byte termination %sabled\n",
723 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
725 printf("%s: Secondary High byte termination %sabled\n",
727 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
729 printf("%s: Secondary Low byte termination %sabled\n",
731 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
743 static const char *split_status_source[] =
751 static const char *pci_status_source[] =
763 static const char *split_status_strings[] =
765 "%s: Received split response in %s.\n",
766 "%s: Received split completion error message in %s\n",
767 "%s: Receive overrun in %s\n",
768 "%s: Count not complete in %s\n",
769 "%s: Split completion data bucket in %s\n",
770 "%s: Split completion address error in %s\n",
771 "%s: Split completion byte count error in %s\n",
772 "%s: Signaled Target-abort to early terminate a split in %s\n"
775 static const char *pci_status_strings[] =
777 "%s: Data Parity Error has been reported via PERR# in %s\n",
778 "%s: Target initial wait state error in %s\n",
779 "%s: Split completion read data parity error in %s\n",
780 "%s: Split completion address attribute parity error in %s\n",
781 "%s: Received a Target Abort in %s\n",
782 "%s: Received a Master Abort in %s\n",
783 "%s: Signal System Error Detected in %s\n",
784 "%s: Address or Write Phase Parity Error Detected in %s.\n"
788 ahd_pci_intr(struct ahd_softc *ahd)
790 uint8_t pci_status[8];
791 ahd_mode_state saved_modes;
797 intstat = ahd_inb(ahd, INTSTAT);
799 if ((intstat & SPLTINT) != 0)
800 ahd_pci_split_intr(ahd, intstat);
802 if ((intstat & PCIINT) == 0)
805 printf("%s: PCI error Interrupt\n", ahd_name(ahd));
806 saved_modes = ahd_save_modes(ahd);
807 ahd_dump_card_state(ahd);
808 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
809 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
813 pci_status[i] = ahd_inb(ahd, reg);
814 /* Clear latched errors. So our interrupt deasserts. */
815 ahd_outb(ahd, reg, pci_status[i]);
818 for (i = 0; i < 8; i++) {
824 for (bit = 0; bit < 8; bit++) {
826 if ((pci_status[i] & (0x1 << bit)) != 0) {
827 static const char *s;
829 s = pci_status_strings[bit];
830 if (i == 7/*TARG*/ && bit == 3)
831 s = "%s: Signaled Target Abort\n";
832 printf(s, ahd_name(ahd), pci_status_source[i]);
836 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
837 PCIR_STATUS + 1, /*bytes*/1);
838 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
839 pci_status1, /*bytes*/1);
840 ahd_restore_modes(ahd, saved_modes);
841 ahd_outb(ahd, CLRINT, CLRPCIINT);
846 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
848 uint8_t split_status[4];
849 uint8_t split_status1[4];
850 uint8_t sg_split_status[2];
851 uint8_t sg_split_status1[2];
852 ahd_mode_state saved_modes;
854 uint16_t pcix_status;
857 * Check for splits in all modes. Modes 0 and 1
858 * additionally have SG engine splits to look at.
860 pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
862 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
863 ahd_name(ahd), pcix_status);
864 saved_modes = ahd_save_modes(ahd);
865 for (i = 0; i < 4; i++) {
866 ahd_set_modes(ahd, i, i);
868 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
869 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
870 /* Clear latched errors. So our interrupt deasserts. */
871 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
872 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
875 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
876 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
877 /* Clear latched errors. So our interrupt deasserts. */
878 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
879 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
882 for (i = 0; i < 4; i++) {
885 for (bit = 0; bit < 8; bit++) {
887 if ((split_status[i] & (0x1 << bit)) != 0) {
888 static const char *s;
890 s = split_status_strings[bit];
891 printf(s, ahd_name(ahd),
892 split_status_source[i]);
898 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
899 static const char *s;
901 s = split_status_strings[bit];
902 printf(s, ahd_name(ahd), "SG");
907 * Clear PCI-X status bits.
909 ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
910 pcix_status, /*bytes*/2);
911 ahd_outb(ahd, CLRINT, CLRSPLTINT);
912 ahd_restore_modes(ahd, saved_modes);
916 ahd_aic7901_setup(struct ahd_softc *ahd)
919 ahd->chip = AHD_AIC7901;
920 ahd->features = AHD_AIC7901_FE;
921 return (ahd_aic790X_setup(ahd));
925 ahd_aic7901A_setup(struct ahd_softc *ahd)
928 ahd->chip = AHD_AIC7901A;
929 ahd->features = AHD_AIC7901A_FE;
930 return (ahd_aic790X_setup(ahd));
934 ahd_aic7902_setup(struct ahd_softc *ahd)
936 ahd->chip = AHD_AIC7902;
937 ahd->features = AHD_AIC7902_FE;
938 return (ahd_aic790X_setup(ahd));
942 ahd_aic790X_setup(struct ahd_softc *ahd)
947 pci = ahd->dev_softc;
948 rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
949 if (rev < ID_AIC7902_PCI_REV_A4) {
950 printf("%s: Unable to attach to unsupported chip revision %d\n",
952 ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
955 ahd->channel = ahd_get_pci_function(pci) + 'A';
956 if (rev < ID_AIC7902_PCI_REV_B0) {
958 * Enable A series workarounds.
960 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
961 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
962 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
963 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
964 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
965 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
966 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
967 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
968 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
969 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
973 * IO Cell paramter setup.
975 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
977 if ((ahd->flags & AHD_HP_BOARD) == 0)
978 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
982 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
983 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
984 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
987 * Some issues have been resolved in the 7901B.
989 if ((ahd->features & AHD_MULTI_FUNC) != 0)
990 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
993 * IO Cell paramter setup.
995 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
996 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
997 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
1000 * Set the PREQDIS bit for H2B which disables some workaround
1001 * that doesn't work on regular PCI busses.
1002 * XXX - Find out exactly what this does from the hardware
1005 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
1006 ahd_pci_write_config(pci, DEVCONFIG1,
1007 devconfig1|PREQDIS, /*bytes*/1);
1008 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);