Commit 03b84f47 authored by Justin T. Gibbs's avatar Justin T. Gibbs

Aic7xxx Driver Update

 o Auto disable PCI parity error reporting after 10 parity errors
   are observed.  The user is given a loud warning message telling
   them that eiter a device plugged into their motherboard or their
   motherboard is not very healthy.
parent b1d85861
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#74 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#75 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -1082,6 +1082,14 @@ struct ahc_softc { ...@@ -1082,6 +1082,14 @@ struct ahc_softc {
/* PCI cacheline size. */ /* PCI cacheline size. */
u_int pci_cachesize; u_int pci_cachesize;
/*
* Count of parity errors we have seen as a target.
* We auto-disable parity error checking after seeing
* AHC_PCI_TARGET_PERR_THRESH number of errors.
*/
u_int pci_target_perr_count;
#define AHC_PCI_TARGET_PERR_THRESH 10
/* Maximum number of sequencer instructions supported. */ /* Maximum number of sequencer instructions supported. */
u_int instruction_ram_size; u_int instruction_ram_size;
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#62 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#63 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -837,14 +837,6 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ...@@ -837,14 +837,6 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
command |= PCIM_CMD_BUSMASTEREN; command |= PCIM_CMD_BUSMASTEREN;
/*
* Disable PCI parity error reporting. Users typically
* do this to work around broken PCI chipsets that get
* the parity timing wrong and thus generate lots of spurious
* errors.
*/
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
command &= ~PCIM_CMD_PERRESPEN;
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1); ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
/* On all PCI adapters, we allow SCB paging */ /* On all PCI adapters, we allow SCB paging */
...@@ -854,6 +846,19 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ...@@ -854,6 +846,19 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
if (error != 0) if (error != 0)
return (error); return (error);
/*
* Disable PCI parity error checking. Users typically
* do this to work around broken PCI chipsets that get
* the parity timing wrong and thus generate lots of spurious
* errors. The chip only allows us to disable *all* parity
* error reporting when doing this, so CIO bus, scb ram, and
* scratch ram parity errors will be ignored too.
*/
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) {
ahc->pause |= FAILDIS;
ahc->unpause |= FAILDIS;
}
ahc->bus_intr = ahc_pci_intr; ahc->bus_intr = ahc_pci_intr;
ahc->bus_chip_init = ahc_pci_chip_init; ahc->bus_chip_init = ahc_pci_chip_init;
ahc->bus_suspend = ahc_pci_suspend; ahc->bus_suspend = ahc_pci_suspend;
...@@ -1998,6 +2003,7 @@ ahc_pci_intr(struct ahc_softc *ahc) ...@@ -1998,6 +2003,7 @@ ahc_pci_intr(struct ahc_softc *ahc)
ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
if (status1 & DPE) { if (status1 & DPE) {
ahc->pci_target_perr_count++;
printf("%s: Data Parity Error Detected during address " printf("%s: Data Parity Error Detected during address "
"or write data phase\n", ahc_name(ahc)); "or write data phase\n", ahc_name(ahc));
} }
...@@ -2029,6 +2035,19 @@ ahc_pci_intr(struct ahc_softc *ahc) ...@@ -2029,6 +2035,19 @@ ahc_pci_intr(struct ahc_softc *ahc)
ahc_outb(ahc, CLRINT, CLRPARERR); ahc_outb(ahc, CLRINT, CLRPARERR);
} }
if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {
printf(
"%s: WARNING WARNING WARNING WARNING\n"
"%s: Too many PCI parity errors observed as a target.\n"
"%s: Some device on this bus is generating bad parity.\n"
"%s: This is an error *observed by*, not *generated by*, this controller.\n"
"%s: PCI parity error checking has been disabled.\n"
"%s: WARNING WARNING WARNING WARNING\n",
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
ahc->pause |= FAILDIS;
ahc->unpause |= FAILDIS;
}
ahc_unpause(ahc); ahc_unpause(ahc);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment