diff options
author | Tejun Heo <htejun@gmail.com> | 2006-03-31 11:38:18 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-01 14:46:09 -0500 |
commit | e82cbdb9a3791f781462c9d00e3486e8fb7e58a8 (patch) | |
tree | 70c08be45f82a44e86a2889a16841ea58c89fa84 | |
parent | e8e0619f68bff8f39d98c46aac85ed1d4557ccfd (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>
-rw-r--r-- | drivers/scsi/libata-core.c | 66 |
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); |
68 | static void ata_set_mode(struct ata_port *ap); | 68 | static int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev); |
69 | static unsigned int ata_dev_set_xfermode(struct ata_port *ap, | 69 | static unsigned int ata_dev_set_xfermode(struct ata_port *ap, |
70 | struct ata_device *dev); | 70 | struct ata_device *dev); |
71 | static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); | 71 | static 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 | ||
1434 | err_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 | */ |
1783 | static void ata_set_mode(struct ata_port *ap) | 1795 | static 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) | |
1867 | err_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) | |||
4278 | int ata_device_resume(struct ata_port *ap, struct ata_device *dev) | 4290 | int 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; |