diff options
Diffstat (limited to 'drivers/ata/libata-core.c')
| -rw-r--r-- | drivers/ata/libata-core.c | 25 | 
1 files changed, 20 insertions, 5 deletions
| diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7ef7c4f216f..932eaee5024 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5111,15 +5111,18 @@ void ata_qc_issue(struct ata_queued_cmd *qc)  	qc->flags |= ATA_QCFLAG_ACTIVE;  	ap->qc_active |= 1 << qc->tag; -	/* We guarantee to LLDs that they will have at least one +	/* +	 * We guarantee to LLDs that they will have at least one  	 * non-zero sg if the command is a data command.  	 */ -	BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); +	if (WARN_ON_ONCE(ata_is_data(prot) && +			 (!qc->sg || !qc->n_elem || !qc->nbytes))) +		goto sys_err;  	if (ata_is_dma(prot) || (ata_is_pio(prot) &&  				 (ap->flags & ATA_FLAG_PIO_DMA)))  		if (ata_sg_setup(qc)) -			goto sg_err; +			goto sys_err;  	/* if device is sleeping, schedule reset and abort the link */  	if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { @@ -5136,7 +5139,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)  		goto err;  	return; -sg_err: +sys_err:  	qc->err_mask |= AC_ERR_SYSTEM;  err:  	ata_qc_complete(qc); @@ -5415,6 +5418,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,   */  int ata_host_suspend(struct ata_host *host, pm_message_t mesg)  { +	unsigned int ehi_flags = ATA_EHI_QUIET;  	int rc;  	/* @@ -5423,7 +5427,18 @@ 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); +	/* +	 * On some hardware, device fails to respond after spun down +	 * for suspend.  As the device won't be used before being +	 * resumed, we don't need to touch the device.  Ask EH to skip +	 * the usual stuff and proceed directly to suspend. +	 * +	 * http://thread.gmane.org/gmane.linux.ide/46764 +	 */ +	if (mesg.event == PM_EVENT_SUSPEND) +		ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY; + +	rc = ata_host_request_pm(host, mesg, 0, ehi_flags, 1);  	if (rc == 0)  		host->dev->power.power_state = mesg;  	return rc; | 
