diff options
-rw-r--r-- | sys/dev/ata/ata-dma.c | 105 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.c | 21 |
2 files changed, 109 insertions, 17 deletions
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 45791b0..3d6ef1e 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -521,17 +521,100 @@ via_82c586: break; case 0x55131039: /* SiS 5591 */ - if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, - ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); - if (bootverbose) - ata_printf(scp, device, - "%s setting UDMA2 on SiS chip\n", - (error) ? "failed" : "success"); - if (!error) { - pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; - return; + if (ata_find_dev(parent, 0x06301039, 0x30) || /* SiS 630 */ + ata_find_dev(parent, 0x06331039, 0x00) || /* SiS 633 */ + ata_find_dev(parent, 0x06351039, 0x00) || /* SiS 635 */ + ata_find_dev(parent, 0x07301039, 0x00) || /* SiS 730 */ + ata_find_dev(parent, 0x07331039, 0x00) || /* SiS 733 */ + ata_find_dev(parent, 0x07351039, 0x00)) { /* SiS 735 */ + int8_t reg = 0x40 + (devno << 1); + int16_t val = pci_read_config(parent, reg, 2) & 0x00ff; + + if (udmamode >= 5) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting UDMA5 on SiS chip\n", + (error) ? "failed" : "success"); + if (!error) { + pci_write_config(parent, reg, val | 0x8100, 2); + scp->mode[ATA_DEV(device)] = ATA_UDMA5; + return; + } + } + if (udmamode >= 4) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting UDMA4 on SiS chip\n", + (error) ? "failed" : "success"); + if (!error) { + pci_write_config(parent, reg, val | 0x8200, 2); + scp->mode[ATA_DEV(device)] = ATA_UDMA4; + return; + } + } + if (udmamode >= 2) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting UDMA2 on SiS chip\n", + (error) ? "failed" : "success"); + if (!error) { + pci_write_config(parent, reg, val | 0x8500, 2); + scp->mode[ATA_DEV(device)] = ATA_UDMA2; + return; + } + } + } else if (ata_find_dev(parent, 0x05301039, 0) || /* SiS 530 */ + ata_find_dev(parent, 0x05401039, 0) || /* SiS 540 */ + ata_find_dev(parent, 0x06201039, 0) || /* SiS 620 */ + ata_find_dev(parent, 0x06301039, 0)) { /* SiS 630 */ + int8_t reg = 0x40 + (devno << 1); + int16_t val = pci_read_config(parent, reg, 2) & 0x0fff; + + if (udmamode >= 4) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting UDMA4 on SiS chip\n", + (error) ? "failed" : "success"); + if (!error) { + pci_write_config(parent, reg, val | 0x9000, 2); + scp->mode[ATA_DEV(device)] = ATA_UDMA4; + return; + } + } + if (udmamode >= 2) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting UDMA2 on SiS chip\n", + (error) ? "failed" : "success"); + if (!error) { + pci_write_config(parent, reg, val | 0xb000, 2); + scp->mode[ATA_DEV(device)] = ATA_UDMA2; + return; + } + } + } else { /* SiS 5591 */ + if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting UDMA2 on SiS chip\n", + (error) ? "failed" : "success"); + if (!error) { + pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); + scp->mode[ATA_DEV(device)] = ATA_UDMA2; + return; + } } } if (wdmamode >=2 && apiomode >= 4) { diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index fb2d23d..658024a 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -68,18 +68,15 @@ void ata_via686b(device_t); int ata_find_dev(device_t dev, u_int32_t devid, u_int32_t revid) { - device_t *children, child; + device_t *children; 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_devid(child) == devid && pci_get_revid(child) >= revid) { + if (pci_get_devid(children[i]) == devid && + pci_get_revid(children[i]) >= revid) { free(children, M_TEMP); return 1; } @@ -170,6 +167,18 @@ ata_pci_match(device_t dev) return "VIA Apollo ATA controller"; case 0x55131039: + if (ata_find_dev(dev, 0x06301039, 0x30) || + ata_find_dev(dev, 0x06331039, 0x00) || + ata_find_dev(dev, 0x06351039, 0x00) || + ata_find_dev(dev, 0x07301039, 0x00) || + ata_find_dev(dev, 0x07331039, 0x00) || + ata_find_dev(dev, 0x07351039, 0x00)) + return "SiS 5591 ATA100 controller"; + if (ata_find_dev(dev, 0x05301039, 0x00) || + ata_find_dev(dev, 0x05401039, 0x00) || + ata_find_dev(dev, 0x06201039, 0x00) || + ata_find_dev(dev, 0x06301039, 0x00)) + return "SiS 5591 ATA66 controller"; return "SiS 5591 ATA33 controller"; case 0x06491095: |