static void sata_dwc_exec_command_by_tag(struct ata_port *ap,
        struct ata_taskfile *tf,
        u8 tag, u32 cmd_issued)
{
    unsigned long flags;
    struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);

    dev_dbg(ap->dev, "%s cmd(0x%02x): %s tag=%d\n", __func__, tf->command,
            ata_get_cmd_descript(tf->command), tag);

    spin_lock_irqsave(&ap->host->lock, flags);
    hsdevp->cmd_issued[tag] = cmd_issued;
    spin_unlock_irqrestore(&ap->host->lock, flags);
    clear_serror();
    ata_sff_exec_command(ap, tf);
}
示例#2
0
/*
 * Function : sata_dwc_exec_command_by_tag
 * arguments : ata_port *ap, ata_taskfile *tf, u8 tag, u32 cmd_issued
 * Return value : None
 * This function keeps track of individual command tag ids and calls
 * ata_exec_command in libata
 */
static void sata_dwc_exec_command_by_tag(struct ata_port *ap,
					 struct ata_taskfile *tf,
					 u8 tag, u32 cmd_issued)
{
	unsigned long flags;
	struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);

	dev_dbg(ap->dev, "%s cmd(0x%02x): %s tag=%d\n", __func__, tf->command,
		ata_get_cmd_descript(tf->command), tag);

	spin_lock_irqsave(&ap->host->lock, flags);
	hsdevp->cmd_issued[tag] = cmd_issued;
	spin_unlock_irqrestore(&ap->host->lock, flags);
	/*
	 * Clear SError before executing a new command.
	 * sata_dwc_scr_write and read can not be used here. Clearing the PM
	 * managed SError register for the disk needs to be done before the
	 * task file is loaded.
	 */
	clear_serror();
	ata_sff_exec_command(ap, tf);
}
static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc)
{
    u32 sactive;
    u8 tag = qc->tag;
    struct ata_port *ap = qc->ap;

#ifdef DEBUG_NCQ
    if (qc->tag > 0 || ap->link.sactive > 1)
        dev_info(ap->dev, "%s ap id=%d cmd(0x%02x)=%s qc tag=%d "
                 "prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n",
                 __func__, ap->print_id, qc->tf.command,
                 ata_get_cmd_descript(qc->tf.command),
                 qc->tag, get_prot_descript(qc->tf.protocol),
                 ap->link.active_tag, ap->link.sactive);
#endif

    if (!ata_is_ncq(qc->tf.protocol))
        tag = 0;
    sata_dwc_qc_prep_by_tag(qc, tag);

    if (ata_is_ncq(qc->tf.protocol)) {
        sactive = core_scr_read(SCR_ACTIVE);
        sactive |= (0x00000001 << tag);
        core_scr_write(SCR_ACTIVE, sactive);

        dev_dbg(qc->ap->dev, "%s: tag=%d ap->link.sactive = 0x%08x "
                "sactive=0x%08x\n", __func__, tag, qc->ap->link.sactive,
                sactive);

        ap->ops->sff_tf_load(ap, &qc->tf);
        sata_dwc_exec_command_by_tag(ap, &qc->tf, qc->tag,
                                     SATA_DWC_CMD_ISSUED_PEND);
    } else {
        ata_sff_qc_issue(qc);
    }
    return 0;
}