Hopefully fix the probing problems that caused lost slaves etc..
This commit is contained in:
parent
8b434b8934
commit
d17388a5b2
@ -765,15 +765,6 @@ static driver_t ata_pcisub_driver = {
|
|||||||
DRIVER_MODULE(ata, atapci, ata_pcisub_driver, ata_devclass, 0, 0);
|
DRIVER_MODULE(ata, atapci, ata_pcisub_driver, ata_devclass, 0, 0);
|
||||||
#endif
|
#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
|
static int
|
||||||
ata_probe(device_t dev)
|
ata_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -835,16 +826,15 @@ ata_probe(device_t dev)
|
|||||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
|
||||||
DELAY(1);
|
DELAY(1);
|
||||||
status0 = inb(scp->ioaddr + ATA_STATUS);
|
status0 = inb(scp->ioaddr + ATA_STATUS);
|
||||||
if ((status0 & 0xf8) != 0xf8 && status0 != 0xa5 && ata_testregs(scp))
|
if ((status0 & 0xf8) != 0xf8 && status0 != 0xa5)
|
||||||
mask |= 0x01;
|
mask |= 0x01;
|
||||||
|
|
||||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
||||||
DELAY(1);
|
DELAY(1);
|
||||||
status1 = inb(scp->ioaddr + ATA_STATUS);
|
status1 = inb(scp->ioaddr + ATA_STATUS);
|
||||||
if ((status1 & 0xf8) != 0xf8 && status1 != 0xa5 && ata_testregs(scp))
|
if ((status1 & 0xf8) != 0xf8 && status1 != 0xa5)
|
||||||
mask |= 0x02;
|
mask |= 0x02;
|
||||||
|
|
||||||
if (bootverbose)
|
/*if (bootverbose)*/
|
||||||
ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n",
|
ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n",
|
||||||
mask, status0, status1);
|
mask, status0, status1);
|
||||||
if (!mask)
|
if (!mask)
|
||||||
@ -1247,45 +1237,58 @@ void
|
|||||||
ata_reset(struct ata_softc *scp, int *mask)
|
ata_reset(struct ata_softc *scp, int *mask)
|
||||||
{
|
{
|
||||||
int timeout;
|
int timeout;
|
||||||
|
u_int8_t a, b, ostat0, ostat1;
|
||||||
u_int8_t status0 = ATA_S_BUSY, status1 = ATA_S_BUSY;
|
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);
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
|
||||||
DELAY(1);
|
DELAY(10);
|
||||||
inb(scp->ioaddr + ATA_STATUS);
|
ostat0 = inb(scp->ioaddr + ATA_STATUS);
|
||||||
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 */
|
/* in some setups we dont want to test for a slave */
|
||||||
if (scp->flags & ATA_NO_SLAVE)
|
if (scp->flags & ATA_NO_SLAVE)
|
||||||
*mask &= ~0x02;
|
*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);
|
||||||
|
scp->devices = 0;
|
||||||
|
|
||||||
/* wait for BUSY to go inactive */
|
/* wait for BUSY to go inactive */
|
||||||
for (timeout = 0; timeout < 310000; timeout++) {
|
for (timeout = 0; timeout < 310000; timeout++) {
|
||||||
if (status0 & ATA_S_BUSY) {
|
if (status0 & ATA_S_BUSY) {
|
||||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
|
||||||
DELAY(1);
|
DELAY(10);
|
||||||
status0 = inb(scp->ioaddr + ATA_STATUS);
|
status0 = inb(scp->ioaddr + ATA_STATUS);
|
||||||
if (!(status0 & ATA_S_BUSY)) {
|
if (!(status0 & ATA_S_BUSY)) {
|
||||||
/* check for ATAPI signature while its still there */
|
/* check for ATAPI signature while its still there */
|
||||||
if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
|
a = inb(scp->ioaddr + ATA_CYL_LSB);
|
||||||
inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
|
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;
|
scp->devices |= ATA_ATAPI_MASTER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status1 & ATA_S_BUSY) {
|
if (status1 & ATA_S_BUSY) {
|
||||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
||||||
DELAY(1);
|
DELAY(10);
|
||||||
status1 = inb(scp->ioaddr + ATA_STATUS);
|
status1 = inb(scp->ioaddr + ATA_STATUS);
|
||||||
if (!(status1 & ATA_S_BUSY)) {
|
if (!(status1 & ATA_S_BUSY)) {
|
||||||
/* check for ATAPI signature while its still there */
|
/* check for ATAPI signature while its still there */
|
||||||
if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
|
a = inb(scp->ioaddr + ATA_CYL_LSB);
|
||||||
inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
|
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;
|
scp->devices |= ATA_ATAPI_SLAVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1300,31 +1303,42 @@ ata_reset(struct ata_softc *scp, int *mask)
|
|||||||
break;
|
break;
|
||||||
DELAY(100);
|
DELAY(100);
|
||||||
}
|
}
|
||||||
DELAY(1);
|
DELAY(10);
|
||||||
outb(scp->altioaddr, ATA_A_4BIT);
|
outb(scp->altioaddr, ATA_A_4BIT);
|
||||||
|
|
||||||
if (status0 & ATA_S_BUSY)
|
if (status0 & ATA_S_BUSY)
|
||||||
*mask &= ~0x01;
|
*mask &= ~0x01;
|
||||||
if (status1 & ATA_S_BUSY)
|
if (status1 & ATA_S_BUSY)
|
||||||
*mask &= ~0x02;
|
*mask &= ~0x02;
|
||||||
if (bootverbose)
|
/*if (bootverbose)*/
|
||||||
ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n",
|
ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n",
|
||||||
*mask, status0, status1);
|
*mask, status0, status1);
|
||||||
if (!mask)
|
if (!mask)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
|
if (*mask & 0x01 && ostat0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
|
||||||
outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
|
||||||
DELAY(1);
|
DELAY(10);
|
||||||
if (ata_testregs(scp))
|
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;
|
scp->devices |= ATA_ATA_MASTER;
|
||||||
}
|
}
|
||||||
if (status1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
|
if (*mask & 0x02 && ostat1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
|
||||||
outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
||||||
DELAY(1);
|
DELAY(10);
|
||||||
if (ata_testregs(scp))
|
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;
|
scp->devices |= ATA_ATA_SLAVE;
|
||||||
}
|
}
|
||||||
|
ata_printf(scp, -1, "devices=%02x\n", scp->devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user