summaryrefslogtreecommitdiff
path: root/sys/dev/ata/ata-all.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ata/ata-all.c')
-rw-r--r--sys/dev/ata/ata-all.c170
1 files changed, 104 insertions, 66 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 12ddcceeb55e..f5330038569c 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";
@@ -267,7 +270,7 @@ ata_pci_match(device_t dev)
if (ata_find_dev(dev, 0x05861106, 0))
return "VIA 82C586 ATA33 controller";
if (ata_find_dev(dev, 0x05961106, 0x12))
- return "VIA 82C596B ATA66 controller";
+ return "VIA 82C596 ATA66 controller";
if (ata_find_dev(dev, 0x05961106, 0))
return "VIA 82C596 ATA33 controller";
if (ata_find_dev(dev, 0x06861106, 0))
@@ -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's 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:
@@ -699,16 +735,7 @@ ata_pcisub_probe(device_t dev)
/* kids of pci ata chipsets has their physical unit number in ivars */
scp->unit = (uintptr_t) device_get_ivars(dev);
-
- /* set the chiptype to the hostchip ID, makes life easier */
- if (ata_find_dev(device_get_parent(dev), 0x05861106, 0))
- scp->chiptype = 0x05861106;
- else if (ata_find_dev(device_get_parent(dev), 0x05961106, 0))
- scp->chiptype = 0x05961106;
- else if (ata_find_dev(device_get_parent(dev), 0x06861106, 0))
- scp->chiptype = 0x06861106;
- else
- scp->chiptype = pci_get_devid(device_get_parent(dev));
+ scp->chiptype = pci_get_devid(device_get_parent(dev));
return ata_probe(dev);
}
@@ -801,50 +828,13 @@ ata_probe(device_t dev)
goto failure;
ata_reset(scp, &mask);
- if (!mask)
- goto failure;
- /*
- * OK, we have at least one device on the chain, check for ATAPI
- * signatures, if none check if its a good old ATA device.
- */
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
- DELAY(1);
- if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
- inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
- scp->devices |= ATA_ATAPI_MASTER;
- }
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
- DELAY(1);
- if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
- inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
- scp->devices |= ATA_ATAPI_SLAVE;
- }
- if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
- DELAY(1);
- outb(scp->ioaddr + ATA_ERROR, 0x58);
- outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
- if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
- inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
- scp->devices |= ATA_ATA_MASTER;
- }
- }
- if (status1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
- DELAY(1);
- outb(scp->ioaddr + ATA_ERROR, 0x58);
- outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
- if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
- inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
- scp->devices |= ATA_ATA_SLAVE;
- }
- }
if (bootverbose)
ata_printf(scp, -1, "devices = 0x%x\n", scp->devices);
- if (!scp->devices) {
+
+ if (!mask)
goto failure;
- }
+
TAILQ_INIT(&scp->ata_queue);
TAILQ_INIT(&scp->atapi_queue);
return 0;
@@ -1086,7 +1076,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 +1084,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));
@@ -1214,7 +1205,7 @@ void
ata_reset(struct ata_softc *scp, int32_t *mask)
{
int32_t timeout;
- u_int8_t status0 = 0, status1 = 0;
+ u_int8_t status0 = ATA_S_BUSY, status1 = ATA_S_BUSY;
/* reset channel */
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
@@ -1229,12 +1220,28 @@ ata_reset(struct ata_softc *scp, int32_t *mask)
/* wait for BUSY to go inactive */
for (timeout = 0; timeout < 310000; timeout++) {
- outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
- DELAY(1);
- status0 = inb(scp->ioaddr + ATA_STATUS);
- outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
- DELAY(1);
- status1 = inb(scp->ioaddr + ATA_STATUS);
+ if (status0 & ATA_S_BUSY) {
+ outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
+ DELAY(1);
+ status0 = inb(scp->ioaddr + ATA_STATUS);
+ if (!(status0 & ATA_S_BUSY)) {
+ /* check for ATAPI signature while its still there */
+ if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
+ inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
+ scp->devices |= ATA_ATAPI_MASTER;
+ }
+ }
+ if (status1 & ATA_S_BUSY) {
+ outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
+ DELAY(1);
+ status1 = inb(scp->ioaddr + ATA_STATUS);
+ if (!(status1 & ATA_S_BUSY)) {
+ /* check for ATAPI signature while its still there */
+ if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
+ inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
+ scp->devices |= ATA_ATAPI_SLAVE;
+ }
+ }
if (*mask == 0x01) /* wait for master only */
if (!(status0 & ATA_S_BUSY))
break;
@@ -1255,6 +1262,34 @@ ata_reset(struct ata_softc *scp, int32_t *mask)
if (bootverbose)
ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n",
*mask, status0, status1);
+ if (!mask) {
+ scp->devices = 0;
+ return;
+ }
+ /*
+ * OK, we have at least one device on the chain, checks for ATAPI
+ * already done, if none check if its a good old ATA device.
+ */
+ if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
+ outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
+ DELAY(1);
+ outb(scp->ioaddr + ATA_ERROR, 0x58);
+ outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
+ if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
+ inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
+ scp->devices |= ATA_ATA_MASTER;
+ }
+ }
+ if (status1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
+ outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
+ DELAY(1);
+ outb(scp->ioaddr + ATA_ERROR, 0x58);
+ outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
+ if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
+ inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
+ scp->devices |= ATA_ATA_SLAVE;
+ }
+ }
}
int32_t
@@ -1460,6 +1495,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 "???";
}
@@ -1512,6 +1548,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)