X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fata%2Flibata-core.c;h=b0b00af90d0e18314782fec05cdd136cbd41eff1;hb=429f731dea577bdd43693940cdca524135287e6a;hp=fd912ccb90f8b84f1e1c6086fd0d850ebf700ae5;hpb=288623a06c652239d2f57d271af12bb024cf7218;p=linux-2.6 diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fd912ccb90..b0b00af90d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -61,7 +61,6 @@ #include #include #include -#include #include #include @@ -74,9 +73,8 @@ const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 }; const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; const struct ata_port_operations ata_base_port_ops = { - .prereset = ata_sff_prereset, - .hardreset = sata_sff_hardreset, - .postreset = ata_sff_postreset, + .prereset = ata_std_prereset, + .postreset = ata_std_postreset, .error_handler = ata_std_error_handler, }; @@ -84,16 +82,7 @@ const struct ata_port_operations sata_port_ops = { .inherits = &ata_base_port_ops, .qc_defer = ata_std_qc_defer, - .sff_dev_select = ata_noop_dev_select, -}; - -const struct ata_port_operations sata_pmp_port_ops = { - .inherits = &sata_port_ops, - - .pmp_prereset = sata_pmp_std_prereset, - .pmp_hardreset = sata_pmp_std_hardreset, - .pmp_postreset = sata_pmp_std_postreset, - .error_handler = sata_pmp_error_handler, + .hardreset = sata_std_hardreset, }; static unsigned int ata_dev_init_params(struct ata_device *dev, @@ -1431,22 +1420,6 @@ static int ata_hpa_resize(struct ata_device *dev) return 0; } -/** - * ata_noop_dev_select - Select device 0/1 on ATA bus - * @ap: ATA channel to manipulate - * @device: ATA device (numbered from zero) to select - * - * This function performs no actual function. - * - * May be used as the dev_select() entry in ata_port_operations. - * - * LOCKING: - * caller. - */ -void ata_noop_dev_select(struct ata_port *ap, unsigned int device) -{ -} - /** * ata_dump_id - IDENTIFY DEVICE info debugging output * @id: IDENTIFY DEVICE page to dump @@ -2304,7 +2277,7 @@ int ata_dev_configure(struct ata_device *dev) * changed notifications and ATAPI ANs. */ if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && - (!ap->nr_pmp_links || + (!sata_pmp_attached(ap) || sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { unsigned int err_mask; @@ -3158,16 +3131,21 @@ static int ata_dev_set_mode(struct ata_device *dev) if (rc) return rc; - /* Old CFA may refuse this command, which is just fine */ - if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id)) - ign_dev_err = 1; - - /* Some very old devices and some bad newer ones fail any kind of - SET_XFERMODE request but support PIO0-2 timings and no IORDY */ - if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) && - dev->pio_mode <= XFER_PIO_2) - ign_dev_err = 1; - + if (dev->xfer_shift == ATA_SHIFT_PIO) { + /* Old CFA may refuse this command, which is just fine */ + if (ata_id_is_cfa(dev->id)) + ign_dev_err = 1; + /* Catch several broken garbage emulations plus some pre + ATA devices */ + if (ata_id_major_version(dev->id) == 0 && + dev->pio_mode <= XFER_PIO_2) + ign_dev_err = 1; + /* Some very old devices and some bad newer ones fail + any kind of SET_XFERMODE request but support PIO0-2 + timings and no IORDY */ + if (!ata_id_has_iordy(dev->id) && dev->pio_mode <= XFER_PIO_2) + ign_dev_err = 1; + } /* Early MWDMA devices do DMA but don't allow DMA mode setting. Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */ if (dev->xfer_shift == ATA_SHIFT_MWDMA && @@ -3310,6 +3288,103 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) return rc; } +/** + * ata_wait_ready - wait for link to become ready + * @link: link to be waited on + * @deadline: deadline jiffies for the operation + * @check_ready: callback to check link readiness + * + * Wait for @link to become ready. @check_ready should return + * positive number if @link is ready, 0 if it isn't, -ENODEV if + * link doesn't seem to be occupied, other errno for other error + * conditions. + * + * Transient -ENODEV conditions are allowed for + * ATA_TMOUT_FF_WAIT. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 if @linke is ready before @deadline; otherwise, -errno. + */ +int ata_wait_ready(struct ata_link *link, unsigned long deadline, + int (*check_ready)(struct ata_link *link)) +{ + unsigned long start = jiffies; + unsigned long nodev_deadline = start + ATA_TMOUT_FF_WAIT; + int warned = 0; + + if (time_after(nodev_deadline, deadline)) + nodev_deadline = deadline; + + while (1) { + unsigned long now = jiffies; + int ready, tmp; + + ready = tmp = check_ready(link); + if (ready > 0) + return 0; + + /* -ENODEV could be transient. Ignore -ENODEV if link + * is online. Also, some SATA devices take a long + * time to clear 0xff after reset. For example, + * HHD424020F7SV00 iVDR needs >= 800ms while Quantum + * GoVault needs even more than that. Wait for + * ATA_TMOUT_FF_WAIT on -ENODEV if link isn't offline. + * + * Note that some PATA controllers (pata_ali) explode + * if status register is read more than once when + * there's no device attached. + */ + if (ready == -ENODEV) { + if (ata_link_online(link)) + ready = 0; + else if ((link->ap->flags & ATA_FLAG_SATA) && + !ata_link_offline(link) && + time_before(now, nodev_deadline)) + ready = 0; + } + + if (ready) + return ready; + if (time_after(now, deadline)) + return -EBUSY; + + if (!warned && time_after(now, start + 5 * HZ) && + (deadline - now > 3 * HZ)) { + ata_link_printk(link, KERN_WARNING, + "link is slow to respond, please be patient " + "(ready=%d)\n", tmp); + warned = 1; + } + + msleep(50); + } +} + +/** + * ata_wait_after_reset - wait for link to become ready after reset + * @link: link to be waited on + * @deadline: deadline jiffies for the operation + * @check_ready: callback to check link readiness + * + * Wait for @link to become ready after reset. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 if @linke is ready before @deadline; otherwise, -errno. + */ +extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, + int (*check_ready)(struct ata_link *link)) +{ + msleep(ATA_WAIT_AFTER_RESET_MSECS); + + return ata_wait_ready(link, deadline, check_ready); +} + /** * sata_link_debounce - debounce SATA phy status * @link: ATA link to debounce SATA phy status for @@ -3396,7 +3471,7 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline) { - u32 scontrol; + u32 scontrol, serror; int rc; if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) @@ -3412,11 +3487,29 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, */ msleep(200); - return sata_link_debounce(link, params, deadline); + if ((rc = sata_link_debounce(link, params, deadline))) + return rc; + + /* Clear SError. PMP and some host PHYs require this to + * operate and clearing should be done before checking PHY + * online status to avoid race condition (hotplugging between + * link resume and status check). + */ + if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) + rc = sata_scr_write(link, SCR_ERROR, serror); + if (rc == 0 || rc == -EINVAL) { + unsigned long flags; + + spin_lock_irqsave(link->ap->lock, flags); + link->eh_info.serror = 0; + spin_unlock_irqrestore(link->ap->lock, flags); + rc = 0; + } + return rc; } /** - * ata_sff_prereset - prepare for reset + * ata_std_prereset - prepare for reset * @link: ATA link to be reset * @deadline: deadline jiffies for the operation * @@ -3432,7 +3525,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, * RETURNS: * 0 on success, -errno otherwise. */ -int ata_sff_prereset(struct ata_link *link, unsigned long deadline) +int ata_std_prereset(struct ata_link *link, unsigned long deadline) { struct ata_port *ap = link->ap; struct ata_eh_context *ehc = &link->eh_context; @@ -3452,15 +3545,9 @@ int ata_sff_prereset(struct ata_link *link, unsigned long deadline) "link for reset (errno=%d)\n", rc); } - /* wait for !BSY if we don't know that no device is attached */ - if (!ata_link_offline(link)) { - rc = ata_sff_wait_ready(ap, deadline); - if (rc && rc != -ENODEV) { - ata_link_printk(link, KERN_WARNING, "device not ready " - "(errno=%d), forcing hardreset\n", rc); - ehc->i.action |= ATA_EH_HARDRESET; - } - } + /* no point in trying softreset on offline link */ + if (ata_link_offline(link)) + ehc->i.action &= ~ATA_EH_SOFTRESET; return 0; } @@ -3470,8 +3557,18 @@ int ata_sff_prereset(struct ata_link *link, unsigned long deadline) * @link: link to reset * @timing: timing parameters { interval, duratinon, timeout } in msec * @deadline: deadline jiffies for the operation + * @online: optional out parameter indicating link onlineness + * @check_ready: optional callback to check link readiness * * SATA phy-reset @link using DET bits of SControl register. + * After hardreset, link readiness is waited upon using + * ata_wait_ready() if @check_ready is specified. LLDs are + * allowed to not specify @check_ready and wait itself after this + * function returns. Device classification is LLD's + * responsibility. + * + * *@online is set to one iff reset succeeded and @link is online + * after reset. * * LOCKING: * Kernel thread context (may sleep) @@ -3480,13 +3577,17 @@ int ata_sff_prereset(struct ata_link *link, unsigned long deadline) * 0 on success, -errno otherwise. */ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, - unsigned long deadline) + unsigned long deadline, + bool *online, int (*check_ready)(struct ata_link *)) { u32 scontrol; int rc; DPRINTK("ENTER\n"); + if (online) + *online = false; + if (sata_set_spd_needed(link)) { /* SATA spec says nothing about how to reconfigure * spd. To be on the safe side, turn off phy during @@ -3520,13 +3621,73 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, /* bring link back */ rc = sata_link_resume(link, timing, deadline); + if (rc) + goto out; + /* if link is offline nothing more to do */ + if (ata_link_offline(link)) + goto out; + + /* Link is online. From this point, -ENODEV too is an error. */ + if (online) + *online = true; + + if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) { + /* If PMP is supported, we have to do follow-up SRST. + * Some PMPs don't send D2H Reg FIS after hardreset if + * the first port is empty. Wait only for + * ATA_TMOUT_PMP_SRST_WAIT. + */ + if (check_ready) { + unsigned long pmp_deadline; + + pmp_deadline = jiffies + ATA_TMOUT_PMP_SRST_WAIT; + if (time_after(pmp_deadline, deadline)) + pmp_deadline = deadline; + ata_wait_ready(link, pmp_deadline, check_ready); + } + rc = -EAGAIN; + goto out; + } + + rc = 0; + if (check_ready) + rc = ata_wait_ready(link, deadline, check_ready); out: + if (rc && rc != -EAGAIN) + ata_link_printk(link, KERN_ERR, + "COMRESET failed (errno=%d)\n", rc); DPRINTK("EXIT, rc=%d\n", rc); return rc; } /** - * ata_sff_postreset - standard postreset callback + * sata_std_hardreset - COMRESET w/o waiting or classification + * @link: link to reset + * @class: resulting class of attached device + * @deadline: deadline jiffies for the operation + * + * Standard SATA COMRESET w/o waiting or classification. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 if link offline, -EAGAIN if link online, -errno on errors. + */ +int sata_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; + int rc; + + /* do hardreset */ + rc = sata_link_hardreset(link, timing, deadline, &online, NULL); + return online ? -EAGAIN : rc; +} + +/** + * ata_std_postreset - standard postreset callback * @link: the target ata_link * @classes: classes of attached devices * @@ -3537,37 +3698,13 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, * LOCKING: * Kernel thread context (may sleep) */ -void ata_sff_postreset(struct ata_link *link, unsigned int *classes) +void ata_std_postreset(struct ata_link *link, unsigned int *classes) { - struct ata_port *ap = link->ap; - u32 serror; - DPRINTK("ENTER\n"); /* print link status */ sata_print_link_status(link); - /* clear SError */ - if (sata_scr_read(link, SCR_ERROR, &serror) == 0) - sata_scr_write(link, SCR_ERROR, serror); - link->eh_info.serror = 0; - - /* is double-select really necessary? */ - if (classes[0] != ATA_DEV_NONE) - ap->ops->sff_dev_select(ap, 1); - if (classes[1] != ATA_DEV_NONE) - ap->ops->sff_dev_select(ap, 0); - - /* bail out if no device is present */ - if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { - DPRINTK("EXIT, no device\n"); - return; - } - - /* set up device control */ - if (ap->ioaddr.ctl_addr) - iowrite8(ap->ctl, ap->ioaddr.ctl_addr); - DPRINTK("EXIT\n"); } @@ -3900,6 +4037,10 @@ static int cable_is_40wire(struct ata_port *ap) /* If the controller thinks we are 80 wire, we are */ if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA) return 0; + /* If the system is known to be 40 wire short cable (eg laptop), + then we allow 80 wire modes even if the drive isn't sure */ + if (ap->cbl == ATA_CBL_PATA40_SHORT) + return 0; /* If the controller doesn't know we scan - Note: We look for all 40 wire detects at this point. @@ -4407,7 +4548,7 @@ static void fill_result_tf(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; qc->result_tf.flags = qc->tf.flags; - ap->ops->sff_tf_read(ap, &qc->result_tf); + ap->ops->qc_fill_rtf(qc); } static void ata_verify_xfer(struct ata_queued_cmd *qc) @@ -4517,7 +4658,6 @@ void ata_qc_complete(struct ata_queued_cmd *qc) * ata_qc_complete_multiple - Complete multiple qcs successfully * @ap: port in question * @qc_active: new qc_active mask - * @finish_qc: LLDD callback invoked before completing a qc * * Complete in-flight commands. This functions is meant to be * called from low-level driver's interrupt routine to complete @@ -4530,8 +4670,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc) * RETURNS: * Number of completed commands on success, -errno otherwise. */ -int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, - void (*finish_qc)(struct ata_queued_cmd *)) +int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active) { int nr_done = 0; u32 done_mask; @@ -4552,8 +4691,6 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, continue; if ((qc = ata_qc_from_tag(ap, i))) { - if (finish_qc) - finish_qc(qc); ata_qc_complete(qc); nr_done++; } @@ -5061,7 +5198,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; #endif +#ifdef CONFIG_ATA_SFF INIT_DELAYED_WORK(&ap->port_task, ata_pio_task); +#endif INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); INIT_LIST_HEAD(&ap->eh_done_q); @@ -6025,33 +6164,20 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, /* * Dummy port_ops */ -static void ata_dummy_noret(struct ata_port *ap) { } -static int ata_dummy_ret0(struct ata_port *ap) { return 0; } -static void ata_dummy_qc_noret(struct ata_queued_cmd *qc) { } - -static u8 ata_dummy_check_status(struct ata_port *ap) +static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc) { - return ATA_DRDY; + return AC_ERR_SYSTEM; } -static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc) +static void ata_dummy_error_handler(struct ata_port *ap) { - return AC_ERR_SYSTEM; + /* truly dummy */ } struct ata_port_operations ata_dummy_port_ops = { - .sff_check_status = ata_dummy_check_status, - .sff_check_altstatus = ata_dummy_check_status, - .sff_dev_select = ata_noop_dev_select, .qc_prep = ata_noop_qc_prep, .qc_issue = ata_dummy_qc_issue, - .freeze = ata_dummy_noret, - .thaw = ata_dummy_noret, - .error_handler = ata_dummy_noret, - .post_internal_cmd = ata_dummy_qc_noret, - .sff_irq_clear = ata_dummy_noret, - .port_start = ata_dummy_ret0, - .port_stop = ata_dummy_noret, + .error_handler = ata_dummy_error_handler, }; const struct ata_port_info ata_dummy_port_info = { @@ -6069,7 +6195,6 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); EXPORT_SYMBOL_GPL(sata_deb_timing_long); EXPORT_SYMBOL_GPL(ata_base_port_ops); EXPORT_SYMBOL_GPL(sata_port_ops); -EXPORT_SYMBOL_GPL(sata_pmp_port_ops); EXPORT_SYMBOL_GPL(ata_dummy_port_ops); EXPORT_SYMBOL_GPL(ata_dummy_port_info); EXPORT_SYMBOL_GPL(ata_std_bios_param); @@ -6083,7 +6208,6 @@ EXPORT_SYMBOL_GPL(ata_host_detach); EXPORT_SYMBOL_GPL(ata_sg_init); EXPORT_SYMBOL_GPL(ata_qc_complete); EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); -EXPORT_SYMBOL_GPL(ata_noop_dev_select); EXPORT_SYMBOL_GPL(sata_print_link_status); EXPORT_SYMBOL_GPL(atapi_cmd_type); EXPORT_SYMBOL_GPL(ata_tf_to_fis); @@ -6102,9 +6226,13 @@ EXPORT_SYMBOL_GPL(ata_noop_qc_prep); EXPORT_SYMBOL_GPL(ata_port_probe); EXPORT_SYMBOL_GPL(ata_dev_disable); EXPORT_SYMBOL_GPL(sata_set_spd); +EXPORT_SYMBOL_GPL(ata_wait_after_reset); EXPORT_SYMBOL_GPL(sata_link_debounce); EXPORT_SYMBOL_GPL(sata_link_resume); +EXPORT_SYMBOL_GPL(ata_std_prereset); EXPORT_SYMBOL_GPL(sata_link_hardreset); +EXPORT_SYMBOL_GPL(sata_std_hardreset); +EXPORT_SYMBOL_GPL(ata_std_postreset); EXPORT_SYMBOL_GPL(ata_dev_classify); EXPORT_SYMBOL_GPL(ata_dev_pair); EXPORT_SYMBOL_GPL(ata_port_disable); @@ -6146,12 +6274,6 @@ EXPORT_SYMBOL_GPL(ata_pci_device_resume); #endif /* CONFIG_PM */ #endif /* CONFIG_PCI */ -EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch); -EXPORT_SYMBOL_GPL(sata_pmp_std_prereset); -EXPORT_SYMBOL_GPL(sata_pmp_std_hardreset); -EXPORT_SYMBOL_GPL(sata_pmp_std_postreset); -EXPORT_SYMBOL_GPL(sata_pmp_error_handler); - EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); EXPORT_SYMBOL_GPL(ata_ehi_push_desc); EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);