From: Tejun Heo Date: Sat, 15 Dec 2007 06:05:00 +0000 (+0900) Subject: libata: ata_dev_disable() should be called from EH context X-Git-Tag: v2.6.24-rc6~23^2~8 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f9ad9b8b96855f529f4fe9db0bf32cd3f14c01b;p=linux-2.6 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: Tejun Heo Signed-off-by: Jeff Garzik --- diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 99a18cea31..c316eacbed 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -7210,18 +7210,14 @@ static void ata_port_detach(struct ata_port *ap) ata_port_wait_eh(ap); - /* EH is now guaranteed to see UNLOADING, so no new device - * will be attached. Disable all existing devices. + /* EH is now guaranteed to see UNLOADING - EH context belongs + * to us. Disable all existing devices. */ - spin_lock_irqsave(ap->lock, flags); - ata_port_for_each_link(link, ap) { ata_link_for_each_dev(dev, link) ata_dev_disable(dev); } - spin_unlock_irqrestore(ap->lock, flags); - /* Final freeze & EH. All in-flight commands are aborted. EH * will be skipped and retrials will be terminated with bad * target.