diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index f003049141bc..abf5cd8d7f9a 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -748,6 +748,49 @@ ata_dmainit(struct ata_channel *ch, int device, atadev->mode = ATA_PIO0 + apiomode; return; + case 0x02121166: /* ServerWorks CSB5 ATA66/100 controller */ + if (udmamode >= 5 && pci_get_revid(parent) >= 0x92) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, + ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_prtdev(atadev, "%s setting UDMA5 on ServerWorks chip\n", + (error) ? "failed" : "success"); + if (!error) { + u_int16_t reg56; + + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) | + (0x01 << devno), 1); + reg56 = pci_read_config(parent, 0x56, 2); + reg56 &= ~(0xf << (devno * 4)); + reg56 |= (0x5 << (devno * 4)); + pci_write_config(parent, 0x56, reg56, 2); + atadev->mode = ATA_UDMA5; + return; + } + } + if (udmamode >= 4) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, + ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_prtdev(atadev, "%s setting UDMA4 on ServerWorks chip\n", + (error) ? "failed" : "success"); + if (!error) { + u_int16_t reg56; + + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) | + (0x01 << devno), 1); + reg56 = pci_read_config(parent, 0x56, 2); + reg56 &= ~(0xf << (devno * 4)); + reg56 |= (0x4 << (devno * 4)); + pci_write_config(parent, 0x56, reg56, 2); + atadev->mode = ATA_UDMA4; + return; + } + } + /* FALLTHROUGH */ + case 0x02111166: /* ServerWorks ROSB4 ATA33 controller */ if (udmamode >= 2) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index f39fc8898b8d..dd5bc645308b 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -227,6 +227,12 @@ ata_pci_match(device_t dev) case 0x02111166: return "ServerWorks ROSB4 ATA33 controller"; + case 0x02121166: + if (pci_get_revid(dev) >= 0x92) + return "ServerWorks CSB5 ATA100 controller"; + else + return "ServerWorks CSB5 ATA66 controller"; + case 0x4d33105a: return "Promise ATA33 controller"; @@ -392,7 +398,7 @@ ata_pci_attach(device_t dev) ATA_OUTB(controller->bmio, 0x1f, ATA_INB(controller->bmio, 0x1f)|0x01); break; - case 0x00041103: /* HighPoint HPT366/368/370/372 */ + case 0x00041103: /* HighPoint HPT366/368/370/372 */ if (pci_get_revid(dev) < 2) { /* HPT 366 */ /* turn off interrupt prediction */ pci_write_config(dev, 0x51, @@ -410,8 +416,8 @@ ata_pci_attach(device_t dev) pci_write_config(dev, 0x5b, 0x22, 1); break; - case 0x00051103: /* HighPoint HPT372 */ - case 0x00081103: /* HighPoint HPT374 */ + case 0x00051103: /* HighPoint HPT372 */ + case 0x00081103: /* HighPoint HPT374 */ /* turn off interrupt prediction */ pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x03), 1); pci_write_config(dev, 0x55, (pci_read_config(dev, 0x55, 1) & ~0x03), 1); @@ -459,9 +465,15 @@ ata_pci_attach(device_t dev) pci_write_config(dev, 0x68, DEV_BSIZE, 2); break; - case 0x10001042: /* RZ 100? known bad, no DMA */ + case 0x02121166: /* ServerWorks CSB5 ATA66/100 controller */ + pci_write_config(dev, 0x5a, + (pci_read_config(dev, 0x5a, 1) & ~0x40) | + (pci_get_revid(dev) >= 0x92) ? 0x03 : 0x02, 1); + break; + + case 0x10001042: /* RZ 100? known bad, no DMA */ case 0x10011042: - case 0x06401095: /* CMD 640 known bad, no DMA */ + case 0x06401095: /* CMD 640 known bad, no DMA */ controller->bmio = NULL; device_printf(dev, "Busmastering DMA disabled\n"); }