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 7ef7c4f216fa..932eaee50245 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) | |||
5111 | qc->flags |= ATA_QCFLAG_ACTIVE; | 5111 | qc->flags |= ATA_QCFLAG_ACTIVE; |
5112 | ap->qc_active |= 1 << qc->tag; | 5112 | ap->qc_active |= 1 << qc->tag; |
5113 | 5113 | ||
5114 | /* We guarantee to LLDs that they will have at least one | 5114 | /* |
5115 | * We guarantee to LLDs that they will have at least one | ||
5115 | * non-zero sg if the command is a data command. | 5116 | * non-zero sg if the command is a data command. |
5116 | */ | 5117 | */ |
5117 | BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); | 5118 | if (WARN_ON_ONCE(ata_is_data(prot) && |
5119 | (!qc->sg || !qc->n_elem || !qc->nbytes))) | ||
5120 | goto sys_err; | ||
5118 | 5121 | ||
5119 | if (ata_is_dma(prot) || (ata_is_pio(prot) && | 5122 | if (ata_is_dma(prot) || (ata_is_pio(prot) && |
5120 | (ap->flags & ATA_FLAG_PIO_DMA))) | 5123 | (ap->flags & ATA_FLAG_PIO_DMA))) |
5121 | if (ata_sg_setup(qc)) | 5124 | if (ata_sg_setup(qc)) |
5122 | goto sg_err; | 5125 | goto sys_err; |
5123 | 5126 | ||
5124 | /* if device is sleeping, schedule reset and abort the link */ | 5127 | /* if device is sleeping, schedule reset and abort the link */ |
5125 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { | 5128 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { |
@@ -5136,7 +5139,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5136 | goto err; | 5139 | goto err; |
5137 | return; | 5140 | return; |
5138 | 5141 | ||
5139 | sg_err: | 5142 | sys_err: |
5140 | qc->err_mask |= AC_ERR_SYSTEM; | 5143 | qc->err_mask |= AC_ERR_SYSTEM; |
5141 | err: | 5144 | err: |
5142 | ata_qc_complete(qc); | 5145 | ata_qc_complete(qc); |
@@ -5415,6 +5418,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, | |||
5415 | */ | 5418 | */ |
5416 | int ata_host_suspend(struct ata_host *host, pm_message_t mesg) | 5419 | int ata_host_suspend(struct ata_host *host, pm_message_t mesg) |
5417 | { | 5420 | { |
5421 | unsigned int ehi_flags = ATA_EHI_QUIET; | ||
5418 | int rc; | 5422 | int rc; |
5419 | 5423 | ||
5420 | /* | 5424 | /* |
@@ -5423,7 +5427,18 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) | |||
5423 | */ | 5427 | */ |
5424 | ata_lpm_enable(host); | 5428 | ata_lpm_enable(host); |
5425 | 5429 | ||
5426 | rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); | 5430 | /* |
5431 | * On some hardware, device fails to respond after spun down | ||
5432 | * for suspend. As the device won't be used before being | ||
5433 | * resumed, we don't need to touch the device. Ask EH to skip | ||
5434 | * the usual stuff and proceed directly to suspend. | ||
5435 | * | ||
5436 | * http://thread.gmane.org/gmane.linux.ide/46764 | ||
5437 | */ | ||
5438 | if (mesg.event == PM_EVENT_SUSPEND) | ||
5439 | ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY; | ||
5440 | |||
5441 | rc = ata_host_request_pm(host, mesg, 0, ehi_flags, 1); | ||
5427 | if (rc == 0) | 5442 | if (rc == 0) |
5428 | host->dev->power.power_state = mesg; | 5443 | host->dev->power.power_state = mesg; |
5429 | return rc; | 5444 | return rc; |