aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2010-08-11 17:17:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-12 11:43:31 -0400
commitd862b13bc8cbab9692fbe0ef44c40d0488b81af1 (patch)
treee8eeff7c7d8759cd6c812a895d2234ddf16d94c7 /drivers/memstick
parent21fd0495ea61d53e0ebe575330e343ce4e6d2a61 (diff)
memstick: fix hangs on unexpected device removal in mspro_blk
mspro_block_remove() is called from detect thread that first calls the mspro_block_stop(), which stops the request queue. If we call del_gendisk() with the queue stopped we get a deadlock. Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Cc: Alex Dubov <oakad@yahoo.com> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/memstick')
-rw-r--r--drivers/memstick/core/mspro_block.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index aa5ac6efd9b9..d3f1a087eced 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -1339,13 +1339,14 @@ static void mspro_block_remove(struct memstick_dev *card)
1339 struct mspro_block_data *msb = memstick_get_drvdata(card); 1339 struct mspro_block_data *msb = memstick_get_drvdata(card);
1340 unsigned long flags; 1340 unsigned long flags;
1341 1341
1342 del_gendisk(msb->disk);
1343 dev_dbg(&card->dev, "mspro block remove\n");
1344 spin_lock_irqsave(&msb->q_lock, flags); 1342 spin_lock_irqsave(&msb->q_lock, flags);
1345 msb->eject = 1; 1343 msb->eject = 1;
1346 blk_start_queue(msb->queue); 1344 blk_start_queue(msb->queue);
1347 spin_unlock_irqrestore(&msb->q_lock, flags); 1345 spin_unlock_irqrestore(&msb->q_lock, flags);
1348 1346
1347 del_gendisk(msb->disk);
1348 dev_dbg(&card->dev, "mspro block remove\n");
1349
1349 blk_cleanup_queue(msb->queue); 1350 blk_cleanup_queue(msb->queue);
1350 msb->queue = NULL; 1351 msb->queue = NULL;
1351 1352