aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/mmc_queue.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-11-14 16:08:16 -0500
committerPierre Ossman <drzeus@drzeus.cx>2006-12-01 13:06:05 -0500
commit89b4e133afea9fce333054b94d89953583a55c19 (patch)
tree23502a0f8b2bd2ebe0b821a152711746b3457560 /drivers/mmc/mmc_queue.c
parent077df884835ebf2b5db16aacd9a24691d89902a0 (diff)
mmc: Flush block queue when removing card
After mmc_block's remove function has exited, we must not touch the card structure in any way. This means we not only must remove the gendisk, we must also flush out any remaning requests already queued up. We previously removed the disk, but didn't flush it, causing oops:es when removing a card in the middle of a transfer. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/mmc_queue.c')
-rw-r--r--drivers/mmc/mmc_queue.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c
index 4e6a534e91d0..5fa72ccb4feb 100644
--- a/drivers/mmc/mmc_queue.c
+++ b/drivers/mmc/mmc_queue.c
@@ -103,6 +103,19 @@ static int mmc_queue_thread(void *d)
103static void mmc_request(request_queue_t *q) 103static void mmc_request(request_queue_t *q)
104{ 104{
105 struct mmc_queue *mq = q->queuedata; 105 struct mmc_queue *mq = q->queuedata;
106 struct request *req;
107 int ret;
108
109 if (!mq) {
110 printk(KERN_ERR "MMC: killing requests for dead queue\n");
111 while ((req = elv_next_request(q)) != NULL) {
112 do {
113 ret = end_that_request_chunk(req, 0,
114 req->current_nr_sectors << 9);
115 } while (ret);
116 }
117 return;
118 }
106 119
107 if (!mq->req) 120 if (!mq->req)
108 wake_up_process(mq->thread); 121 wake_up_process(mq->thread);
@@ -168,6 +181,15 @@ EXPORT_SYMBOL(mmc_init_queue);
168 181
169void mmc_cleanup_queue(struct mmc_queue *mq) 182void mmc_cleanup_queue(struct mmc_queue *mq)
170{ 183{
184 request_queue_t *q = mq->queue;
185 unsigned long flags;
186
187 /* Mark that we should start throwing out stragglers */
188 spin_lock_irqsave(q->queue_lock, flags);
189 q->queuedata = NULL;
190 spin_unlock_irqrestore(q->queue_lock, flags);
191
192 /* Then terminate our worker thread */
171 kthread_stop(mq->thread); 193 kthread_stop(mq->thread);
172 194
173 kfree(mq->sg); 195 kfree(mq->sg);