From 7c5a0723d7bdabc563be893ee5215bd45de14186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Sun, 2 Dec 2001 10:48:52 +0000 Subject: [PATCH] Initial support for the newer SiS chipsets, based on docs we finally got from SiS. This should also close PR 32421 which has patches which seem to set the timing registers wrongly according to SiS... --- sys/dev/ata/ata-dma.c | 105 +++++++++++++++++++++++++++++++++++++----- 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 45791b05560f..3d6ef1e38e8e 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -521,17 +521,100 @@ ata_dmainit(struct ata_softc *scp, int device, 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 fb2d23d02e08..658024acc7a0 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: