Commit 7f9ad9b8 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

libata: ata_dev_disable() should be called from EH context

ata_port_detach() calls ata_dev_disable() with host lock held but
ata_dev_disable() should be called from EH context.  ata_port_detach()
steals EH context by setting ATA_PFLAG_UNLOADAING and flushing EH.
Drop locking around ata_dev_disable() and note that ata_port_detach()
owns EH context at that point.
Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent ce2e0abb
...@@ -7210,18 +7210,14 @@ static void ata_port_detach(struct ata_port *ap) ...@@ -7210,18 +7210,14 @@ static void ata_port_detach(struct ata_port *ap)
ata_port_wait_eh(ap); ata_port_wait_eh(ap);
/* EH is now guaranteed to see UNLOADING, so no new device /* EH is now guaranteed to see UNLOADING - EH context belongs
* will be attached. Disable all existing devices. * to us. Disable all existing devices.
*/ */
spin_lock_irqsave(ap->lock, flags);
ata_port_for_each_link(link, ap) { ata_port_for_each_link(link, ap) {
ata_link_for_each_dev(dev, link) ata_link_for_each_dev(dev, link)
ata_dev_disable(dev); ata_dev_disable(dev);
} }
spin_unlock_irqrestore(ap->lock, flags);
/* Final freeze & EH. All in-flight commands are aborted. EH /* Final freeze & EH. All in-flight commands are aborted. EH
* will be skipped and retrials will be terminated with bad * will be skipped and retrials will be terminated with bad
* target. * target.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment