diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 69698ed1df5..6f850bb6203 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 d4d89177806..73bfbe2bbe3 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 e51f36eb936..11ddf4fddfa 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -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 deaecd2e02e..dbf7560d694 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 d47b92a8f8d..2d924559154 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #if NAPM > 0 diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index f7544f56b34..f6f6dd40dda 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index c8a06715636..7710ba51490 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index 9e4d8ead9a1..5574da3a50e 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include