diff options
author | scottl <scottl@FreeBSD.org> | 2002-12-04 22:51:29 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2002-12-04 22:51:29 +0000 |
commit | 431996dcfdb9d7dc0c841fc72cf956b46b36b557 (patch) | |
tree | 241ff845336085b89ceac47b876e92ae2d0e1507 /sys | |
parent | bc339ca6acda0076ad5db38b2234fa348494a1e1 (diff) | |
download | FreeBSD-src-431996dcfdb9d7dc0c841fc72cf956b46b36b557.zip FreeBSD-src-431996dcfdb9d7dc0c841fc72cf956b46b36b557.tar.gz |
Last minute fixes to ahc and ahd:
ahd_pci.c:
Retrieve the allow_memio hint from the resource manager to
determine whether or not to try PCI MEMIO.
aic79xx_osm.h:
aic7xxx_osm.h:
Don't wrongly abuse the callout_reset() interface when trying
to abuse timeouts generated from the CAM layer. This fixes the
console freeze and lost timeout problem that many have reported,
especially on SMP systems.
aic79xx_pci.c
aic7xxx_pci.c
Rewrite the MEMIO test routine to prevent certain broken chipsets
from trying to burst multiple DWORDs to the registers. Also make
the routine better detect byte merging by the host bridge and
deal with it.
aic79xx.reg:
Correct an incorrect register definition.
Approved by: re (rwatson, jhb)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/aic7xxx/ahd_pci.c | 16 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx.reg | 5 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx_osm.h | 7 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx_pci.c | 57 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_osm.h | 7 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_pci.c | 49 |
6 files changed, 94 insertions, 47 deletions
diff --git a/sys/dev/aic7xxx/ahd_pci.c b/sys/dev/aic7xxx/ahd_pci.c index 6268d5b..9549a4a 100644 --- a/sys/dev/aic7xxx/ahd_pci.c +++ b/sys/dev/aic7xxx/ahd_pci.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#9 $ + * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahd_pci.c#10 $ * * $FreeBSD$ */ @@ -150,14 +150,26 @@ ahd_pci_map_registers(struct ahd_softc *ahd) int regs_type; int regs_id; int regs_id2; + int allow_memio; command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1); regs = NULL; regs2 = NULL; regs_type = 0; regs_id = 0; + + /* Retrieve the per-device 'allow_memio' hint */ + if (resource_int_value(device_get_name(ahd->dev_softc), + device_get_unit(ahd->dev_softc), + "allow_memio", &allow_memio) != 0) { + if (bootverbose) + device_printf(ahd->dev_softc, + "Defaulting to MEMIO on\n"); + } + if ((command & PCIM_CMD_MEMEN) != 0 - && (ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) { + && (ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0 + && allow_memio != 0) { regs_type = SYS_RES_MEMORY; regs_id = AHD_PCI_MEMADDR; diff --git a/sys/dev/aic7xxx/aic79xx.reg b/sys/dev/aic7xxx/aic79xx.reg index 7611b9a..9949d3b 100644 --- a/sys/dev/aic7xxx/aic79xx.reg +++ b/sys/dev/aic7xxx/aic79xx.reg @@ -39,7 +39,7 @@ * * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#55 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#56 $" /* * This file is processed by the aic7xxx_asm utility for use in assembling @@ -190,6 +190,7 @@ register CLRINT { field CLRHWERRINT 0x80 /* Rev B or greater */ field CLRBRKADRINT 0x40 field CLRSWTMINT 0x20 + field CLRPCIINT 0x10 field CLRSCSIINT 0x08 field CLRSEQINT 0x04 field CLRCMDINT 0x02 @@ -1168,7 +1169,7 @@ register MSIPCISTAT { * PCI Status for Target */ register TARGPCISTAT { - address 0x0A6 + address 0x0A7 access_mode RW modes M_CFG field DPE 0x80 diff --git a/sys/dev/aic7xxx/aic79xx_osm.h b/sys/dev/aic7xxx/aic79xx_osm.h index 6379a02..9813986 100644 --- a/sys/dev/aic7xxx/aic79xx_osm.h +++ b/sys/dev/aic7xxx/aic79xx_osm.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#18 $ + * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#19 $ * * $FreeBSD$ */ @@ -239,8 +239,9 @@ ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg) static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec) { - callout_reset(scb->io_ctx->ccb_h.timeout_ch.callout, - (usec * hz)/1000000, ahd_timeout, scb); + untimeout(ahd_timeout, (caddr_t)scb, scb->io_ctx->ccb_h.timeout_ch); + scb->io_ctx->ccb_h.timeout_ch = + timeout(ahd_timeout, scb, (usec * hz)/1000000); } /*************************** Device Access ************************************/ diff --git a/sys/dev/aic7xxx/aic79xx_pci.c b/sys/dev/aic7xxx/aic79xx_pci.c index fdbfc45..7dd68a3 100644 --- a/sys/dev/aic7xxx/aic79xx_pci.c +++ b/sys/dev/aic7xxx/aic79xx_pci.c @@ -38,7 +38,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#54 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#60 $ * * $FreeBSD$ */ @@ -175,8 +175,8 @@ struct ahd_pci_identity ahd_pci_ident_table [] = }, /* Generic chip probes for devices we don't know 'exactly' */ { - ID_AIC7901A & ID_ALL_MASK, - ID_ALL_MASK, + ID_AIC7901A & ID_DEV_VENDOR_MASK, + ID_DEV_VENDOR_MASK, "Adaptec AIC7901A Ultra320 SCSI adapter", ahd_aic7901A_setup }, @@ -378,7 +378,16 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) int ahd_pci_test_register_access(struct ahd_softc *ahd) { - int i; + ahd_mode_state saved_modes; + int error; + uint8_t seqctl; + + saved_modes = ahd_save_modes(ahd); + error = EIO; + + /* Enable PCI error interrupt status */ + seqctl = ahd_inb(ahd, SEQCTL0); + ahd_outb(ahd, SEQCTL0, seqctl & ~FAILDIS); /* * First a simple test to see if any @@ -389,7 +398,7 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) * use for this test. */ if (ahd_inb(ahd, HCNTRL) == 0xFF) - return (EIO); + goto fail; /* * Next create a situation where write combining @@ -398,19 +407,26 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) * either, so look for data corruption and/or flaged * PCI errors. */ - for (i = 0; i < 16; i++) - ahd_outb(ahd, SRAM_BASE + i, i); + ahd_outl(ahd, SRAM_BASE, 0x5aa555aa); + if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa) + goto fail; + + if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { + u_int targpcistat; + + ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); + targpcistat = ahd_inb(ahd, TARGPCISTAT); + if ((targpcistat & STA) != 0) + goto fail; + } - for (i = 0; i < 16; i++) - if (ahd_inb(ahd, SRAM_BASE + i) != i) - return (EIO); + error = 0; +fail: if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { - ahd_mode_state saved_modes; - u_int targpcistat; - u_int pci_status1; + u_int targpcistat; + u_int pci_status1; - saved_modes = ahd_save_modes(ahd); ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); targpcistat = ahd_inb(ahd, TARGPCISTAT); @@ -420,13 +436,12 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) PCIR_STATUS + 1, /*bytes*/1); ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, pci_status1, /*bytes*/1); - ahd_restore_modes(ahd, saved_modes); - - if ((targpcistat & STA) != 0) - return (EIO); + ahd_outb(ahd, CLRINT, CLRPCIINT); } - return (0); + ahd_restore_modes(ahd, saved_modes); + ahd_outb(ahd, SEQCTL0, seqctl); + return (error); } /* @@ -731,7 +746,7 @@ ahd_pci_intr(struct ahd_softc *ahd) s = pci_status_strings[bit]; if (i == 7/*TARG*/ && bit == 3) - s = "%s: Signal Target Abort\n"; + s = "%s: Signaled Target Abort\n"; printf(s, ahd_name(ahd), pci_status_source[i]); } } @@ -741,6 +756,7 @@ ahd_pci_intr(struct ahd_softc *ahd) ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1, pci_status1, /*bytes*/1); ahd_restore_modes(ahd, saved_modes); + ahd_outb(ahd, CLRINT, CLRPCIINT); ahd_unpause(ahd); } @@ -810,6 +826,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) */ ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS, pcix_status, /*bytes*/2); + ahd_outb(ahd, CLRINT, CLRSPLTINT); ahd_restore_modes(ahd, saved_modes); } diff --git a/sys/dev/aic7xxx/aic7xxx_osm.h b/sys/dev/aic7xxx/aic7xxx_osm.h index ff80362..a5bdc18 100644 --- a/sys/dev/aic7xxx/aic7xxx_osm.h +++ b/sys/dev/aic7xxx/aic7xxx_osm.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#13 $ + * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#14 $ * * $FreeBSD$ */ @@ -251,8 +251,9 @@ ahc_timer_reset(ahc_timer_t *timer, u_int usec, ahc_callback_t *func, void *arg) static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec) { - callout_reset(scb->io_ctx->ccb_h.timeout_ch.callout, - (usec * hz)/1000000, ahc_timeout, scb); + untimeout(ahc_timeout, (caddr_t)scb, scb->io_ctx->ccb_h.timeout_ch); + scb->io_ctx->ccb_h.timeout_ch = + timeout(ahc_timeout, scb, (usec * hz)/1000000); } /*************************** Device Access ************************************/ diff --git a/sys/dev/aic7xxx/aic7xxx_pci.c b/sys/dev/aic7xxx/aic7xxx_pci.c index 9b93595..959908d 100644 --- a/sys/dev/aic7xxx/aic7xxx_pci.c +++ b/sys/dev/aic7xxx/aic7xxx_pci.c @@ -39,7 +39,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#52 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#53 $ * * $FreeBSD$ */ @@ -1202,8 +1202,15 @@ done: int ahc_pci_test_register_access(struct ahc_softc *ahc) { - int i; - u_int status1; + int error; + u_int status1; + uint8_t seqctl; + + error = EIO; + + /* Enable PCI error interrupt status */ + seqctl = ahc_inb(ahc, SEQCTL); + ahc_outb(ahc, SEQCTL, seqctl & ~FAILDIS); /* * First a simple test to see if any @@ -1214,7 +1221,7 @@ ahc_pci_test_register_access(struct ahc_softc *ahc) * use for this test. */ if (ahc_inb(ahc, HCNTRL) == 0xFF) - return (EIO); + goto fail; /* * Next create a situation where write combining @@ -1223,25 +1230,33 @@ ahc_pci_test_register_access(struct ahc_softc *ahc) * either, so look for data corruption and/or flagged * PCI errors. */ - for (i = 0; i < 16; i++) - ahc_outb(ahc, SRAM_BASE + i, i); + ahc_outb(ahc, SRAM_BASE, 0xaa); + ahc_outb(ahc, SRAM_BASE + 1, 0x55); + ahc_outb(ahc, SRAM_BASE + 2, 0xa5); + ahc_outb(ahc, SRAM_BASE + 3, 0x5a); - for (i = 0; i < 16; i++) - if (ahc_inb(ahc, SRAM_BASE + i) != i) - return (EIO); + if ((ahc_inb(ahc, SRAM_BASE) != 0xaa) + || (ahc_inb(ahc, SRAM_BASE + 1) != 0x55) + || (ahc_inb(ahc, SRAM_BASE + 2) != 0xa5) + || (ahc_inb(ahc, SRAM_BASE + 3) != 0x5a)) + goto fail; status1 = ahc_pci_read_config(ahc->dev_softc, PCIR_STATUS + 1, /*bytes*/1); - if ((status1 & STA) != 0) { + if ((status1 & STA) != 0) + goto fail; - /* Silently clear any latched errors. */ - ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, - status1, /*bytes*/1); - ahc_outb(ahc, CLRINT, CLRPARERR); - return (EIO); - } + error = 0; - return (0); +fail: + /* Silently clear any latched errors. */ + status1 = ahc_pci_read_config(ahc->dev_softc, + PCIR_STATUS + 1, /*bytes*/1); + ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, + status1, /*bytes*/1); + ahc_outb(ahc, CLRINT, CLRPARERR); + ahc_outb(ahc, SEQCTL, seqctl); + return (error); } /* |