summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1999-12-14 10:25:28 +0000
committersos <sos@FreeBSD.org>1999-12-14 10:25:28 +0000
commit358ef546e609097f0c8b22e8b948b8c24f8aad20 (patch)
tree1e73717c6d53fd8743637f44b22a4ba9e5d4eb2b
parentf4c90f500152b9b554ae0edd6f880931b7dab5bf (diff)
downloadFreeBSD-src-358ef546e609097f0c8b22e8b948b8c24f8aad20.zip
FreeBSD-src-358ef546e609097f0c8b22e8b948b8c24f8aad20.tar.gz
Have another go at the VIA support, this time use the PCI ID form the
main component in the southbridge chip to determine which VIA chip we are dealing with. Try to enable DMA on generic controllers that say they has the capability, instead of relying on the BIOS to have set it up.
-rw-r--r--sys/dev/ata/ata-all.c37
-rw-r--r--sys/dev/ata/ata-all.h1
-rw-r--r--sys/dev/ata/ata-disk.c3
-rw-r--r--sys/dev/ata/ata-dma.c20
-rw-r--r--sys/dev/ata/atapi-all.c1
-rw-r--r--sys/dev/ata/atapi-cd.c1
-rw-r--r--sys/dev/ata/atapi-fd.c1
-rw-r--r--sys/dev/ata/atapi-tape.c1
8 files changed, 48 insertions, 17 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 69698ed..6f850bb 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -196,12 +196,10 @@ ata_pcimatch(device_t dev)
case 0x522910b9:
return "AcerLabs Aladdin ATA controller";
case 0x05711106: /* 82c586 & 82c686 */
- switch (pci_read_config(dev, 0x08, 1)) {
- case 1:
+ if (ata_find_dev(dev, 0x05861106))
return "VIA 82C586 ATA controller";
- case 6:
+ if (ata_find_dev(dev, 0x06861106))
return "VIA 82C686 ATA controller";
- }
return "VIA Apollo ATA controller";
case 0x55131039:
return "SiS 5591 ATA controller";
@@ -276,7 +274,6 @@ ata_pciattach(device_t dev)
else {
iobase_1 = pci_read_config(dev, 0x10, 4) & IOMASK;
altiobase_1 = pci_read_config(dev, 0x14, 4) & IOMASK;
- bmaddr_1 = pci_read_config(dev, 0x20, 4) & IOMASK;
irq1 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff;
}
@@ -288,7 +285,6 @@ ata_pciattach(device_t dev)
else {
iobase_2 = pci_read_config(dev, 0x18, 4) & IOMASK;
altiobase_2 = pci_read_config(dev, 0x1c, 4) & IOMASK;
- bmaddr_2 = (pci_read_config(dev, 0x20, 4) & IOMASK) + ATA_BM_OFFSET1;
irq2 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff;
}
@@ -310,11 +306,12 @@ ata_pciattach(device_t dev)
else {
if (type == 0x4d33105a || type == 0x4d38105a || type == 0x00041103) {
/* Promise and HPT366 controllers support busmastering DMA */
+ bmaddr_1 = pci_read_config(dev, 0x20, 4) & IOMASK;
+ bmaddr_2 = (pci_read_config(dev, 0x20, 4) & IOMASK)+ATA_BM_OFFSET1;
printf("ata-pci%d: Busmastering DMA supported\n", unit);
}
else {
- /* we dont know this controller, disable busmastering DMA */
- bmaddr_1 = bmaddr_2 = 0;
+ /* we dont know this controller, no busmastering DMA */
printf("ata-pci%d: Busmastering DMA not supported\n", unit);
}
}
@@ -948,3 +945,27 @@ bpack(int8_t *src, int8_t *dst, int32_t len)
}
dst[j] = 0x00;
}
+
+int32_t
+ata_find_dev(device_t dev, int32_t type)
+{
+ device_t *children, child;
+ int nchildren, i;
+
+ if (device_get_children(device_get_parent(dev), &children, &nchildren))
+ return 0;
+
+ for (i = 0; i < nchildren; i++) {
+ child = children[i];
+
+ /* check that it's on the same silicon and the device we want */
+ if (pci_get_slot(dev) == pci_get_slot(child) &&
+ pci_get_vendor(child) == (type & 0xffff) &&
+ pci_get_device(child) == ((type & 0xffff0000)>>16)) {
+ free(children, M_TEMP);
+ return 1;
+ }
+ }
+ free(children, M_TEMP);
+ return 0;
+}
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index d4d8917..73bfbe2 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -196,3 +196,4 @@ int8_t *ata_mode2str(int32_t);
void bswap(int8_t *, int32_t);
void btrim(int8_t *, int32_t);
void bpack(int8_t *, int8_t *, int32_t);
+int32_t ata_find_dev(device_t, int32_t);
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index e51f36e..11ddf4f 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -37,6 +37,7 @@
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/disk.h>
#include <sys/devicestat.h>
@@ -479,7 +480,7 @@ ad_transfer(struct ad_request *request)
if (ata_command(adp->controller, adp->unit, cmd,
cylinder, head, sector, count, 0, ATA_IMMEDIATE))
- printf("ad%d: wouldn't take transfer command - HELP!\n", adp->lun);
+ printf("ad%d: wouldn't take transfer command\n", adp->lun);
}
/* if this is a DMA transaction start it, return and wait for interrupt */
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index deaecd2..dbf7560 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -249,11 +249,11 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
/* we could set PIO mode timings, but we assume the BIOS did that */
break;
- case 0x05711106: /* VIA Apollo 82c571 / 82c586 / 82c686 */
+ case 0x05711106: /* VIA Apollo 82C571 / 82C586 / 82C686 */
devno = (scp->unit << 1) + ((device == ATA_MASTER) ? 0 : 1);
- /* UDMA4 mode only on rev 6 (VT82C686) hardware */
- if (udmamode >= 4 && pci_read_config(scp->dev, 0x08, 1) == 0x06) {
+ /* UDMA4 mode only on VT82C686 hardware */
+ if (udmamode >= 4 && ata_find_dev(scp->dev, 0x06861106)) {
int8_t byte = pci_read_config(scp->dev, 0x53 - devno, 1);
/* enable UDMA transfer modes setting by SETFEATURES cmd */
@@ -271,8 +271,10 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
pci_write_config(scp->dev, 0x53 - devno, byte, 1);
}
- /* UDMA2 mode only on rev 1 and up (VT82C586, VT82C686) hardware */
- if (udmamode >= 2 && pci_read_config(scp->dev, 0x08, 1) >= 0x01) {
+ /* UDMA2 mode only on rev 1 and better 82C586 & 82C586 chips */
+ if (udmamode >= 2 && pci_read_config(scp->dev, 0x08, 1) >= 0x01 &&
+ (ata_find_dev(scp->dev, 0x05861106) ||
+ ata_find_dev(scp->dev, 0x06861106))) {
int8_t byte = pci_read_config(scp->dev, 0x53 - devno, 1);
/* enable UDMA transfer modes setting by SETFEATURES cmd */
@@ -289,7 +291,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
struct ata_params *ap = ((struct ad_softc *)
(scp->dev_softc[(device==ATA_MASTER)?0:1]))->ata_parm;
- if ((pci_read_config(scp->dev, 0x08, 1) == 0x06) &&
+ if (ata_find_dev(scp->dev, 0x06861106) &&
(ap->udmamodes & 0x10) && !ap->cblid) {
pci_write_config(scp->dev, 0x53 - devno,
(byte & 0x1c) | 0x42, 1);
@@ -476,10 +478,12 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
break;
/* well, we have no support for this, but try anyways */
- if (((wdmamode >= 2 && apiomode >= 4) || udmamode >= 2) &&
- (inb(scp->bmaddr + ATA_BMSTAT_PORT) &
+ if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) {
+#if MAYBE_NOT
+ && (inb(scp->bmaddr + ATA_BMSTAT_PORT) &
((device == ATA_MASTER) ?
ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) {
+#endif
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index d47b92a..2d92455 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -38,6 +38,7 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/malloc.h>
#include <machine/clock.h>
#if NAPM > 0
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index f7544f5..f6f6dd4 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -35,6 +35,7 @@
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/disklabel.h>
#include <sys/devicestat.h>
#include <sys/cdio.h>
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index c8a0671..7710ba5 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.c
@@ -35,6 +35,7 @@
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/disk.h>
#include <sys/devicestat.h>
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index 9e4d8ea..5574da3 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -35,6 +35,7 @@
#include <sys/conf.h>
#include <sys/malloc.h>
#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/mtio.h>
#include <sys/disklabel.h>
#include <sys/devicestat.h>
OpenPOWER on IntegriCloud