Set some termination defaults correctly. Test register access like
in the original FreeBSD driver.
This commit is contained in:
parent
00cb14ef50
commit
7bff47db67
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ahd_pci.c,v 1.9 2003/10/10 05:57:26 thorpej Exp $ */
|
||||
/* $NetBSD: ahd_pci.c,v 1.10 2003/10/10 12:58:38 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Product specific probe and attach routines for:
|
||||
|
@ -49,7 +49,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ahd_pci.c,v 1.9 2003/10/10 05:57:26 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ahd_pci.c,v 1.10 2003/10/10 12:58:38 fvdl Exp $");
|
||||
|
||||
#define AHD_PCI_IOADDR PCI_MAPREG_START /* I/O Address */
|
||||
#define AHD_PCI_MEMADDR (PCI_MAPREG_START + 4) /* Mem I/O Address */
|
||||
|
@ -380,6 +380,8 @@ ahd_pci_attach(parent, self, aux)
|
|||
LIST_INIT(&ahd->pending_scbs);
|
||||
ahd_timer_init(&ahd->reset_timer);
|
||||
ahd_timer_init(&ahd->stat_timer);
|
||||
ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A
|
||||
| AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
|
||||
ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
|
||||
ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
|
||||
ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
|
||||
|
@ -443,6 +445,8 @@ ahd_pci_attach(parent, self, aux)
|
|||
/*offset*/0x100,
|
||||
/*size*/0x100,
|
||||
&ahd->bshs[1]);
|
||||
if (ahd_pci_test_register_access(ahd) != 0)
|
||||
memh_valid = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -590,6 +594,98 @@ ahd_pci_attach(parent, self, aux)
|
|||
ahd_attach(ahd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform some simple tests that should catch situations where
|
||||
* our registers are invalidly mapped.
|
||||
*/
|
||||
int
|
||||
ahd_pci_test_register_access(struct ahd_softc *ahd)
|
||||
{
|
||||
uint32_t cmd;
|
||||
struct ahd_pci_busdata *bd = ahd->bus_data;
|
||||
u_int targpcistat;
|
||||
uint32_t pci_status1;
|
||||
int error;
|
||||
uint8_t hcntrl;
|
||||
|
||||
error = EIO;
|
||||
|
||||
/*
|
||||
* Enable PCI error interrupt status, but suppress NMIs
|
||||
* generated by SERR raised due to target aborts.
|
||||
*/
|
||||
cmd = pci_conf_read(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG);
|
||||
pci_conf_write(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG,
|
||||
cmd & ~PCI_COMMAND_SERR_ENABLE);
|
||||
|
||||
/*
|
||||
* First a simple test to see if any
|
||||
* registers can be read. Reading
|
||||
* HCNTRL has no side effects and has
|
||||
* at least one bit that is guaranteed to
|
||||
* be zero so it is a good register to
|
||||
* use for this test.
|
||||
*/
|
||||
hcntrl = ahd_inb(ahd, HCNTRL);
|
||||
if (hcntrl == 0xFF)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Next create a situation where write combining
|
||||
* or read prefetching could be initiated by the
|
||||
* CPU or host bridge. Our device does not support
|
||||
* either, so look for data corruption and/or flaged
|
||||
* PCI errors. First pause without causing another
|
||||
* chip reset.
|
||||
*/
|
||||
hcntrl &= ~CHIPRST;
|
||||
ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
|
||||
while (ahd_is_paused(ahd) == 0)
|
||||
;
|
||||
|
||||
/* Clear any PCI errors that occurred before our driver attached. */
|
||||
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
|
||||
targpcistat = ahd_inb(ahd, TARGPCISTAT);
|
||||
ahd_outb(ahd, TARGPCISTAT, targpcistat);
|
||||
pci_status1 = pci_conf_read(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG);
|
||||
pci_conf_write(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG, pci_status1);
|
||||
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
|
||||
ahd_outb(ahd, CLRINT, CLRPCIINT);
|
||||
|
||||
ahd_outb(ahd, SEQCTL0, PERRORDIS);
|
||||
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;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
fail:
|
||||
if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
|
||||
|
||||
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
|
||||
targpcistat = ahd_inb(ahd, TARGPCISTAT);
|
||||
|
||||
/* Silently clear any latched errors. */
|
||||
ahd_outb(ahd, TARGPCISTAT, targpcistat);
|
||||
pci_status1 = pci_conf_read(bd->pc, bd->tag,
|
||||
PCI_COMMAND_STATUS_REG);
|
||||
pci_conf_write(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG,
|
||||
pci_status1);
|
||||
ahd_outb(ahd, CLRINT, CLRPCIINT);
|
||||
}
|
||||
ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
|
||||
pci_conf_write(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG, cmd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the external port logic for a serial eeprom
|
||||
|
|
Loading…
Reference in New Issue