diff options
author | Tejun Heo <htejun@gmail.com> | 2008-04-07 09:47:19 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 15:44:23 -0400 |
commit | ac371987a81c61c2efbd6931245cdcaf43baad89 (patch) | |
tree | f88970931b26d2ad344d7d67ddabc64d9b48181d /drivers/ata/libata-pmp.c | |
parent | 57c9efdfb3cee5d4564fcb5f70555e2edb1bc52a (diff) |
libata: clear SError after link resume
SError used to be cleared in ->postreset. This has small hotplug race
condition. If a device is plugged in after reset is complete but
postreset hasn't run yet, its hotplug event gets lost when SError is
cleared. This patch makes sata_link_resume() clear SError. This
kills the race condition and makes a lot of sense as some PMP and host
PHYs don't work properly without SError cleared.
This change makes sata_pmp_std_{pre|post}_reset()'s unnecessary as
they become identical to ata_std counterparts. It also simplifies
sata_pmp_hardreset() and ahci_vt8251_hardreset().
Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata/libata-pmp.c')
-rw-r--r-- | drivers/ata/libata-pmp.c | 93 |
1 files changed, 1 insertions, 92 deletions
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 7f1a87f01ab2..2f8a9577c26d 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c | |||
@@ -176,49 +176,6 @@ int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val) | |||
176 | } | 176 | } |
177 | 177 | ||
178 | /** | 178 | /** |
179 | * sata_pmp_std_prereset - prepare PMP link for reset | ||
180 | * @link: link to be reset | ||
181 | * @deadline: deadline jiffies for the operation | ||
182 | * | ||
183 | * @link is about to be reset. Initialize it. | ||
184 | * | ||
185 | * LOCKING: | ||
186 | * Kernel thread context (may sleep) | ||
187 | * | ||
188 | * RETURNS: | ||
189 | * 0 on success, -errno otherwise. | ||
190 | */ | ||
191 | int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline) | ||
192 | { | ||
193 | struct ata_eh_context *ehc = &link->eh_context; | ||
194 | const unsigned long *timing = sata_ehc_deb_timing(ehc); | ||
195 | int rc; | ||
196 | |||
197 | /* if we're about to do hardreset, nothing more to do */ | ||
198 | if (ehc->i.action & ATA_EH_HARDRESET) | ||
199 | return 0; | ||
200 | |||
201 | /* resume link */ | ||
202 | rc = sata_link_resume(link, timing, deadline); | ||
203 | if (rc) { | ||
204 | /* phy resume failed */ | ||
205 | ata_link_printk(link, KERN_WARNING, "failed to resume link " | ||
206 | "for reset (errno=%d)\n", rc); | ||
207 | return rc; | ||
208 | } | ||
209 | |||
210 | /* clear SError bits including .X which blocks the port when set */ | ||
211 | rc = sata_scr_write(link, SCR_ERROR, 0xffffffff); | ||
212 | if (rc) { | ||
213 | ata_link_printk(link, KERN_ERR, | ||
214 | "failed to clear SError (errno=%d)\n", rc); | ||
215 | return rc; | ||
216 | } | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * sata_pmp_std_hardreset - standard hardreset method for PMP link | 179 | * sata_pmp_std_hardreset - standard hardreset method for PMP link |
223 | * @link: link to be reset | 180 | * @link: link to be reset |
224 | * @class: resulting class of attached device | 181 | * @class: resulting class of attached device |
@@ -238,33 +195,13 @@ int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline) | |||
238 | int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, | 195 | int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, |
239 | unsigned long deadline) | 196 | unsigned long deadline) |
240 | { | 197 | { |
241 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | ||
242 | bool online; | ||
243 | u32 tmp; | 198 | u32 tmp; |
244 | int rc; | 199 | int rc; |
245 | 200 | ||
246 | DPRINTK("ENTER\n"); | 201 | DPRINTK("ENTER\n"); |
247 | 202 | ||
248 | /* do hardreset */ | 203 | rc = sata_std_hardreset(link, class, deadline); |
249 | rc = sata_link_hardreset(link, timing, deadline, &online, NULL); | ||
250 | if (rc) { | ||
251 | ata_link_printk(link, KERN_ERR, | ||
252 | "COMRESET failed (errno=%d)\n", rc); | ||
253 | goto out; | ||
254 | } | ||
255 | |||
256 | /* clear SError bits including .X which blocks the port when set */ | ||
257 | rc = sata_scr_write(link, SCR_ERROR, 0xffffffff); | ||
258 | if (rc) { | ||
259 | ata_link_printk(link, KERN_ERR, "failed to clear SError " | ||
260 | "during hardreset (errno=%d)\n", rc); | ||
261 | goto out; | ||
262 | } | ||
263 | 204 | ||
264 | /* if device is present, follow up with srst to wait for !BSY */ | ||
265 | if (online) | ||
266 | rc = -EAGAIN; | ||
267 | out: | ||
268 | /* if SCR isn't accessible, we need to reset the PMP */ | 205 | /* if SCR isn't accessible, we need to reset the PMP */ |
269 | if (rc && rc != -EAGAIN && sata_scr_read(link, SCR_STATUS, &tmp)) | 206 | if (rc && rc != -EAGAIN && sata_scr_read(link, SCR_STATUS, &tmp)) |
270 | rc = -ERESTART; | 207 | rc = -ERESTART; |
@@ -274,34 +211,6 @@ int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, | |||
274 | } | 211 | } |
275 | 212 | ||
276 | /** | 213 | /** |
277 | * ata_std_postreset - standard postreset method for PMP link | ||
278 | * @link: the target ata_link | ||
279 | * @classes: classes of attached devices | ||
280 | * | ||
281 | * This function is invoked after a successful reset. Note that | ||
282 | * the device might have been reset more than once using | ||
283 | * different reset methods before postreset is invoked. | ||
284 | * | ||
285 | * LOCKING: | ||
286 | * Kernel thread context (may sleep) | ||
287 | */ | ||
288 | void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class) | ||
289 | { | ||
290 | u32 serror; | ||
291 | |||
292 | DPRINTK("ENTER\n"); | ||
293 | |||
294 | /* clear SError */ | ||
295 | if (sata_scr_read(link, SCR_ERROR, &serror) == 0) | ||
296 | sata_scr_write(link, SCR_ERROR, serror); | ||
297 | |||
298 | /* print link status */ | ||
299 | sata_print_link_status(link); | ||
300 | |||
301 | DPRINTK("EXIT\n"); | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * sata_pmp_read_gscr - read GSCR block of SATA PMP | 214 | * sata_pmp_read_gscr - read GSCR block of SATA PMP |
306 | * @dev: PMP device | 215 | * @dev: PMP device |
307 | * @gscr: buffer to read GSCR block into | 216 | * @gscr: buffer to read GSCR block into |