aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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