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 struct ahd_pci_identity ahd_pci_ident_table
[] =
102 /* aic7901 based controllers */
106 "Adaptec 29320A Ultra320 SCSI adapter",
112 "Adaptec 29320ALP Ultra320 SCSI adapter",
115 /* aic7901A based controllers */
119 "Adaptec 29320LP Ultra320 SCSI adapter",
122 /* aic7902 based controllers */
126 "Adaptec 29320 Ultra320 SCSI adapter",
132 "Adaptec 29320B Ultra320 SCSI adapter",
138 "Adaptec 39320 Ultra320 SCSI adapter",
144 "Adaptec 39320 Ultra320 SCSI adapter",
150 "Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",
156 "Adaptec 39320A Ultra320 SCSI adapter",
162 "Adaptec 39320D Ultra320 SCSI adapter",
168 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
174 "Adaptec 39320D Ultra320 SCSI adapter",
180 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
183 /* Generic chip probes for devices we don't know 'exactly' */
185 ID_AIC7901
& ID_9005_GENERIC_MASK
,
186 ID_9005_GENERIC_MASK
,
187 "Adaptec AIC7901 Ultra320 SCSI adapter",
191 ID_AIC7901A
& ID_DEV_VENDOR_MASK
,
193 "Adaptec AIC7901A Ultra320 SCSI adapter",
197 ID_AIC7902
& ID_9005_GENERIC_MASK
,
198 ID_9005_GENERIC_MASK
,
199 "Adaptec AIC7902 Ultra320 SCSI adapter",
204 const u_int ahd_num_pci_devs
= ARRAY_SIZE(ahd_pci_ident_table
);
206 #define DEVCONFIG 0x40
207 #define PCIXINITPAT 0x0000E000ul
208 #define PCIXINIT_PCI33_66 0x0000E000ul
209 #define PCIXINIT_PCIX50_66 0x0000C000ul
210 #define PCIXINIT_PCIX66_100 0x0000A000ul
211 #define PCIXINIT_PCIX100_133 0x00008000ul
212 #define PCI_BUS_MODES_INDEX(devconfig) \
213 (((devconfig) & PCIXINITPAT) >> 13)
214 static const char *pci_bus_modes
[] =
216 "PCI bus mode unknown",
217 "PCI bus mode unknown",
218 "PCI bus mode unknown",
219 "PCI bus mode unknown",
226 #define TESTMODE 0x00000800ul
227 #define IRDY_RST 0x00000200ul
228 #define FRAME_RST 0x00000100ul
229 #define PCI64BIT 0x00000080ul
230 #define MRDCEN 0x00000040ul
231 #define ENDIANSEL 0x00000020ul
232 #define MIXQWENDIANEN 0x00000008ul
233 #define DACEN 0x00000004ul
234 #define STPWLEVEL 0x00000002ul
235 #define QWENDIANSEL 0x00000001ul
237 #define DEVCONFIG1 0x44
240 #define CSIZE_LATTIME 0x0c
241 #define CACHESIZE 0x000000fful
242 #define LATTIME 0x0000ff00ul
244 static int ahd_check_extport(struct ahd_softc
*ahd
);
245 static void ahd_configure_termination(struct ahd_softc
*ahd
,
246 u_int adapter_control
);
247 static void ahd_pci_split_intr(struct ahd_softc
*ahd
, u_int intstat
);
249 struct ahd_pci_identity
*
250 ahd_find_pci_device(ahd_dev_softc_t pci
)
257 struct ahd_pci_identity
*entry
;
260 vendor
= ahd_pci_read_config(pci
, PCIR_DEVVENDOR
, /*bytes*/2);
261 device
= ahd_pci_read_config(pci
, PCIR_DEVICE
, /*bytes*/2);
262 subvendor
= ahd_pci_read_config(pci
, PCIR_SUBVEND_0
, /*bytes*/2);
263 subdevice
= ahd_pci_read_config(pci
, PCIR_SUBDEV_0
, /*bytes*/2);
264 full_id
= ahd_compose_id(device
,
270 * Controllers, mask out the IROC/HostRAID bit
273 full_id
&= ID_ALL_IROC_MASK
;
275 for (i
= 0; i
< ahd_num_pci_devs
; i
++) {
276 entry
= &ahd_pci_ident_table
[i
];
277 if (entry
->full_id
== (full_id
& entry
->id_mask
)) {
278 /* Honor exclusion entries. */
279 if (entry
->name
== NULL
)
288 ahd_pci_config(struct ahd_softc
*ahd
, struct ahd_pci_identity
*entry
)
290 struct scb_data
*shared_scb_data
;
296 shared_scb_data
= NULL
;
297 ahd
->description
= entry
->name
;
299 * Record if this is an HP board.
301 subvendor
= ahd_pci_read_config(ahd
->dev_softc
,
302 PCIR_SUBVEND_0
, /*bytes*/2);
303 if (subvendor
== SUBID_HP
)
304 ahd
->flags
|= AHD_HP_BOARD
;
306 error
= entry
->setup(ahd
);
310 devconfig
= ahd_pci_read_config(ahd
->dev_softc
, DEVCONFIG
, /*bytes*/4);
311 if ((devconfig
& PCIXINITPAT
) == PCIXINIT_PCI33_66
) {
312 ahd
->chip
|= AHD_PCI
;
313 /* Disable PCIX workarounds when running in PCI mode. */
314 ahd
->bugs
&= ~AHD_PCIX_BUG_MASK
;
316 ahd
->chip
|= AHD_PCIX
;
318 ahd
->bus_description
= pci_bus_modes
[PCI_BUS_MODES_INDEX(devconfig
)];
320 ahd_power_state_change(ahd
, AHD_POWER_STATE_D0
);
322 error
= ahd_pci_map_registers(ahd
);
327 * If we need to support high memory, enable dual
328 * address cycles. This bit must be set to enable
329 * high address bit generation even if we are on a
330 * 64bit bus (PCI64BIT set in devconfig).
332 if ((ahd
->flags
& (AHD_39BIT_ADDRESSING
|AHD_64BIT_ADDRESSING
)) != 0) {
336 printf("%s: Enabling 39Bit Addressing\n",
338 devconfig
= ahd_pci_read_config(ahd
->dev_softc
,
339 DEVCONFIG
, /*bytes*/4);
341 ahd_pci_write_config(ahd
->dev_softc
, DEVCONFIG
,
342 devconfig
, /*bytes*/4);
345 /* Ensure busmastering is enabled */
346 command
= ahd_pci_read_config(ahd
->dev_softc
, PCIR_COMMAND
, /*bytes*/2);
347 command
|= PCIM_CMD_BUSMASTEREN
;
348 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
, command
, /*bytes*/2);
350 error
= ahd_softc_init(ahd
);
354 ahd
->bus_intr
= ahd_pci_intr
;
356 error
= ahd_reset(ahd
, /*reinit*/FALSE
);
361 ahd_pci_read_config(ahd
->dev_softc
, CSIZE_LATTIME
,
362 /*bytes*/1) & CACHESIZE
;
363 ahd
->pci_cachesize
*= 4;
365 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
366 /* See if we have a SEEPROM and perform auto-term */
367 error
= ahd_check_extport(ahd
);
371 /* Core initialization */
372 error
= ahd_init(ahd
);
377 * Allow interrupts now that we are completely setup.
379 error
= ahd_pci_map_int(ahd
);
386 * Perform some simple tests that should catch situations where
387 * our registers are invalidly mapped.
390 ahd_pci_test_register_access(struct ahd_softc
*ahd
)
401 * Enable PCI error interrupt status, but suppress NMIs
402 * generated by SERR raised due to target aborts.
404 cmd
= ahd_pci_read_config(ahd
->dev_softc
, PCIR_COMMAND
, /*bytes*/2);
405 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
,
406 cmd
& ~PCIM_CMD_SERRESPEN
, /*bytes*/2);
409 * First a simple test to see if any
410 * registers can be read. Reading
411 * HCNTRL has no side effects and has
412 * at least one bit that is guaranteed to
413 * be zero so it is a good register to
416 hcntrl
= ahd_inb(ahd
, HCNTRL
);
421 * Next create a situation where write combining
422 * or read prefetching could be initiated by the
423 * CPU or host bridge. Our device does not support
424 * either, so look for data corruption and/or flaged
425 * PCI errors. First pause without causing another
429 ahd_outb(ahd
, HCNTRL
, hcntrl
|PAUSE
);
430 while (ahd_is_paused(ahd
) == 0)
433 /* Clear any PCI errors that occurred before our driver attached. */
434 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
435 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
436 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
437 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
438 PCIR_STATUS
+ 1, /*bytes*/1);
439 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
440 pci_status1
, /*bytes*/1);
441 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
442 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
444 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
);
445 ahd_outl(ahd
, SRAM_BASE
, 0x5aa555aa);
446 if (ahd_inl(ahd
, SRAM_BASE
) != 0x5aa555aa)
449 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
452 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
453 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
454 if ((targpcistat
& STA
) != 0)
461 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
463 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
464 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
466 /* Silently clear any latched errors. */
467 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
468 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
469 PCIR_STATUS
+ 1, /*bytes*/1);
470 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
471 pci_status1
, /*bytes*/1);
472 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
474 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
|FAILDIS
);
475 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
, cmd
, /*bytes*/2);
480 * Check the external port logic for a serial eeprom
481 * and termination/cable detection contrls.
484 ahd_check_extport(struct ahd_softc
*ahd
)
486 struct vpd_config vpd
;
487 struct seeprom_config
*sc
;
488 u_int adapter_control
;
492 sc
= ahd
->seep_config
;
493 have_seeprom
= ahd_acquire_seeprom(ahd
);
498 * Fetch VPD for this function and parse it.
501 printf("%s: Reading VPD from SEEPROM...",
504 /* Address is always in units of 16bit words */
505 start_addr
= ((2 * sizeof(*sc
))
506 + (sizeof(vpd
) * (ahd
->channel
- 'A'))) / 2;
508 error
= ahd_read_seeprom(ahd
, (uint16_t *)&vpd
,
509 start_addr
, sizeof(vpd
)/2,
512 error
= ahd_parse_vpddata(ahd
, &vpd
);
514 printf("%s: VPD parsing %s\n",
516 error
== 0 ? "successful" : "failed");
519 printf("%s: Reading SEEPROM...", ahd_name(ahd
));
521 /* Address is always in units of 16bit words */
522 start_addr
= (sizeof(*sc
) / 2) * (ahd
->channel
- 'A');
524 error
= ahd_read_seeprom(ahd
, (uint16_t *)sc
,
525 start_addr
, sizeof(*sc
)/2,
526 /*bytestream*/FALSE
);
529 printf("Unable to read SEEPROM\n");
532 have_seeprom
= ahd_verify_cksum(sc
);
535 if (have_seeprom
== 0)
536 printf ("checksum error\n");
541 ahd_release_seeprom(ahd
);
548 * Pull scratch ram settings and treat them as
549 * if they are the contents of an seeprom if
550 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
551 * in SCB 0xFF. We manually compose the data as 16bit
552 * values to avoid endian issues.
554 ahd_set_scbptr(ahd
, 0xFF);
555 nvram_scb
= ahd_inb_scbram(ahd
, SCB_BASE
+ NVRAM_SCB_OFFSET
);
556 if (nvram_scb
!= 0xFF
557 && ((ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
558 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'D'
559 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
560 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'T')
561 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'B'
562 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'I'
563 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'O'
564 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'S')
565 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
566 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'S'
567 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
568 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'I'))) {
572 ahd_set_scbptr(ahd
, nvram_scb
);
573 sc_data
= (uint16_t *)sc
;
574 for (i
= 0; i
< 64; i
+= 2)
575 *sc_data
++ = ahd_inw_scbram(ahd
, SCB_BASE
+i
);
576 have_seeprom
= ahd_verify_cksum(sc
);
578 ahd
->flags
|= AHD_SCB_CONFIG_USED
;
583 if (have_seeprom
!= 0
584 && (ahd_debug
& AHD_DUMP_SEEPROM
) != 0) {
588 printf("%s: Seeprom Contents:", ahd_name(ahd
));
589 sc_data
= (uint16_t *)sc
;
590 for (i
= 0; i
< (sizeof(*sc
)); i
+= 2)
591 printf("\n\t0x%.4x", sc_data
[i
]);
598 printf("%s: No SEEPROM available.\n", ahd_name(ahd
));
599 ahd
->flags
|= AHD_USEDEFAULTS
;
600 error
= ahd_default_config(ahd
);
601 adapter_control
= CFAUTOTERM
|CFSEAUTOTERM
;
602 free(ahd
->seep_config
, M_DEVBUF
);
603 ahd
->seep_config
= NULL
;
605 error
= ahd_parse_cfgdata(ahd
, sc
);
606 adapter_control
= sc
->adapter_control
;
611 ahd_configure_termination(ahd
, adapter_control
);
617 ahd_configure_termination(struct ahd_softc
*ahd
, u_int adapter_control
)
624 devconfig
= ahd_pci_read_config(ahd
->dev_softc
, DEVCONFIG
, /*bytes*/4);
625 devconfig
&= ~STPWLEVEL
;
626 if ((ahd
->flags
& AHD_STPWLEVEL_A
) != 0)
627 devconfig
|= STPWLEVEL
;
629 printf("%s: STPWLEVEL is %s\n",
630 ahd_name(ahd
), (devconfig
& STPWLEVEL
) ? "on" : "off");
631 ahd_pci_write_config(ahd
->dev_softc
, DEVCONFIG
, devconfig
, /*bytes*/4);
633 /* Make sure current sensing is off. */
634 if ((ahd
->flags
& AHD_CURRENT_SENSING
) != 0) {
635 (void)ahd_write_flexport(ahd
, FLXADDR_ROMSTAT_CURSENSECTL
, 0);
639 * Read to sense. Write to set.
641 error
= ahd_read_flexport(ahd
, FLXADDR_TERMCTL
, &termctl
);
642 if ((adapter_control
& CFAUTOTERM
) == 0) {
644 printf("%s: Manual Primary Termination\n",
646 termctl
&= ~(FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
);
647 if ((adapter_control
& CFSTERM
) != 0)
648 termctl
|= FLX_TERMCTL_ENPRILOW
;
649 if ((adapter_control
& CFWSTERM
) != 0)
650 termctl
|= FLX_TERMCTL_ENPRIHIGH
;
651 } else if (error
!= 0) {
652 printf("%s: Primary Auto-Term Sensing failed! "
653 "Using Defaults.\n", ahd_name(ahd
));
654 termctl
= FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
;
657 if ((adapter_control
& CFSEAUTOTERM
) == 0) {
659 printf("%s: Manual Secondary Termination\n",
661 termctl
&= ~(FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
);
662 if ((adapter_control
& CFSELOWTERM
) != 0)
663 termctl
|= FLX_TERMCTL_ENSECLOW
;
664 if ((adapter_control
& CFSEHIGHTERM
) != 0)
665 termctl
|= FLX_TERMCTL_ENSECHIGH
;
666 } else if (error
!= 0) {
667 printf("%s: Secondary Auto-Term Sensing failed! "
668 "Using Defaults.\n", ahd_name(ahd
));
669 termctl
|= FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
;
673 * Now set the termination based on what we found.
675 sxfrctl1
= ahd_inb(ahd
, SXFRCTL1
) & ~STPWEN
;
676 ahd
->flags
&= ~AHD_TERM_ENB_A
;
677 if ((termctl
& FLX_TERMCTL_ENPRILOW
) != 0) {
678 ahd
->flags
|= AHD_TERM_ENB_A
;
681 /* Must set the latch once in order to be effective. */
682 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
|STPWEN
);
683 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
);
685 error
= ahd_write_flexport(ahd
, FLXADDR_TERMCTL
, termctl
);
687 printf("%s: Unable to set termination settings!\n",
689 } else if (bootverbose
) {
690 printf("%s: Primary High byte termination %sabled\n",
692 (termctl
& FLX_TERMCTL_ENPRIHIGH
) ? "En" : "Dis");
694 printf("%s: Primary Low byte termination %sabled\n",
696 (termctl
& FLX_TERMCTL_ENPRILOW
) ? "En" : "Dis");
698 printf("%s: Secondary High byte termination %sabled\n",
700 (termctl
& FLX_TERMCTL_ENSECHIGH
) ? "En" : "Dis");
702 printf("%s: Secondary Low byte termination %sabled\n",
704 (termctl
& FLX_TERMCTL_ENSECLOW
) ? "En" : "Dis");
716 static const char *split_status_source
[] =
724 static const char *pci_status_source
[] =
736 static const char *split_status_strings
[] =
738 "%s: Received split response in %s.\n",
739 "%s: Received split completion error message in %s\n",
740 "%s: Receive overrun in %s\n",
741 "%s: Count not complete in %s\n",
742 "%s: Split completion data bucket in %s\n",
743 "%s: Split completion address error in %s\n",
744 "%s: Split completion byte count error in %s\n",
745 "%s: Signaled Target-abort to early terminate a split in %s\n"
748 static const char *pci_status_strings
[] =
750 "%s: Data Parity Error has been reported via PERR# in %s\n",
751 "%s: Target initial wait state error in %s\n",
752 "%s: Split completion read data parity error in %s\n",
753 "%s: Split completion address attribute parity error in %s\n",
754 "%s: Received a Target Abort in %s\n",
755 "%s: Received a Master Abort in %s\n",
756 "%s: Signal System Error Detected in %s\n",
757 "%s: Address or Write Phase Parity Error Detected in %s.\n"
761 ahd_pci_intr(struct ahd_softc
*ahd
)
763 uint8_t pci_status
[8];
764 ahd_mode_state saved_modes
;
770 intstat
= ahd_inb(ahd
, INTSTAT
);
772 if ((intstat
& SPLTINT
) != 0)
773 ahd_pci_split_intr(ahd
, intstat
);
775 if ((intstat
& PCIINT
) == 0)
778 printf("%s: PCI error Interrupt\n", ahd_name(ahd
));
779 saved_modes
= ahd_save_modes(ahd
);
780 ahd_dump_card_state(ahd
);
781 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
782 for (i
= 0, reg
= DF0PCISTAT
; i
< 8; i
++, reg
++) {
786 pci_status
[i
] = ahd_inb(ahd
, reg
);
787 /* Clear latched errors. So our interrupt deasserts. */
788 ahd_outb(ahd
, reg
, pci_status
[i
]);
791 for (i
= 0; i
< 8; i
++) {
797 for (bit
= 0; bit
< 8; bit
++) {
799 if ((pci_status
[i
] & (0x1 << bit
)) != 0) {
800 static const char *s
;
802 s
= pci_status_strings
[bit
];
803 if (i
== 7/*TARG*/ && bit
== 3)
804 s
= "%s: Signaled Target Abort\n";
805 printf(s
, ahd_name(ahd
), pci_status_source
[i
]);
809 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
810 PCIR_STATUS
+ 1, /*bytes*/1);
811 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
812 pci_status1
, /*bytes*/1);
813 ahd_restore_modes(ahd
, saved_modes
);
814 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
819 ahd_pci_split_intr(struct ahd_softc
*ahd
, u_int intstat
)
821 uint8_t split_status
[4];
822 uint8_t split_status1
[4];
823 uint8_t sg_split_status
[2];
824 uint8_t sg_split_status1
[2];
825 ahd_mode_state saved_modes
;
827 uint16_t pcix_status
;
830 * Check for splits in all modes. Modes 0 and 1
831 * additionally have SG engine splits to look at.
833 pcix_status
= ahd_pci_read_config(ahd
->dev_softc
, PCIXR_STATUS
,
835 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
836 ahd_name(ahd
), pcix_status
);
837 saved_modes
= ahd_save_modes(ahd
);
838 for (i
= 0; i
< 4; i
++) {
839 ahd_set_modes(ahd
, i
, i
);
841 split_status
[i
] = ahd_inb(ahd
, DCHSPLTSTAT0
);
842 split_status1
[i
] = ahd_inb(ahd
, DCHSPLTSTAT1
);
843 /* Clear latched errors. So our interrupt deasserts. */
844 ahd_outb(ahd
, DCHSPLTSTAT0
, split_status
[i
]);
845 ahd_outb(ahd
, DCHSPLTSTAT1
, split_status1
[i
]);
848 sg_split_status
[i
] = ahd_inb(ahd
, SGSPLTSTAT0
);
849 sg_split_status1
[i
] = ahd_inb(ahd
, SGSPLTSTAT1
);
850 /* Clear latched errors. So our interrupt deasserts. */
851 ahd_outb(ahd
, SGSPLTSTAT0
, sg_split_status
[i
]);
852 ahd_outb(ahd
, SGSPLTSTAT1
, sg_split_status1
[i
]);
855 for (i
= 0; i
< 4; i
++) {
858 for (bit
= 0; bit
< 8; bit
++) {
860 if ((split_status
[i
] & (0x1 << bit
)) != 0) {
861 static const char *s
;
863 s
= split_status_strings
[bit
];
864 printf(s
, ahd_name(ahd
),
865 split_status_source
[i
]);
871 if ((sg_split_status
[i
] & (0x1 << bit
)) != 0) {
872 static const char *s
;
874 s
= split_status_strings
[bit
];
875 printf(s
, ahd_name(ahd
), "SG");
880 * Clear PCI-X status bits.
882 ahd_pci_write_config(ahd
->dev_softc
, PCIXR_STATUS
,
883 pcix_status
, /*bytes*/2);
884 ahd_outb(ahd
, CLRINT
, CLRSPLTINT
);
885 ahd_restore_modes(ahd
, saved_modes
);
889 ahd_aic7901_setup(struct ahd_softc
*ahd
)
892 ahd
->chip
= AHD_AIC7901
;
893 ahd
->features
= AHD_AIC7901_FE
;
894 return (ahd_aic790X_setup(ahd
));
898 ahd_aic7901A_setup(struct ahd_softc
*ahd
)
901 ahd
->chip
= AHD_AIC7901A
;
902 ahd
->features
= AHD_AIC7901A_FE
;
903 return (ahd_aic790X_setup(ahd
));
907 ahd_aic7902_setup(struct ahd_softc
*ahd
)
909 ahd
->chip
= AHD_AIC7902
;
910 ahd
->features
= AHD_AIC7902_FE
;
911 return (ahd_aic790X_setup(ahd
));
915 ahd_aic790X_setup(struct ahd_softc
*ahd
)
920 pci
= ahd
->dev_softc
;
921 rev
= ahd_pci_read_config(pci
, PCIR_REVID
, /*bytes*/1);
922 if (rev
< ID_AIC7902_PCI_REV_A4
) {
923 printf("%s: Unable to attach to unsupported chip revision %d\n",
925 ahd_pci_write_config(pci
, PCIR_COMMAND
, 0, /*bytes*/2);
928 ahd
->channel
= ahd_get_pci_function(pci
) + 'A';
929 if (rev
< ID_AIC7902_PCI_REV_B0
) {
931 * Enable A series workarounds.
933 ahd
->bugs
|= AHD_SENT_SCB_UPDATE_BUG
|AHD_ABORT_LQI_BUG
934 | AHD_PKT_BITBUCKET_BUG
|AHD_LONG_SETIMO_BUG
935 | AHD_NLQICRC_DELAYED_BUG
|AHD_SCSIRST_BUG
936 | AHD_LQO_ATNO_BUG
|AHD_AUTOFLUSH_BUG
937 | AHD_CLRLQO_AUTOCLR_BUG
|AHD_PCIX_MMAPIO_BUG
938 | AHD_PCIX_CHIPRST_BUG
|AHD_PCIX_SCBRAM_RD_BUG
939 | AHD_PKTIZED_STATUS_BUG
|AHD_PKT_LUN_BUG
940 | AHD_MDFF_WSCBPTR_BUG
|AHD_REG_SLOW_SETTLE_BUG
941 | AHD_SET_MODE_BUG
|AHD_BUSFREEREV_BUG
942 | AHD_NONPACKFIFO_BUG
|AHD_PACED_NEGTABLE_BUG
946 * IO Cell paramter setup.
948 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
950 if ((ahd
->flags
& AHD_HP_BOARD
) == 0)
951 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVA
);
953 /* This is revision B and newer. */
954 extern uint32_t aic79xx_slowcrc
;
957 ahd
->features
|= AHD_RTI
|AHD_NEW_IOCELL_OPTS
958 | AHD_NEW_DFCNTRL_OPTS
|AHD_FAST_CDB_DELIVERY
959 | AHD_BUSFREEREV_BUG
;
960 ahd
->bugs
|= AHD_LQOOVERRUN_BUG
|AHD_EARLY_REQ_BUG
;
962 /* If the user requested the the SLOWCRC bit to be set. */
964 ahd
->features
|= AHD_AIC79XXB_SLOWCRC
;
967 * Some issues have been resolved in the 7901B.
969 if ((ahd
->features
& AHD_MULTI_FUNC
) != 0)
970 ahd
->bugs
|= AHD_INTCOLLISION_BUG
|AHD_ABORT_LQI_BUG
;
973 * IO Cell paramter setup.
975 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
976 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVB
);
977 AHD_SET_AMPLITUDE(ahd
, AHD_AMPLITUDE_DEF
);
980 * Set the PREQDIS bit for H2B which disables some workaround
981 * that doesn't work on regular PCI busses.
982 * XXX - Find out exactly what this does from the hardware
985 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);
986 ahd_pci_write_config(pci
, DEVCONFIG1
,
987 devconfig1
|PREQDIS
, /*bytes*/1);
988 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);