diff options
author | sos <sos@FreeBSD.org> | 2002-01-28 13:17:10 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2002-01-28 13:17:10 +0000 |
commit | 6c8ad084e0b2beebee4b2b89037cf295671e7aca (patch) | |
tree | 717aa94c0592408ecfe0dce7b7f69c369ea858c9 /sys | |
parent | e6cd71c92fdbf640f092adeec62318bb798c73c3 (diff) | |
download | FreeBSD-src-6c8ad084e0b2beebee4b2b89037cf295671e7aca.zip FreeBSD-src-6c8ad084e0b2beebee4b2b89037cf295671e7aca.tar.gz |
Add support for the Promise TX4.
Rearrange the support for the VIA chips, and add experimental
support for ATA133 on the newest chips.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ata/ata-dma.c | 150 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.c | 36 |
2 files changed, 118 insertions, 68 deletions
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index b47e7f3..f634053 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 1998,1999,2000,2001,2002 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -403,49 +403,68 @@ ata_dmainit(struct ata_softc *scp, int device, } goto via_82c586; - case 0x05711106: /* VIA 82C571, 82C586, 82C596, 82C686 */ - if (ata_find_dev(parent, 0x06861106, 0x40) || - ata_find_dev(parent, 0x82311106, 0) || - ata_find_dev(parent, 0x30741106, 0)) { /* 82C686b */ - 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 VIA chip\n", - (error) ? "failed" : "success"); - if (!error) { - pci_write_config(parent, 0x53 - devno, 0xf0, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; - return; - } + case 0x05711106: /* VIA 82C571, 82C586, 82C596, 82C686 , 8231, 8233 */ + { + int via_modes[4][7] = { + { 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* ATA33 */ + { 0x00, 0x00, 0xea, 0x00, 0xe8, 0x00, 0x00 }, /* ATA66 */ + { 0x00, 0x00, 0xf4, 0x00, 0xf1, 0xf0, 0x00 }, /* ATA100 */ + { 0x00, 0x00, 0xf6, 0x00, 0xf2, 0xf1, 0xf0 }}; /* ATA133 */ + int *reg_val = NULL; + + if (ata_find_dev(parent, 0x31471106, 0x40)) { /* 8233a */ + udmamode = imin(udmamode, 6); + reg_val = via_modes[3]; } - if (udmamode >= 4) { + else if (ata_find_dev(parent, 0x06861106, 0x40) || /* 82C686b */ + ata_find_dev(parent, 0x82311106, 0) || /* 8231 */ + ata_find_dev(parent, 0x30741106, 0) || /* 8233 */ + ata_find_dev(parent, 0x31091106, 0)) { /* 8233c */ + udmamode = imin(udmamode, 5); + reg_val = via_modes[2]; + } + else if (ata_find_dev(parent, 0x06861106, 0x10) || /* 82C686a */ + ata_find_dev(parent, 0x05961106, 0x12)) { /* 82C596b */ + udmamode = imin(udmamode, 4); + reg_val = via_modes[1]; + } + else if (ata_find_dev(parent, 0x06861106, 0x0)) { /* 82C686 */ + udmamode = imin(udmamode, 2); + reg_val = via_modes[1]; + } + else if (ata_find_dev(parent, 0x05961106, 0) || /* 82C596a */ + ata_find_dev(parent, 0x05861106, 0x03)) { /* 82C586b */ +via_82c586: + udmamode = imin(udmamode, 2); + reg_val = via_modes[0]; + } + else + udmamode = 0; + + if (udmamode >= 6) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, - ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); + ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on VIA chip\n", + ata_printf(scp, device, "%s setting UDMA6 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { - pci_write_config(parent, 0x53 - devno, 0xf1, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + pci_write_config(parent, 0x53 - devno, reg_val[6], 1); + scp->mode[ATA_DEV(device)] = ATA_UDMA6; return; } } - if (udmamode >= 2) { + if (udmamode >= 5) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, - ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); + ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on VIA chip\n", + ata_printf(scp, device, "%s setting UDMA5 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { - pci_write_config(parent, 0x53 - devno, 0xf4, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + pci_write_config(parent, 0x53 - devno, reg_val[5], 1); + scp->mode[ATA_DEV(device)] = ATA_UDMA5; return; } } - } - else if (ata_find_dev(parent, 0x06861106, 0) || /* 82C686a */ - ata_find_dev(parent, 0x05961106, 0x12)) { /* 82C596b */ if (udmamode >= 4) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -453,7 +472,7 @@ ata_dmainit(struct ata_softc *scp, int device, ata_printf(scp, device, "%s setting UDMA4 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { - pci_write_config(parent, 0x53 - devno, 0xe8, 1); + pci_write_config(parent, 0x53 - devno, reg_val[4], 1); scp->mode[ATA_DEV(device)] = ATA_UDMA4; return; } @@ -465,29 +484,12 @@ ata_dmainit(struct ata_softc *scp, int device, ata_printf(scp, device, "%s setting UDMA2 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { - pci_write_config(parent, 0x53 - devno, 0xea, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; - return; - } - } - } - else if (ata_find_dev(parent, 0x05961106, 0) || /* 82C596a */ - ata_find_dev(parent, 0x05861106, 0x03)) { /* 82C586b */ -via_82c586: - 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 %s chip\n", - (error) ? "failed" : "success", - ((scp->chiptype == 0x74091022) || - (scp->chiptype == 0x74111022)) ? "AMD" : "VIA"); - if (!error) { - pci_write_config(parent, 0x53 - devno, 0xc0, 1); + pci_write_config(parent, 0x53 - devno, reg_val[2], 1); scp->mode[ATA_DEV(device)] = ATA_UDMA2; return; } } + } if (wdmamode >= 2 && apiomode >= 4) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, @@ -794,20 +796,44 @@ via_82c586: /* we could set PIO mode timings, but we assume the BIOS did that */ break; + case 0x4d69105a: /* Promise TX2 ATA133 controllers */ + ATA_OUTB(scp->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 6 && !(ATA_INB(scp->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, "%s setting UDMA6 on Promise chip\n", + (error) ? "failed" : "success"); + if (!error) { + scp->mode[ATA_DEV(device)] = ATA_UDMA6; + return; + } + } + /* FALLTHROUGH */ + case 0x4d68105a: /* Promise TX2 ATA100 controllers */ case 0x6268105a: /* Promise TX2 ATA100 controllers */ - case 0x4d69105a: /* Promise TX2 ATA133 controllers */ + ATA_OUTB(scp->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 5 && !(ATA_INB(scp->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + 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 Promise chip\n", + (error) ? "failed" : "success"); + if (!error) { + scp->mode[ATA_DEV(device)] = ATA_UDMA5; + return; + } + } ATA_OUTB(scp->r_bmio, ATA_BMDEVSPEC_0, 0x0b); if (udmamode >= 4 && !(ATA_INB(scp->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, - ATA_UDMA + udmamode, ATA_C_F_SETXFER, - ATA_WAIT_READY); + ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting %s on Promise chip\n", - (error) ? "failed" : "success", - ata_mode2str(ATA_UDMA + udmamode)); + ata_printf(scp, device, "%s setting UDMA4 on Promise chip\n", + (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_UDMA + udmamode; + scp->mode[ATA_DEV(device)] = ATA_UDMA4; return; } } @@ -933,7 +959,7 @@ via_82c586: return; } } - if (!ATAPI_DEVICE(scp, device) && udmamode >=4 && + if (!ATAPI_DEVICE(scp, device) && udmamode >= 4 && !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -1042,7 +1068,7 @@ ata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, } dma_base = vtophys(data); - dma_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); + dma_count = imin(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); data += dma_count; count -= dma_count; @@ -1055,9 +1081,9 @@ ata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, return -1; } dma_base = vtophys(data); - dma_count = min(count, PAGE_SIZE); - data += min(count, PAGE_SIZE); - count -= min(count, PAGE_SIZE); + dma_count = imin(count, PAGE_SIZE); + data += imin(count, PAGE_SIZE); + count -= imin(count, PAGE_SIZE); } dmatab[i].base = dma_base; dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; @@ -1116,7 +1142,7 @@ cyrix_timing(struct ata_softc *scp, int devno, int mode) ATA_OUTL(scp->r_bmio, (devno << 3) + 0x20, reg20); ATA_OUTL(scp->r_bmio, (devno << 3) + 0x24, reg24); } - + static void promise_timing(struct ata_softc *scp, int devno, int mode) { diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index da054a2..44c558b 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -164,12 +164,19 @@ ata_pci_match(device_t dev) return "VIA 82C596 ATA66 controller"; if (ata_find_dev(dev, 0x05961106, 0)) return "VIA 82C596 ATA33 controller"; - if (ata_find_dev(dev, 0x06861106, 0x40) || - ata_find_dev(dev, 0x82311106, 0) || - ata_find_dev(dev, 0x30741106, 0)) + if (ata_find_dev(dev, 0x06861106, 0x40)) return "VIA 82C686 ATA100 controller"; - if (ata_find_dev(dev, 0x06861106, 0)) + if (ata_find_dev(dev, 0x06861106, 0x10)) return "VIA 82C686 ATA66 controller"; + if (ata_find_dev(dev, 0x06861106, 0)) + return "VIA 82C686 ATA33 controller"; + if (ata_find_dev(dev, 0x82311106, 0)) + return "VIA 8231 ATA100 controller"; + if (ata_find_dev(dev, 0x30741106, 0) || + ata_find_dev(dev, 0x31091106, 0)) + return "VIA 8233 ATA100 controller"; + if (ata_find_dev(dev, 0x31471106, 0)) + return "VIA 8233 ATA133 controller"; return "VIA Apollo ATA controller"; case 0x55131039: @@ -232,6 +239,23 @@ ata_pci_match(device_t dev) case 0x4d68105a: case 0x6268105a: + if (pci_get_devid(GRANDPARENT(dev)) == 0x00221011 && + pci_get_class(GRANDPARENT(dev)) == PCIC_BRIDGE) { + static long start = 0, end = 0; + + /* we belive we are on a TX4, now do our (simple) magic */ + if (pci_get_slot(dev) == 1) { + bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &end); + return "Promise TX4 ATA100 controller (channel 0+1)"; + } + else if (pci_get_slot(dev) == 2 && start && end) { + bus_set_resource(dev, SYS_RES_IRQ, 0, start, end); + start = end = 0; + return "Promise TX4 ATA100 controller (channel 2+3)"; + } + else + start = end = 0; + } return "Promise TX2 ATA100 controller"; case 0x4d69105a: @@ -376,8 +400,8 @@ ata_pci_attach(device_t dev) break; case 0x05711106: /* VIA 82C586, '596, '686 default setup */ - /* prepare for ATA-66 on the 82C686a and rev 0x12 and newer 82C596's */ - if ((ata_find_dev(dev, 0x06861106, 0) && + /* prepare for ATA-66 on the 82C686a and 82C596b */ + if ((ata_find_dev(dev, 0x06861106, 0x10) && !ata_find_dev(dev, 0x06861106, 0x40)) || ata_find_dev(dev, 0x05961106, 0x12)) pci_write_config(dev, 0x50, 0x030b030b, 4); |