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 #include "aic79xx_pci.h"
56 static __inline
uint64_t
57 ahd_compose_id(u_int device
, u_int vendor
, u_int subdevice
, u_int subvendor
)
63 | ((uint64_t)vendor
<< 32)
64 | ((uint64_t)device
<< 48);
69 #define ID_AIC7902_PCI_REV_A4 0x3
70 #define ID_AIC7902_PCI_REV_B0 0x10
71 #define SUBID_HP 0x0E11
73 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
75 #define DEVID_9005_TYPE(id) ((id) & 0xF)
76 #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
77 #define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */
78 #define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */
79 #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
81 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
83 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
85 #define SUBID_9005_TYPE(id) ((id) & 0xF)
86 #define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */
87 #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
89 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
91 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
93 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
94 #define SUBID_9005_SEEPTYPE_NONE 0x0
95 #define SUBID_9005_SEEPTYPE_4K 0x1
97 static ahd_device_setup_t ahd_aic7901_setup
;
98 static ahd_device_setup_t ahd_aic7901A_setup
;
99 static ahd_device_setup_t ahd_aic7902_setup
;
100 static ahd_device_setup_t ahd_aic790X_setup
;
102 struct ahd_pci_identity ahd_pci_ident_table
[] =
104 /* aic7901 based controllers */
108 "Adaptec 29320A Ultra320 SCSI adapter",
114 "Adaptec 29320ALP Ultra320 SCSI adapter",
117 /* aic7902 based controllers */
121 "Adaptec 29320 Ultra320 SCSI adapter",
127 "Adaptec 29320B Ultra320 SCSI adapter",
133 "Adaptec 29320LP Ultra320 SCSI adapter",
139 "Adaptec 39320 Ultra320 SCSI adapter",
145 "Adaptec 39320 Ultra320 SCSI adapter",
151 "Adaptec 39320A Ultra320 SCSI adapter",
157 "Adaptec 39320D Ultra320 SCSI adapter",
163 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
169 "Adaptec 39320D Ultra320 SCSI adapter",
175 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
178 /* Generic chip probes for devices we don't know 'exactly' */
180 ID_AIC7901
& ID_9005_GENERIC_MASK
,
181 ID_9005_GENERIC_MASK
,
182 "Adaptec AIC7901 Ultra320 SCSI adapter",
186 ID_AIC7901A
& ID_DEV_VENDOR_MASK
,
188 "Adaptec AIC7901A Ultra320 SCSI adapter",
192 ID_AIC7902
& ID_9005_GENERIC_MASK
,
193 ID_9005_GENERIC_MASK
,
194 "Adaptec AIC7902 Ultra320 SCSI adapter",
199 const u_int ahd_num_pci_devs
= NUM_ELEMENTS(ahd_pci_ident_table
);
201 #define DEVCONFIG 0x40
202 #define PCIXINITPAT 0x0000E000ul
203 #define PCIXINIT_PCI33_66 0x0000E000ul
204 #define PCIXINIT_PCIX50_66 0x0000C000ul
205 #define PCIXINIT_PCIX66_100 0x0000A000ul
206 #define PCIXINIT_PCIX100_133 0x00008000ul
207 #define PCI_BUS_MODES_INDEX(devconfig) \
208 (((devconfig) & PCIXINITPAT) >> 13)
209 static const char *pci_bus_modes
[] =
211 "PCI bus mode unknown",
212 "PCI bus mode unknown",
213 "PCI bus mode unknown",
214 "PCI bus mode unknown",
221 #define TESTMODE 0x00000800ul
222 #define IRDY_RST 0x00000200ul
223 #define FRAME_RST 0x00000100ul
224 #define PCI64BIT 0x00000080ul
225 #define MRDCEN 0x00000040ul
226 #define ENDIANSEL 0x00000020ul
227 #define MIXQWENDIANEN 0x00000008ul
228 #define DACEN 0x00000004ul
229 #define STPWLEVEL 0x00000002ul
230 #define QWENDIANSEL 0x00000001ul
232 #define DEVCONFIG1 0x44
235 #define CSIZE_LATTIME 0x0c
236 #define CACHESIZE 0x000000fful
237 #define LATTIME 0x0000ff00ul
239 static int ahd_check_extport(struct ahd_softc
*ahd
);
240 static void ahd_configure_termination(struct ahd_softc
*ahd
,
241 u_int adapter_control
);
242 static void ahd_pci_split_intr(struct ahd_softc
*ahd
, u_int intstat
);
244 struct ahd_pci_identity
*
245 ahd_find_pci_device(ahd_dev_softc_t pci
)
252 struct ahd_pci_identity
*entry
;
255 vendor
= ahd_pci_read_config(pci
, PCIR_DEVVENDOR
, /*bytes*/2);
256 device
= ahd_pci_read_config(pci
, PCIR_DEVICE
, /*bytes*/2);
257 subvendor
= ahd_pci_read_config(pci
, PCIR_SUBVEND_0
, /*bytes*/2);
258 subdevice
= ahd_pci_read_config(pci
, PCIR_SUBDEV_0
, /*bytes*/2);
259 full_id
= ahd_compose_id(device
,
265 * Controllers, mask out the IROC/HostRAID bit
268 full_id
&= ID_ALL_IROC_MASK
;
270 for (i
= 0; i
< ahd_num_pci_devs
; i
++) {
271 entry
= &ahd_pci_ident_table
[i
];
272 if (entry
->full_id
== (full_id
& entry
->id_mask
)) {
273 /* Honor exclusion entries. */
274 if (entry
->name
== NULL
)
283 ahd_pci_config(struct ahd_softc
*ahd
, struct ahd_pci_identity
*entry
)
285 struct scb_data
*shared_scb_data
;
291 shared_scb_data
= NULL
;
292 ahd
->description
= entry
->name
;
294 * Record if this is an HP board.
296 subvendor
= ahd_pci_read_config(ahd
->dev_softc
,
297 PCIR_SUBVEND_0
, /*bytes*/2);
298 if (subvendor
== SUBID_HP
)
299 ahd
->flags
|= AHD_HP_BOARD
;
301 error
= entry
->setup(ahd
);
305 devconfig
= ahd_pci_read_config(ahd
->dev_softc
, DEVCONFIG
, /*bytes*/4);
306 if ((devconfig
& PCIXINITPAT
) == PCIXINIT_PCI33_66
) {
307 ahd
->chip
|= AHD_PCI
;
308 /* Disable PCIX workarounds when running in PCI mode. */
309 ahd
->bugs
&= ~AHD_PCIX_BUG_MASK
;
311 ahd
->chip
|= AHD_PCIX
;
313 ahd
->bus_description
= pci_bus_modes
[PCI_BUS_MODES_INDEX(devconfig
)];
315 ahd_power_state_change(ahd
, AHD_POWER_STATE_D0
);
317 error
= ahd_pci_map_registers(ahd
);
322 * If we need to support high memory, enable dual
323 * address cycles. This bit must be set to enable
324 * high address bit generation even if we are on a
325 * 64bit bus (PCI64BIT set in devconfig).
327 if ((ahd
->flags
& (AHD_39BIT_ADDRESSING
|AHD_64BIT_ADDRESSING
)) != 0) {
331 printf("%s: Enabling 39Bit Addressing\n",
333 devconfig
= ahd_pci_read_config(ahd
->dev_softc
,
334 DEVCONFIG
, /*bytes*/4);
336 ahd_pci_write_config(ahd
->dev_softc
, DEVCONFIG
,
337 devconfig
, /*bytes*/4);
340 /* Ensure busmastering is enabled */
341 command
= ahd_pci_read_config(ahd
->dev_softc
, PCIR_COMMAND
, /*bytes*/2);
342 command
|= PCIM_CMD_BUSMASTEREN
;
343 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
, command
, /*bytes*/2);
345 error
= ahd_softc_init(ahd
);
349 ahd
->bus_intr
= ahd_pci_intr
;
351 error
= ahd_reset(ahd
, /*reinit*/FALSE
);
356 ahd_pci_read_config(ahd
->dev_softc
, CSIZE_LATTIME
,
357 /*bytes*/1) & CACHESIZE
;
358 ahd
->pci_cachesize
*= 4;
360 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
361 /* See if we have a SEEPROM and perform auto-term */
362 error
= ahd_check_extport(ahd
);
366 /* Core initialization */
367 error
= ahd_init(ahd
);
372 * Allow interrupts now that we are completely setup.
374 error
= ahd_pci_map_int(ahd
);
381 * Perform some simple tests that should catch situations where
382 * our registers are invalidly mapped.
385 ahd_pci_test_register_access(struct ahd_softc
*ahd
)
396 * Enable PCI error interrupt status, but suppress NMIs
397 * generated by SERR raised due to target aborts.
399 cmd
= ahd_pci_read_config(ahd
->dev_softc
, PCIR_COMMAND
, /*bytes*/2);
400 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
,
401 cmd
& ~PCIM_CMD_SERRESPEN
, /*bytes*/2);
404 * First a simple test to see if any
405 * registers can be read. Reading
406 * HCNTRL has no side effects and has
407 * at least one bit that is guaranteed to
408 * be zero so it is a good register to
411 hcntrl
= ahd_inb(ahd
, HCNTRL
);
416 * Next create a situation where write combining
417 * or read prefetching could be initiated by the
418 * CPU or host bridge. Our device does not support
419 * either, so look for data corruption and/or flaged
420 * PCI errors. First pause without causing another
424 ahd_outb(ahd
, HCNTRL
, hcntrl
|PAUSE
);
425 while (ahd_is_paused(ahd
) == 0)
428 /* Clear any PCI errors that occurred before our driver attached. */
429 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
430 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
431 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
432 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
433 PCIR_STATUS
+ 1, /*bytes*/1);
434 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
435 pci_status1
, /*bytes*/1);
436 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
437 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
439 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
);
440 ahd_outl(ahd
, SRAM_BASE
, 0x5aa555aa);
441 if (ahd_inl(ahd
, SRAM_BASE
) != 0x5aa555aa)
444 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
447 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
448 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
449 if ((targpcistat
& STA
) != 0)
456 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
458 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
459 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
461 /* Silently clear any latched errors. */
462 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
463 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
464 PCIR_STATUS
+ 1, /*bytes*/1);
465 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
466 pci_status1
, /*bytes*/1);
467 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
469 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
|FAILDIS
);
470 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
, cmd
, /*bytes*/2);
475 * Check the external port logic for a serial eeprom
476 * and termination/cable detection contrls.
479 ahd_check_extport(struct ahd_softc
*ahd
)
481 struct vpd_config vpd
;
482 struct seeprom_config
*sc
;
483 u_int adapter_control
;
487 sc
= ahd
->seep_config
;
488 have_seeprom
= ahd_acquire_seeprom(ahd
);
493 * Fetch VPD for this function and parse it.
496 printf("%s: Reading VPD from SEEPROM...",
499 /* Address is always in units of 16bit words */
500 start_addr
= ((2 * sizeof(*sc
))
501 + (sizeof(vpd
) * (ahd
->channel
- 'A'))) / 2;
503 error
= ahd_read_seeprom(ahd
, (uint16_t *)&vpd
,
504 start_addr
, sizeof(vpd
)/2,
507 error
= ahd_parse_vpddata(ahd
, &vpd
);
509 printf("%s: VPD parsing %s\n",
511 error
== 0 ? "successful" : "failed");
514 printf("%s: Reading SEEPROM...", ahd_name(ahd
));
516 /* Address is always in units of 16bit words */
517 start_addr
= (sizeof(*sc
) / 2) * (ahd
->channel
- 'A');
519 error
= ahd_read_seeprom(ahd
, (uint16_t *)sc
,
520 start_addr
, sizeof(*sc
)/2,
521 /*bytestream*/FALSE
);
524 printf("Unable to read SEEPROM\n");
527 have_seeprom
= ahd_verify_cksum(sc
);
530 if (have_seeprom
== 0)
531 printf ("checksum error\n");
536 ahd_release_seeprom(ahd
);
543 * Pull scratch ram settings and treat them as
544 * if they are the contents of an seeprom if
545 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
546 * in SCB 0xFF. We manually compose the data as 16bit
547 * values to avoid endian issues.
549 ahd_set_scbptr(ahd
, 0xFF);
550 nvram_scb
= ahd_inb_scbram(ahd
, SCB_BASE
+ NVRAM_SCB_OFFSET
);
551 if (nvram_scb
!= 0xFF
552 && ((ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
553 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'D'
554 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
555 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'T')
556 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'B'
557 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'I'
558 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'O'
559 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'S')
560 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
561 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'S'
562 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
563 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'I'))) {
567 ahd_set_scbptr(ahd
, nvram_scb
);
568 sc_data
= (uint16_t *)sc
;
569 for (i
= 0; i
< 64; i
+= 2)
570 *sc_data
++ = ahd_inw_scbram(ahd
, SCB_BASE
+i
);
571 have_seeprom
= ahd_verify_cksum(sc
);
573 ahd
->flags
|= AHD_SCB_CONFIG_USED
;
578 if (have_seeprom
!= 0
579 && (ahd_debug
& AHD_DUMP_SEEPROM
) != 0) {
583 printf("%s: Seeprom Contents:", ahd_name(ahd
));
584 sc_data
= (uint16_t *)sc
;
585 for (i
= 0; i
< (sizeof(*sc
)); i
+= 2)
586 printf("\n\t0x%.4x", sc_data
[i
]);
593 printf("%s: No SEEPROM available.\n", ahd_name(ahd
));
594 ahd
->flags
|= AHD_USEDEFAULTS
;
595 error
= ahd_default_config(ahd
);
596 adapter_control
= CFAUTOTERM
|CFSEAUTOTERM
;
597 free(ahd
->seep_config
, M_DEVBUF
);
598 ahd
->seep_config
= NULL
;
600 error
= ahd_parse_cfgdata(ahd
, sc
);
601 adapter_control
= sc
->adapter_control
;
606 ahd_configure_termination(ahd
, adapter_control
);
612 ahd_configure_termination(struct ahd_softc
*ahd
, u_int adapter_control
)
619 devconfig
= ahd_pci_read_config(ahd
->dev_softc
, DEVCONFIG
, /*bytes*/4);
620 devconfig
&= ~STPWLEVEL
;
621 if ((ahd
->flags
& AHD_STPWLEVEL_A
) != 0)
622 devconfig
|= STPWLEVEL
;
624 printf("%s: STPWLEVEL is %s\n",
625 ahd_name(ahd
), (devconfig
& STPWLEVEL
) ? "on" : "off");
626 ahd_pci_write_config(ahd
->dev_softc
, DEVCONFIG
, devconfig
, /*bytes*/4);
628 /* Make sure current sensing is off. */
629 if ((ahd
->flags
& AHD_CURRENT_SENSING
) != 0) {
630 (void)ahd_write_flexport(ahd
, FLXADDR_ROMSTAT_CURSENSECTL
, 0);
634 * Read to sense. Write to set.
636 error
= ahd_read_flexport(ahd
, FLXADDR_TERMCTL
, &termctl
);
637 if ((adapter_control
& CFAUTOTERM
) == 0) {
639 printf("%s: Manual Primary Termination\n",
641 termctl
&= ~(FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
);
642 if ((adapter_control
& CFSTERM
) != 0)
643 termctl
|= FLX_TERMCTL_ENPRILOW
;
644 if ((adapter_control
& CFWSTERM
) != 0)
645 termctl
|= FLX_TERMCTL_ENPRIHIGH
;
646 } else if (error
!= 0) {
647 printf("%s: Primary Auto-Term Sensing failed! "
648 "Using Defaults.\n", ahd_name(ahd
));
649 termctl
= FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
;
652 if ((adapter_control
& CFSEAUTOTERM
) == 0) {
654 printf("%s: Manual Secondary Termination\n",
656 termctl
&= ~(FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
);
657 if ((adapter_control
& CFSELOWTERM
) != 0)
658 termctl
|= FLX_TERMCTL_ENSECLOW
;
659 if ((adapter_control
& CFSEHIGHTERM
) != 0)
660 termctl
|= FLX_TERMCTL_ENSECHIGH
;
661 } else if (error
!= 0) {
662 printf("%s: Secondary Auto-Term Sensing failed! "
663 "Using Defaults.\n", ahd_name(ahd
));
664 termctl
|= FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
;
668 * Now set the termination based on what we found.
670 sxfrctl1
= ahd_inb(ahd
, SXFRCTL1
) & ~STPWEN
;
671 if ((termctl
& FLX_TERMCTL_ENPRILOW
) != 0) {
672 ahd
->flags
|= AHD_TERM_ENB_A
;
675 /* Must set the latch once in order to be effective. */
676 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
|STPWEN
);
677 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
);
679 error
= ahd_write_flexport(ahd
, FLXADDR_TERMCTL
, termctl
);
681 printf("%s: Unable to set termination settings!\n",
683 } else if (bootverbose
) {
684 printf("%s: Primary High byte termination %sabled\n",
686 (termctl
& FLX_TERMCTL_ENPRIHIGH
) ? "En" : "Dis");
688 printf("%s: Primary Low byte termination %sabled\n",
690 (termctl
& FLX_TERMCTL_ENPRILOW
) ? "En" : "Dis");
692 printf("%s: Secondary High byte termination %sabled\n",
694 (termctl
& FLX_TERMCTL_ENSECHIGH
) ? "En" : "Dis");
696 printf("%s: Secondary Low byte termination %sabled\n",
698 (termctl
& FLX_TERMCTL_ENSECLOW
) ? "En" : "Dis");
710 static const char *split_status_source
[] =
718 static const char *pci_status_source
[] =
730 static const char *split_status_strings
[] =
732 "%s: Received split response in %s.\n",
733 "%s: Received split completion error message in %s\n",
734 "%s: Receive overrun in %s\n",
735 "%s: Count not complete in %s\n",
736 "%s: Split completion data bucket in %s\n",
737 "%s: Split completion address error in %s\n",
738 "%s: Split completion byte count error in %s\n",
739 "%s: Signaled Target-abort to early terminate a split in %s\n"
742 static const char *pci_status_strings
[] =
744 "%s: Data Parity Error has been reported via PERR# in %s\n",
745 "%s: Target initial wait state error in %s\n",
746 "%s: Split completion read data parity error in %s\n",
747 "%s: Split completion address attribute parity error in %s\n",
748 "%s: Received a Target Abort in %s\n",
749 "%s: Received a Master Abort in %s\n",
750 "%s: Signal System Error Detected in %s\n",
751 "%s: Address or Write Phase Parity Error Detected in %s.\n"
755 ahd_pci_intr(struct ahd_softc
*ahd
)
757 uint8_t pci_status
[8];
758 ahd_mode_state saved_modes
;
764 intstat
= ahd_inb(ahd
, INTSTAT
);
766 if ((intstat
& SPLTINT
) != 0)
767 ahd_pci_split_intr(ahd
, intstat
);
769 if ((intstat
& PCIINT
) == 0)
772 printf("%s: PCI error Interrupt\n", ahd_name(ahd
));
773 saved_modes
= ahd_save_modes(ahd
);
774 ahd_dump_card_state(ahd
);
775 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
776 for (i
= 0, reg
= DF0PCISTAT
; i
< 8; i
++, reg
++) {
780 pci_status
[i
] = ahd_inb(ahd
, reg
);
781 /* Clear latched errors. So our interrupt deasserts. */
782 ahd_outb(ahd
, reg
, pci_status
[i
]);
785 for (i
= 0; i
< 8; i
++) {
791 for (bit
= 0; bit
< 8; bit
++) {
793 if ((pci_status
[i
] & (0x1 << bit
)) != 0) {
794 static const char *s
;
796 s
= pci_status_strings
[bit
];
797 if (i
== 7/*TARG*/ && bit
== 3)
798 s
= "%s: Signaled Target Abort\n";
799 printf(s
, ahd_name(ahd
), pci_status_source
[i
]);
803 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
804 PCIR_STATUS
+ 1, /*bytes*/1);
805 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
806 pci_status1
, /*bytes*/1);
807 ahd_restore_modes(ahd
, saved_modes
);
808 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
813 ahd_pci_split_intr(struct ahd_softc
*ahd
, u_int intstat
)
815 uint8_t split_status
[4];
816 uint8_t split_status1
[4];
817 uint8_t sg_split_status
[2];
818 uint8_t sg_split_status1
[2];
819 ahd_mode_state saved_modes
;
821 uint16_t pcix_status
;
824 * Check for splits in all modes. Modes 0 and 1
825 * additionally have SG engine splits to look at.
827 pcix_status
= ahd_pci_read_config(ahd
->dev_softc
, PCIXR_STATUS
,
829 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
830 ahd_name(ahd
), pcix_status
);
831 saved_modes
= ahd_save_modes(ahd
);
832 for (i
= 0; i
< 4; i
++) {
833 ahd_set_modes(ahd
, i
, i
);
835 split_status
[i
] = ahd_inb(ahd
, DCHSPLTSTAT0
);
836 split_status1
[i
] = ahd_inb(ahd
, DCHSPLTSTAT1
);
837 /* Clear latched errors. So our interrupt deasserts. */
838 ahd_outb(ahd
, DCHSPLTSTAT0
, split_status
[i
]);
839 ahd_outb(ahd
, DCHSPLTSTAT1
, split_status1
[i
]);
842 sg_split_status
[i
] = ahd_inb(ahd
, SGSPLTSTAT0
);
843 sg_split_status1
[i
] = ahd_inb(ahd
, SGSPLTSTAT1
);
844 /* Clear latched errors. So our interrupt deasserts. */
845 ahd_outb(ahd
, SGSPLTSTAT0
, sg_split_status
[i
]);
846 ahd_outb(ahd
, SGSPLTSTAT1
, sg_split_status1
[i
]);
849 for (i
= 0; i
< 4; i
++) {
852 for (bit
= 0; bit
< 8; bit
++) {
854 if ((split_status
[i
] & (0x1 << bit
)) != 0) {
855 static const char *s
;
857 s
= split_status_strings
[bit
];
858 printf(s
, ahd_name(ahd
),
859 split_status_source
[i
]);
865 if ((sg_split_status
[i
] & (0x1 << bit
)) != 0) {
866 static const char *s
;
868 s
= split_status_strings
[bit
];
869 printf(s
, ahd_name(ahd
), "SG");
874 * Clear PCI-X status bits.
876 ahd_pci_write_config(ahd
->dev_softc
, PCIXR_STATUS
,
877 pcix_status
, /*bytes*/2);
878 ahd_outb(ahd
, CLRINT
, CLRSPLTINT
);
879 ahd_restore_modes(ahd
, saved_modes
);
883 ahd_aic7901_setup(struct ahd_softc
*ahd
)
886 ahd
->chip
= AHD_AIC7901
;
887 ahd
->features
= AHD_AIC7901_FE
;
888 return (ahd_aic790X_setup(ahd
));
892 ahd_aic7901A_setup(struct ahd_softc
*ahd
)
895 ahd
->chip
= AHD_AIC7901A
;
896 ahd
->features
= AHD_AIC7901A_FE
;
897 return (ahd_aic790X_setup(ahd
));
901 ahd_aic7902_setup(struct ahd_softc
*ahd
)
903 ahd
->chip
= AHD_AIC7902
;
904 ahd
->features
= AHD_AIC7902_FE
;
905 return (ahd_aic790X_setup(ahd
));
909 ahd_aic790X_setup(struct ahd_softc
*ahd
)
914 pci
= ahd
->dev_softc
;
915 rev
= ahd_pci_read_config(pci
, PCIR_REVID
, /*bytes*/1);
916 if (rev
< ID_AIC7902_PCI_REV_A4
) {
917 printf("%s: Unable to attach to unsupported chip revision %d\n",
919 ahd_pci_write_config(pci
, PCIR_COMMAND
, 0, /*bytes*/2);
922 ahd
->channel
= ahd_get_pci_function(pci
) + 'A';
923 if (rev
< ID_AIC7902_PCI_REV_B0
) {
925 * Enable A series workarounds.
927 ahd
->bugs
|= AHD_SENT_SCB_UPDATE_BUG
|AHD_ABORT_LQI_BUG
928 | AHD_PKT_BITBUCKET_BUG
|AHD_LONG_SETIMO_BUG
929 | AHD_NLQICRC_DELAYED_BUG
|AHD_SCSIRST_BUG
930 | AHD_LQO_ATNO_BUG
|AHD_AUTOFLUSH_BUG
931 | AHD_CLRLQO_AUTOCLR_BUG
|AHD_PCIX_MMAPIO_BUG
932 | AHD_PCIX_CHIPRST_BUG
|AHD_PCIX_SCBRAM_RD_BUG
933 | AHD_PKTIZED_STATUS_BUG
|AHD_PKT_LUN_BUG
934 | AHD_MDFF_WSCBPTR_BUG
|AHD_REG_SLOW_SETTLE_BUG
935 | AHD_SET_MODE_BUG
|AHD_BUSFREEREV_BUG
936 | AHD_NONPACKFIFO_BUG
|AHD_PACED_NEGTABLE_BUG
940 * IO Cell paramter setup.
942 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
944 if ((ahd
->flags
& AHD_HP_BOARD
) == 0)
945 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVA
);
949 ahd
->features
|= AHD_RTI
|AHD_NEW_IOCELL_OPTS
950 | AHD_NEW_DFCNTRL_OPTS
|AHD_FAST_CDB_DELIVERY
;
951 ahd
->bugs
|= AHD_LQOOVERRUN_BUG
|AHD_EARLY_REQ_BUG
;
954 * Some issues have been resolved in the 7901B.
956 if ((ahd
->features
& AHD_MULTI_FUNC
) != 0)
957 ahd
->bugs
|= AHD_INTCOLLISION_BUG
|AHD_ABORT_LQI_BUG
;
960 * IO Cell paramter setup.
962 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
963 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVB
);
964 AHD_SET_AMPLITUDE(ahd
, AHD_AMPLITUDE_DEF
);
967 * Set the PREQDIS bit for H2B which disables some workaround
968 * that doesn't work on regular PCI busses.
969 * XXX - Find out exactly what this does from the hardware
972 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);
973 ahd_pci_write_config(pci
, DEVCONFIG1
,
974 devconfig1
|PREQDIS
, /*bytes*/1);
975 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);