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
;
292 shared_scb_data
= NULL
;
293 ahd
->description
= entry
->name
;
295 * Record if this is an HP board.
297 subvendor
= ahd_pci_read_config(ahd
->dev_softc
,
298 PCIR_SUBVEND_0
, /*bytes*/2);
299 if (subvendor
== SUBID_HP
)
300 ahd
->flags
|= AHD_HP_BOARD
;
302 error
= entry
->setup(ahd
);
306 devconfig
= ahd_pci_read_config(ahd
->dev_softc
, DEVCONFIG
, /*bytes*/4);
307 if ((devconfig
& PCIXINITPAT
) == PCIXINIT_PCI33_66
) {
308 ahd
->chip
|= AHD_PCI
;
309 /* Disable PCIX workarounds when running in PCI mode. */
310 ahd
->bugs
&= ~AHD_PCIX_BUG_MASK
;
312 ahd
->chip
|= AHD_PCIX
;
314 ahd
->bus_description
= pci_bus_modes
[PCI_BUS_MODES_INDEX(devconfig
)];
316 ahd_power_state_change(ahd
, AHD_POWER_STATE_D0
);
318 error
= ahd_pci_map_registers(ahd
);
323 * If we need to support high memory, enable dual
324 * address cycles. This bit must be set to enable
325 * high address bit generation even if we are on a
326 * 64bit bus (PCI64BIT set in devconfig).
328 if ((ahd
->flags
& (AHD_39BIT_ADDRESSING
|AHD_64BIT_ADDRESSING
)) != 0) {
332 printf("%s: Enabling 39Bit Addressing\n",
334 devconfig
= ahd_pci_read_config(ahd
->dev_softc
,
335 DEVCONFIG
, /*bytes*/4);
337 ahd_pci_write_config(ahd
->dev_softc
, DEVCONFIG
,
338 devconfig
, /*bytes*/4);
341 /* Ensure busmastering is enabled */
342 command
= ahd_pci_read_config(ahd
->dev_softc
, PCIR_COMMAND
, /*bytes*/2);
343 command
|= PCIM_CMD_BUSMASTEREN
;
344 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
, command
, /*bytes*/2);
346 error
= ahd_softc_init(ahd
);
350 ahd
->bus_intr
= ahd_pci_intr
;
352 error
= ahd_reset(ahd
, /*reinit*/FALSE
);
357 ahd_pci_read_config(ahd
->dev_softc
, CSIZE_LATTIME
,
358 /*bytes*/1) & CACHESIZE
;
359 ahd
->pci_cachesize
*= 4;
361 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
362 /* See if we have a SEEPROM and perform auto-term */
363 error
= ahd_check_extport(ahd
);
367 /* Core initialization */
368 error
= ahd_init(ahd
);
373 * Allow interrupts now that we are completely setup.
375 error
= ahd_pci_map_int(ahd
);
381 * Link this softc in with all other ahd instances.
383 ahd_softc_insert(ahd
);
389 * Perform some simple tests that should catch situations where
390 * our registers are invalidly mapped.
393 ahd_pci_test_register_access(struct ahd_softc
*ahd
)
404 * Enable PCI error interrupt status, but suppress NMIs
405 * generated by SERR raised due to target aborts.
407 cmd
= ahd_pci_read_config(ahd
->dev_softc
, PCIR_COMMAND
, /*bytes*/2);
408 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
,
409 cmd
& ~PCIM_CMD_SERRESPEN
, /*bytes*/2);
412 * First a simple test to see if any
413 * registers can be read. Reading
414 * HCNTRL has no side effects and has
415 * at least one bit that is guaranteed to
416 * be zero so it is a good register to
419 hcntrl
= ahd_inb(ahd
, HCNTRL
);
424 * Next create a situation where write combining
425 * or read prefetching could be initiated by the
426 * CPU or host bridge. Our device does not support
427 * either, so look for data corruption and/or flaged
428 * PCI errors. First pause without causing another
432 ahd_outb(ahd
, HCNTRL
, hcntrl
|PAUSE
);
433 while (ahd_is_paused(ahd
) == 0)
436 /* Clear any PCI errors that occurred before our driver attached. */
437 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
438 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
439 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
440 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
441 PCIR_STATUS
+ 1, /*bytes*/1);
442 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
443 pci_status1
, /*bytes*/1);
444 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
445 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
447 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
);
448 ahd_outl(ahd
, SRAM_BASE
, 0x5aa555aa);
449 if (ahd_inl(ahd
, SRAM_BASE
) != 0x5aa555aa)
452 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
455 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
456 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
457 if ((targpcistat
& STA
) != 0)
464 if ((ahd_inb(ahd
, INTSTAT
) & PCIINT
) != 0) {
466 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
467 targpcistat
= ahd_inb(ahd
, TARGPCISTAT
);
469 /* Silently clear any latched errors. */
470 ahd_outb(ahd
, TARGPCISTAT
, targpcistat
);
471 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
472 PCIR_STATUS
+ 1, /*bytes*/1);
473 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
474 pci_status1
, /*bytes*/1);
475 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
477 ahd_outb(ahd
, SEQCTL0
, PERRORDIS
|FAILDIS
);
478 ahd_pci_write_config(ahd
->dev_softc
, PCIR_COMMAND
, cmd
, /*bytes*/2);
483 * Check the external port logic for a serial eeprom
484 * and termination/cable detection contrls.
487 ahd_check_extport(struct ahd_softc
*ahd
)
489 struct vpd_config vpd
;
490 struct seeprom_config
*sc
;
491 u_int adapter_control
;
495 sc
= ahd
->seep_config
;
496 have_seeprom
= ahd_acquire_seeprom(ahd
);
501 * Fetch VPD for this function and parse it.
504 printf("%s: Reading VPD from SEEPROM...",
507 /* Address is always in units of 16bit words */
508 start_addr
= ((2 * sizeof(*sc
))
509 + (sizeof(vpd
) * (ahd
->channel
- 'A'))) / 2;
511 error
= ahd_read_seeprom(ahd
, (uint16_t *)&vpd
,
512 start_addr
, sizeof(vpd
)/2,
515 error
= ahd_parse_vpddata(ahd
, &vpd
);
517 printf("%s: VPD parsing %s\n",
519 error
== 0 ? "successful" : "failed");
522 printf("%s: Reading SEEPROM...", ahd_name(ahd
));
524 /* Address is always in units of 16bit words */
525 start_addr
= (sizeof(*sc
) / 2) * (ahd
->channel
- 'A');
527 error
= ahd_read_seeprom(ahd
, (uint16_t *)sc
,
528 start_addr
, sizeof(*sc
)/2,
529 /*bytestream*/FALSE
);
532 printf("Unable to read SEEPROM\n");
535 have_seeprom
= ahd_verify_cksum(sc
);
538 if (have_seeprom
== 0)
539 printf ("checksum error\n");
544 ahd_release_seeprom(ahd
);
551 * Pull scratch ram settings and treat them as
552 * if they are the contents of an seeprom if
553 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
554 * in SCB 0xFF. We manually compose the data as 16bit
555 * values to avoid endian issues.
557 ahd_set_scbptr(ahd
, 0xFF);
558 nvram_scb
= ahd_inb_scbram(ahd
, SCB_BASE
+ NVRAM_SCB_OFFSET
);
559 if (nvram_scb
!= 0xFF
560 && ((ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
561 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'D'
562 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
563 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'T')
564 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'B'
565 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'I'
566 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'O'
567 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'S')
568 || (ahd_inb_scbram(ahd
, SCB_BASE
+ 0) == 'A'
569 && ahd_inb_scbram(ahd
, SCB_BASE
+ 1) == 'S'
570 && ahd_inb_scbram(ahd
, SCB_BASE
+ 2) == 'P'
571 && ahd_inb_scbram(ahd
, SCB_BASE
+ 3) == 'I'))) {
575 ahd_set_scbptr(ahd
, nvram_scb
);
576 sc_data
= (uint16_t *)sc
;
577 for (i
= 0; i
< 64; i
+= 2)
578 *sc_data
++ = ahd_inw_scbram(ahd
, SCB_BASE
+i
);
579 have_seeprom
= ahd_verify_cksum(sc
);
581 ahd
->flags
|= AHD_SCB_CONFIG_USED
;
586 if (have_seeprom
!= 0
587 && (ahd_debug
& AHD_DUMP_SEEPROM
) != 0) {
591 printf("%s: Seeprom Contents:", ahd_name(ahd
));
592 sc_data
= (uint16_t *)sc
;
593 for (i
= 0; i
< (sizeof(*sc
)); i
+= 2)
594 printf("\n\t0x%.4x", sc_data
[i
]);
601 printf("%s: No SEEPROM available.\n", ahd_name(ahd
));
602 ahd
->flags
|= AHD_USEDEFAULTS
;
603 error
= ahd_default_config(ahd
);
604 adapter_control
= CFAUTOTERM
|CFSEAUTOTERM
;
605 free(ahd
->seep_config
, M_DEVBUF
);
606 ahd
->seep_config
= NULL
;
608 error
= ahd_parse_cfgdata(ahd
, sc
);
609 adapter_control
= sc
->adapter_control
;
614 ahd_configure_termination(ahd
, adapter_control
);
620 ahd_configure_termination(struct ahd_softc
*ahd
, u_int adapter_control
)
627 devconfig
= ahd_pci_read_config(ahd
->dev_softc
, DEVCONFIG
, /*bytes*/4);
628 devconfig
&= ~STPWLEVEL
;
629 if ((ahd
->flags
& AHD_STPWLEVEL_A
) != 0)
630 devconfig
|= STPWLEVEL
;
632 printf("%s: STPWLEVEL is %s\n",
633 ahd_name(ahd
), (devconfig
& STPWLEVEL
) ? "on" : "off");
634 ahd_pci_write_config(ahd
->dev_softc
, DEVCONFIG
, devconfig
, /*bytes*/4);
636 /* Make sure current sensing is off. */
637 if ((ahd
->flags
& AHD_CURRENT_SENSING
) != 0) {
638 (void)ahd_write_flexport(ahd
, FLXADDR_ROMSTAT_CURSENSECTL
, 0);
642 * Read to sense. Write to set.
644 error
= ahd_read_flexport(ahd
, FLXADDR_TERMCTL
, &termctl
);
645 if ((adapter_control
& CFAUTOTERM
) == 0) {
647 printf("%s: Manual Primary Termination\n",
649 termctl
&= ~(FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
);
650 if ((adapter_control
& CFSTERM
) != 0)
651 termctl
|= FLX_TERMCTL_ENPRILOW
;
652 if ((adapter_control
& CFWSTERM
) != 0)
653 termctl
|= FLX_TERMCTL_ENPRIHIGH
;
654 } else if (error
!= 0) {
655 printf("%s: Primary Auto-Term Sensing failed! "
656 "Using Defaults.\n", ahd_name(ahd
));
657 termctl
= FLX_TERMCTL_ENPRILOW
|FLX_TERMCTL_ENPRIHIGH
;
660 if ((adapter_control
& CFSEAUTOTERM
) == 0) {
662 printf("%s: Manual Secondary Termination\n",
664 termctl
&= ~(FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
);
665 if ((adapter_control
& CFSELOWTERM
) != 0)
666 termctl
|= FLX_TERMCTL_ENSECLOW
;
667 if ((adapter_control
& CFSEHIGHTERM
) != 0)
668 termctl
|= FLX_TERMCTL_ENSECHIGH
;
669 } else if (error
!= 0) {
670 printf("%s: Secondary Auto-Term Sensing failed! "
671 "Using Defaults.\n", ahd_name(ahd
));
672 termctl
|= FLX_TERMCTL_ENSECLOW
|FLX_TERMCTL_ENSECHIGH
;
676 * Now set the termination based on what we found.
678 sxfrctl1
= ahd_inb(ahd
, SXFRCTL1
) & ~STPWEN
;
679 if ((termctl
& FLX_TERMCTL_ENPRILOW
) != 0) {
680 ahd
->flags
|= AHD_TERM_ENB_A
;
683 /* Must set the latch once in order to be effective. */
684 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
|STPWEN
);
685 ahd_outb(ahd
, SXFRCTL1
, sxfrctl1
);
687 error
= ahd_write_flexport(ahd
, FLXADDR_TERMCTL
, termctl
);
689 printf("%s: Unable to set termination settings!\n",
691 } else if (bootverbose
) {
692 printf("%s: Primary High byte termination %sabled\n",
694 (termctl
& FLX_TERMCTL_ENPRIHIGH
) ? "En" : "Dis");
696 printf("%s: Primary Low byte termination %sabled\n",
698 (termctl
& FLX_TERMCTL_ENPRILOW
) ? "En" : "Dis");
700 printf("%s: Secondary High byte termination %sabled\n",
702 (termctl
& FLX_TERMCTL_ENSECHIGH
) ? "En" : "Dis");
704 printf("%s: Secondary Low byte termination %sabled\n",
706 (termctl
& FLX_TERMCTL_ENSECLOW
) ? "En" : "Dis");
718 static const char *split_status_source
[] =
726 static const char *pci_status_source
[] =
738 static const char *split_status_strings
[] =
740 "%s: Received split response in %s.\n",
741 "%s: Received split completion error message in %s\n",
742 "%s: Receive overrun in %s\n",
743 "%s: Count not complete in %s\n",
744 "%s: Split completion data bucket in %s\n",
745 "%s: Split completion address error in %s\n",
746 "%s: Split completion byte count error in %s\n",
747 "%s: Signaled Target-abort to early terminate a split in %s\n"
750 static const char *pci_status_strings
[] =
752 "%s: Data Parity Error has been reported via PERR# in %s\n",
753 "%s: Target initial wait state error in %s\n",
754 "%s: Split completion read data parity error in %s\n",
755 "%s: Split completion address attribute parity error in %s\n",
756 "%s: Received a Target Abort in %s\n",
757 "%s: Received a Master Abort in %s\n",
758 "%s: Signal System Error Detected in %s\n",
759 "%s: Address or Write Phase Parity Error Detected in %s.\n"
763 ahd_pci_intr(struct ahd_softc
*ahd
)
765 uint8_t pci_status
[8];
766 ahd_mode_state saved_modes
;
772 intstat
= ahd_inb(ahd
, INTSTAT
);
774 if ((intstat
& SPLTINT
) != 0)
775 ahd_pci_split_intr(ahd
, intstat
);
777 if ((intstat
& PCIINT
) == 0)
780 printf("%s: PCI error Interrupt\n", ahd_name(ahd
));
781 saved_modes
= ahd_save_modes(ahd
);
782 ahd_dump_card_state(ahd
);
783 ahd_set_modes(ahd
, AHD_MODE_CFG
, AHD_MODE_CFG
);
784 for (i
= 0, reg
= DF0PCISTAT
; i
< 8; i
++, reg
++) {
788 pci_status
[i
] = ahd_inb(ahd
, reg
);
789 /* Clear latched errors. So our interrupt deasserts. */
790 ahd_outb(ahd
, reg
, pci_status
[i
]);
793 for (i
= 0; i
< 8; i
++) {
799 for (bit
= 0; bit
< 8; bit
++) {
801 if ((pci_status
[i
] & (0x1 << bit
)) != 0) {
802 static const char *s
;
804 s
= pci_status_strings
[bit
];
805 if (i
== 7/*TARG*/ && bit
== 3)
806 s
= "%s: Signaled Target Abort\n";
807 printf(s
, ahd_name(ahd
), pci_status_source
[i
]);
811 pci_status1
= ahd_pci_read_config(ahd
->dev_softc
,
812 PCIR_STATUS
+ 1, /*bytes*/1);
813 ahd_pci_write_config(ahd
->dev_softc
, PCIR_STATUS
+ 1,
814 pci_status1
, /*bytes*/1);
815 ahd_restore_modes(ahd
, saved_modes
);
816 ahd_outb(ahd
, CLRINT
, CLRPCIINT
);
821 ahd_pci_split_intr(struct ahd_softc
*ahd
, u_int intstat
)
823 uint8_t split_status
[4];
824 uint8_t split_status1
[4];
825 uint8_t sg_split_status
[2];
826 uint8_t sg_split_status1
[2];
827 ahd_mode_state saved_modes
;
829 uint16_t pcix_status
;
832 * Check for splits in all modes. Modes 0 and 1
833 * additionally have SG engine splits to look at.
835 pcix_status
= ahd_pci_read_config(ahd
->dev_softc
, PCIXR_STATUS
,
837 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
838 ahd_name(ahd
), pcix_status
);
839 saved_modes
= ahd_save_modes(ahd
);
840 for (i
= 0; i
< 4; i
++) {
841 ahd_set_modes(ahd
, i
, i
);
843 split_status
[i
] = ahd_inb(ahd
, DCHSPLTSTAT0
);
844 split_status1
[i
] = ahd_inb(ahd
, DCHSPLTSTAT1
);
845 /* Clear latched errors. So our interrupt deasserts. */
846 ahd_outb(ahd
, DCHSPLTSTAT0
, split_status
[i
]);
847 ahd_outb(ahd
, DCHSPLTSTAT1
, split_status1
[i
]);
850 sg_split_status
[i
] = ahd_inb(ahd
, SGSPLTSTAT0
);
851 sg_split_status1
[i
] = ahd_inb(ahd
, SGSPLTSTAT1
);
852 /* Clear latched errors. So our interrupt deasserts. */
853 ahd_outb(ahd
, SGSPLTSTAT0
, sg_split_status
[i
]);
854 ahd_outb(ahd
, SGSPLTSTAT1
, sg_split_status1
[i
]);
857 for (i
= 0; i
< 4; i
++) {
860 for (bit
= 0; bit
< 8; bit
++) {
862 if ((split_status
[i
] & (0x1 << bit
)) != 0) {
863 static const char *s
;
865 s
= split_status_strings
[bit
];
866 printf(s
, ahd_name(ahd
),
867 split_status_source
[i
]);
873 if ((sg_split_status
[i
] & (0x1 << bit
)) != 0) {
874 static const char *s
;
876 s
= split_status_strings
[bit
];
877 printf(s
, ahd_name(ahd
), "SG");
882 * Clear PCI-X status bits.
884 ahd_pci_write_config(ahd
->dev_softc
, PCIXR_STATUS
,
885 pcix_status
, /*bytes*/2);
886 ahd_outb(ahd
, CLRINT
, CLRSPLTINT
);
887 ahd_restore_modes(ahd
, saved_modes
);
891 ahd_aic7901_setup(struct ahd_softc
*ahd
)
894 ahd
->chip
= AHD_AIC7901
;
895 ahd
->features
= AHD_AIC7901_FE
;
896 return (ahd_aic790X_setup(ahd
));
900 ahd_aic7901A_setup(struct ahd_softc
*ahd
)
903 ahd
->chip
= AHD_AIC7901A
;
904 ahd
->features
= AHD_AIC7901A_FE
;
905 return (ahd_aic790X_setup(ahd
));
909 ahd_aic7902_setup(struct ahd_softc
*ahd
)
911 ahd
->chip
= AHD_AIC7902
;
912 ahd
->features
= AHD_AIC7902_FE
;
913 return (ahd_aic790X_setup(ahd
));
917 ahd_aic790X_setup(struct ahd_softc
*ahd
)
922 pci
= ahd
->dev_softc
;
923 rev
= ahd_pci_read_config(pci
, PCIR_REVID
, /*bytes*/1);
924 if (rev
< ID_AIC7902_PCI_REV_A4
) {
925 printf("%s: Unable to attach to unsupported chip revision %d\n",
927 ahd_pci_write_config(pci
, PCIR_COMMAND
, 0, /*bytes*/2);
930 ahd
->channel
= ahd_get_pci_function(pci
) + 'A';
931 if (rev
< ID_AIC7902_PCI_REV_B0
) {
933 * Enable A series workarounds.
935 ahd
->bugs
|= AHD_SENT_SCB_UPDATE_BUG
|AHD_ABORT_LQI_BUG
936 | AHD_PKT_BITBUCKET_BUG
|AHD_LONG_SETIMO_BUG
937 | AHD_NLQICRC_DELAYED_BUG
|AHD_SCSIRST_BUG
938 | AHD_LQO_ATNO_BUG
|AHD_AUTOFLUSH_BUG
939 | AHD_CLRLQO_AUTOCLR_BUG
|AHD_PCIX_MMAPIO_BUG
940 | AHD_PCIX_CHIPRST_BUG
|AHD_PCIX_SCBRAM_RD_BUG
941 | AHD_PKTIZED_STATUS_BUG
|AHD_PKT_LUN_BUG
942 | AHD_MDFF_WSCBPTR_BUG
|AHD_REG_SLOW_SETTLE_BUG
943 | AHD_SET_MODE_BUG
|AHD_BUSFREEREV_BUG
944 | AHD_NONPACKFIFO_BUG
|AHD_PACED_NEGTABLE_BUG
948 * IO Cell paramter setup.
950 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
952 if ((ahd
->flags
& AHD_HP_BOARD
) == 0)
953 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVA
);
957 ahd
->features
|= AHD_RTI
|AHD_NEW_IOCELL_OPTS
958 | AHD_NEW_DFCNTRL_OPTS
|AHD_FAST_CDB_DELIVERY
;
959 ahd
->bugs
|= AHD_LQOOVERRUN_BUG
|AHD_EARLY_REQ_BUG
;
962 * Some issues have been resolved in the 7901B.
964 if ((ahd
->features
& AHD_MULTI_FUNC
) != 0)
965 ahd
->bugs
|= AHD_INTCOLLISION_BUG
|AHD_ABORT_LQI_BUG
;
968 * IO Cell paramter setup.
970 AHD_SET_PRECOMP(ahd
, AHD_PRECOMP_CUTBACK_29
);
971 AHD_SET_SLEWRATE(ahd
, AHD_SLEWRATE_DEF_REVB
);
972 AHD_SET_AMPLITUDE(ahd
, AHD_AMPLITUDE_DEF
);
975 * Set the PREQDIS bit for H2B which disables some workaround
976 * that doesn't work on regular PCI busses.
977 * XXX - Find out exactly what this does from the hardware
980 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);
981 ahd_pci_write_config(pci
, DEVCONFIG1
,
982 devconfig1
|PREQDIS
, /*bytes*/1);
983 devconfig1
= ahd_pci_read_config(pci
, DEVCONFIG1
, /*bytes*/1);