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#92 $
45 #include "aic79xx_osm.h"
46 #include "aic79xx_inline.h"
48 #include <dev/aic7xxx/aic79xx_osm.h>
49 #include <dev/aic7xxx/aic79xx_inline.h>
52 #include "aic79xx_pci.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_AIC7902_PCI_REV_A4 0x3
68 #define ID_AIC7902_PCI_REV_B0 0x10
69 #define SUBID_HP 0x0E11
71 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
73 #define DEVID_9005_TYPE(id) ((id) & 0xF)
74 #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
75 #define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */
76 #define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */
77 #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
79 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
81 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
83 #define SUBID_9005_TYPE(id) ((id) & 0xF)
84 #define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */
85 #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
87 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
89 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
91 #define SUBID_9005_SEEPTYPE(id) (((id) & 0x0C0) >> 6)
92 #define SUBID_9005_SEEPTYPE_NONE 0x0
93 #define SUBID_9005_SEEPTYPE_4K 0x1
95 static ahd_device_setup_t ahd_aic7901_setup;
96 static ahd_device_setup_t ahd_aic7901A_setup;
97 static ahd_device_setup_t ahd_aic7902_setup;
98 static ahd_device_setup_t ahd_aic790X_setup;
100 static const struct ahd_pci_identity ahd_pci_ident_table[] =
102 /* aic7901 based controllers */
106 "Adaptec 29320A Ultra320 SCSI adapter",
112 "Adaptec 29320ALP PCIx Ultra320 SCSI adapter",
118 "Adaptec 29320LPE PCIe Ultra320 SCSI adapter",
121 /* aic7901A based controllers */
125 "Adaptec 29320LP Ultra320 SCSI adapter",
128 /* aic7902 based controllers */
132 "Adaptec 29320 Ultra320 SCSI adapter",
138 "Adaptec 29320B Ultra320 SCSI adapter",
144 "Adaptec 39320 Ultra320 SCSI adapter",
150 "Adaptec 39320 Ultra320 SCSI adapter",
156 "Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",
162 "Adaptec 39320A Ultra320 SCSI adapter",
168 "Adaptec 39320D Ultra320 SCSI adapter",
174 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
180 "Adaptec 39320D Ultra320 SCSI adapter",
186 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
189 /* Generic chip probes for devices we don't know 'exactly' */
191 ID_AIC7901 & ID_9005_GENERIC_MASK,
192 ID_9005_GENERIC_MASK,
193 "Adaptec AIC7901 Ultra320 SCSI adapter",
197 ID_AIC7901A & ID_DEV_VENDOR_MASK,
199 "Adaptec AIC7901A Ultra320 SCSI adapter",
203 ID_AIC7902 & ID_9005_GENERIC_MASK,
204 ID_9005_GENERIC_MASK,
205 "Adaptec AIC7902 Ultra320 SCSI adapter",
210 static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
212 #define DEVCONFIG 0x40
213 #define PCIXINITPAT 0x0000E000ul
214 #define PCIXINIT_PCI33_66 0x0000E000ul
215 #define PCIXINIT_PCIX50_66 0x0000C000ul
216 #define PCIXINIT_PCIX66_100 0x0000A000ul
217 #define PCIXINIT_PCIX100_133 0x00008000ul
218 #define PCI_BUS_MODES_INDEX(devconfig) \
219 (((devconfig) & PCIXINITPAT) >> 13)
220 static const char *pci_bus_modes[] =
222 "PCI bus mode unknown",
223 "PCI bus mode unknown",
224 "PCI bus mode unknown",
225 "PCI bus mode unknown",
232 #define TESTMODE 0x00000800ul
233 #define IRDY_RST 0x00000200ul
234 #define FRAME_RST 0x00000100ul
235 #define PCI64BIT 0x00000080ul
236 #define MRDCEN 0x00000040ul
237 #define ENDIANSEL 0x00000020ul
238 #define MIXQWENDIANEN 0x00000008ul
239 #define DACEN 0x00000004ul
240 #define STPWLEVEL 0x00000002ul
241 #define QWENDIANSEL 0x00000001ul
243 #define DEVCONFIG1 0x44
246 #define CSIZE_LATTIME 0x0c
247 #define CACHESIZE 0x000000fful
248 #define LATTIME 0x0000ff00ul
250 static int ahd_check_extport(struct ahd_softc *ahd);
251 static void ahd_configure_termination(struct ahd_softc *ahd,
252 u_int adapter_control);
253 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
254 static void ahd_pci_intr(struct ahd_softc *ahd);
256 const struct ahd_pci_identity *
257 ahd_find_pci_device(ahd_dev_softc_t pci)
264 const struct ahd_pci_identity *entry;
267 vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
268 device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
269 subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
270 subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
271 full_id = ahd_compose_id(device,
277 * Controllers, mask out the IROC/HostRAID bit
280 full_id &= ID_ALL_IROC_MASK;
282 for (i = 0; i < ahd_num_pci_devs; i++) {
283 entry = &ahd_pci_ident_table[i];
284 if (entry->full_id == (full_id & entry->id_mask)) {
285 /* Honor exclusion entries. */
286 if (entry->name == NULL)
295 ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
297 struct scb_data *shared_scb_data;
303 shared_scb_data = NULL;
304 ahd->description = entry->name;
306 * Record if this is an HP board.
308 subvendor = ahd_pci_read_config(ahd->dev_softc,
309 PCIR_SUBVEND_0, /*bytes*/2);
310 if (subvendor == SUBID_HP)
311 ahd->flags |= AHD_HP_BOARD;
313 error = entry->setup(ahd);
317 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
318 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
319 ahd->chip |= AHD_PCI;
320 /* Disable PCIX workarounds when running in PCI mode. */
321 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
323 ahd->chip |= AHD_PCIX;
325 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
327 ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
329 error = ahd_pci_map_registers(ahd);
334 * If we need to support high memory, enable dual
335 * address cycles. This bit must be set to enable
336 * high address bit generation even if we are on a
337 * 64bit bus (PCI64BIT set in devconfig).
339 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
343 printf("%s: Enabling 39Bit Addressing\n",
345 devconfig = ahd_pci_read_config(ahd->dev_softc,
346 DEVCONFIG, /*bytes*/4);
348 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
349 devconfig, /*bytes*/4);
352 /* Ensure busmastering is enabled */
353 command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
354 command |= PCIM_CMD_BUSMASTEREN;
355 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
357 error = ahd_softc_init(ahd);
361 ahd->bus_intr = ahd_pci_intr;
363 error = ahd_reset(ahd, /*reinit*/FALSE);
368 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
369 /*bytes*/1) & CACHESIZE;
370 ahd->pci_cachesize *= 4;
372 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
373 /* See if we have a SEEPROM and perform auto-term */
374 error = ahd_check_extport(ahd);
378 /* Core initialization */
379 error = ahd_init(ahd);
384 * Allow interrupts now that we are completely setup.
386 error = ahd_pci_map_int(ahd);
394 ahd_pci_suspend(struct ahd_softc *ahd)
397 * Save chip register configuration data for chip resets
398 * that occur during runtime and resume events.
400 ahd->suspend_state.pci_state.devconfig =
401 ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
402 ahd->suspend_state.pci_state.command =
403 ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1);
404 ahd->suspend_state.pci_state.csize_lattime =
405 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, /*bytes*/1);
410 ahd_pci_resume(struct ahd_softc *ahd)
412 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
413 ahd->suspend_state.pci_state.devconfig, /*bytes*/4);
414 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
415 ahd->suspend_state.pci_state.command, /*bytes*/1);
416 ahd_pci_write_config(ahd->dev_softc, CSIZE_LATTIME,
417 ahd->suspend_state.pci_state.csize_lattime, /*bytes*/1);
422 * Perform some simple tests that should catch situations where
423 * our registers are invalidly mapped.
426 ahd_pci_test_register_access(struct ahd_softc *ahd)
437 * Enable PCI error interrupt status, but suppress NMIs
438 * generated by SERR raised due to target aborts.
440 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
441 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
442 cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
445 * First a simple test to see if any
446 * registers can be read. Reading
447 * HCNTRL has no side effects and has
448 * at least one bit that is guaranteed to
449 * be zero so it is a good register to
452 hcntrl = ahd_inb(ahd, HCNTRL);
457 * Next create a situation where write combining
458 * or read prefetching could be initiated by the
459 * CPU or host bridge. Our device does not support
460 * either, so look for data corruption and/or flaged
461 * PCI errors. First pause without causing another
465 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
466 while (ahd_is_paused(ahd) == 0)
469 /* Clear any PCI errors that occurred before our driver attached. */
470 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
471 targpcistat = ahd_inb(ahd, TARGPCISTAT);
472 ahd_outb(ahd, TARGPCISTAT, targpcistat);
473 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
474 PCIR_STATUS + 1, /*bytes*/1);
475 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
476 pci_status1, /*bytes*/1);
477 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
478 ahd_outb(ahd, CLRINT, CLRPCIINT);
480 ahd_outb(ahd, SEQCTL0, PERRORDIS);
481 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
482 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
485 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
488 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
489 targpcistat = ahd_inb(ahd, TARGPCISTAT);
490 if ((targpcistat & STA) != 0)
497 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
499 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
500 targpcistat = ahd_inb(ahd, TARGPCISTAT);
502 /* Silently clear any latched errors. */
503 ahd_outb(ahd, TARGPCISTAT, targpcistat);
504 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
505 PCIR_STATUS + 1, /*bytes*/1);
506 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
507 pci_status1, /*bytes*/1);
508 ahd_outb(ahd, CLRINT, CLRPCIINT);
510 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
511 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
516 * Check the external port logic for a serial eeprom
517 * and termination/cable detection contrls.
520 ahd_check_extport(struct ahd_softc *ahd)
522 struct vpd_config vpd;
523 struct seeprom_config *sc;
524 u_int adapter_control;
528 sc = ahd->seep_config;
529 have_seeprom = ahd_acquire_seeprom(ahd);
534 * Fetch VPD for this function and parse it.
537 printf("%s: Reading VPD from SEEPROM...",
540 /* Address is always in units of 16bit words */
541 start_addr = ((2 * sizeof(*sc))
542 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
544 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
545 start_addr, sizeof(vpd)/2,
548 error = ahd_parse_vpddata(ahd, &vpd);
550 printf("%s: VPD parsing %s\n",
552 error == 0 ? "successful" : "failed");
555 printf("%s: Reading SEEPROM...", ahd_name(ahd));
557 /* Address is always in units of 16bit words */
558 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
560 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
561 start_addr, sizeof(*sc)/2,
562 /*bytestream*/FALSE);
565 printf("Unable to read SEEPROM\n");
568 have_seeprom = ahd_verify_cksum(sc);
571 if (have_seeprom == 0)
572 printf ("checksum error\n");
577 ahd_release_seeprom(ahd);
584 * Pull scratch ram settings and treat them as
585 * if they are the contents of an seeprom if
586 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
587 * in SCB 0xFF. We manually compose the data as 16bit
588 * values to avoid endian issues.
590 ahd_set_scbptr(ahd, 0xFF);
591 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
592 if (nvram_scb != 0xFF
593 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
594 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
595 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
596 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
597 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
598 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
599 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
600 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
601 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
602 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
603 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
604 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
608 ahd_set_scbptr(ahd, nvram_scb);
609 sc_data = (uint16_t *)sc;
610 for (i = 0; i < 64; i += 2)
611 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
612 have_seeprom = ahd_verify_cksum(sc);
614 ahd->flags |= AHD_SCB_CONFIG_USED;
619 if (have_seeprom != 0
620 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
624 printf("%s: Seeprom Contents:", ahd_name(ahd));
625 sc_data = (uint16_t *)sc;
626 for (i = 0; i < (sizeof(*sc)); i += 2)
627 printf("\n\t0x%.4x", sc_data[i]);
634 printf("%s: No SEEPROM available.\n", ahd_name(ahd));
635 ahd->flags |= AHD_USEDEFAULTS;
636 error = ahd_default_config(ahd);
637 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
638 free(ahd->seep_config, M_DEVBUF);
639 ahd->seep_config = NULL;
641 error = ahd_parse_cfgdata(ahd, sc);
642 adapter_control = sc->adapter_control;
647 ahd_configure_termination(ahd, adapter_control);
653 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
660 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
661 devconfig &= ~STPWLEVEL;
662 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
663 devconfig |= STPWLEVEL;
665 printf("%s: STPWLEVEL is %s\n",
666 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
667 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
669 /* Make sure current sensing is off. */
670 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
671 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
675 * Read to sense. Write to set.
677 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
678 if ((adapter_control & CFAUTOTERM) == 0) {
680 printf("%s: Manual Primary Termination\n",
682 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
683 if ((adapter_control & CFSTERM) != 0)
684 termctl |= FLX_TERMCTL_ENPRILOW;
685 if ((adapter_control & CFWSTERM) != 0)
686 termctl |= FLX_TERMCTL_ENPRIHIGH;
687 } else if (error != 0) {
688 printf("%s: Primary Auto-Term Sensing failed! "
689 "Using Defaults.\n", ahd_name(ahd));
690 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
693 if ((adapter_control & CFSEAUTOTERM) == 0) {
695 printf("%s: Manual Secondary Termination\n",
697 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
698 if ((adapter_control & CFSELOWTERM) != 0)
699 termctl |= FLX_TERMCTL_ENSECLOW;
700 if ((adapter_control & CFSEHIGHTERM) != 0)
701 termctl |= FLX_TERMCTL_ENSECHIGH;
702 } else if (error != 0) {
703 printf("%s: Secondary Auto-Term Sensing failed! "
704 "Using Defaults.\n", ahd_name(ahd));
705 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
709 * Now set the termination based on what we found.
711 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
712 ahd->flags &= ~AHD_TERM_ENB_A;
713 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
714 ahd->flags |= AHD_TERM_ENB_A;
717 /* Must set the latch once in order to be effective. */
718 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
719 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
721 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
723 printf("%s: Unable to set termination settings!\n",
725 } else if (bootverbose) {
726 printf("%s: Primary High byte termination %sabled\n",
728 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
730 printf("%s: Primary Low byte termination %sabled\n",
732 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
734 printf("%s: Secondary High byte termination %sabled\n",
736 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
738 printf("%s: Secondary Low byte termination %sabled\n",
740 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
752 static const char *split_status_source[] =
760 static const char *pci_status_source[] =
772 static const char *split_status_strings[] =
774 "%s: Received split response in %s.\n",
775 "%s: Received split completion error message in %s\n",
776 "%s: Receive overrun in %s\n",
777 "%s: Count not complete in %s\n",
778 "%s: Split completion data bucket in %s\n",
779 "%s: Split completion address error in %s\n",
780 "%s: Split completion byte count error in %s\n",
781 "%s: Signaled Target-abort to early terminate a split in %s\n"
784 static const char *pci_status_strings[] =
786 "%s: Data Parity Error has been reported via PERR# in %s\n",
787 "%s: Target initial wait state error in %s\n",
788 "%s: Split completion read data parity error in %s\n",
789 "%s: Split completion address attribute parity error in %s\n",
790 "%s: Received a Target Abort in %s\n",
791 "%s: Received a Master Abort in %s\n",
792 "%s: Signal System Error Detected in %s\n",
793 "%s: Address or Write Phase Parity Error Detected in %s.\n"
797 ahd_pci_intr(struct ahd_softc *ahd)
799 uint8_t pci_status[8];
800 ahd_mode_state saved_modes;
806 intstat = ahd_inb(ahd, INTSTAT);
808 if ((intstat & SPLTINT) != 0)
809 ahd_pci_split_intr(ahd, intstat);
811 if ((intstat & PCIINT) == 0)
814 printf("%s: PCI error Interrupt\n", ahd_name(ahd));
815 saved_modes = ahd_save_modes(ahd);
816 ahd_dump_card_state(ahd);
817 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
818 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
822 pci_status[i] = ahd_inb(ahd, reg);
823 /* Clear latched errors. So our interrupt deasserts. */
824 ahd_outb(ahd, reg, pci_status[i]);
827 for (i = 0; i < 8; i++) {
833 for (bit = 0; bit < 8; bit++) {
835 if ((pci_status[i] & (0x1 << bit)) != 0) {
836 static const char *s;
838 s = pci_status_strings[bit];
839 if (i == 7/*TARG*/ && bit == 3)
840 s = "%s: Signaled Target Abort\n";
841 printf(s, ahd_name(ahd), pci_status_source[i]);
845 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
846 PCIR_STATUS + 1, /*bytes*/1);
847 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
848 pci_status1, /*bytes*/1);
849 ahd_restore_modes(ahd, saved_modes);
850 ahd_outb(ahd, CLRINT, CLRPCIINT);
855 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
857 uint8_t split_status[4];
858 uint8_t split_status1[4];
859 uint8_t sg_split_status[2];
860 uint8_t sg_split_status1[2];
861 ahd_mode_state saved_modes;
863 uint16_t pcix_status;
866 * Check for splits in all modes. Modes 0 and 1
867 * additionally have SG engine splits to look at.
869 pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
871 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
872 ahd_name(ahd), pcix_status);
873 saved_modes = ahd_save_modes(ahd);
874 for (i = 0; i < 4; i++) {
875 ahd_set_modes(ahd, i, i);
877 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
878 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
879 /* Clear latched errors. So our interrupt deasserts. */
880 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
881 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
884 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
885 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
886 /* Clear latched errors. So our interrupt deasserts. */
887 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
888 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
891 for (i = 0; i < 4; i++) {
894 for (bit = 0; bit < 8; bit++) {
896 if ((split_status[i] & (0x1 << bit)) != 0) {
897 static const char *s;
899 s = split_status_strings[bit];
900 printf(s, ahd_name(ahd),
901 split_status_source[i]);
907 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
908 static const char *s;
910 s = split_status_strings[bit];
911 printf(s, ahd_name(ahd), "SG");
916 * Clear PCI-X status bits.
918 ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
919 pcix_status, /*bytes*/2);
920 ahd_outb(ahd, CLRINT, CLRSPLTINT);
921 ahd_restore_modes(ahd, saved_modes);
925 ahd_aic7901_setup(struct ahd_softc *ahd)
928 ahd->chip = AHD_AIC7901;
929 ahd->features = AHD_AIC7901_FE;
930 return (ahd_aic790X_setup(ahd));
934 ahd_aic7901A_setup(struct ahd_softc *ahd)
937 ahd->chip = AHD_AIC7901A;
938 ahd->features = AHD_AIC7901A_FE;
939 return (ahd_aic790X_setup(ahd));
943 ahd_aic7902_setup(struct ahd_softc *ahd)
945 ahd->chip = AHD_AIC7902;
946 ahd->features = AHD_AIC7902_FE;
947 return (ahd_aic790X_setup(ahd));
951 ahd_aic790X_setup(struct ahd_softc *ahd)
956 pci = ahd->dev_softc;
957 rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
958 if (rev < ID_AIC7902_PCI_REV_A4) {
959 printf("%s: Unable to attach to unsupported chip revision %d\n",
961 ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
964 ahd->channel = ahd_get_pci_function(pci) + 'A';
965 if (rev < ID_AIC7902_PCI_REV_B0) {
967 * Enable A series workarounds.
969 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
970 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
971 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
972 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
973 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
974 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
975 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
976 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
977 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
978 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
982 * IO Cell parameter setup.
984 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
986 if ((ahd->flags & AHD_HP_BOARD) == 0)
987 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
989 /* This is revision B and newer. */
990 extern uint32_t aic79xx_slowcrc;
993 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
994 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY
995 | AHD_BUSFREEREV_BUG;
996 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
998 /* If the user requested that the SLOWCRC bit to be set. */
1000 ahd->features |= AHD_AIC79XXB_SLOWCRC;
1003 * Some issues have been resolved in the 7901B.
1005 if ((ahd->features & AHD_MULTI_FUNC) != 0)
1006 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
1009 * IO Cell parameter setup.
1011 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
1012 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
1013 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
1016 * Set the PREQDIS bit for H2B which disables some workaround
1017 * that doesn't work on regular PCI busses.
1018 * XXX - Find out exactly what this does from the hardware
1021 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
1022 ahd_pci_write_config(pci, DEVCONFIG1,
1023 devconfig1|PREQDIS, /*bytes*/1);
1024 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);