diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/libata-eh.c | 102 |
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 |