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.
This commit is contained in:
parent
21d19cbd64
commit
dbdfe960cb
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user