X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fata%2Flibata-core.c;h=4dc429fd00560172b0a6f17eb9b08aa21132cef6;hb=b558edddb1c42c70a30cfe494984d4be409f7b2b;hp=fbc24358ada030bf3cc329682ee617374229dd3a;hpb=91e229bbad6524aabaac8717b2f559283670c37a;p=linux-2.6-omap-h63xx.git diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fbc24358ada..4dc429fd005 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -106,14 +106,15 @@ static struct ata_force_ent *ata_force_tbl; static int ata_force_tbl_size; static char ata_force_param_buf[PAGE_SIZE] __initdata; -module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0444); +/* param_buf is thrown away after initialization, disallow read */ +module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0); MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)"); int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); -int atapi_dmadir = 0; +static int atapi_dmadir = 0; module_param(atapi_dmadir, int, 0444); MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)"); @@ -324,6 +325,44 @@ static void ata_force_horkage(struct ata_device *dev) } } +/** + * atapi_cmd_type - Determine ATAPI command type from SCSI opcode + * @opcode: SCSI opcode + * + * Determine ATAPI command type from @opcode. + * + * LOCKING: + * None. + * + * RETURNS: + * ATAPI_{READ|WRITE|READ_CD|PASS_THRU|MISC} + */ +int atapi_cmd_type(u8 opcode) +{ + switch (opcode) { + case GPCMD_READ_10: + case GPCMD_READ_12: + return ATAPI_READ; + + case GPCMD_WRITE_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_10: + return ATAPI_WRITE; + + case GPCMD_READ_CD: + case GPCMD_READ_CD_MSF: + return ATAPI_READ_CD; + + case ATA_16: + case ATA_12: + if (atapi_passthru16) + return ATAPI_PASS_THRU; + /* fall thru */ + default: + return ATAPI_MISC; + } +} + /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert @@ -971,7 +1010,7 @@ static void ata_dev_disable_pm(struct ata_device *dev) void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy) { ap->pm_policy = policy; - ap->link.eh_info.action |= ATA_EHI_LPM; + ap->link.eh_info.action |= ATA_EH_LPM; ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY; ata_port_schedule_eh(ap); } @@ -1415,12 +1454,12 @@ static int ata_hpa_resize(struct ata_device *dev) /* read native max address */ rc = ata_read_native_max_address(dev, &native_sectors); if (rc) { - /* If HPA isn't going to be unlocked, skip HPA - * resizing from the next try. + /* If device aborted the command or HPA isn't going to + * be unlocked, skip HPA resizing. */ - if (!ata_ignore_hpa) { + if (rc == -EACCES || !ata_ignore_hpa) { ata_dev_printk(dev, KERN_WARNING, "HPA support seems " - "broken, will skip HPA handling\n"); + "broken, skipping HPA handling\n"); dev->horkage |= ATA_HORKAGE_BROKEN_HPA; /* we can continue if device aborted the command */ @@ -1719,7 +1758,7 @@ void ata_port_flush_task(struct ata_port *ap) cancel_rearming_delayed_work(&ap->port_task); if (ata_msg_ctl(ap)) - ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__); + ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __func__); } static void ata_qc_complete_internal(struct ata_queued_cmd *qc) @@ -2056,7 +2095,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int rc; if (ata_msg_ctl(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__); ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ retry: @@ -2091,24 +2130,34 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, id, sizeof(id[0]) * ATA_ID_WORDS, 0); if (err_mask) { if (err_mask & AC_ERR_NODEV_HINT) { - DPRINTK("ata%u.%d: NODEV after polling detection\n", - ap->print_id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, + "NODEV after polling detection\n"); return -ENOENT; } - /* Device or controller might have reported the wrong - * device class. Give a shot at the other IDENTIFY if - * the current one is aborted by the device. - */ - if (may_fallback && - (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { - may_fallback = 0; + if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { + /* Device or controller might have reported + * the wrong device class. Give a shot at the + * other IDENTIFY if the current one is + * aborted by the device. + */ + if (may_fallback) { + may_fallback = 0; - if (class == ATA_DEV_ATA) - class = ATA_DEV_ATAPI; - else - class = ATA_DEV_ATA; - goto retry; + if (class == ATA_DEV_ATA) + class = ATA_DEV_ATAPI; + else + class = ATA_DEV_ATA; + goto retry; + } + + /* Control reaches here iff the device aborted + * both flavors of IDENTIFYs which happens + * sometimes with phantom devices. + */ + ata_dev_printk(dev, KERN_DEBUG, + "both IDENTIFYs aborted, assuming NODEV\n"); + return -ENOENT; } rc = -EIO; @@ -2253,12 +2302,12 @@ int ata_dev_configure(struct ata_device *dev) if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n", - __FUNCTION__); + __func__); return 0; } if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__); /* set horkage */ dev->horkage |= ata_dev_blacklisted(dev); @@ -2279,7 +2328,7 @@ int ata_dev_configure(struct ata_device *dev) ata_dev_printk(dev, KERN_DEBUG, "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " "85:%04x 86:%04x 87:%04x 88:%04x\n", - __FUNCTION__, + __func__, id[49], id[82], id[83], id[84], id[85], id[86], id[87], id[88]); @@ -2511,13 +2560,13 @@ int ata_dev_configure(struct ata_device *dev) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", - __FUNCTION__, ata_chk_status(ap)); + __func__, ata_chk_status(ap)); return 0; err_out_nosup: if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, - "%s: EXIT, err\n", __FUNCTION__); + "%s: EXIT, err\n", __func__); return rc; } @@ -2649,7 +2698,7 @@ int ata_bus_probe(struct ata_port *ap) specific sequence bass-ackwards so that PDIAG- is released by the slave device */ - ata_link_for_each_dev(dev, &ap->link) { + ata_link_for_each_dev_reverse(dev, &ap->link) { if (tries[dev->devno]) dev->class = classes[dev->devno]; @@ -3900,17 +3949,6 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) const unsigned long *timing = sata_ehc_deb_timing(ehc); int rc; - /* handle link resume */ - if ((ehc->i.flags & ATA_EHI_RESUME_LINK) && - (link->flags & ATA_LFLAG_HRST_TO_RESUME)) - ehc->i.action |= ATA_EH_HARDRESET; - - /* Some PMPs don't work with only SRST, force hardreset if PMP - * is supported. - */ - if (ap->flags & ATA_FLAG_PMP) - ehc->i.action |= ATA_EH_HARDRESET; - /* if we're about to do hardreset, nothing more to do */ if (ehc->i.action & ATA_EH_HARDRESET) return 0; @@ -3924,10 +3962,8 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) "link for reset (errno=%d)\n", rc); } - /* Wait for !BSY if the controller can wait for the first D2H - * Reg FIS and we don't know that no device is attached. - */ - if (!(link->flags & ATA_LFLAG_SKIP_D2H_BSY) && !ata_link_offline(link)) { + /* wait for !BSY if we don't know that no device is attached */ + if (!ata_link_offline(link)) { rc = ata_wait_ready(ap, deadline); if (rc && rc != -ENODEV) { ata_link_printk(link, KERN_WARNING, "device not ready " @@ -6006,9 +6042,9 @@ void ata_qc_issue(struct ata_queued_cmd *qc) if (ata_sg_setup(qc)) goto sg_err; - /* if device is sleeping, schedule softreset and abort the link */ + /* if device is sleeping, schedule reset and abort the link */ if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { - link->eh_info.action |= ATA_EH_SOFTRESET; + link->eh_info.action |= ATA_EH_RESET; ata_ehi_push_desc(&link->eh_info, "waking up from sleep"); ata_link_abort(link); return; @@ -6567,6 +6603,8 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) ata_lpm_enable(host); rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); + if (rc == 0) + host->dev->power.power_state = mesg; return rc; } @@ -6583,8 +6621,9 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) */ void ata_host_resume(struct ata_host *host) { - ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET, + ata_host_request_pm(host, PMSG_ON, ATA_EH_RESET, ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); + host->dev->power.power_state = PMSG_ON; /* reenable link pm */ ata_lpm_disable(host); @@ -7117,9 +7156,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) /* kick EH for boot probing */ spin_lock_irqsave(ap->lock, flags); - ehi->probe_mask = - (1 << ata_link_max_devices(&ap->link)) - 1; - ehi->action |= ATA_EH_SOFTRESET; + ehi->probe_mask |= ATA_ALL_DEVICES; + ehi->action |= ATA_EH_RESET; ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; ap->pflags &= ~ATA_PFLAG_INITIALIZING; @@ -7760,6 +7798,7 @@ EXPORT_SYMBOL_GPL(ata_tf_read); EXPORT_SYMBOL_GPL(ata_noop_dev_select); EXPORT_SYMBOL_GPL(ata_std_dev_select); EXPORT_SYMBOL_GPL(sata_print_link_status); +EXPORT_SYMBOL_GPL(atapi_cmd_type); EXPORT_SYMBOL_GPL(ata_tf_to_fis); EXPORT_SYMBOL_GPL(ata_tf_from_fis); EXPORT_SYMBOL_GPL(ata_pack_xfermask);