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:
|
* Product specific probe and attach routines for:
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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_IOADDR PCI_MAPREG_START /* I/O Address */
|
||||||
#define AHD_PCI_MEMADDR (PCI_MAPREG_START + 4) /* Mem 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);
|
LIST_INIT(&ahd->pending_scbs);
|
||||||
ahd_timer_init(&ahd->reset_timer);
|
ahd_timer_init(&ahd->reset_timer);
|
||||||
ahd_timer_init(&ahd->stat_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_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
|
||||||
ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
|
ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
|
||||||
ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
|
ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
|
||||||
|
@ -443,6 +445,8 @@ ahd_pci_attach(parent, self, aux)
|
||||||
/*offset*/0x100,
|
/*offset*/0x100,
|
||||||
/*size*/0x100,
|
/*size*/0x100,
|
||||||
&ahd->bshs[1]);
|
&ahd->bshs[1]);
|
||||||
|
if (ahd_pci_test_register_access(ahd) != 0)
|
||||||
|
memh_valid = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -590,6 +594,98 @@ ahd_pci_attach(parent, self, aux)
|
||||||
ahd_attach(ahd);
|
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
|
* Check the external port logic for a serial eeprom
|
||||||
|
|
Loading…
Reference in New Issue