summaryrefslogtreecommitdiff
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3d0027ec33c2..3b6243f0f91e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1540,6 +1540,7 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
{
struct ata_link *link = dev->link;
struct ata_port *ap = link->ap;
+ const bool owns_eh_mutex = ap->host->eh_owner == current;
u8 command = tf->command;
struct ata_queued_cmd *qc;
struct scatterlist sgl;
@@ -1604,7 +1605,7 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
qc->private_data = &wait;
qc->complete_fn = ata_qc_complete_internal;
- ata_qc_issue(qc);
+ ata_qc_issue(ap, qc);
spin_unlock_irqrestore(ap->lock, flags);
@@ -1617,11 +1618,25 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
}
}
- ata_eh_release(ap);
+ if (owns_eh_mutex) {
+ /*
+ * To prevent that the compiler complains about the
+ * ata_eh_release() call below.
+ */
+ __acquire(&ap->host->eh_mutex);
+ ata_eh_release(ap);
+ }
rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
- ata_eh_acquire(ap);
+ if (owns_eh_mutex) {
+ ata_eh_acquire(ap);
+ /*
+ * To prevent that the compiler complains about the above
+ * ata_eh_acquire() call.
+ */
+ __release(&ap->host->eh_mutex);
+ }
ata_sff_flush_pio_task(ap);
@@ -5135,6 +5150,7 @@ EXPORT_SYMBOL_GPL(ata_qc_get_active);
/**
* ata_qc_issue - issue taskfile to device
+ * @ap: ATA port of interest
* @qc: command to issue to device
*
* Prepare an ATA command to submission to device.
@@ -5145,9 +5161,9 @@ EXPORT_SYMBOL_GPL(ata_qc_get_active);
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-void ata_qc_issue(struct ata_queued_cmd *qc)
+void ata_qc_issue(struct ata_port *ap, struct ata_queued_cmd *qc)
+ __must_hold(ap->lock)
{
- struct ata_port *ap = qc->ap;
struct ata_link *link = qc->dev->link;
u8 prot = qc->tf.protocol;
@@ -6820,6 +6836,7 @@ EXPORT_SYMBOL_GPL(ata_ratelimit);
* Might sleep.
*/
void ata_msleep(struct ata_port *ap, unsigned int msecs)
+ __context_unsafe(conditional locking)
{
bool owns_eh = ap && ap->host->eh_owner == current;
@@ -6894,6 +6911,7 @@ static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
}
static void ata_dummy_error_handler(struct ata_port *ap)
+ __must_hold(&ap->host->eh_mutex)
{
/* truly dummy */
}