diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2006-11-14 16:08:16 -0500 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2006-12-01 13:06:05 -0500 |
commit | 89b4e133afea9fce333054b94d89953583a55c19 (patch) | |
tree | 23502a0f8b2bd2ebe0b821a152711746b3457560 /drivers/mmc/mmc_queue.c | |
parent | 077df884835ebf2b5db16aacd9a24691d89902a0 (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.c | 22 |
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) | |||
103 | static void mmc_request(request_queue_t *q) | 103 | static 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 | ||
169 | void mmc_cleanup_queue(struct mmc_queue *mq) | 182 | void 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); |