summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/ahci.c14
-rw-r--r--drivers/ata/libata-core.c33
-rw-r--r--drivers/ata/sata_inic162x.c3
3 files changed, 30 insertions, 20 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 0319f10d42d..d9617892fc2 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -960,15 +960,13 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class,
*/
msleep(150);
- *class = ATA_DEV_NONE;
- if (ata_port_online(ap)) {
- rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV) {
- reason = "device not ready";
- goto fail;
- }
- *class = ahci_dev_classify(ap);
+ rc = ata_wait_ready(ap, deadline);
+ /* link occupied, -ENODEV too is an error */
+ if (rc) {
+ reason = "device not ready";
+ goto fail;
}
+ *class = ahci_dev_classify(ap);
DPRINTK("EXIT, class=%u\n", *class);
return 0;
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 84e9448c12d..49d26675932 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3027,15 +3027,18 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int dev0 = devmask & (1 << 0);
unsigned int dev1 = devmask & (1 << 1);
- int rc;
+ int rc, ret = 0;
/* if device 0 was found in ata_devchk, wait for its
* BSY bit to clear
*/
if (dev0) {
rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV)
- return rc;
+ if (rc) {
+ if (rc != -ENODEV)
+ return rc;
+ ret = rc;
+ }
}
/* if device 1 was found in ata_devchk, wait for
@@ -3055,8 +3058,11 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
}
if (dev1) {
rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV)
- return rc;
+ if (rc) {
+ if (rc != -ENODEV)
+ return rc;
+ ret = rc;
+ }
}
/* is all this really necessary? */
@@ -3066,7 +3072,7 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
if (dev0)
ap->ops->dev_select(ap, 0);
- return 0;
+ return ret;
}
static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
@@ -3100,7 +3106,7 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
* pulldown resistor.
*/
if (ata_check_status(ap) == 0xFF)
- return 0;
+ return -ENODEV;
return ata_bus_post_reset(ap, devmask, deadline);
}
@@ -3131,6 +3137,7 @@ void ata_bus_reset(struct ata_port *ap)
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
u8 err;
unsigned int dev0, dev1 = 0, devmask = 0;
+ int rc;
DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no);
@@ -3152,9 +3159,11 @@ void ata_bus_reset(struct ata_port *ap)
ap->ops->dev_select(ap, 0);
/* issue bus reset */
- if (ap->flags & ATA_FLAG_SRST)
- if (ata_bus_softreset(ap, devmask, jiffies + 40 * HZ))
+ if (ap->flags & ATA_FLAG_SRST) {
+ rc = ata_bus_softreset(ap, devmask, jiffies + 40 * HZ);
+ if (rc && rc != -ENODEV)
goto err_out;
+ }
/*
* determine by signature whether we have ATA or ATAPI devices
@@ -3417,7 +3426,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
/* issue bus reset */
DPRINTK("about to softreset, devmask=%x\n", devmask);
rc = ata_bus_softreset(ap, devmask, deadline);
- if (rc) {
+ /* if link is occupied, -ENODEV too is an error */
+ if (rc && (rc != -ENODEV || sata_scr_valid(ap))) {
ata_port_printk(ap, KERN_ERR, "SRST failed (errno=%d)\n", rc);
return rc;
}
@@ -3534,7 +3544,8 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
msleep(150);
rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV) {
+ /* link occupied, -ENODEV too is an error */
+ if (rc) {
ata_port_printk(ap, KERN_ERR,
"COMRESET failed (errno=%d)\n", rc);
return rc;
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 25b747e2613..b3b62e985f1 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -453,7 +453,8 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class,
msleep(150);
rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV) {
+ /* link occupied, -ENODEV too is an error */
+ if (rc) {
ata_port_printk(ap, KERN_WARNING, "device not ready "
"after hardreset (errno=%d)\n", rc);
return rc;