summaryrefslogtreecommitdiff
path: root/sys/dev/pci/pciide.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/pciide.c')
-rw-r--r--sys/dev/pci/pciide.c102
1 files changed, 63 insertions, 39 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c
index 6257f350367..a0c3c5fea89 100644
--- a/sys/dev/pci/pciide.c
+++ b/sys/dev/pci/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.57 2001/07/19 18:16:22 csapuntz Exp $ */
+/* $OpenBSD: pciide.c,v 1.58 2001/07/20 05:56:25 csapuntz Exp $ */
/* $NetBSD: pciide.c,v 1.110 2001/03/20 17:56:46 bouyer Exp $ */
/*
@@ -2039,66 +2039,79 @@ apollo_chip_map(sc, pa)
{
struct pciide_channel *cp;
pcireg_t interface = PCI_INTERFACE(pa->pa_class);
- pcireg_t rev = PCI_REVISION(pa->pa_class);
int channel;
- u_int32_t ideconf, udma_conf, old_udma_conf;
+ u_int32_t ideconf;
bus_size_t cmdsize, ctlsize;
+ pcitag_t pcib_tag;
+ pcireg_t pcib_id, pcib_class;
if (pciide_chipen(sc, pa) == 0)
return;
- printf(": DMA");
+ pcib_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 0);
+
+ pcib_id = pci_conf_read(sc->sc_pc, pcib_tag, PCI_ID_REG);
+ pcib_class = pci_conf_read(sc->sc_pc, pcib_tag, PCI_CLASS_REG);
+
+ switch (PCI_PRODUCT(pcib_id)) {
+ case PCI_PRODUCT_VIATECH_VT82C586_ISA:
+ if (PCI_REVISION(pcib_class) >= 0x02) {
+ printf(": ATA33");
+ sc->sc_wdcdev.UDMA_cap = 2;
+ } else {
+ printf(": DMA");
+ sc->sc_wdcdev.UDMA_cap = 0;
+ }
+ break;
+ case PCI_PRODUCT_VIATECH_VT82C596A:
+ if (PCI_REVISION(pcib_class) >= 0x12) {
+ printf(": ATA66");
+ sc->sc_wdcdev.UDMA_cap = 4;
+ } else {
+ printf(": ATA33");
+ sc->sc_wdcdev.UDMA_cap = 2;
+ }
+ break;
+
+ case PCI_PRODUCT_VIATECH_VT82C686A_ISA:
+ if (PCI_REVISION(pcib_class) >= 0x40) {
+ printf(": ATA100");
+ sc->sc_wdcdev.UDMA_cap = 5;
+ } else {
+ printf(": ATA66");
+ sc->sc_wdcdev.UDMA_cap = 4;
+ }
+ break;
+ default:
+ printf(": DMA");
+ sc->sc_wdcdev.UDMA_cap = 0;
+ break;
+ }
+
pciide_mapreg_dma(sc, pa);
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
WDC_CAPABILITY_MODE;
if (sc->sc_dma_ok) {
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
sc->sc_wdcdev.irqack = pciide_irqack;
- if (sc->sc_pp->ide_product == PCI_PRODUCT_VIATECH_VT82C571
- && rev >= 6)
+ if (sc->sc_wdcdev.UDMA_cap > 0)
sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
}
sc->sc_wdcdev.PIO_cap = 4;
sc->sc_wdcdev.DMA_cap = 2;
- sc->sc_wdcdev.UDMA_cap = 2;
sc->sc_wdcdev.set_modes = apollo_setup_channel;
sc->sc_wdcdev.channels = sc->wdc_chanarray;
sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
- old_udma_conf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA);
WDCDEBUG_PRINT(("apollo_chip_map: old APO_IDECONF=0x%x, "
"APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n",
pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF),
pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC),
pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM),
- old_udma_conf),
+ pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)),
DEBUG_PROBE);
- if (rev >= 6) {
- pci_conf_write(sc->sc_pc, sc->sc_tag,
- old_udma_conf | (APO_UDMA_PIO_MODE(0, 0) | APO_UDMA_EN(0, 0)
- | APO_UDMA_EN_MTH(0, 0) | APO_UDMA_CLK66(0)),
- APO_UDMA);
- udma_conf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA);
- WDCDEBUG_PRINT(("apollo_chip_map: APO_UDMA now 0x%x\n",
- udma_conf), DEBUG_PROBE);
- if ((udma_conf & (APO_UDMA_PIO_MODE(0, 0) | APO_UDMA_EN(0, 0) |
- APO_UDMA_EN_MTH(0, 0))) ==
- (APO_UDMA_PIO_MODE(0, 0) | APO_UDMA_EN(0, 0) |
- APO_UDMA_EN_MTH(0, 0))) {
- if ((udma_conf & APO_UDMA_CLK66(0)) ==
- APO_UDMA_CLK66(0)) {
- printf("%s: Ultra/66 capable\n",
- sc->sc_wdcdev.sc_dev.dv_xname);
- sc->sc_wdcdev.UDMA_cap = 4;
- }
- } else {
- sc->sc_wdcdev.cap &= ~WDC_CAPABILITY_UDMA;
- }
- pci_conf_write(sc->sc_pc, sc->sc_tag, old_udma_conf, APO_UDMA);
- }
-
for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
cp = &sc->pciide_channels[channel];
if (pciide_chansetup(sc, channel, interface) == 0)
@@ -2191,12 +2204,23 @@ apollo_setup_channel(chp)
/* use Ultra/DMA */
drvp->drive_flags &= ~DRIVE_DMA;
udmatim_reg |= APO_UDMA_EN(chp->channel, drive) |
- APO_UDMA_EN_MTH(chp->channel, drive) |
- APO_UDMA_TIME(chp->channel, drive,
- apollo_udma_tim[drvp->UDMA_mode]);
- if (drvp->UDMA_mode > 2)
- udmatim_reg |=
- APO_UDMA_CLK66(chp->channel);
+ APO_UDMA_EN_MTH(chp->channel, drive);
+
+ if (sc->sc_wdcdev.UDMA_cap == 5) {
+ /* 686b */
+ udmatim_reg |= APO_UDMA_CLK66(chp->channel);
+ udmatim_reg |= APO_UDMA_TIME(chp->channel,
+ drive, apollo_udma100_tim[drvp->UDMA_mode]);
+ } else if (sc->sc_wdcdev.UDMA_cap == 4) {
+ /* 596b or 686a */
+ udmatim_reg |= APO_UDMA_CLK66(chp->channel);
+ udmatim_reg |= APO_UDMA_TIME(chp->channel,
+ drive, apollo_udma66_tim[drvp->UDMA_mode]);
+ } else {
+ /* 596a or 586b */
+ udmatim_reg |= APO_UDMA_TIME(chp->channel,
+ drive, apollo_udma33_tim[drvp->UDMA_mode]);
+ }
/* can use PIO timings, MW DMA unused */
mode = drvp->PIO_mode;
} else {