diff options
author | Tejun Heo <htejun@gmail.com> | 2008-04-07 17:47:19 +0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 23:44:23 +0400 |
commit | ac371987a81c61c2efbd6931245cdcaf43baad89 (patch) | |
tree | f88970931b26d2ad344d7d67ddabc64d9b48181d /drivers/ata/libata-pmp.c | |
parent | 57c9efdfb3cee5d4564fcb5f70555e2edb1bc52a (diff) | |
download | linux-ac371987a81c61c2efbd6931245cdcaf43baad89.tar.xz |
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) } /** - * sata_pmp_std_prereset - prepare PMP link for reset - * @link: link to be reset - * @deadline: deadline jiffies for the operation - * - * @link is about to be reset. Initialize it. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline) -{ - struct ata_eh_context *ehc = &link->eh_context; - const unsigned long *timing = sata_ehc_deb_timing(ehc); - int rc; - - /* if we're about to do hardreset, nothing more to do */ - if (ehc->i.action & ATA_EH_HARDRESET) - return 0; - - /* resume link */ - rc = sata_link_resume(link, timing, deadline); - if (rc) { - /* phy resume failed */ - ata_link_printk(link, KERN_WARNING, "failed to resume link " - "for reset (errno=%d)\n", rc); - return rc; - } - - /* clear SError bits including .X which blocks the port when set */ - rc = sata_scr_write(link, SCR_ERROR, 0xffffffff); - if (rc) { - ata_link_printk(link, KERN_ERR, - "failed to clear SError (errno=%d)\n", rc); - return rc; - } - - return 0; -} - -/** * sata_pmp_std_hardreset - standard hardreset method for PMP link * @link: link to be reset * @class: resulting class of attached device @@ -238,33 +195,13 @@ int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline) int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { - const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); - bool online; u32 tmp; int rc; DPRINTK("ENTER\n"); - /* do hardreset */ - rc = sata_link_hardreset(link, timing, deadline, &online, NULL); - if (rc) { - ata_link_printk(link, KERN_ERR, - "COMRESET failed (errno=%d)\n", rc); - goto out; - } - - /* clear SError bits including .X which blocks the port when set */ - rc = sata_scr_write(link, SCR_ERROR, 0xffffffff); - if (rc) { - ata_link_printk(link, KERN_ERR, "failed to clear SError " - "during hardreset (errno=%d)\n", rc); - goto out; - } + rc = sata_std_hardreset(link, class, deadline); - /* if device is present, follow up with srst to wait for !BSY */ - if (online) - rc = -EAGAIN; - out: /* if SCR isn't accessible, we need to reset the PMP */ if (rc && rc != -EAGAIN && sata_scr_read(link, SCR_STATUS, &tmp)) rc = -ERESTART; @@ -274,34 +211,6 @@ int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, } /** - * ata_std_postreset - standard postreset method for PMP link - * @link: the target ata_link - * @classes: classes of attached devices - * - * This function is invoked after a successful reset. Note that - * the device might have been reset more than once using - * different reset methods before postreset is invoked. - * - * LOCKING: - * Kernel thread context (may sleep) - */ -void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class) -{ - u32 serror; - - DPRINTK("ENTER\n"); - - /* clear SError */ - if (sata_scr_read(link, SCR_ERROR, &serror) == 0) - sata_scr_write(link, SCR_ERROR, serror); - - /* print link status */ - sata_print_link_status(link); - - DPRINTK("EXIT\n"); -} - -/** * sata_pmp_read_gscr - read GSCR block of SATA PMP * @dev: PMP device * @gscr: buffer to read GSCR block into |