diff options
author | Tejun Heo <htejun@gmail.com> | 2006-03-24 01:25:31 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-24 09:39:57 -0500 |
commit | 83206a2903fd2ddb1761d906b2b3b3de17ef87f1 (patch) | |
tree | 405de7b43809146ae27a52cad00a897369644f61 /drivers/scsi/libata-core.c | |
parent | fcef978f9d4bd6ec43f89031442ee205987a912a (diff) |
[PATCH] libata: make ata_set_mode() responsible for failure handling
Make ata_set_mode() responsible for determining whether to take port
or device offline on failure. ata_dev_set_xfermode() and
ata_dev_set_mode() indicate error to the caller instead of disabling
port directly on failure. Also, for consistency, ata_dev_present()
check is done in ata_set_mode() instead of ata_dev_set_mode().
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.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index b08e79ffd769..6970f6867334 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -64,7 +64,8 @@ | |||
64 | static unsigned int ata_dev_init_params(struct ata_port *ap, | 64 | static unsigned int ata_dev_init_params(struct ata_port *ap, |
65 | struct ata_device *dev); | 65 | struct ata_device *dev); |
66 | static void ata_set_mode(struct ata_port *ap); | 66 | static void ata_set_mode(struct ata_port *ap); |
67 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); | 67 | static unsigned int ata_dev_set_xfermode(struct ata_port *ap, |
68 | struct ata_device *dev); | ||
68 | static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); | 69 | static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); |
69 | 70 | ||
70 | static unsigned int ata_unique_id = 1; | 71 | static unsigned int ata_unique_id = 1; |
@@ -1742,20 +1743,28 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, | |||
1742 | return 0; | 1743 | return 0; |
1743 | } | 1744 | } |
1744 | 1745 | ||
1745 | static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) | 1746 | static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) |
1746 | { | 1747 | { |
1747 | if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED)) | 1748 | unsigned int err_mask; |
1748 | return; | 1749 | int rc; |
1749 | 1750 | ||
1750 | if (dev->xfer_shift == ATA_SHIFT_PIO) | 1751 | if (dev->xfer_shift == ATA_SHIFT_PIO) |
1751 | dev->flags |= ATA_DFLAG_PIO; | 1752 | dev->flags |= ATA_DFLAG_PIO; |
1752 | 1753 | ||
1753 | ata_dev_set_xfermode(ap, dev); | 1754 | err_mask = ata_dev_set_xfermode(ap, dev); |
1755 | if (err_mask) { | ||
1756 | printk(KERN_ERR | ||
1757 | "ata%u: failed to set xfermode (err_mask=0x%x)\n", | ||
1758 | ap->id, err_mask); | ||
1759 | return -EIO; | ||
1760 | } | ||
1754 | 1761 | ||
1755 | if (ata_dev_revalidate(ap, dev, 0)) { | 1762 | rc = ata_dev_revalidate(ap, dev, 0); |
1756 | printk(KERN_ERR "ata%u: failed to revalidate after set " | 1763 | if (rc) { |
1757 | "xfermode, disabled\n", ap->id); | 1764 | printk(KERN_ERR |
1758 | ata_port_disable(ap); | 1765 | "ata%u: failed to revalidate after set xfermode\n", |
1766 | ap->id); | ||
1767 | return rc; | ||
1759 | } | 1768 | } |
1760 | 1769 | ||
1761 | DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", | 1770 | DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", |
@@ -1764,6 +1773,7 @@ static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) | |||
1764 | printk(KERN_INFO "ata%u: dev %u configured for %s\n", | 1773 | printk(KERN_INFO "ata%u: dev %u configured for %s\n", |
1765 | ap->id, dev->devno, | 1774 | ap->id, dev->devno, |
1766 | ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); | 1775 | ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); |
1776 | return 0; | ||
1767 | } | 1777 | } |
1768 | 1778 | ||
1769 | static int ata_host_set_pio(struct ata_port *ap) | 1779 | static int ata_host_set_pio(struct ata_port *ap) |
@@ -1847,11 +1857,15 @@ static void ata_set_mode(struct ata_port *ap) | |||
1847 | ata_host_set_dma(ap); | 1857 | ata_host_set_dma(ap); |
1848 | 1858 | ||
1849 | /* step 4: update devices' xfer mode */ | 1859 | /* step 4: update devices' xfer mode */ |
1850 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1860 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
1851 | ata_dev_set_mode(ap, &ap->device[i]); | 1861 | struct ata_device *dev = &ap->device[i]; |
1852 | 1862 | ||
1853 | if (ap->flags & ATA_FLAG_PORT_DISABLED) | 1863 | if (!ata_dev_present(dev)) |
1854 | return; | 1864 | continue; |
1865 | |||
1866 | if (ata_dev_set_mode(ap, dev)) | ||
1867 | goto err_out; | ||
1868 | } | ||
1855 | 1869 | ||
1856 | if (ap->ops->post_set_mode) | 1870 | if (ap->ops->post_set_mode) |
1857 | ap->ops->post_set_mode(ap); | 1871 | ap->ops->post_set_mode(ap); |
@@ -2724,11 +2738,16 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) | |||
2724 | * | 2738 | * |
2725 | * LOCKING: | 2739 | * LOCKING: |
2726 | * PCI/etc. bus probe sem. | 2740 | * PCI/etc. bus probe sem. |
2741 | * | ||
2742 | * RETURNS: | ||
2743 | * 0 on success, AC_ERR_* mask otherwise. | ||
2727 | */ | 2744 | */ |
2728 | 2745 | ||
2729 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | 2746 | static unsigned int ata_dev_set_xfermode(struct ata_port *ap, |
2747 | struct ata_device *dev) | ||
2730 | { | 2748 | { |
2731 | struct ata_taskfile tf; | 2749 | struct ata_taskfile tf; |
2750 | unsigned int err_mask; | ||
2732 | 2751 | ||
2733 | /* set up set-features taskfile */ | 2752 | /* set up set-features taskfile */ |
2734 | DPRINTK("set features - xfer mode\n"); | 2753 | DPRINTK("set features - xfer mode\n"); |
@@ -2740,13 +2759,10 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
2740 | tf.protocol = ATA_PROT_NODATA; | 2759 | tf.protocol = ATA_PROT_NODATA; |
2741 | tf.nsect = dev->xfer_mode; | 2760 | tf.nsect = dev->xfer_mode; |
2742 | 2761 | ||
2743 | if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) { | 2762 | err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); |
2744 | printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n", | ||
2745 | ap->id); | ||
2746 | ata_port_disable(ap); | ||
2747 | } | ||
2748 | 2763 | ||
2749 | DPRINTK("EXIT\n"); | 2764 | DPRINTK("EXIT, err_mask=%x\n", err_mask); |
2765 | return err_mask; | ||
2750 | } | 2766 | } |
2751 | 2767 | ||
2752 | /** | 2768 | /** |