summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ata/ata-dma.c105
-rw-r--r--sys/dev/ata/ata-pci.c21
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:
OpenPOWER on IntegriCloud