|
@@ -2328,11 +2328,14 @@ static inline void ata_tf_to_host(struct ata_port *ap,
|
|
* Sleep until ATA Status register bit BSY clears,
|
|
* Sleep until ATA Status register bit BSY clears,
|
|
* or a timeout occurs.
|
|
* or a timeout occurs.
|
|
*
|
|
*
|
|
- * LOCKING: None.
|
|
|
|
|
|
+ * LOCKING:
|
|
|
|
+ * Kernel thread context (may sleep).
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on success, -errno otherwise.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
-unsigned int ata_busy_sleep (struct ata_port *ap,
|
|
|
|
- unsigned long tmout_pat, unsigned long tmout)
|
|
|
|
|
|
+int ata_busy_sleep(struct ata_port *ap,
|
|
|
|
+ unsigned long tmout_pat, unsigned long tmout)
|
|
{
|
|
{
|
|
unsigned long timer_start, timeout;
|
|
unsigned long timer_start, timeout;
|
|
u8 status;
|
|
u8 status;
|
|
@@ -2340,27 +2343,32 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
|
|
status = ata_busy_wait(ap, ATA_BUSY, 300);
|
|
status = ata_busy_wait(ap, ATA_BUSY, 300);
|
|
timer_start = jiffies;
|
|
timer_start = jiffies;
|
|
timeout = timer_start + tmout_pat;
|
|
timeout = timer_start + tmout_pat;
|
|
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
|
|
|
|
|
|
+ while (status != 0xff && (status & ATA_BUSY) &&
|
|
|
|
+ time_before(jiffies, timeout)) {
|
|
msleep(50);
|
|
msleep(50);
|
|
status = ata_busy_wait(ap, ATA_BUSY, 3);
|
|
status = ata_busy_wait(ap, ATA_BUSY, 3);
|
|
}
|
|
}
|
|
|
|
|
|
- if (status & ATA_BUSY)
|
|
|
|
|
|
+ if (status != 0xff && (status & ATA_BUSY))
|
|
ata_port_printk(ap, KERN_WARNING,
|
|
ata_port_printk(ap, KERN_WARNING,
|
|
"port is slow to respond, please be patient "
|
|
"port is slow to respond, please be patient "
|
|
"(Status 0x%x)\n", status);
|
|
"(Status 0x%x)\n", status);
|
|
|
|
|
|
timeout = timer_start + tmout;
|
|
timeout = timer_start + tmout;
|
|
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
|
|
|
|
|
|
+ while (status != 0xff && (status & ATA_BUSY) &&
|
|
|
|
+ time_before(jiffies, timeout)) {
|
|
msleep(50);
|
|
msleep(50);
|
|
status = ata_chk_status(ap);
|
|
status = ata_chk_status(ap);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (status == 0xff)
|
|
|
|
+ return -ENODEV;
|
|
|
|
+
|
|
if (status & ATA_BUSY) {
|
|
if (status & ATA_BUSY) {
|
|
ata_port_printk(ap, KERN_ERR, "port failed to respond "
|
|
ata_port_printk(ap, KERN_ERR, "port failed to respond "
|
|
"(%lu secs, Status 0x%x)\n",
|
|
"(%lu secs, Status 0x%x)\n",
|
|
tmout / HZ, status);
|
|
tmout / HZ, status);
|
|
- return 1;
|
|
|
|
|
|
+ return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -2451,10 +2459,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
|
|
* the bus shows 0xFF because the odd clown forgets the D7
|
|
* the bus shows 0xFF because the odd clown forgets the D7
|
|
* pulldown resistor.
|
|
* pulldown resistor.
|
|
*/
|
|
*/
|
|
- if (ata_check_status(ap) == 0xFF) {
|
|
|
|
- ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
|
|
|
|
- return AC_ERR_OTHER;
|
|
|
|
- }
|
|
|
|
|
|
+ if (ata_check_status(ap) == 0xFF)
|
|
|
|
+ return 0;
|
|
|
|
|
|
ata_bus_post_reset(ap, devmask);
|
|
ata_bus_post_reset(ap, devmask);
|
|
|
|
|