summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-07-20 05:56:26 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-07-20 05:56:26 +0000
commit9e20bb450329b10408d80b8ebed0b59b2d08e48b (patch)
treeb369ba6c6e4df102cc0ad68924a343074502f518 /sys/dev/pci
parent9bb969be60ecc43df7377a21fa735dc03c3eff56 (diff)
Add pa_bus to pci_attach_args
Better VIA IDE chipset handling. From NetBSD
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci.c3
-rw-r--r--sys/dev/pci/pciide.c102
-rw-r--r--sys/dev/pci/pciide_apollo_reg.h8
-rw-r--r--sys/dev/pci/pcivar.h3
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;