aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-sff.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-07 09:47:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:22 -0400
commitaa2731ad9ad80ac3fca48bd1c4cf0eceede4810e (patch)
treedb6d3327017b9b84355aba49a5ccd5c322d3f248 /drivers/ata/libata-sff.c
parent705e76beb90b97421e1f61e857c4246799781bb5 (diff)
libata: separate out ata_wait_ready() and implement ata_wait_after_reset()
Factor out waiting logic (which is common to all ATA controllers) from ata_sff_wait_ready() into ata_wait_ready(). ata_wait_ready() takes @check_ready function pointer and uses it to poll for readiness. This allows non-SFF controllers to use ata_wait_ready() to wait for link readiness. This patch also implements ata_wait_after_reset() - generic version of ata_sff_wait_after_reset() - using ata_wait_ready(). ata_sff_wait_ready() is reimplemented using ata_wait_ready() and ata_sff_check_ready(). Functionality remains the same. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r--drivers/ata/libata-sff.c62
1 files changed, 12 insertions, 50 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 6e8de3c1595..78912c5011a 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -308,6 +308,17 @@ int ata_sff_busy_sleep(struct ata_port *ap,
308 return 0; 308 return 0;
309} 309}
310 310
311static int ata_sff_check_ready(struct ata_link *link)
312{
313 u8 status = link->ap->ops->sff_check_status(link->ap);
314
315 if (!(status & ATA_BUSY))
316 return 1;
317 if (status == 0xff)
318 return -ENODEV;
319 return 0;
320}
321
311/** 322/**
312 * ata_sff_wait_ready - sleep until BSY clears, or timeout 323 * ata_sff_wait_ready - sleep until BSY clears, or timeout
313 * @link: SFF link to wait ready status for 324 * @link: SFF link to wait ready status for
@@ -324,56 +335,7 @@ int ata_sff_busy_sleep(struct ata_port *ap,
324 */ 335 */
325int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline) 336int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline)
326{ 337{
327 struct ata_port *ap = link->ap; 338 return ata_wait_ready(link, deadline, ata_sff_check_ready);
328 unsigned long start = jiffies;
329 unsigned long nodev_deadline = start + ATA_TMOUT_FF_WAIT;
330 int warned = 0;
331
332 if (time_after(nodev_deadline, deadline))
333 nodev_deadline = deadline;
334
335 while (1) {
336 u8 status = ap->ops->sff_check_status(ap);
337 unsigned long now = jiffies;
338
339 if (!(status & ATA_BUSY))
340 return 0;
341
342 /* No device status could be transient. Ignore it if
343 * link is online. Also, some SATA devices take a
344 * long time to clear 0xff after reset. For example,
345 * HHD424020F7SV00 iVDR needs >= 800ms while Quantum
346 * GoVault needs even more than that. Wait for
347 * ATA_TMOUT_FF_WAIT on -ENODEV if link isn't offline.
348 *
349 * Note that some PATA controllers (pata_ali) explode
350 * if status register is read more than once when
351 * there's no device attached.
352 */
353 if (status == 0xff) {
354 if (ata_link_online(link))
355 status = ATA_BUSY;
356 else if ((link->ap->flags & ATA_FLAG_SATA) &&
357 !ata_link_offline(link) &&
358 time_before(now, nodev_deadline))
359 status = ATA_BUSY;
360 if (status == 0xff)
361 return -ENODEV;
362 }
363
364 if (time_after(now, deadline))
365 return -EBUSY;
366
367 if (!warned && time_after(now, start + 5 * HZ) &&
368 (deadline - now > 3 * HZ)) {
369 ata_link_printk(link, KERN_WARNING,
370 "link is slow to respond, please be patient "
371 "(Status 0x%x)\n", status);
372 warned = 1;
373 }
374
375 msleep(50);
376 }
377} 339}
378 340
379/** 341/**