diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index ac200cbad80b..c7a6977e0faa 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -2580,11 +2580,13 @@ static int ahci_sata_connect(struct ahci_channel *ch) { u_int32_t status; - int timeout; + int timeout, found = 0; /* Wait up to 100ms for "connect well" */ for (timeout = 0; timeout < 1000 ; timeout++) { status = ATA_INL(ch->r_mem, AHCI_P_SSTS); + if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) + found = 1; if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) @@ -2596,12 +2598,15 @@ ahci_sata_connect(struct ahci_channel *ch) } return (0); } + if (found == 0 && timeout >= 100) + break; DELAY(100); } - if (timeout >= 1000) { + if (timeout >= 1000 || !found) { if (bootverbose) { - device_printf(ch->dev, "SATA connect timeout status=%08x\n", - status); + device_printf(ch->dev, + "SATA connect timeout time=%dus status=%08x\n", + timeout * 100, status); } return (0); } diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c index 69e7a14357aa..6b6e1b7173ce 100644 --- a/sys/dev/mvs/mvs.c +++ b/sys/dev/mvs/mvs.c @@ -2102,11 +2102,13 @@ static int mvs_sata_connect(struct mvs_channel *ch) { u_int32_t status; - int timeout; + int timeout, found = 0; /* Wait up to 100ms for "connect well" */ - for (timeout = 0; timeout < 100 ; timeout++) { + for (timeout = 0; timeout < 1000 ; timeout++) { status = ATA_INL(ch->r_mem, SATA_SS); + if ((status & SATA_SS_DET_MASK) != SATA_SS_DET_NO_DEVICE) + found = 1; if (((status & SATA_SS_DET_MASK) == SATA_SS_DET_PHY_ONLINE) && ((status & SATA_SS_SPD_MASK) != SATA_SS_SPD_NO_SPEED) && ((status & SATA_SS_IPM_MASK) == SATA_SS_IPM_ACTIVE)) @@ -2118,18 +2120,21 @@ mvs_sata_connect(struct mvs_channel *ch) } return (0); } - DELAY(1000); + if (found == 0 && timeout >= 100) + break; + DELAY(100); } - if (timeout >= 100) { + if (timeout >= 1000 || !found) { if (bootverbose) { - device_printf(ch->dev, "SATA connect timeout status=%08x\n", - status); + device_printf(ch->dev, + "SATA connect timeout time=%dus status=%08x\n", + timeout * 100, status); } return (0); } if (bootverbose) { - device_printf(ch->dev, "SATA connect time=%dms status=%08x\n", - timeout, status); + device_printf(ch->dev, "SATA connect time=%dus status=%08x\n", + timeout * 100, status); } /* Clear SATA error register */ ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff); @@ -2155,11 +2160,10 @@ mvs_sata_phy_reset(device_t dev) ATA_OUTL(ch->r_mem, SATA_SC, SATA_SC_DET_RESET | val | SATA_SC_IPM_DIS_PARTIAL | SATA_SC_IPM_DIS_SLUMBER); - DELAY(5000); + DELAY(1000); ATA_OUTL(ch->r_mem, SATA_SC, SATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 : (SATA_SC_IPM_DIS_PARTIAL | SATA_SC_IPM_DIS_SLUMBER))); - DELAY(5000); if (!mvs_sata_connect(ch)) { if (ch->pm_level > 0) ATA_OUTL(ch->r_mem, SATA_SC, SATA_SC_DET_DISABLE); diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 6e77e2ecb54f..c18b449f0a47 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -1540,10 +1540,10 @@ siis_devreset(device_t dev) ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_DEV_RESET); while (((val = ATA_INL(ch->r_mem, SIIS_P_STS)) & SIIS_P_CTL_DEV_RESET) != 0) { - DELAY(1000); - if (timeout++ > 100) { - device_printf(dev, "device reset stuck (timeout %dms) " - "status = %08x\n", timeout, val); + DELAY(100); + if (timeout++ > 1000) { + device_printf(dev, "device reset stuck " + "(timeout 100ms) status = %08x\n", val); return (EBUSY); } } @@ -1731,27 +1731,39 @@ static int siis_sata_connect(struct siis_channel *ch) { u_int32_t status; - int timeout; + int timeout, found = 0; /* Wait up to 100ms for "connect well" */ - for (timeout = 0; timeout < 100 ; timeout++) { + for (timeout = 0; timeout < 1000 ; timeout++) { status = ATA_INL(ch->r_mem, SIIS_P_SSTS); + if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) + found = 1; if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) break; - DELAY(1000); + if ((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_OFFLINE) { + if (bootverbose) { + device_printf(ch->dev, "SATA offline status=%08x\n", + status); + } + return (0); + } + if (found == 0 && timeout >= 100) + break; + DELAY(100); } - if (timeout >= 100) { + if (timeout >= 1000 || !found) { if (bootverbose) { - device_printf(ch->dev, "SATA connect timeout status=%08x\n", - status); + device_printf(ch->dev, + "SATA connect timeout time=%dus status=%08x\n", + timeout * 100, status); } return (0); } if (bootverbose) { - device_printf(ch->dev, "SATA connect time=%dms status=%08x\n", - timeout, status); + device_printf(ch->dev, "SATA connect time=%dus status=%08x\n", + timeout * 100, status); } /* Clear SATA error register */ ATA_OUTL(ch->r_mem, SIIS_P_SERR, 0xffffffff);