aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-05-18 12:15:06 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-19 17:51:47 -0400
commit932648b007de76badc61c1b13d7282288dbe887e (patch)
tree3a3c00f6068f530632012ee3a6aaccedbe1158ba /drivers/ata/libata-eh.c
parent0cbf0711a1ebcc4d3aea8e11def684afc2c07ef8 (diff)
libata: reorganize ata_eh_reset() no reset method path
Reorganize ata_eh_reset() such that @prereset() is called even when no reset method is available and if block is used instead of goto to skip actual reset. This makes no reset case behave better (readiness wait) and future changes easier. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c102
1 files changed, 52 insertions, 50 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 62e033146bed..a34adc2c85df 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2098,7 +2098,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
2098 u32 sstatus; 2098 u32 sstatus;
2099 int rc; 2099 int rc;
2100 2100
2101 /* about to reset */ 2101 /*
2102 * Prepare to reset
2103 */
2102 spin_lock_irqsave(ap->lock, flags); 2104 spin_lock_irqsave(ap->lock, flags);
2103 ap->pflags |= ATA_PFLAG_RESETTING; 2105 ap->pflags |= ATA_PFLAG_RESETTING;
2104 spin_unlock_irqrestore(ap->lock, flags); 2106 spin_unlock_irqrestore(ap->lock, flags);
@@ -2124,16 +2126,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
2124 ap->ops->set_piomode(ap, dev); 2126 ap->ops->set_piomode(ap, dev);
2125 } 2127 }
2126 2128
2127 if (!softreset && !hardreset) {
2128 if (verbose)
2129 ata_link_printk(link, KERN_INFO, "no reset method "
2130 "available, skipping reset\n");
2131 if (!(lflags & ATA_LFLAG_ASSUME_CLASS))
2132 lflags |= ATA_LFLAG_ASSUME_ATA;
2133 goto done;
2134 }
2135
2136 /* prefer hardreset */ 2129 /* prefer hardreset */
2130 reset = NULL;
2137 ehc->i.action &= ~ATA_EH_RESET; 2131 ehc->i.action &= ~ATA_EH_RESET;
2138 if (hardreset) { 2132 if (hardreset) {
2139 reset = hardreset; 2133 reset = hardreset;
@@ -2141,11 +2135,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
2141 } else if (softreset) { 2135 } else if (softreset) {
2142 reset = softreset; 2136 reset = softreset;
2143 ehc->i.action = ATA_EH_SOFTRESET; 2137 ehc->i.action = ATA_EH_SOFTRESET;
2144 } else {
2145 ata_link_printk(link, KERN_ERR, "BUG: no reset method, "
2146 "please report to linux-ide@vger.kernel.org\n");
2147 dump_stack();
2148 return -EINVAL;
2149 } 2138 }
2150 2139
2151 if (prereset) { 2140 if (prereset) {
@@ -2165,55 +2154,68 @@ int ata_eh_reset(struct ata_link *link, int classify,
2165 "prereset failed (errno=%d)\n", rc); 2154 "prereset failed (errno=%d)\n", rc);
2166 goto out; 2155 goto out;
2167 } 2156 }
2168 }
2169 2157
2170 /* prereset() might have cleared ATA_EH_RESET */ 2158 /* prereset() might have cleared ATA_EH_RESET. If so,
2171 if (!(ehc->i.action & ATA_EH_RESET)) { 2159 * bang classes and return.
2172 /* prereset told us not to reset, bang classes and return */ 2160 */
2173 ata_link_for_each_dev(dev, link) 2161 if (reset && !(ehc->i.action & ATA_EH_RESET)) {
2174 classes[dev->devno] = ATA_DEV_NONE; 2162 ata_link_for_each_dev(dev, link)
2175 rc = 0; 2163 classes[dev->devno] = ATA_DEV_NONE;
2176 goto out; 2164 rc = 0;
2165 goto out;
2166 }
2177 } 2167 }
2178 2168
2179 retry: 2169 retry:
2170 /*
2171 * Perform reset
2172 */
2180 deadline = jiffies + ata_eh_reset_timeouts[try++]; 2173 deadline = jiffies + ata_eh_reset_timeouts[try++];
2181 2174
2182 /* shut up during boot probing */ 2175 if (reset) {
2183 if (verbose) 2176 if (verbose)
2184 ata_link_printk(link, KERN_INFO, "%s resetting link\n", 2177 ata_link_printk(link, KERN_INFO, "%s resetting link\n",
2185 reset == softreset ? "soft" : "hard"); 2178 reset == softreset ? "soft" : "hard");
2186 2179
2187 /* mark that this EH session started with reset */ 2180 /* mark that this EH session started with reset */
2188 if (reset == hardreset) 2181 if (reset == hardreset)
2189 ehc->i.flags |= ATA_EHI_DID_HARDRESET; 2182 ehc->i.flags |= ATA_EHI_DID_HARDRESET;
2190 else 2183 else
2191 ehc->i.flags |= ATA_EHI_DID_SOFTRESET; 2184 ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
2192 2185
2193 rc = ata_do_reset(link, reset, classes, deadline); 2186 rc = ata_do_reset(link, reset, classes, deadline);
2194 2187
2195 if (reset == hardreset && 2188 if (reset == hardreset &&
2196 ata_eh_followup_srst_needed(link, rc, classify, classes)) { 2189 ata_eh_followup_srst_needed(link, rc, classify, classes)) {
2197 /* okay, let's do follow-up softreset */ 2190 /* okay, let's do follow-up softreset */
2198 reset = softreset; 2191 reset = softreset;
2199 2192
2200 if (!reset) { 2193 if (!reset) {
2201 ata_link_printk(link, KERN_ERR, 2194 ata_link_printk(link, KERN_ERR,
2202 "follow-up softreset required " 2195 "follow-up softreset required "
2203 "but no softreset avaliable\n"); 2196 "but no softreset avaliable\n");
2204 rc = -EINVAL; 2197 rc = -EINVAL;
2205 goto fail; 2198 goto fail;
2199 }
2200
2201 ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
2202 rc = ata_do_reset(link, reset, classes, deadline);
2206 } 2203 }
2207 2204
2208 ata_eh_about_to_do(link, NULL, ATA_EH_RESET); 2205 /* -EAGAIN can happen if we skipped followup SRST */
2209 rc = ata_do_reset(link, reset, classes, deadline); 2206 if (rc && rc != -EAGAIN)
2207 goto fail;
2208 } else {
2209 if (verbose)
2210 ata_link_printk(link, KERN_INFO, "no reset method "
2211 "available, skipping reset\n");
2212 if (!(lflags & ATA_LFLAG_ASSUME_CLASS))
2213 lflags |= ATA_LFLAG_ASSUME_ATA;
2210 } 2214 }
2211 2215
2212 /* -EAGAIN can happen if we skipped followup SRST */ 2216 /*
2213 if (rc && rc != -EAGAIN) 2217 * Post-reset processing
2214 goto fail; 2218 */
2215
2216 done:
2217 ata_link_for_each_dev(dev, link) { 2219 ata_link_for_each_dev(dev, link) {
2218 /* After the reset, the device state is PIO 0 and the 2220 /* After the reset, the device state is PIO 0 and the
2219 * controller state is undefined. Reset also wakes up 2221 * controller state is undefined. Reset also wakes up