aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/libata-eh.c13
-rw-r--r--include/linux/libata.h2
3 files changed, 16 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e294731a7edd..5028396029b3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2158,6 +2158,7 @@ int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
2158 2158
2159static int ata_dev_set_mode(struct ata_device *dev) 2159static int ata_dev_set_mode(struct ata_device *dev)
2160{ 2160{
2161 struct ata_eh_context *ehc = &dev->ap->eh_context;
2161 unsigned int err_mask; 2162 unsigned int err_mask;
2162 int rc; 2163 int rc;
2163 2164
@@ -2172,7 +2173,9 @@ static int ata_dev_set_mode(struct ata_device *dev)
2172 return -EIO; 2173 return -EIO;
2173 } 2174 }
2174 2175
2176 ehc->i.flags |= ATA_EHI_POST_SETMODE;
2175 rc = ata_dev_revalidate(dev, 0); 2177 rc = ata_dev_revalidate(dev, 0);
2178 ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
2176 if (rc) 2179 if (rc)
2177 return rc; 2180 return rc;
2178 2181
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 7c446442616c..477648801a65 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1653,6 +1653,11 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1653 1653
1654 ata_eh_done(ap, dev, ATA_EH_REVALIDATE); 1654 ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
1655 1655
1656 /* Configuration may have changed, reconfigure
1657 * transfer mode.
1658 */
1659 ehc->i.flags |= ATA_EHI_SETMODE;
1660
1656 /* schedule the scsi_rescan_device() here */ 1661 /* schedule the scsi_rescan_device() here */
1657 queue_work(ata_aux_wq, &(ap->scsi_rescan_task)); 1662 queue_work(ata_aux_wq, &(ap->scsi_rescan_task));
1658 } else if (dev->class == ATA_DEV_UNKNOWN && 1663 } else if (dev->class == ATA_DEV_UNKNOWN &&
@@ -1675,6 +1680,9 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1675 spin_lock_irqsave(ap->lock, flags); 1680 spin_lock_irqsave(ap->lock, flags);
1676 ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; 1681 ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
1677 spin_unlock_irqrestore(ap->lock, flags); 1682 spin_unlock_irqrestore(ap->lock, flags);
1683
1684 /* new device discovered, configure transfer mode */
1685 ehc->i.flags |= ATA_EHI_SETMODE;
1678 } 1686 }
1679 } 1687 }
1680 1688
@@ -1990,13 +1998,14 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1990 if (rc) 1998 if (rc)
1991 goto dev_fail; 1999 goto dev_fail;
1992 2000
1993 /* configure transfer mode if the port has been reset */ 2001 /* configure transfer mode if necessary */
1994 if (ehc->i.flags & ATA_EHI_DID_RESET) { 2002 if (ehc->i.flags & ATA_EHI_SETMODE) {
1995 rc = ata_set_mode(ap, &dev); 2003 rc = ata_set_mode(ap, &dev);
1996 if (rc) { 2004 if (rc) {
1997 down_xfermask = 1; 2005 down_xfermask = 1;
1998 goto dev_fail; 2006 goto dev_fail;
1999 } 2007 }
2008 ehc->i.flags &= ~ATA_EHI_SETMODE;
2000 } 2009 }
2001 2010
2002 /* suspend devices */ 2011 /* suspend devices */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 949484627e67..0d0ddeaee73f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -284,6 +284,8 @@ enum {
284 284
285 ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ 285 ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */
286 ATA_EHI_PRINTINFO = (1 << 17), /* print configuration info */ 286 ATA_EHI_PRINTINFO = (1 << 17), /* print configuration info */
287 ATA_EHI_SETMODE = (1 << 18), /* configure transfer mode */
288 ATA_EHI_POST_SETMODE = (1 << 19), /* revaildating after setmode */
287 289
288 ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, 290 ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
289 291