diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/pci.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/pciide.c | 102 | ||||
-rw-r--r-- | sys/dev/pci/pciide_apollo_reg.h | 8 | ||||
-rw-r--r-- | sys/dev/pci/pcivar.h | 3 |
4 files changed, 72 insertions, 44 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 01cbb2556f7..41f5dadbd22 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci.c,v 1.20 2001/06/26 22:22:41 jason Exp $ */ +/* $OpenBSD: pci.c,v 1.21 2001/07/20 05:56:25 csapuntz Exp $ */ /* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */ /* @@ -187,6 +187,7 @@ pciattach(parent, self, aux) pa.pa_pc = pc; pa.pa_device = device; pa.pa_function = function; + pa.pa_bus = bus; pa.pa_tag = tag; pa.pa_id = id; pa.pa_class = class; 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 { diff --git a/sys/dev/pci/pciide_apollo_reg.h b/sys/dev/pci/pciide_apollo_reg.h index 6191d57f74e..07bbad4b104 100644 --- a/sys/dev/pci/pciide_apollo_reg.h +++ b/sys/dev/pci/pciide_apollo_reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide_apollo_reg.h,v 1.4 2001/04/04 07:02:54 csapuntz Exp $ */ +/* $OpenBSD: pciide_apollo_reg.h,v 1.5 2001/07/20 05:56:25 csapuntz Exp $ */ /* $NetBSD: pciide_apollo_reg.h,v 1.8 2001/01/05 18:04:43 bouyer Exp $ */ /* @@ -88,7 +88,7 @@ /* UltraDMA control (586A/B and higher only) */ #define APO_UDMA 0x50 #define APO_UDMA_MASK(channel) (0xffff << ((1 - (channel)) << 4)) -#define APO_UDMA_TIME(channel, drive, x) (((x) & 0x3) << \ +#define APO_UDMA_TIME(channel, drive, x) (((x) & 0xf) << \ (((1 - (channel)) << 4) + ((1 - (drive)) << 3))) #define APO_UDMA_PIO_MODE(channel, drive) (0x20 << \ (((1 - (channel)) << 4) + ((1 - (drive)) << 3))) @@ -98,6 +98,8 @@ (((1 - (channel)) << 4) + ((1 - (drive)) << 3))) #define APO_UDMA_CLK66(channel) (0x08 << ((1 - (channel)) << 4)) -static int8_t apollo_udma_tim[] = {0x03, 0x02, 0x00, 0x02, 0x00}; +static int8_t apollo_udma100_tim[] = {0x0f, 0x07, 0x04, 0x02, 0x01, 0x00}; +static int8_t apollo_udma66_tim[] = {0x03, 0x03, 0x02, 0x01, 0x00}; +static int8_t apollo_udma33_tim[] = {0x03, 0x02, 0x00}; static int8_t apollo_pio_set[] = {0x0a, 0x0a, 0x0a, 0x02, 0x02}; static int8_t apollo_pio_rec[] = {0x08, 0x08, 0x08, 0x02, 0x00}; diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index bc11ab3917b..b06ba8874aa 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcivar.h,v 1.19 2001/06/12 15:40:33 niklas Exp $ */ +/* $OpenBSD: pcivar.h,v 1.20 2001/07/20 05:56:25 csapuntz Exp $ */ /* $NetBSD: pcivar.h,v 1.23 1997/06/06 23:48:05 thorpej Exp $ */ /* @@ -107,6 +107,7 @@ struct pci_attach_args { int pa_flags; /* flags; see below */ u_int pa_device; + u_int pa_bus; u_int pa_function; pcitag_t pa_tag; pcireg_t pa_id, pa_class; |