summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-dma.c
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2002-09-12 15:25:59 +0000
committersos <sos@FreeBSD.org>2002-09-12 15:25:59 +0000
commit379b6995567f687b1332ae52cdffe42f3bba6232 (patch)
tree126ffc976bc688d3be1f102f7b3c371ca55ce3c0 /sys/dev/ata/ata-dma.c
parente43ba4717db0415b7a4ccb851d494df0ffa242b7 (diff)
downloadFreeBSD-src-379b6995567f687b1332ae52cdffe42f3bba6232.zip
FreeBSD-src-379b6995567f687b1332ae52cdffe42f3bba6232.tar.gz
Add preliminary mostly untested support for the Silicon Image Sil680 chip.
Diffstat (limited to 'sys/dev/ata/ata-dma.c')
-rw-r--r--sys/dev/ata/ata-dma.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 4cbf6d2..65a5298 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -738,6 +738,88 @@ ata_dmainit(struct ata_device *atadev, int apiomode, int wdmamode, int udmamode)
/* we could set PIO mode timings, but we assume the BIOS did that */
break;
+ case 0x06801095: /* Sil 0680 ATA133 controller */
+ {
+ u_int8_t ureg = 0xac + (device * 0x02) + (channel * 0x10);
+ u_int8_t uval = pci_read_config(parent, ureg, 1);
+ u_int8_t mreg = channel ? 0x84 : 0x80;
+ u_int8_t mask = device ? 0x30 : 0x03;
+ u_int8_t mode = pci_read_config(parent, mreg, 1);
+
+ /* enable UDMA mode */
+ pci_write_config(parent, mreg,
+ (mode & ~mask) | (device ? 0x30 : 0x03), 1);
+ if (udmamode >= 6) {
+ error = ata_command(atadev, ATA_C_SETFEATURES, 0,
+ ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_prtdev(atadev, "%s setting UDMA6 on Sil chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, ureg, (uval & 0x3f) | 0x01, 1);
+ ata_dmacreate(atadev, apiomode, ATA_UDMA6);
+ return;
+ }
+ }
+ if (udmamode >= 5) {
+ 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 Sil chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, ureg, (uval & 0x3f) | 0x02, 1);
+ ata_dmacreate(atadev, apiomode, 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 Sil chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, ureg, (uval & 0x3f) | 0x03, 1);
+ ata_dmacreate(atadev, apiomode, ATA_UDMA4);
+ return;
+ }
+ }
+ if (udmamode >= 2) {
+ error = ata_command(atadev, ATA_C_SETFEATURES, 0,
+ ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_prtdev(atadev, "%s setting UDMA2 on Sil chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, ureg, (uval & 0x3f) | 0x07, 1);
+ ata_dmacreate(atadev, apiomode, ATA_UDMA2);
+ return;
+ }
+ }
+
+ /* disable UDMA mode and enable WDMA mode */
+ pci_write_config(parent, mreg,
+ (mode & ~mask) | (device ? 0x20 : 0x02), 1);
+ if (wdmamode >= 2 && apiomode >= 4) {
+ error = ata_command(atadev, ATA_C_SETFEATURES, 0,
+ ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_prtdev(atadev, "%s setting WDMA2 on Sil chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, ureg - 0x4, 0x10c1, 2);
+ ata_dmacreate(atadev, apiomode, ATA_WDMA2);
+ return;
+ }
+ }
+
+ /* restore PIO mode */
+ pci_write_config(parent, mreg, mode, 1);
+ }
+ /* we could set PIO mode timings, but we assume the BIOS did that */
+ break;
+
case 0x06491095: /* CMD 649 ATA100 controller */
if (udmamode >= 5) {
u_int8_t umode;
OpenPOWER on IntegriCloud