aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-03-31 11:38:18 -0500
committerJeff Garzik <jeff@garzik.org>2006-04-01 14:46:09 -0500
commite82cbdb9a3791f781462c9d00e3486e8fb7e58a8 (patch)
tree70c08be45f82a44e86a2889a16841ea58c89fa84 /drivers/scsi/libata-core.c
parente8e0619f68bff8f39d98c46aac85ed1d4557ccfd (diff)
[PATCH] libata: don't disable devices from ata_set_mode()
When ata_set_mode() fails on a device, make ata_set_mode() return error code and pointer to the device instead of disabling it directly. This gives more control to higher level driving logic. This patch does not change the end result (configured transfer mode) although it may make libata repeat mode configuration to the peer of a failing device. Later ata_bus_probe() rewrite will make full use of this change. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c66
1 files changed, 40 insertions, 26 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f04561abf6d8..061b0b6544cc 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -65,7 +65,7 @@ static unsigned int ata_dev_init_params(struct ata_port *ap,
65 struct ata_device *dev, 65 struct ata_device *dev,
66 u16 heads, 66 u16 heads,
67 u16 sectors); 67 u16 sectors);
68static void ata_set_mode(struct ata_port *ap); 68static int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
69static unsigned int ata_dev_set_xfermode(struct ata_port *ap, 69static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
70 struct ata_device *dev); 70 struct ata_device *dev);
71static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); 71static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev);
@@ -1368,6 +1368,7 @@ static int ata_bus_probe(struct ata_port *ap)
1368{ 1368{
1369 unsigned int classes[ATA_MAX_DEVICES]; 1369 unsigned int classes[ATA_MAX_DEVICES];
1370 int i, rc, found = 0; 1370 int i, rc, found = 0;
1371 struct ata_device *dev;
1371 1372
1372 ata_port_probe(ap); 1373 ata_port_probe(ap);
1373 1374
@@ -1397,8 +1398,7 @@ static int ata_bus_probe(struct ata_port *ap)
1397 1398
1398 /* read IDENTIFY page and configure devices */ 1399 /* read IDENTIFY page and configure devices */
1399 for (i = 0; i < ATA_MAX_DEVICES; i++) { 1400 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1400 struct ata_device *dev = &ap->device[i]; 1401 dev = &ap->device[i];
1401
1402 dev->class = classes[i]; 1402 dev->class = classes[i];
1403 1403
1404 if (!ata_dev_enabled(dev)) 1404 if (!ata_dev_enabled(dev))
@@ -1418,20 +1418,26 @@ static int ata_bus_probe(struct ata_port *ap)
1418 found = 1; 1418 found = 1;
1419 } 1419 }
1420 1420
1421 if (!found) 1421 /* configure transfer mode */
1422 goto err_out_disable; 1422 if (ap->ops->set_mode) {
1423 1423 /* FIXME: make ->set_mode handle no device case and
1424 if (ap->ops->set_mode) 1424 * return error code and failing device on failure as
1425 ap->ops->set_mode(ap); 1425 * ata_set_mode() does.
1426 else 1426 */
1427 ata_set_mode(ap); 1427 if (found)
1428 1428 ap->ops->set_mode(ap);
1429 if (ap->flags & ATA_FLAG_PORT_DISABLED) 1429 rc = 0;
1430 goto err_out_disable; 1430 } else {
1431 while (ata_set_mode(ap, &dev))
1432 ata_dev_disable(ap, dev);
1433 }
1431 1434
1432 return 0; 1435 for (i = 0; i < ATA_MAX_DEVICES; i++)
1436 if (ata_dev_enabled(&ap->device[i]))
1437 return 0;
1433 1438
1434err_out_disable: 1439 /* no device present, disable port */
1440 ata_port_disable(ap);
1435 ap->ops->port_disable(ap); 1441 ap->ops->port_disable(ap);
1436 return -ENODEV; 1442 return -ENODEV;
1437} 1443}
@@ -1774,16 +1780,22 @@ static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
1774/** 1780/**
1775 * ata_set_mode - Program timings and issue SET FEATURES - XFER 1781 * ata_set_mode - Program timings and issue SET FEATURES - XFER
1776 * @ap: port on which timings will be programmed 1782 * @ap: port on which timings will be programmed
1783 * @r_failed_dev: out paramter for failed device
1777 * 1784 *
1778 * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). 1785 * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If
1786 * ata_set_mode() fails, pointer to the failing device is
1787 * returned in @r_failed_dev.
1779 * 1788 *
1780 * LOCKING: 1789 * LOCKING:
1781 * PCI/etc. bus probe sem. 1790 * PCI/etc. bus probe sem.
1791 *
1792 * RETURNS:
1793 * 0 on success, negative errno otherwise
1782 */ 1794 */
1783static void ata_set_mode(struct ata_port *ap) 1795static int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
1784{ 1796{
1785 struct ata_device *dev; 1797 struct ata_device *dev;
1786 int i, rc, used_dma = 0, found = 0; 1798 int i, rc = 0, used_dma = 0, found = 0;
1787 1799
1788 /* step 1: calculate xfer_mask */ 1800 /* step 1: calculate xfer_mask */
1789 for (i = 0; i < ATA_MAX_DEVICES; i++) { 1801 for (i = 0; i < ATA_MAX_DEVICES; i++) {
@@ -1806,7 +1818,7 @@ static void ata_set_mode(struct ata_port *ap)
1806 used_dma = 1; 1818 used_dma = 1;
1807 } 1819 }
1808 if (!found) 1820 if (!found)
1809 return; 1821 goto out;
1810 1822
1811 /* step 2: always set host PIO timings */ 1823 /* step 2: always set host PIO timings */
1812 for (i = 0; i < ATA_MAX_DEVICES; i++) { 1824 for (i = 0; i < ATA_MAX_DEVICES; i++) {
@@ -1818,7 +1830,7 @@ static void ata_set_mode(struct ata_port *ap)
1818 printk(KERN_WARNING "ata%u: dev %u no PIO support\n", 1830 printk(KERN_WARNING "ata%u: dev %u no PIO support\n",
1819 ap->id, dev->devno); 1831 ap->id, dev->devno);
1820 rc = -EINVAL; 1832 rc = -EINVAL;
1821 goto err_out; 1833 goto out;
1822 } 1834 }
1823 1835
1824 dev->xfer_mode = dev->pio_mode; 1836 dev->xfer_mode = dev->pio_mode;
@@ -1849,7 +1861,7 @@ static void ata_set_mode(struct ata_port *ap)
1849 1861
1850 rc = ata_dev_set_mode(ap, dev); 1862 rc = ata_dev_set_mode(ap, dev);
1851 if (rc) 1863 if (rc)
1852 goto err_out; 1864 goto out;
1853 } 1865 }
1854 1866
1855 /* Record simplex status. If we selected DMA then the other 1867 /* Record simplex status. If we selected DMA then the other
@@ -1862,10 +1874,10 @@ static void ata_set_mode(struct ata_port *ap)
1862 if (ap->ops->post_set_mode) 1874 if (ap->ops->post_set_mode)
1863 ap->ops->post_set_mode(ap); 1875 ap->ops->post_set_mode(ap);
1864 1876
1865 return; 1877 out:
1866 1878 if (rc)
1867err_out: 1879 *r_failed_dev = dev;
1868 ata_port_disable(ap); 1880 return rc;
1869} 1881}
1870 1882
1871/** 1883/**
@@ -4278,8 +4290,10 @@ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
4278int ata_device_resume(struct ata_port *ap, struct ata_device *dev) 4290int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
4279{ 4291{
4280 if (ap->flags & ATA_FLAG_SUSPENDED) { 4292 if (ap->flags & ATA_FLAG_SUSPENDED) {
4293 struct ata_device *failed_dev;
4281 ap->flags &= ~ATA_FLAG_SUSPENDED; 4294 ap->flags &= ~ATA_FLAG_SUSPENDED;
4282 ata_set_mode(ap); 4295 while (ata_set_mode(ap, &failed_dev))
4296 ata_dev_disable(ap, failed_dev);
4283 } 4297 }
4284 if (!ata_dev_enabled(dev)) 4298 if (!ata_dev_enabled(dev))
4285 return 0; 4299 return 0;