summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2002-12-04 22:51:29 +0000
committerscottl <scottl@FreeBSD.org>2002-12-04 22:51:29 +0000
commit431996dcfdb9d7dc0c841fc72cf956b46b36b557 (patch)
tree241ff845336085b89ceac47b876e92ae2d0e1507
parentbc339ca6acda0076ad5db38b2234fa348494a1e1 (diff)
downloadFreeBSD-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)
-rw-r--r--sys/dev/aic7xxx/ahd_pci.c16
-rw-r--r--sys/dev/aic7xxx/aic79xx.reg5
-rw-r--r--sys/dev/aic7xxx/aic79xx_osm.h7
-rw-r--r--sys/dev/aic7xxx/aic79xx_pci.c57
-rw-r--r--sys/dev/aic7xxx/aic7xxx_osm.h7
-rw-r--r--sys/dev/aic7xxx/aic7xxx_pci.c49
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);
}
/*
OpenPOWER on IntegriCloud