diff options
Diffstat (limited to 'sys/dev/aic7xxx/aic7xxx_pci.c')
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_pci.c | 67 |
1 files changed, 43 insertions, 24 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx_pci.c b/sys/dev/aic7xxx/aic7xxx_pci.c index 959908d..ed1e641 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#53 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 $ * * $FreeBSD$ */ @@ -641,6 +641,7 @@ const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table); #define AHC_494X_SLOT_CHANNEL_D 7 #define DEVCONFIG 0x40 +#define PCIERRGENDIS 0x80000000ul #define SCBSIZE32 0x00010000ul /* aic789X only */ #define REXTVALID 0x00001000ul /* ultra cards only */ #define MPORTMODE 0x00000400ul /* aic7870+ only */ @@ -785,6 +786,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) u_int sxfrctl1; u_int scsiseq; u_int dscommand0; + uint32_t devconfig; int error; uint8_t sblkctl; @@ -809,6 +811,8 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) */ ahc_intr_enable(ahc, FALSE); + devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); + /* * If we need to support high memory, enable dual * address cycles. This bit must be set to enable @@ -816,21 +820,30 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) * 64bit bus (PCI64BIT set in devconfig). */ if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { - uint32_t devconfig; if (bootverbose) printf("%s: Enabling 39Bit Addressing\n", ahc_name(ahc)); - devconfig = ahc_pci_read_config(ahc->dev_softc, - DEVCONFIG, /*bytes*/4); devconfig |= DACEN; - ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, - devconfig, /*bytes*/4); } + /* Ensure that pci error generation, a test feature, is disabled. */ + devconfig |= PCIERRGENDIS; + + ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); + /* Ensure busmastering is enabled */ command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); 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); /* On all PCI adapters, we allow SCB paging */ @@ -947,7 +960,8 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) * a SEEPROM. */ /* See if someone else set us up already */ - if (scsiseq != 0) { + if ((ahc->flags & AHC_NO_BIOS_INIT) == 0 + && scsiseq != 0) { printf("%s: Using left over BIOS settings\n", ahc_name(ahc)); ahc->flags &= ~AHC_USEDEFAULTS; @@ -1202,15 +1216,20 @@ done: int ahc_pci_test_register_access(struct ahc_softc *ahc) { - int error; - u_int status1; - uint8_t seqctl; + int error; + u_int status1; + uint32_t cmd; + uint8_t hcntrl; error = EIO; - /* Enable PCI error interrupt status */ - seqctl = ahc_inb(ahc, SEQCTL); - ahc_outb(ahc, SEQCTL, seqctl & ~FAILDIS); + /* + * Enable PCI error interrupt status, but suppress NMIs + * generated by SERR raised due to target aborts. + */ + cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, + cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); /* * First a simple test to see if any @@ -1220,7 +1239,8 @@ ahc_pci_test_register_access(struct ahc_softc *ahc) * be zero so it is a good register to * use for this test. */ - if (ahc_inb(ahc, HCNTRL) == 0xFF) + hcntrl = ahc_inb(ahc, HCNTRL); + if (hcntrl == 0xFF) goto fail; /* @@ -1230,15 +1250,13 @@ ahc_pci_test_register_access(struct ahc_softc *ahc) * either, so look for data corruption and/or flagged * PCI errors. */ - 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); - - 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)) + ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); + while (ahc_is_paused(ahc) == 0) + ; + ahc_outb(ahc, SEQCTL, PERRORDIS); + ahc_outb(ahc, SCBPTR, 0); + ahc_outl(ahc, SCB_BASE, 0x5aa555aa); + if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa) goto fail; status1 = ahc_pci_read_config(ahc->dev_softc, @@ -1255,7 +1273,8 @@ fail: ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, status1, /*bytes*/1); ahc_outb(ahc, CLRINT, CLRPARERR); - ahc_outb(ahc, SEQCTL, seqctl); + ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); return (error); } |