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 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 struct ahd_pci_identity
*
257 ahd_find_pci_device(ahd_dev_softc_t pci
)
264 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
, 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
);
393 * Perform some simple tests that should catch situations where
394 * our registers are invalidly mapped.
397 ahd_pci_test_register_access(struct ahd_softc
*ahd
)
408 * Enable PCI error interrupt status, but suppress NMIs
409 * generated by SERR raised due to target aborts.
411 cmd
= ahd_pci_read_config(ahd
->dev_softc
, PCIR_COMMAND
, /*bytes*/2);
412 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
,
413 cmd
& ~PCIM_CMD_SERRESPEN
, /*bytes*/2);
416 * First a simple test to see if any
417 * registers can be read. Reading
418 * HCNTRL has no side effects and has
419 * at least one bit that is guaranteed to
420 * be zero so it is a good register to
423 hcntrl
= ahd_inb(ahd
, HCNTRL
);
428 * Next create a situation where write combining
429 * or read prefetching could be initiated by the
430 * CPU or host bridge. Our device does not support
431 * either, so look for data corruption and/or flaged
432 * PCI errors. First pause without causing another
436 ahd_outb(ahd
, HCNTRL
, hcntrl
|PAUSE
);
437 while (ahd_is_paused(ahd
) == 0)
440 /* Clear any PCI errors that occurred before our driver attached. */
441 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
442 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
443 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
444 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
445 PCIR_STATUS
+ 1, /*bytes*/1);
446 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
447 pci_status1
, /*bytes*/1);
448 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
449 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
451 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
);
452 ahd_outl(ahd
, SRAM_BASE
, 0x5aa555aa);
453 if (ahd_inl(ahd
, SRAM_BASE
) != 0x5aa555aa)
456 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
459 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
460 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
461 if ((targpcistat
& STA
) != 0)
468 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
470 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
471 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
473 /* Silently clear any latched errors. */
474 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
475 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
476 PCIR_STATUS
+ 1, /*bytes*/1);
477 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
478 pci_status1
, /*bytes*/1);
479 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
481 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
|FAILDIS
);
482 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
, cmd
, /*bytes*/2);
487 * Check the external port logic for a serial eeprom
488 * and termination/cable detection contrls.
491 ahd_check_extport(struct ahd_softc
*ahd
)
493 struct vpd_config vpd
;
494 struct seeprom_config
*sc
;
495 u_int adapter_control
;
499 sc
= ahd
->seep_config
;
500 have_seeprom
= ahd_acquire_seeprom(ahd
);
505 * Fetch VPD for this function and parse it.
508 printf("%s: Reading VPD from SEEPROM...",
511 /* Address is always in units of 16bit words */
512 start_addr
= ((2 * sizeof(*sc
))
513 + (sizeof(vpd
) * (ahd
->channel
- 'A'))) / 2;
515 error
= ahd_read_seeprom(ahd
, (uint16_t *)&vpd
,
516 start_addr
, sizeof(vpd
)/2,
519 error
= ahd_parse_vpddata(ahd
, &vpd
);
521 printf("%s: VPD parsing %s\n",
523 error
== 0 ? "successful" : "failed");
526 printf("%s: Reading SEEPROM...", ahd_name(ahd
));
528 /* Address is always in units of 16bit words */
529 start_addr
= (sizeof(*sc
) / 2) * (ahd
->channel
- 'A');
531 error
= ahd_read_seeprom(ahd
, (uint16_t *)sc
,
532 start_addr
, sizeof(*sc
)/2,
533 /*bytestream*/FALSE
);
536 printf("Unable to read SEEPROM\n");
539 have_seeprom
= ahd_verify_cksum(sc
);
542 if (have_seeprom
== 0)
543 printf ("checksum error\n");
548 ahd_release_seeprom(ahd
);
555 * Pull scratch ram settings and treat them as
556 * if they are the contents of an seeprom if
557 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
558 * in SCB 0xFF. We manually compose the data as 16bit
559 * values to avoid endian issues.
561 ahd_set_scbptr(ahd
, 0xFF);
562 nvram_scb
= ahd_inb_scbram(ahd
, SCB_BASE
+ NVRAM_SCB_OFFSET
);
563 if (nvram_scb
!= 0xFF
564 && ((ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
565 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'D'
566 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
567 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'T')
568 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'B'
569 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'I'
570 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'O'
571 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'S')
572 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
573 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'S'
574 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
575 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'I'))) {
579 ahd_set_scbptr(ahd
, nvram_scb
);
580 sc_data
= (uint16_t *)sc
;
581 for (i
= 0; i
< 64; i
+= 2)
582 *sc_data
++ = ahd_inw_scbram(ahd
, SCB_BASE
+i
);
583 have_seeprom
= ahd_verify_cksum(sc
);
585 ahd
->flags
|= AHD_SCB_CONFIG_USED
;
590 if (have_seeprom
!= 0
591 && (ahd_debug
& AHD_DUMP_SEEPROM
) != 0) {
595 printf("%s: Seeprom Contents:", ahd_name(ahd
));
596 sc_data
= (uint16_t *)sc
;
597 for (i
= 0; i
< (sizeof(*sc
)); i
+= 2)
598 printf("\n\t0x%.4x", sc_data
[i
]);
605 printf("%s: No SEEPROM available.\n", ahd_name(ahd
));
606 ahd
->flags
|= AHD_USEDEFAULTS
;
607 error
= ahd_default_config(ahd
);
608 adapter_control
= CFAUTOTERM
|CFSEAUTOTERM
;
609 free(ahd
->seep_config
, M_DEVBUF
);
610 ahd
->seep_config
= NULL
;
612 error
= ahd_parse_cfgdata(ahd
, sc
);
613 adapter_control
= sc
->adapter_control
;
618 ahd_configure_termination(ahd
, adapter_control
);
624 ahd_configure_termination(struct ahd_softc
*ahd
, u_int adapter_control
)
631 devconfig
= ahd_pci_read_config(ahd
->dev_softc
, DEVCONFIG
, /*bytes*/4);
632 devconfig
&= ~STPWLEVEL
;
633 if ((ahd
->flags
& AHD_STPWLEVEL_A
) != 0)
634 devconfig
|= STPWLEVEL
;
636 printf("%s: STPWLEVEL is %s\n",
637 ahd_name(ahd
), (devconfig
& STPWLEVEL
) ? "on" : "off");
638 ahd_pci_write_config(ahd
->dev_softc
, DEVCONFIG
, devconfig
, /*bytes*/4);
640 /* Make sure current sensing is off. */
641 if ((ahd
->flags
& AHD_CURRENT_SENSING
) != 0) {
642 (void)ahd_write_flexport(ahd
, FLXADDR_ROMSTAT_CURSENSECTL
, 0);
646 * Read to sense. Write to set.
648 error
= ahd_read_flexport(ahd
, FLXADDR_TERMCTL
, &termctl
);
649 if ((adapter_control
& CFAUTOTERM
) == 0) {
651 printf("%s: Manual Primary Termination\n",
653 termctl
&= ~(FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
);
654 if ((adapter_control
& CFSTERM
) != 0)
655 termctl
|= FLX_TERMCTL_ENPRILOW
;
656 if ((adapter_control
& CFWSTERM
) != 0)
657 termctl
|= FLX_TERMCTL_ENPRIHIGH
;
658 } else if (error
!= 0) {
659 printf("%s: Primary Auto-Term Sensing failed! "
660 "Using Defaults.\n", ahd_name(ahd
));
661 termctl
= FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
;
664 if ((adapter_control
& CFSEAUTOTERM
) == 0) {
666 printf("%s: Manual Secondary Termination\n",
668 termctl
&= ~(FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
);
669 if ((adapter_control
& CFSELOWTERM
) != 0)
670 termctl
|= FLX_TERMCTL_ENSECLOW
;
671 if ((adapter_control
& CFSEHIGHTERM
) != 0)
672 termctl
|= FLX_TERMCTL_ENSECHIGH
;
673 } else if (error
!= 0) {
674 printf("%s: Secondary Auto-Term Sensing failed! "
675 "Using Defaults.\n", ahd_name(ahd
));
676 termctl
|= FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
;
680 * Now set the termination based on what we found.
682 sxfrctl1
= ahd_inb(ahd
, SXFRCTL1
) & ~STPWEN
;
683 ahd
->flags
&= ~AHD_TERM_ENB_A
;
684 if ((termctl
& FLX_TERMCTL_ENPRILOW
) != 0) {
685 ahd
->flags
|= AHD_TERM_ENB_A
;
688 /* Must set the latch once in order to be effective. */
689 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
|STPWEN
);
690 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
);
692 error
= ahd_write_flexport(ahd
, FLXADDR_TERMCTL
, termctl
);
694 printf("%s: Unable to set termination settings!\n",
696 } else if (bootverbose
) {
697 printf("%s: Primary High byte termination %sabled\n",
699 (termctl
& FLX_TERMCTL_ENPRIHIGH
) ? "En" : "Dis");
701 printf("%s: Primary Low byte termination %sabled\n",
703 (termctl
& FLX_TERMCTL_ENPRILOW
) ? "En" : "Dis");
705 printf("%s: Secondary High byte termination %sabled\n",
707 (termctl
& FLX_TERMCTL_ENSECHIGH
) ? "En" : "Dis");
709 printf("%s: Secondary Low byte termination %sabled\n",
711 (termctl
& FLX_TERMCTL_ENSECLOW
) ? "En" : "Dis");
723 static const char *split_status_source
[] =
731 static const char *pci_status_source
[] =
743 static const char *split_status_strings
[] =
745 "%s: Received split response in %s.\n",
746 "%s: Received split completion error message in %s\n",
747 "%s: Receive overrun in %s\n",
748 "%s: Count not complete in %s\n",
749 "%s: Split completion data bucket in %s\n",
750 "%s: Split completion address error in %s\n",
751 "%s: Split completion byte count error in %s\n",
752 "%s: Signaled Target-abort to early terminate a split in %s\n"
755 static const char *pci_status_strings
[] =
757 "%s: Data Parity Error has been reported via PERR# in %s\n",
758 "%s: Target initial wait state error in %s\n",
759 "%s: Split completion read data parity error in %s\n",
760 "%s: Split completion address attribute parity error in %s\n",
761 "%s: Received a Target Abort in %s\n",
762 "%s: Received a Master Abort in %s\n",
763 "%s: Signal System Error Detected in %s\n",
764 "%s: Address or Write Phase Parity Error Detected in %s.\n"
768 ahd_pci_intr(struct ahd_softc
*ahd
)
770 uint8_t pci_status
[8];
771 ahd_mode_state saved_modes
;
777 intstat
= ahd_inb(ahd
, INTSTAT
);
779 if ((intstat
& SPLTINT
) != 0)
780 ahd_pci_split_intr(ahd
, intstat
);
782 if ((intstat
& PCIINT
) == 0)
785 printf("%s: PCI error Interrupt\n", ahd_name(ahd
));
786 saved_modes
= ahd_save_modes(ahd
);
787 ahd_dump_card_state(ahd
);
788 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
789 for (i
= 0, reg
= DF0PCISTAT
; i
< 8; i
++, reg
++) {
793 pci_status
[i
] = ahd_inb(ahd
, reg
);
794 /* Clear latched errors. So our interrupt deasserts. */
795 ahd_outb(ahd
, reg
, pci_status
[i
]);
798 for (i
= 0; i
< 8; i
++) {
804 for (bit
= 0; bit
< 8; bit
++) {
806 if ((pci_status
[i
] & (0x1 << bit
)) != 0) {
807 static const char *s
;
809 s
= pci_status_strings
[bit
];
810 if (i
== 7/*TARG*/ && bit
== 3)
811 s
= "%s: Signaled Target Abort\n";
812 printf(s
, ahd_name(ahd
), pci_status_source
[i
]);
816 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
817 PCIR_STATUS
+ 1, /*bytes*/1);
818 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
819 pci_status1
, /*bytes*/1);
820 ahd_restore_modes(ahd
, saved_modes
);
821 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
826 ahd_pci_split_intr(struct ahd_softc
*ahd
, u_int intstat
)
828 uint8_t split_status
[4];
829 uint8_t split_status1
[4];
830 uint8_t sg_split_status
[2];
831 uint8_t sg_split_status1
[2];
832 ahd_mode_state saved_modes
;
834 uint16_t pcix_status
;
837 * Check for splits in all modes. Modes 0 and 1
838 * additionally have SG engine splits to look at.
840 pcix_status
= ahd_pci_read_config(ahd
->dev_softc
, PCIXR_STATUS
,
842 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
843 ahd_name(ahd
), pcix_status
);
844 saved_modes
= ahd_save_modes(ahd
);
845 for (i
= 0; i
< 4; i
++) {
846 ahd_set_modes(ahd
, i
, i
);
848 split_status
[i
] = ahd_inb(ahd
, DCHSPLTSTAT0
);
849 split_status1
[i
] = ahd_inb(ahd
, DCHSPLTSTAT1
);
850 /* Clear latched errors. So our interrupt deasserts. */
851 ahd_outb(ahd
, DCHSPLTSTAT0
, split_status
[i
]);
852 ahd_outb(ahd
, DCHSPLTSTAT1
, split_status1
[i
]);
855 sg_split_status
[i
] = ahd_inb(ahd
, SGSPLTSTAT0
);
856 sg_split_status1
[i
] = ahd_inb(ahd
, SGSPLTSTAT1
);
857 /* Clear latched errors. So our interrupt deasserts. */
858 ahd_outb(ahd
, SGSPLTSTAT0
, sg_split_status
[i
]);
859 ahd_outb(ahd
, SGSPLTSTAT1
, sg_split_status1
[i
]);
862 for (i
= 0; i
< 4; i
++) {
865 for (bit
= 0; bit
< 8; bit
++) {
867 if ((split_status
[i
] & (0x1 << bit
)) != 0) {
868 static const char *s
;
870 s
= split_status_strings
[bit
];
871 printf(s
, ahd_name(ahd
),
872 split_status_source
[i
]);
878 if ((sg_split_status
[i
] & (0x1 << bit
)) != 0) {
879 static const char *s
;
881 s
= split_status_strings
[bit
];
882 printf(s
, ahd_name(ahd
), "SG");
887 * Clear PCI-X status bits.
889 ahd_pci_write_config(ahd
->dev_softc
, PCIXR_STATUS
,
890 pcix_status
, /*bytes*/2);
891 ahd_outb(ahd
, CLRINT
, CLRSPLTINT
);
892 ahd_restore_modes(ahd
, saved_modes
);
896 ahd_aic7901_setup(struct ahd_softc
*ahd
)
899 ahd
->chip
= AHD_AIC7901
;
900 ahd
->features
= AHD_AIC7901_FE
;
901 return (ahd_aic790X_setup(ahd
));
905 ahd_aic7901A_setup(struct ahd_softc
*ahd
)
908 ahd
->chip
= AHD_AIC7901A
;
909 ahd
->features
= AHD_AIC7901A_FE
;
910 return (ahd_aic790X_setup(ahd
));
914 ahd_aic7902_setup(struct ahd_softc
*ahd
)
916 ahd
->chip
= AHD_AIC7902
;
917 ahd
->features
= AHD_AIC7902_FE
;
918 return (ahd_aic790X_setup(ahd
));
922 ahd_aic790X_setup(struct ahd_softc
*ahd
)
927 pci
= ahd
->dev_softc
;
928 rev
= ahd_pci_read_config(pci
, PCIR_REVID
, /*bytes*/1);
929 if (rev
< ID_AIC7902_PCI_REV_A4
) {
930 printf("%s: Unable to attach to unsupported chip revision %d\n",
932 ahd_pci_write_config(pci
, PCIR_COMMAND
, 0, /*bytes*/2);
935 ahd
->channel
= ahd_get_pci_function(pci
) + 'A';
936 if (rev
< ID_AIC7902_PCI_REV_B0
) {
938 * Enable A series workarounds.
940 ahd
->bugs
|= AHD_SENT_SCB_UPDATE_BUG
|AHD_ABORT_LQI_BUG
941 | AHD_PKT_BITBUCKET_BUG
|AHD_LONG_SETIMO_BUG
942 | AHD_NLQICRC_DELAYED_BUG
|AHD_SCSIRST_BUG
943 | AHD_LQO_ATNO_BUG
|AHD_AUTOFLUSH_BUG
944 | AHD_CLRLQO_AUTOCLR_BUG
|AHD_PCIX_MMAPIO_BUG
945 | AHD_PCIX_CHIPRST_BUG
|AHD_PCIX_SCBRAM_RD_BUG
946 | AHD_PKTIZED_STATUS_BUG
|AHD_PKT_LUN_BUG
947 | AHD_MDFF_WSCBPTR_BUG
|AHD_REG_SLOW_SETTLE_BUG
948 | AHD_SET_MODE_BUG
|AHD_BUSFREEREV_BUG
949 | AHD_NONPACKFIFO_BUG
|AHD_PACED_NEGTABLE_BUG
953 * IO Cell paramter setup.
955 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
957 if ((ahd
->flags
& AHD_HP_BOARD
) == 0)
958 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVA
);
960 /* This is revision B and newer. */
961 extern uint32_t aic79xx_slowcrc
;
964 ahd
->features
|= AHD_RTI
|AHD_NEW_IOCELL_OPTS
965 | AHD_NEW_DFCNTRL_OPTS
|AHD_FAST_CDB_DELIVERY
966 | AHD_BUSFREEREV_BUG
;
967 ahd
->bugs
|= AHD_LQOOVERRUN_BUG
|AHD_EARLY_REQ_BUG
;
969 /* If the user requested the the SLOWCRC bit to be set. */
971 ahd
->features
|= AHD_AIC79XXB_SLOWCRC
;
974 * Some issues have been resolved in the 7901B.
976 if ((ahd
->features
& AHD_MULTI_FUNC
) != 0)
977 ahd
->bugs
|= AHD_INTCOLLISION_BUG
|AHD_ABORT_LQI_BUG
;
980 * IO Cell paramter setup.
982 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
983 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVB
);
984 AHD_SET_AMPLITUDE(ahd
, AHD_AMPLITUDE_DEF
);
987 * Set the PREQDIS bit for H2B which disables some workaround
988 * that doesn't work on regular PCI busses.
989 * XXX - Find out exactly what this does from the hardware
992 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);
993 ahd_pci_write_config(pci
, DEVCONFIG1
,
994 devconfig1
|PREQDIS
, /*bytes*/1);
995 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);