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...
This commit is contained in:
sos 2000-08-06 19:51:58 +00:00
parent 4107ac6e87
commit 09cda20f32
3 changed files with 200 additions and 65 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
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 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
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 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"%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 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"%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 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"%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 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
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 */
if (pci_get_revid(parent) >= 0x03) { /* HPT370 */
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;
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;
}
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 */