aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-05-04 15:27:47 -0400
committerJeff Garzik <jeff@garzik.org>2007-05-11 18:01:03 -0400
commit9666f4009c22f6520ac3fb8a19c9e32ab973e828 (patch)
treeeaac13cd5890af6298e5576a48c29891f0890bd1 /drivers/ata/libata-eh.c
parent0a3fd051c7036ef71b58863f8e5da7c3dabd9d3f (diff)
libata: reimplement suspend/resume support using sdev->manage_start_stop
Reimplement suspend/resume support using sdev->manage_start_stop. * Device suspend/resume is now SCSI layer's responsibility and the code is simplified a lot. * DPM is dropped. This also simplifies code a lot. Suspend/resume status is port-wide now. * ata_scsi_device_suspend/resume() and ata_dev_ready() removed. * Resume now has to wait for disk to spin up before proceeding. I couldn't find easy way out as libata is in EH waiting for the disk to be ready and sd is waiting for EH to complete to issue START_STOP. * sdev->manage_start_stop is set to 1 in ata_scsi_slave_config(). This fixes spindown on shutdown and suspend-to-disk. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c237
1 files changed, 4 insertions, 233 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 8256655ce7d9..412d6049afa3 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -77,29 +77,12 @@ static void ata_eh_finish(struct ata_port *ap);
77#ifdef CONFIG_PM 77#ifdef CONFIG_PM
78static void ata_eh_handle_port_suspend(struct ata_port *ap); 78static void ata_eh_handle_port_suspend(struct ata_port *ap);
79static void ata_eh_handle_port_resume(struct ata_port *ap); 79static void ata_eh_handle_port_resume(struct ata_port *ap);
80static int ata_eh_suspend(struct ata_port *ap,
81 struct ata_device **r_failed_dev);
82static void ata_eh_prep_resume(struct ata_port *ap);
83static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev);
84#else /* CONFIG_PM */ 80#else /* CONFIG_PM */
85static void ata_eh_handle_port_suspend(struct ata_port *ap) 81static void ata_eh_handle_port_suspend(struct ata_port *ap)
86{ } 82{ }
87 83
88static void ata_eh_handle_port_resume(struct ata_port *ap) 84static void ata_eh_handle_port_resume(struct ata_port *ap)
89{ } 85{ }
90
91static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
92{
93 return 0;
94}
95
96static void ata_eh_prep_resume(struct ata_port *ap)
97{ }
98
99static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
100{
101 return 0;
102}
103#endif /* CONFIG_PM */ 86#endif /* CONFIG_PM */
104 87
105static void ata_ering_record(struct ata_ering *ering, int is_io, 88static void ata_ering_record(struct ata_ering *ering, int is_io,
@@ -1791,7 +1774,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1791 if (ehc->i.flags & ATA_EHI_DID_RESET) 1774 if (ehc->i.flags & ATA_EHI_DID_RESET)
1792 readid_flags |= ATA_READID_POSTRESET; 1775 readid_flags |= ATA_READID_POSTRESET;
1793 1776
1794 if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { 1777 if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
1795 if (ata_port_offline(ap)) { 1778 if (ata_port_offline(ap)) {
1796 rc = -EIO; 1779 rc = -EIO;
1797 goto err; 1780 goto err;
@@ -1872,166 +1855,6 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1872 return rc; 1855 return rc;
1873} 1856}
1874 1857
1875#ifdef CONFIG_PM
1876/**
1877 * ata_eh_suspend - handle suspend EH action
1878 * @ap: target host port
1879 * @r_failed_dev: result parameter to indicate failing device
1880 *
1881 * Handle suspend EH action. Disk devices are spinned down and
1882 * other types of devices are just marked suspended. Once
1883 * suspended, no EH action to the device is allowed until it is
1884 * resumed.
1885 *
1886 * LOCKING:
1887 * Kernel thread context (may sleep).
1888 *
1889 * RETURNS:
1890 * 0 on success, -errno otherwise
1891 */
1892static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
1893{
1894 struct ata_device *dev;
1895 int i, rc = 0;
1896
1897 DPRINTK("ENTER\n");
1898
1899 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1900 unsigned long flags;
1901 unsigned int action, err_mask;
1902
1903 dev = &ap->device[i];
1904 action = ata_eh_dev_action(dev);
1905
1906 if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND))
1907 continue;
1908
1909 WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED);
1910
1911 ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND);
1912
1913 if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
1914 /* flush cache */
1915 rc = ata_flush_cache(dev);
1916 if (rc)
1917 break;
1918
1919 /* spin down */
1920 err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1);
1921 if (err_mask) {
1922 ata_dev_printk(dev, KERN_ERR, "failed to "
1923 "spin down (err_mask=0x%x)\n",
1924 err_mask);
1925 rc = -EIO;
1926 break;
1927 }
1928 }
1929
1930 spin_lock_irqsave(ap->lock, flags);
1931 dev->flags |= ATA_DFLAG_SUSPENDED;
1932 spin_unlock_irqrestore(ap->lock, flags);
1933
1934 ata_eh_done(ap, dev, ATA_EH_SUSPEND);
1935 }
1936
1937 if (rc)
1938 *r_failed_dev = dev;
1939
1940 DPRINTK("EXIT\n");
1941 return rc;
1942}
1943
1944/**
1945 * ata_eh_prep_resume - prep for resume EH action
1946 * @ap: target host port
1947 *
1948 * Clear SUSPENDED in preparation for scheduled resume actions.
1949 * This allows other parts of EH to access the devices being
1950 * resumed.
1951 *
1952 * LOCKING:
1953 * Kernel thread context (may sleep).
1954 */
1955static void ata_eh_prep_resume(struct ata_port *ap)
1956{
1957 struct ata_device *dev;
1958 unsigned long flags;
1959 int i;
1960
1961 DPRINTK("ENTER\n");
1962
1963 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1964 unsigned int action;
1965
1966 dev = &ap->device[i];
1967 action = ata_eh_dev_action(dev);
1968
1969 if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
1970 continue;
1971
1972 spin_lock_irqsave(ap->lock, flags);
1973 dev->flags &= ~ATA_DFLAG_SUSPENDED;
1974 spin_unlock_irqrestore(ap->lock, flags);
1975 }
1976
1977 DPRINTK("EXIT\n");
1978}
1979
1980/**
1981 * ata_eh_resume - handle resume EH action
1982 * @ap: target host port
1983 * @r_failed_dev: result parameter to indicate failing device
1984 *
1985 * Handle resume EH action. Target devices are already reset and
1986 * revalidated. Spinning up is the only operation left.
1987 *
1988 * LOCKING:
1989 * Kernel thread context (may sleep).
1990 *
1991 * RETURNS:
1992 * 0 on success, -errno otherwise
1993 */
1994static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
1995{
1996 struct ata_device *dev;
1997 int i, rc = 0;
1998
1999 DPRINTK("ENTER\n");
2000
2001 for (i = 0; i < ATA_MAX_DEVICES; i++) {
2002 unsigned int action, err_mask;
2003
2004 dev = &ap->device[i];
2005 action = ata_eh_dev_action(dev);
2006
2007 if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
2008 continue;
2009
2010 ata_eh_about_to_do(ap, dev, ATA_EH_RESUME);
2011
2012 if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
2013 err_mask = ata_do_simple_cmd(dev,
2014 ATA_CMD_IDLEIMMEDIATE);
2015 if (err_mask) {
2016 ata_dev_printk(dev, KERN_ERR, "failed to "
2017 "spin up (err_mask=0x%x)\n",
2018 err_mask);
2019 rc = -EIO;
2020 break;
2021 }
2022 }
2023
2024 ata_eh_done(ap, dev, ATA_EH_RESUME);
2025 }
2026
2027 if (rc)
2028 *r_failed_dev = dev;
2029
2030 DPRINTK("EXIT\n");
2031 return 0;
2032}
2033#endif /* CONFIG_PM */
2034
2035static int ata_port_nr_enabled(struct ata_port *ap) 1858static int ata_port_nr_enabled(struct ata_port *ap)
2036{ 1859{
2037 int i, cnt = 0; 1860 int i, cnt = 0;
@@ -2057,17 +1880,6 @@ static int ata_eh_skip_recovery(struct ata_port *ap)
2057 struct ata_eh_context *ehc = &ap->eh_context; 1880 struct ata_eh_context *ehc = &ap->eh_context;
2058 int i; 1881 int i;
2059 1882
2060 /* skip if all possible devices are suspended */
2061 for (i = 0; i < ata_port_max_devices(ap); i++) {
2062 struct ata_device *dev = &ap->device[i];
2063
2064 if (!(dev->flags & ATA_DFLAG_SUSPENDED))
2065 break;
2066 }
2067
2068 if (i == ata_port_max_devices(ap))
2069 return 1;
2070
2071 /* thaw frozen port, resume link and recover failed devices */ 1883 /* thaw frozen port, resume link and recover failed devices */
2072 if ((ap->pflags & ATA_PFLAG_FROZEN) || 1884 if ((ap->pflags & ATA_PFLAG_FROZEN) ||
2073 (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) 1885 (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
@@ -2147,9 +1959,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
2147 if (ap->pflags & ATA_PFLAG_UNLOADING) 1959 if (ap->pflags & ATA_PFLAG_UNLOADING)
2148 goto out; 1960 goto out;
2149 1961
2150 /* prep for resume */
2151 ata_eh_prep_resume(ap);
2152
2153 /* skip EH if possible. */ 1962 /* skip EH if possible. */
2154 if (ata_eh_skip_recovery(ap)) 1963 if (ata_eh_skip_recovery(ap))
2155 ehc->i.action = 0; 1964 ehc->i.action = 0;
@@ -2177,11 +1986,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
2177 if (rc) 1986 if (rc)
2178 goto dev_fail; 1987 goto dev_fail;
2179 1988
2180 /* resume devices */
2181 rc = ata_eh_resume(ap, &dev);
2182 if (rc)
2183 goto dev_fail;
2184
2185 /* configure transfer mode if necessary */ 1989 /* configure transfer mode if necessary */
2186 if (ehc->i.flags & ATA_EHI_SETMODE) { 1990 if (ehc->i.flags & ATA_EHI_SETMODE) {
2187 rc = ata_set_mode(ap, &dev); 1991 rc = ata_set_mode(ap, &dev);
@@ -2190,11 +1994,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
2190 ehc->i.flags &= ~ATA_EHI_SETMODE; 1994 ehc->i.flags &= ~ATA_EHI_SETMODE;
2191 } 1995 }
2192 1996
2193 /* suspend devices */
2194 rc = ata_eh_suspend(ap, &dev);
2195 if (rc)
2196 goto dev_fail;
2197
2198 goto out; 1997 goto out;
2199 1998
2200 dev_fail: 1999 dev_fail:
@@ -2390,22 +2189,13 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
2390 * 2189 *
2391 * Resume @ap. 2190 * Resume @ap.
2392 * 2191 *
2393 * This function also waits upto one second until all devices
2394 * hanging off this port requests resume EH action. This is to
2395 * prevent invoking EH and thus reset multiple times on resume.
2396 *
2397 * On DPM resume, where some of devices might not be resumed
2398 * together, this may delay port resume upto one second, but such
2399 * DPM resumes are rare and 1 sec delay isn't too bad.
2400 *
2401 * LOCKING: 2192 * LOCKING:
2402 * Kernel thread context (may sleep). 2193 * Kernel thread context (may sleep).
2403 */ 2194 */
2404static void ata_eh_handle_port_resume(struct ata_port *ap) 2195static void ata_eh_handle_port_resume(struct ata_port *ap)
2405{ 2196{
2406 unsigned long timeout;
2407 unsigned long flags; 2197 unsigned long flags;
2408 int i, rc = 0; 2198 int rc = 0;
2409 2199
2410 /* are we resuming? */ 2200 /* are we resuming? */
2411 spin_lock_irqsave(ap->lock, flags); 2201 spin_lock_irqsave(ap->lock, flags);
@@ -2416,31 +2206,12 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
2416 } 2206 }
2417 spin_unlock_irqrestore(ap->lock, flags); 2207 spin_unlock_irqrestore(ap->lock, flags);
2418 2208
2419 /* spurious? */ 2209 WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
2420 if (!(ap->pflags & ATA_PFLAG_SUSPENDED))
2421 goto done;
2422 2210
2423 if (ap->ops->port_resume) 2211 if (ap->ops->port_resume)
2424 rc = ap->ops->port_resume(ap); 2212 rc = ap->ops->port_resume(ap);
2425 2213
2426 /* give devices time to request EH */ 2214 /* report result */
2427 timeout = jiffies + HZ; /* 1s max */
2428 while (1) {
2429 for (i = 0; i < ATA_MAX_DEVICES; i++) {
2430 struct ata_device *dev = &ap->device[i];
2431 unsigned int action = ata_eh_dev_action(dev);
2432
2433 if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
2434 !(action & ATA_EH_RESUME))
2435 break;
2436 }
2437
2438 if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout))
2439 break;
2440 msleep(10);
2441 }
2442
2443 done:
2444 spin_lock_irqsave(ap->lock, flags); 2215 spin_lock_irqsave(ap->lock, flags);
2445 ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); 2216 ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
2446 if (ap->pm_result) { 2217 if (ap->pm_result) {