diff options
author | Tejun Heo <htejun@gmail.com> | 2007-08-06 05:36:23 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-12 14:55:30 -0400 |
commit | f58229f8060055b08b34008ea08f31de1e2f003c (patch) | |
tree | 6ca5ef546671cb975ef3632fb032c238eaf1bb4c /drivers/ata/libata-eh.c | |
parent | 9af5c9c97dc9d599281778864c72b385f0c63341 (diff) |
libata-link: implement and use link/device iterators
Multiple links and different number of devices per link should be
considered to iterate over links and devices. This patch implements
and uses link and device iterators - ata_port_for_each_link() and
ata_link_for_each_dev() - and ata_link_max_devices().
This change makes a lot of functions iterate over only possible
devices instead of from dev 0 to dev ATA_MAX_DEVICES. All such
changes have been examined and nothing should be broken.
While at it, add a separating comment before device helpers to
distinguish them better from link helpers and others.
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.c | 117 |
1 files changed, 59 insertions, 58 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index e2681f56ed44..8c37ec0bbf6c 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -200,23 +200,24 @@ static unsigned int ata_eh_dev_action(struct ata_device *dev) | |||
200 | return ehc->i.action | ehc->i.dev_action[dev->devno]; | 200 | return ehc->i.action | ehc->i.dev_action[dev->devno]; |
201 | } | 201 | } |
202 | 202 | ||
203 | static void ata_eh_clear_action(struct ata_device *dev, | 203 | static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev, |
204 | struct ata_eh_info *ehi, unsigned int action) | 204 | struct ata_eh_info *ehi, unsigned int action) |
205 | { | 205 | { |
206 | int i; | 206 | struct ata_device *tdev; |
207 | 207 | ||
208 | if (!dev) { | 208 | if (!dev) { |
209 | ehi->action &= ~action; | 209 | ehi->action &= ~action; |
210 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 210 | ata_link_for_each_dev(tdev, link) |
211 | ehi->dev_action[i] &= ~action; | 211 | ehi->dev_action[tdev->devno] &= ~action; |
212 | } else { | 212 | } else { |
213 | /* doesn't make sense for port-wide EH actions */ | 213 | /* doesn't make sense for port-wide EH actions */ |
214 | WARN_ON(!(action & ATA_EH_PERDEV_MASK)); | 214 | WARN_ON(!(action & ATA_EH_PERDEV_MASK)); |
215 | 215 | ||
216 | /* break ehi->action into ehi->dev_action */ | 216 | /* break ehi->action into ehi->dev_action */ |
217 | if (ehi->action & action) { | 217 | if (ehi->action & action) { |
218 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 218 | ata_link_for_each_dev(tdev, link) |
219 | ehi->dev_action[i] |= ehi->action & action; | 219 | ehi->dev_action[tdev->devno] |= |
220 | ehi->action & action; | ||
220 | ehi->action &= ~action; | 221 | ehi->action &= ~action; |
221 | } | 222 | } |
222 | 223 | ||
@@ -922,7 +923,8 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) | |||
922 | */ | 923 | */ |
923 | static void ata_eh_detach_dev(struct ata_device *dev) | 924 | static void ata_eh_detach_dev(struct ata_device *dev) |
924 | { | 925 | { |
925 | struct ata_port *ap = dev->link->ap; | 926 | struct ata_link *link = dev->link; |
927 | struct ata_port *ap = link->ap; | ||
926 | unsigned long flags; | 928 | unsigned long flags; |
927 | 929 | ||
928 | ata_dev_disable(dev); | 930 | ata_dev_disable(dev); |
@@ -937,8 +939,8 @@ static void ata_eh_detach_dev(struct ata_device *dev) | |||
937 | } | 939 | } |
938 | 940 | ||
939 | /* clear per-dev EH actions */ | 941 | /* clear per-dev EH actions */ |
940 | ata_eh_clear_action(dev, &dev->link->eh_info, ATA_EH_PERDEV_MASK); | 942 | ata_eh_clear_action(link, dev, &link->eh_info, ATA_EH_PERDEV_MASK); |
941 | ata_eh_clear_action(dev, &dev->link->eh_context.i, ATA_EH_PERDEV_MASK); | 943 | ata_eh_clear_action(link, dev, &link->eh_context.i, ATA_EH_PERDEV_MASK); |
942 | 944 | ||
943 | spin_unlock_irqrestore(ap->lock, flags); | 945 | spin_unlock_irqrestore(ap->lock, flags); |
944 | } | 946 | } |
@@ -978,7 +980,7 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, | |||
978 | ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | 980 | ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; |
979 | } | 981 | } |
980 | 982 | ||
981 | ata_eh_clear_action(dev, ehi, action); | 983 | ata_eh_clear_action(&ap->link, dev, ehi, action); |
982 | 984 | ||
983 | if (!(ehc->i.flags & ATA_EHI_QUIET)) | 985 | if (!(ehc->i.flags & ATA_EHI_QUIET)) |
984 | ap->pflags |= ATA_PFLAG_RECOVERED; | 986 | ap->pflags |= ATA_PFLAG_RECOVERED; |
@@ -1009,7 +1011,7 @@ static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, | |||
1009 | ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | 1011 | ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; |
1010 | } | 1012 | } |
1011 | 1013 | ||
1012 | ata_eh_clear_action(dev, &ehc->i, action); | 1014 | ata_eh_clear_action(&ap->link, dev, &ehc->i, action); |
1013 | } | 1015 | } |
1014 | 1016 | ||
1015 | /** | 1017 | /** |
@@ -1736,10 +1738,11 @@ static void ata_eh_report(struct ata_port *ap) | |||
1736 | static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, | 1738 | static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, |
1737 | unsigned int *classes, unsigned long deadline) | 1739 | unsigned int *classes, unsigned long deadline) |
1738 | { | 1740 | { |
1739 | int i, rc; | 1741 | struct ata_device *dev; |
1742 | int rc; | ||
1740 | 1743 | ||
1741 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1744 | ata_link_for_each_dev(dev, &ap->link) |
1742 | classes[i] = ATA_DEV_UNKNOWN; | 1745 | classes[dev->devno] = ATA_DEV_UNKNOWN; |
1743 | 1746 | ||
1744 | rc = reset(ap, classes, deadline); | 1747 | rc = reset(ap, classes, deadline); |
1745 | if (rc) | 1748 | if (rc) |
@@ -1749,14 +1752,16 @@ static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, | |||
1749 | * is complete and convert all ATA_DEV_UNKNOWN to | 1752 | * is complete and convert all ATA_DEV_UNKNOWN to |
1750 | * ATA_DEV_NONE. | 1753 | * ATA_DEV_NONE. |
1751 | */ | 1754 | */ |
1752 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1755 | ata_link_for_each_dev(dev, &ap->link) |
1753 | if (classes[i] != ATA_DEV_UNKNOWN) | 1756 | if (classes[dev->devno] != ATA_DEV_UNKNOWN) |
1754 | break; | 1757 | break; |
1755 | 1758 | ||
1756 | if (i < ATA_MAX_DEVICES) | 1759 | if (dev) { |
1757 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1760 | ata_link_for_each_dev(dev, &ap->link) { |
1758 | if (classes[i] == ATA_DEV_UNKNOWN) | 1761 | if (classes[dev->devno] == ATA_DEV_UNKNOWN) |
1759 | classes[i] = ATA_DEV_NONE; | 1762 | classes[dev->devno] = ATA_DEV_NONE; |
1763 | } | ||
1764 | } | ||
1760 | 1765 | ||
1761 | return 0; | 1766 | return 0; |
1762 | } | 1767 | } |
@@ -1781,10 +1786,11 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1781 | unsigned int *classes = ehc->classes; | 1786 | unsigned int *classes = ehc->classes; |
1782 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); | 1787 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); |
1783 | int try = 0; | 1788 | int try = 0; |
1789 | struct ata_device *dev; | ||
1784 | unsigned long deadline; | 1790 | unsigned long deadline; |
1785 | unsigned int action; | 1791 | unsigned int action; |
1786 | ata_reset_fn_t reset; | 1792 | ata_reset_fn_t reset; |
1787 | int i, rc; | 1793 | int rc; |
1788 | 1794 | ||
1789 | /* about to reset */ | 1795 | /* about to reset */ |
1790 | ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); | 1796 | ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); |
@@ -1808,8 +1814,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1808 | "port disabled. ignoring.\n"); | 1814 | "port disabled. ignoring.\n"); |
1809 | ehc->i.action &= ~ATA_EH_RESET_MASK; | 1815 | ehc->i.action &= ~ATA_EH_RESET_MASK; |
1810 | 1816 | ||
1811 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1817 | ata_link_for_each_dev(dev, &ap->link) |
1812 | classes[i] = ATA_DEV_NONE; | 1818 | classes[dev->devno] = ATA_DEV_NONE; |
1813 | 1819 | ||
1814 | rc = 0; | 1820 | rc = 0; |
1815 | } else | 1821 | } else |
@@ -1826,8 +1832,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1826 | reset = softreset; | 1832 | reset = softreset; |
1827 | else { | 1833 | else { |
1828 | /* prereset told us not to reset, bang classes and return */ | 1834 | /* prereset told us not to reset, bang classes and return */ |
1829 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1835 | ata_link_for_each_dev(dev, &ap->link) |
1830 | classes[i] = ATA_DEV_NONE; | 1836 | classes[dev->devno] = ATA_DEV_NONE; |
1831 | rc = 0; | 1837 | rc = 0; |
1832 | goto out; | 1838 | goto out; |
1833 | } | 1839 | } |
@@ -1908,8 +1914,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1908 | /* After the reset, the device state is PIO 0 and the | 1914 | /* After the reset, the device state is PIO 0 and the |
1909 | * controller state is undefined. Record the mode. | 1915 | * controller state is undefined. Record the mode. |
1910 | */ | 1916 | */ |
1911 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1917 | ata_link_for_each_dev(dev, &ap->link) |
1912 | ap->link.device[i].pio_mode = XFER_PIO_0; | 1918 | dev->pio_mode = XFER_PIO_0; |
1913 | 1919 | ||
1914 | /* record current link speed */ | 1920 | /* record current link speed */ |
1915 | if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0) | 1921 | if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0) |
@@ -1935,7 +1941,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
1935 | struct ata_device *dev; | 1941 | struct ata_device *dev; |
1936 | unsigned int new_mask = 0; | 1942 | unsigned int new_mask = 0; |
1937 | unsigned long flags; | 1943 | unsigned long flags; |
1938 | int i, rc = 0; | 1944 | int rc = 0; |
1939 | 1945 | ||
1940 | DPRINTK("ENTER\n"); | 1946 | DPRINTK("ENTER\n"); |
1941 | 1947 | ||
@@ -1943,11 +1949,9 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
1943 | * be done backwards such that PDIAG- is released by the slave | 1949 | * be done backwards such that PDIAG- is released by the slave |
1944 | * device before the master device is identified. | 1950 | * device before the master device is identified. |
1945 | */ | 1951 | */ |
1946 | for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) { | 1952 | ata_link_for_each_dev_reverse(dev, &ap->link) { |
1947 | unsigned int action, readid_flags = 0; | 1953 | unsigned int action = ata_eh_dev_action(dev); |
1948 | 1954 | unsigned int readid_flags = 0; | |
1949 | dev = &ap->link.device[i]; | ||
1950 | action = ata_eh_dev_action(dev); | ||
1951 | 1955 | ||
1952 | if (ehc->i.flags & ATA_EHI_DID_RESET) | 1956 | if (ehc->i.flags & ATA_EHI_DID_RESET) |
1953 | readid_flags |= ATA_READID_POSTRESET; | 1957 | readid_flags |= ATA_READID_POSTRESET; |
@@ -1981,7 +1985,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
1981 | dev->id); | 1985 | dev->id); |
1982 | switch (rc) { | 1986 | switch (rc) { |
1983 | case 0: | 1987 | case 0: |
1984 | new_mask |= 1 << i; | 1988 | new_mask |= 1 << dev->devno; |
1985 | break; | 1989 | break; |
1986 | case -ENOENT: | 1990 | case -ENOENT: |
1987 | /* IDENTIFY was issued to non-existent | 1991 | /* IDENTIFY was issued to non-existent |
@@ -2005,10 +2009,8 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
2005 | /* Configure new devices forward such that user doesn't see | 2009 | /* Configure new devices forward such that user doesn't see |
2006 | * device detection messages backwards. | 2010 | * device detection messages backwards. |
2007 | */ | 2011 | */ |
2008 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2012 | ata_link_for_each_dev(dev, &ap->link) { |
2009 | dev = &ap->link.device[i]; | 2013 | if (!(new_mask & (1 << dev->devno))) |
2010 | |||
2011 | if (!(new_mask & (1 << i))) | ||
2012 | continue; | 2014 | continue; |
2013 | 2015 | ||
2014 | ehc->i.flags |= ATA_EHI_PRINTINFO; | 2016 | ehc->i.flags |= ATA_EHI_PRINTINFO; |
@@ -2035,20 +2037,22 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
2035 | 2037 | ||
2036 | static int ata_port_nr_enabled(struct ata_port *ap) | 2038 | static int ata_port_nr_enabled(struct ata_port *ap) |
2037 | { | 2039 | { |
2038 | int i, cnt = 0; | 2040 | struct ata_device *dev; |
2041 | int cnt = 0; | ||
2039 | 2042 | ||
2040 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 2043 | ata_link_for_each_dev(dev, &ap->link) |
2041 | if (ata_dev_enabled(&ap->link.device[i])) | 2044 | if (ata_dev_enabled(dev)) |
2042 | cnt++; | 2045 | cnt++; |
2043 | return cnt; | 2046 | return cnt; |
2044 | } | 2047 | } |
2045 | 2048 | ||
2046 | static int ata_port_nr_vacant(struct ata_port *ap) | 2049 | static int ata_port_nr_vacant(struct ata_port *ap) |
2047 | { | 2050 | { |
2048 | int i, cnt = 0; | 2051 | struct ata_device *dev; |
2052 | int cnt = 0; | ||
2049 | 2053 | ||
2050 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 2054 | ata_link_for_each_dev(dev, &ap->link) |
2051 | if (ap->link.device[i].class == ATA_DEV_UNKNOWN) | 2055 | if (dev->class == ATA_DEV_UNKNOWN) |
2052 | cnt++; | 2056 | cnt++; |
2053 | return cnt; | 2057 | return cnt; |
2054 | } | 2058 | } |
@@ -2056,7 +2060,7 @@ static int ata_port_nr_vacant(struct ata_port *ap) | |||
2056 | static int ata_eh_skip_recovery(struct ata_port *ap) | 2060 | static int ata_eh_skip_recovery(struct ata_port *ap) |
2057 | { | 2061 | { |
2058 | struct ata_eh_context *ehc = &ap->link.eh_context; | 2062 | struct ata_eh_context *ehc = &ap->link.eh_context; |
2059 | int i; | 2063 | struct ata_device *dev; |
2060 | 2064 | ||
2061 | /* thaw frozen port, resume link and recover failed devices */ | 2065 | /* thaw frozen port, resume link and recover failed devices */ |
2062 | if ((ap->pflags & ATA_PFLAG_FROZEN) || | 2066 | if ((ap->pflags & ATA_PFLAG_FROZEN) || |
@@ -2064,9 +2068,7 @@ static int ata_eh_skip_recovery(struct ata_port *ap) | |||
2064 | return 0; | 2068 | return 0; |
2065 | 2069 | ||
2066 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ | 2070 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ |
2067 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2071 | ata_link_for_each_dev(dev, &ap->link) { |
2068 | struct ata_device *dev = &ap->link.device[i]; | ||
2069 | |||
2070 | if (dev->class == ATA_DEV_UNKNOWN && | 2072 | if (dev->class == ATA_DEV_UNKNOWN && |
2071 | ehc->classes[dev->devno] != ATA_DEV_NONE) | 2073 | ehc->classes[dev->devno] != ATA_DEV_NONE) |
2072 | return 0; | 2074 | return 0; |
@@ -2153,19 +2155,18 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2153 | { | 2155 | { |
2154 | struct ata_eh_context *ehc = &ap->link.eh_context; | 2156 | struct ata_eh_context *ehc = &ap->link.eh_context; |
2155 | struct ata_device *dev; | 2157 | struct ata_device *dev; |
2156 | int i, rc; | 2158 | int rc; |
2157 | 2159 | ||
2158 | DPRINTK("ENTER\n"); | 2160 | DPRINTK("ENTER\n"); |
2159 | 2161 | ||
2160 | /* prep for recovery */ | 2162 | /* prep for recovery */ |
2161 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2163 | ata_link_for_each_dev(dev, &ap->link) { |
2162 | dev = &ap->link.device[i]; | ||
2163 | |||
2164 | ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; | 2164 | ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; |
2165 | 2165 | ||
2166 | /* collect port action mask recorded in dev actions */ | 2166 | /* collect port action mask recorded in dev actions */ |
2167 | ehc->i.action |= ehc->i.dev_action[i] & ~ATA_EH_PERDEV_MASK; | 2167 | ehc->i.action |= |
2168 | ehc->i.dev_action[i] &= ATA_EH_PERDEV_MASK; | 2168 | ehc->i.dev_action[dev->devno] & ~ATA_EH_PERDEV_MASK; |
2169 | ehc->i.dev_action[dev->devno] &= ATA_EH_PERDEV_MASK; | ||
2169 | 2170 | ||
2170 | /* process hotplug request */ | 2171 | /* process hotplug request */ |
2171 | if (dev->flags & ATA_DFLAG_DETACH) | 2172 | if (dev->flags & ATA_DFLAG_DETACH) |
@@ -2192,8 +2193,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2192 | if (ata_eh_skip_recovery(ap)) | 2193 | if (ata_eh_skip_recovery(ap)) |
2193 | ehc->i.action = 0; | 2194 | ehc->i.action = 0; |
2194 | 2195 | ||
2195 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 2196 | ata_link_for_each_dev(dev, &ap->link) |
2196 | ehc->classes[i] = ATA_DEV_UNKNOWN; | 2197 | ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; |
2197 | 2198 | ||
2198 | /* reset */ | 2199 | /* reset */ |
2199 | if (ehc->i.action & ATA_EH_RESET_MASK) { | 2200 | if (ehc->i.action & ATA_EH_RESET_MASK) { |
@@ -2241,8 +2242,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2241 | 2242 | ||
2242 | out: | 2243 | out: |
2243 | if (rc) { | 2244 | if (rc) { |
2244 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 2245 | ata_link_for_each_dev(dev, &ap->link); |
2245 | ata_dev_disable(&ap->link.device[i]); | 2246 | ata_dev_disable(dev); |
2246 | } | 2247 | } |
2247 | 2248 | ||
2248 | DPRINTK("EXIT, rc=%d\n", rc); | 2249 | DPRINTK("EXIT, rc=%d\n", rc); |