summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2000-08-06 19:51:58 +0000
committersos <sos@FreeBSD.org>2000-08-06 19:51:58 +0000
commit09cda20f320a0f4a9163372573b18604e0c4ae85 (patch)
tree3b3486582ae703e41019cfa273f367b713620cb0
parent4107ac6e879229638b611bfee2a35fa8f0db1968 (diff)
downloadFreeBSD-src-09cda20f320a0f4a9163372573b18604e0c4ae85.zip
FreeBSD-src-09cda20f320a0f4a9163372573b18604e0c4ae85.tar.gz
Add experimental code for ATA100 support on:
Promise Ultra100 / Fasttrak100 HighPoint HPT370 controllers (fx Abit KA7-100 onboard ctrl, Abit HotRod 100) Intel ICH2 (Intel 815E based motherboards) So far I can read >90MB/s on the Promise and the HPT370. I can write >64MB/s on the promise and >50MB/s on the HPT370 so it seems writing is still done in ATA66 mode :( The ICH2 support is untested as of yet...
-rw-r--r--sys/dev/ata/ata-all.c56
-rw-r--r--sys/dev/ata/ata-all.h1
-rw-r--r--sys/dev/ata/ata-dma.c206
3 files changed, 199 insertions, 64 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 9d37879..a699be4 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -254,11 +254,14 @@ ata_pci_match(device_t dev)
case 0x71998086:
return "Intel PIIX4 ATA33 controller";
+ case 0x24218086:
+ return "Intel ICH0 ATA33 controller";
+
case 0x24118086:
return "Intel ICH ATA66 controller";
- case 0x24218086:
- return "Intel ICH0 ATA33 controller";
+ case 0x244b8086:
+ return "Intel ICH2 ATA100 controller";
case 0x522910b9:
return "AcerLabs Aladdin ATA33 controller";
@@ -294,8 +297,22 @@ ata_pci_match(device_t dev)
case 0x4d38105a:
return "Promise ATA66 controller";
+ case 0x4d30105a:
+ return "Promise ATA100 controller";
+
case 0x00041103:
- return "HighPoint HPT366 ATA66 controller";
+ switch (pci_get_revid(dev)) {
+ case 0x00:
+ case 0x01:
+ return "HighPoint HPT366 ATA66 controller";
+ case 0x02:
+ return "HighPoint HPT368 ATA66 controller";
+ case 0x03:
+ case 0x04:
+ return "HighPoint HPT370 ATA100 controller";
+ default:
+ return "Unknown revision HighPoint ATA controller";
+ }
/* unsupported but known chipsets, generic DMA only */
case 0x10001042:
@@ -379,8 +396,9 @@ ata_pci_attach(device_t dev)
device_printf(dev, "Busmastering DMA not enabled\n");
}
else {
- if (type == 0x4d33105a || type == 0x4d38105a || type == 0x00041103) {
- /* Promise and HPT366 controllers support busmastering DMA */
+ if (type == 0x4d33105a || type == 0x4d38105a ||
+ type == 0x4d30105a || type == 0x00041103) {
+ /* Promise and HighPoint controllers support busmastering DMA */
rid = 0x20;
sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0, ~0, 1, RF_ACTIVE);
@@ -398,6 +416,7 @@ ata_pci_attach(device_t dev)
break;
case 0x4d38105a: /* Promise 66's need their clock changed */
+ case 0x4d30105a: /* Promise 100 too */
outb(rman_get_start(sc->bmio) + 0x11,
inb(rman_get_start(sc->bmio) + 0x11) | 0x0a);
/* FALLTHROUGH */
@@ -407,8 +426,25 @@ ata_pci_attach(device_t dev)
inb(rman_get_start(sc->bmio) + 0x1f) | 0x01);
break;
- case 0x00041103: /* HPT366 turn of fast interrupt prediction */
- pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x80), 1);
+ case 0x00041103: /* HighPoint's need to turn off interrupt prediction */
+ switch (pci_get_revid(dev)) {
+ case 0x00:
+ case 0x01:
+ pci_write_config(dev, 0x51,
+ (pci_read_config(dev, 0x51, 1) & ~0x80), 1);
+ break;
+
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ pci_write_config(dev, 0x51,
+ (pci_read_config(dev, 0x51, 1) & ~0x02), 1);
+ pci_write_config(dev, 0x55,
+ (pci_read_config(dev, 0x55, 1) & ~0x02), 1);
+ pci_write_config(dev, 0x5a,
+ (pci_read_config(dev, 0x5a, 1) & ~0x10), 1);
+
+ }
break;
case 0x05711106:
@@ -1086,7 +1122,7 @@ ata_intr(void *data)
*/
switch (scp->chiptype) {
#if NPCI > 0
- case 0x00041103: /* HighPoint HPT366 */
+ case 0x00041103: /* HighPoint HPT366/368/370 */
if (!((dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT))
return;
outb(scp->bmaddr + ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT);
@@ -1094,6 +1130,7 @@ ata_intr(void *data)
case 0x4d33105a: /* Promise 33's */
case 0x4d38105a: /* Promise 66's */
+ case 0x4d30105a: /* Promise 100's */
{
struct ata_pci_softc *sc=device_get_softc(device_get_parent(scp->dev));
@@ -1463,6 +1500,7 @@ ata_mode2str(int32_t mode)
case ATA_WDMA2: return "WDMA2";
case ATA_UDMA2: return "UDMA33";
case ATA_UDMA4: return "UDMA66";
+ case ATA_UDMA5: return "UDMA100";
case ATA_DMA: return "BIOSDMA";
default: return "???";
}
@@ -1515,6 +1553,8 @@ int
ata_umode(struct ata_params *ap)
{
if (ap->atavalid & ATA_FLAG_88) {
+ if (ap->udmamodes & 0x20)
+ return 5;
if (ap->udmamodes & 0x10)
return 4;
if (ap->udmamodes & 0x08)
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 14a3d97..811b989 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -279,6 +279,7 @@ struct ata_softc {
#define ATA_WDMA2 0x22
#define ATA_UDMA2 0x42
#define ATA_UDMA4 0x44
+#define ATA_UDMA5 0x45
int32_t flags; /* controller flags */
#define ATA_DMA_ACTIVE 0x01
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 908a376..1d82ee7 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -48,7 +48,7 @@
/* prototypes */
static void promise_timing(struct ata_softc *, int32_t, int32_t);
-static void hpt366_timing(struct ata_softc *, int32_t, int32_t);
+static void hpt_timing(struct ata_softc *, int32_t, int32_t);
/* misc defines */
#ifdef __alpha__
@@ -61,8 +61,8 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
int32_t apiomode, int32_t wdmamode, int32_t udmamode)
{
device_t parent = device_get_parent(scp->dev);
- int32_t devno = (scp->unit << 1) + ATA_DEV(device);
- int32_t error;
+ int devno = (scp->unit << 1) + ATA_DEV(device);
+ int error;
/* set our most pessimistic default mode */
scp->mode[ATA_DEV(device)] = ATA_PIO;
@@ -101,6 +101,39 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
switch (scp->chiptype) {
+ case 0x244b8086: /* Intel ICH2 */
+ if (udmamode >= 5) {
+ int32_t mask48, new48;
+ int16_t word54;
+
+ word54 = pci_read_config(parent, 0x54, 2);
+ if (word54 & (0x10 << devno)) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device,
+ "%s setting up UDMA5 mode on ICH2 chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
+ new48 = (1 << devno) + (1 << (16 + (devno << 2)));
+ pci_write_config(parent, 0x48,
+ (pci_read_config(parent, 0x48, 4) &
+ ~mask48) | new48, 4);
+ pci_write_config(parent, 0x54, word54 & ~(0x1000<<devno),2);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA5;
+ return;
+ }
+ }
+ }
+ if (udmamode >= 4) {
+ int16_t word54;
+
+ word54 = pci_read_config(parent, 0x54, 2);
+ pci_write_config(parent, 0x54, word54 & ~(0x1000 << devno), 2);
+ }
+ /* FALLTHROUGH */
+
case 0x24118086: /* Intel ICH */
if (udmamode >= 4) {
int32_t mask48, new48;
@@ -112,8 +145,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
ATA_UDMA4, ATA_C_F_SETXFER,ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA4 mode on ICH chip\n",
- (error) ? "failed" : "success");
+ "%s setting up UDMA4 mode on ICH%s chip\n",
+ (error) ? "failed" : "success",
+ (scp->chiptype == 0x244b8086) ? "2" : "");
if (!error) {
mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
new48 = (1 << devno) + (2 << (16 + (devno << 2)));
@@ -126,6 +160,12 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
}
}
+ if (udmamode >= 2) {
+ int16_t word54;
+
+ word54 = pci_read_config(parent, 0x54, 2);
+ pci_write_config(parent, 0x54, word54 & ~(1 << devno), 2);
+ }
/* FALLTHROUGH */
case 0x71118086: /* Intel PIIX4 */
@@ -139,8 +179,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (bootverbose)
ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n",
(error) ? "failed" : "success",
- (scp->chiptype == 0x24118086) ? "ICH" :
- (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
+ (scp->chiptype == 0x244b8086) ? "ICH2" :
+ (scp->chiptype == 0x24118086) ? "ICH" :
+ (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
if (!error) {
mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
new48 = (1 << devno) + (2 << (16 + (devno << 2)));
@@ -178,9 +219,10 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (bootverbose)
ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n",
(error) ? "failed" : "success",
- (scp->chiptype == 0x70108086) ? "PIIX3" :
+ (scp->chiptype == 0x244b8086) ? "ICH2" :
(scp->chiptype == 0x24118086) ? "ICH" :
- (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
+ (scp->chiptype == 0x24218086) ? "ICH0" :
+ (scp->chiptype == 0x70108086) ? "PIIX3":"PIIX4");
if (!error) {
if (device == ATA_MASTER) {
mask40 = 0x0000330f;
@@ -444,12 +486,28 @@ via_generic:
case 0x4d33105a: /* Promise Ultra33 / FastTrak33 controllers */
case 0x4d38105a: /* Promise Ultra66 / FastTrak66 controllers */
+ case 0x4d30105a: /* Promise Ultra100 / FastTrak100 controllers */
/* the Promise can only do DMA on ATA disks not on ATAPI devices */
if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
(device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
break;
- if (udmamode >=4 && scp->chiptype == 0x4d38105a &&
+ if (udmamode >=5 && scp->chiptype == 0x4d30105a &&
+ !(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device,
+ "%s setting up UDMA5 mode on Promise chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ promise_timing(scp, devno, ATA_UDMA5);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA5;
+ return;
+ }
+ }
+ if (udmamode >=4 &&
+ (scp->chiptype == 0x4d38105a || scp->chiptype == 0x4d30105a) &&
!(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -501,13 +559,29 @@ via_generic:
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
return;
- case 0x00041103: /* HighPoint HPT366 controller */
+ case 0x00041103: /* HighPoint HPT366/368/370 controllers */
/* no ATAPI devices for now */
if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
(device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
break;
- if (udmamode >=4 && !(pci_read_config(parent, 0x5a, 1) & 0x2)) {
+ if (udmamode >=5 && pci_get_revid(parent) >= 0x03 &&
+ !(pci_read_config(parent, 0x5a, 1) & (scp->unit ? 0x01 : 0x02))) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device,
+ "%s setting up UDMA5 mode on HPT370 chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ hpt_timing(scp, devno, ATA_UDMA5);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA5;
+ return;
+ }
+ }
+
+ if (udmamode >=4 &&
+ !(pci_read_config(parent, 0x5a, 1) & (scp->unit ? 0x01 : 0x02))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
@@ -515,7 +589,7 @@ via_generic:
"%s setting up UDMA4 mode on HPT366 chip\n",
(error) ? "failed" : "success");
if (!error) {
- hpt366_timing(scp, devno, ATA_UDMA4);
+ hpt_timing(scp, devno, ATA_UDMA4);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
return;
}
@@ -528,7 +602,7 @@ via_generic:
"%s setting up UDMA2 mode on HPT366 chip\n",
(error) ? "failed" : "success");
if (!error) {
- hpt366_timing(scp, devno, ATA_UDMA2);
+ hpt_timing(scp, devno, ATA_UDMA2);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
return;
}
@@ -541,7 +615,7 @@ via_generic:
"%s setting up WDMA2 mode on HPT366 chip\n",
(error) ? "failed" : "success");
if (!error) {
- hpt366_timing(scp, devno, ATA_WDMA2);
+ hpt_timing(scp, devno, ATA_WDMA2);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
return;
}
@@ -553,7 +627,7 @@ via_generic:
ata_printf(scp, device, "%s setting up PIO%d mode on HPT366 chip\n",
(error) ? "failed" : "success",
(apiomode >= 0) ? apiomode : 0);
- hpt366_timing(scp, devno, ata_pio2mode(apiomode));
+ hpt_timing(scp, devno, ata_pio2mode(apiomode));
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
return;
@@ -607,7 +681,7 @@ ata_dmasetup(struct ata_softc *scp, int32_t device,
{
struct ata_dmaentry *dmatab;
u_int32_t dma_count, dma_base;
- int32_t i = 0;
+ int i = 0;
if (((uintptr_t)data & 1) || (count & 1))
return -1;
@@ -708,6 +782,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
break;
case 0x4d38105a: /* Promise 66's */
+ case 0x4d30105a: /* Promise 100's */
switch (mode) {
default:
case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break;
@@ -718,6 +793,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break;
case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break;
case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break;
+ case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break;
}
break;
}
@@ -725,53 +801,71 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
}
static void
-hpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
+hpt_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
{
device_t parent = device_get_parent(scp->dev);
u_int32_t timing;
- switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
- case 0x85: /* 25Mhz */
- switch (mode) {
- case ATA_PIO0: timing = 0xc0d08585; break;
- case ATA_PIO1: timing = 0xc0d08572; break;
- case ATA_PIO2: timing = 0xc0ca8542; break;
- case ATA_PIO3: timing = 0xc0ca8532; break;
- case ATA_PIO4: timing = 0xc0ca8521; break;
- case ATA_WDMA2: timing = 0xa0ca8521; break;
- case ATA_UDMA2: timing = 0x90cf8521; break;
- case ATA_UDMA4: timing = 0x90c98521; break;
- default: timing = 0x01208585;
- }
- break;
- default:
- case 0xa7: /* 33MHz */
+ if (pci_get_revid(parent) >= 0x03) { /* HPT370 */
switch (mode) {
- case ATA_PIO0: timing = 0xc0d0a7aa; break;
- case ATA_PIO1: timing = 0xc0d0a7a3; break;
- case ATA_PIO2: timing = 0xc0d0a753; break;
- case ATA_PIO3: timing = 0xc0c8a742; break;
- case ATA_PIO4: timing = 0xc0c8a731; break;
- case ATA_WDMA2: timing = 0xa0c8a731; break;
- case ATA_UDMA2: timing = 0x90caa731; break;
- case ATA_UDMA4: timing = 0x90c9a731; break;
- default: timing = 0x0120a7a7;
+ case ATA_PIO0: timing = 0x06914e57; break;
+ case ATA_PIO1: timing = 0x06914e43; break;
+ case ATA_PIO2: timing = 0x06514e33; break;
+ case ATA_PIO3: timing = 0x06514e22; break;
+ case ATA_PIO4: timing = 0x06514e21; break;
+ case ATA_WDMA2: timing = 0x26514e21; break;
+ case ATA_UDMA2: timing = 0x16494e31; break;
+ case ATA_UDMA4: timing = 0x16454e31; break;
+ case ATA_UDMA5: timing = 0x16454e31; break;
+ default: timing = 0x06514e57;
}
- break;
- case 0xd9: /* 40Mhz */
- switch (mode) {
- case ATA_PIO0: timing = 0xc018d9d9; break;
- case ATA_PIO1: timing = 0xc010d9c7; break;
- case ATA_PIO2: timing = 0xc010d997; break;
- case ATA_PIO3: timing = 0xc010d974; break;
- case ATA_PIO4: timing = 0xc008d963; break;
- case ATA_WDMA2: timing = 0xa008d943; break;
- case ATA_UDMA2: timing = 0x900bd943; break;
- case ATA_UDMA4: timing = 0x900fd943; break;
- default: timing = 0x0120d9d9;
+ pci_write_config(parent, 0x40 + (devno << 2) , timing, 4);
+ pci_write_config(parent, 0x5b, 0x22, 1);
+ }
+ else { /* HPT36[68] */
+ switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
+ case 0x85: /* 25Mhz */
+ switch (mode) {
+ case ATA_PIO0: timing = 0xc0d08585; break;
+ case ATA_PIO1: timing = 0xc0d08572; break;
+ case ATA_PIO2: timing = 0xc0ca8542; break;
+ case ATA_PIO3: timing = 0xc0ca8532; break;
+ case ATA_PIO4: timing = 0xc0ca8521; break;
+ case ATA_WDMA2: timing = 0xa0ca8521; break;
+ case ATA_UDMA2: timing = 0x90cf8521; break;
+ case ATA_UDMA4: timing = 0x90c98521; break;
+ default: timing = 0x01208585;
+ }
+ break;
+ default:
+ case 0xa7: /* 33MHz */
+ switch (mode) {
+ case ATA_PIO0: timing = 0xc0d0a7aa; break;
+ case ATA_PIO1: timing = 0xc0d0a7a3; break;
+ case ATA_PIO2: timing = 0xc0d0a753; break;
+ case ATA_PIO3: timing = 0xc0c8a742; break;
+ case ATA_PIO4: timing = 0xc0c8a731; break;
+ case ATA_WDMA2: timing = 0xa0c8a731; break;
+ case ATA_UDMA2: timing = 0x90caa731; break;
+ case ATA_UDMA4: timing = 0x90c9a731; break;
+ default: timing = 0x0120a7a7;
+ }
+ break;
+ case 0xd9: /* 40Mhz */
+ switch (mode) {
+ case ATA_PIO0: timing = 0xc018d9d9; break;
+ case ATA_PIO1: timing = 0xc010d9c7; break;
+ case ATA_PIO2: timing = 0xc010d997; break;
+ case ATA_PIO3: timing = 0xc010d974; break;
+ case ATA_PIO4: timing = 0xc008d963; break;
+ case ATA_WDMA2: timing = 0xa008d943; break;
+ case ATA_UDMA2: timing = 0x900bd943; break;
+ case ATA_UDMA4: timing = 0x900fd943; break;
+ default: timing = 0x0120d9d9;
+ }
}
+ pci_write_config(parent, 0x40 + (devno << 2), (timing & ~0x80000000),4);
}
- pci_write_config(parent, 0x40 + (devno << 2) , (timing & ~0x80000000), 4);
}
#else /* NPCI > 0 */
OpenPOWER on IntegriCloud