aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-03-24 01:25:31 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-24 09:39:57 -0500
commit83206a2903fd2ddb1761d906b2b3b3de17ef87f1 (patch)
tree405de7b43809146ae27a52cad00a897369644f61 /drivers/scsi/libata-core.c
parentfcef978f9d4bd6ec43f89031442ee205987a912a (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.c56
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 @@
64static unsigned int ata_dev_init_params(struct ata_port *ap, 64static unsigned int ata_dev_init_params(struct ata_port *ap,
65 struct ata_device *dev); 65 struct ata_device *dev);
66static void ata_set_mode(struct ata_port *ap); 66static void ata_set_mode(struct ata_port *ap);
67static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); 67static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
68 struct ata_device *dev);
68static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); 69static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev);
69 70
70static unsigned int ata_unique_id = 1; 71static 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
1745static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) 1746static 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
1769static int ata_host_set_pio(struct ata_port *ap) 1779static 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
2729static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) 2746static 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/**