diff options
author | sos <sos@FreeBSD.org> | 2000-11-12 20:40:05 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2000-11-12 20:40:05 +0000 |
commit | d17388a5b237b0370d7e306255870c472cf2a4ef (patch) | |
tree | dcd4d587ec4130a70f5d16051882f55a6cc65387 /sys/dev/ata | |
parent | 8b434b8934afbc111310983998496e70c63ae63e (diff) | |
download | FreeBSD-src-d17388a5b237b0370d7e306255870c472cf2a4ef.zip FreeBSD-src-d17388a5b237b0370d7e306255870c472cf2a4ef.tar.gz |
Hopefully fix the probing problems that caused lost slaves etc..
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-all.c | 120 |
1 files changed, 67 insertions, 53 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 28586d0..98aa0b8 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -766,15 +766,6 @@ DRIVER_MODULE(ata, atapci, ata_pcisub_driver, ata_devclass, 0, 0); #endif static int -ata_testregs(struct ata_softc *scp) -{ - outb(scp->ioaddr + ATA_ERROR, 0x58); - outb(scp->ioaddr + ATA_CYL_LSB, 0xa5); - return (inb(scp->ioaddr + ATA_ERROR) != 0x58 && - inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5); -} - -static int ata_probe(device_t dev) { struct ata_softc *scp = device_get_softc(dev); @@ -835,16 +826,15 @@ ata_probe(device_t dev) outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER); DELAY(1); status0 = inb(scp->ioaddr + ATA_STATUS); - if ((status0 & 0xf8) != 0xf8 && status0 != 0xa5 && ata_testregs(scp)) + if ((status0 & 0xf8) != 0xf8 && status0 != 0xa5) mask |= 0x01; - outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); DELAY(1); status1 = inb(scp->ioaddr + ATA_STATUS); - if ((status1 & 0xf8) != 0xf8 && status1 != 0xa5 && ata_testregs(scp)) + if ((status1 & 0xf8) != 0xf8 && status1 != 0xa5) mask |= 0x02; - if (bootverbose) + /*if (bootverbose)*/ ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n", mask, status0, status1); if (!mask) @@ -1247,50 +1237,63 @@ void ata_reset(struct ata_softc *scp, int *mask) { int timeout; + u_int8_t a, b, ostat0, ostat1; u_int8_t status0 = ATA_S_BUSY, status1 = ATA_S_BUSY; - /* reset channel */ + /* get the current status of the devices */ + outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); + DELAY(10); + ostat1 = inb(scp->ioaddr + ATA_STATUS); outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER); - DELAY(1); - inb(scp->ioaddr + ATA_STATUS); + DELAY(10); + ostat0 = inb(scp->ioaddr + ATA_STATUS); + + /* in some setups we dont want to test for a slave */ + if (scp->flags & ATA_NO_SLAVE) + *mask &= ~0x02; + + /*if (bootverbose)*/ + ata_printf(scp, -1, "mask=%02x ostat0=%02x ostat2=%02x\n", + *mask, ostat0, ostat1); + + /* reset channel */ outb(scp->altioaddr, ATA_A_IDS | ATA_A_RESET); DELAY(10000); outb(scp->altioaddr, ATA_A_IDS); DELAY(100000); inb(scp->ioaddr + ATA_ERROR); - DELAY(3000); scp->devices = 0; - /* in some setups we dont want to test for a slave */ - if (scp->flags & ATA_NO_SLAVE) - *mask &= ~0x02; - /* wait for BUSY to go inactive */ for (timeout = 0; timeout < 310000; timeout++) { 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; - } - } + outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER); + DELAY(10); + status0 = inb(scp->ioaddr + ATA_STATUS); + if (!(status0 & ATA_S_BUSY)) { + /* check for ATAPI signature while its still there */ + a = inb(scp->ioaddr + ATA_CYL_LSB); + b = inb(scp->ioaddr + ATA_CYL_MSB); +ata_printf(scp, ATA_MASTER, "ATAPI probe a=%02x b=%02x\n", a, b); + if (a == ATAPI_MAGIC_LSB && b == ATAPI_MAGIC_MSB) + scp->devices |= ATA_ATAPI_MASTER; + } + } + if (status1 & ATA_S_BUSY) { + outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); + DELAY(10); + status1 = inb(scp->ioaddr + ATA_STATUS); + if (!(status1 & ATA_S_BUSY)) { + /* check for ATAPI signature while its still there */ + a = inb(scp->ioaddr + ATA_CYL_LSB); + b = inb(scp->ioaddr + ATA_CYL_MSB); +ata_printf(scp, ATA_SLAVE, "ATAPI probe a=%02x b=%02x\n", a, b); + if (a == ATAPI_MAGIC_LSB && b == ATAPI_MAGIC_MSB) + scp->devices |= ATA_ATAPI_SLAVE; + } + } if (*mask == 0x01) /* wait for master only */ - if (!(status0 & ATA_S_BUSY)) + if (!(status0 & ATA_S_BUSY)) break; if (*mask == 0x02) /* wait for slave only */ if (!(status1 & ATA_S_BUSY)) @@ -1300,31 +1303,42 @@ ata_reset(struct ata_softc *scp, int *mask) break; DELAY(100); } - DELAY(1); + DELAY(10); outb(scp->altioaddr, ATA_A_4BIT); if (status0 & ATA_S_BUSY) *mask &= ~0x01; if (status1 & ATA_S_BUSY) *mask &= ~0x02; - if (bootverbose) + /*if (bootverbose)*/ ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n", *mask, status0, status1); if (!mask) return; - if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) { - outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER)); - DELAY(1); - if (ata_testregs(scp)) + if (*mask & 0x01 && ostat0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) { + outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER); + DELAY(10); + outb(scp->ioaddr + ATA_ERROR, 0x58); + outb(scp->ioaddr + ATA_CYL_LSB, 0xa5); + a = inb(scp->ioaddr + ATA_ERROR); + b = inb(scp->ioaddr + ATA_CYL_LSB); +ata_printf(scp, ATA_MASTER, "ATA probe a=%02x b=%02x\n", a, b); + if (a != 0x58 && b == 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); - if (ata_testregs(scp)) + if (*mask & 0x02 && ostat1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) { + outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); + DELAY(10); + outb(scp->ioaddr + ATA_ERROR, 0x58); + outb(scp->ioaddr + ATA_CYL_LSB, 0xa5); + a = inb(scp->ioaddr + ATA_ERROR); + b = inb(scp->ioaddr + ATA_CYL_LSB); +ata_printf(scp, ATA_SLAVE, "ATA probe a=%02x b=%02x\n", a, b); + if (a != 0x58 && b == 0xa5) scp->devices |= ATA_ATA_SLAVE; } +ata_printf(scp, -1, "devices=%02x\n", scp->devices); } int |