Ensure the queue is flushed when destroying the mmc block device
Pierre Ossman
drzeus-list at drzeus.unroutablecx
Thu Nov 16 11:15:25 EST 2006
Commit: 9f9151dbc02eb20bc5b1485f62867821f20fa4a2
Parent: bc0b9a38bcd71cef7cb013b8593d80f2f54c924a
commit 9f9151dbc02eb20bc5b1485f62867821f20fa4a2
Author: Pierre Ossman <drzeus-list at drzeus.cx>
AuthorDate: Thu Nov 16 11:19:13 2006 -0500
Commit: Andres Salomon <dilinger at debian.org>
CommitDate: Thu Nov 16 11:19:13 2006 -0500
Ensure the queue is flushed when destroying the mmc block device
Signed-off-by: Andres Salomon <dilinger at debian.org>
---
drivers/mmc/mmc_block.c | 15 ++++++---------
drivers/mmc/mmc_queue.c | 22 ++++++++++++++++++++++
2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index 0ea0e92..8939b8d 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -83,7 +83,6 @@ static void mmc_blk_put(struct mmc_blk_d
md->usage--;
if (md->usage == 0) {
put_disk(md->disk);
- mmc_cleanup_queue(&md->queue);
kfree(md);
}
mutex_unlock(&open_lock);
@@ -225,10 +224,10 @@ static int mmc_blk_issue_rq(struct mmc_q
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
struct mmc_blk_request brq;
- int ret;
+ int ret = 1;
if (mmc_card_claim_host(card))
- goto cmd_err;
+ goto flush_queue;
do {
struct mmc_command cmd;
@@ -350,8 +349,6 @@ #endif
return 1;
cmd_err:
- ret = 1;
-
/*
* If this is an SD card and we're writing, we can first
* mark the known good sectors as ok.
@@ -385,6 +382,7 @@ #endif
mmc_card_release_host(card);
+flush_queue:
spin_lock_irq(&md->lock);
while (ret) {
ret = end_that_request_chunk(req, 0,
@@ -558,12 +556,11 @@ static void mmc_blk_remove(struct mmc_ca
if (md) {
int devidx;
+ /* Stop new requests from getting into the queue */
del_gendisk(md->disk);
- /*
- * I think this is needed.
- */
- md->disk->queue = NULL;
+ /* Then flush out any already in there */
+ mmc_cleanup_queue(&md->queue);
devidx = md->disk->first_minor >> MMC_SHIFT;
__clear_bit(devidx, dev_use);
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c
index 4ccdd82..b6769e2 100644
--- a/drivers/mmc/mmc_queue.c
+++ b/drivers/mmc/mmc_queue.c
@@ -111,6 +111,19 @@ static int mmc_queue_thread(void *d)
static void mmc_request(request_queue_t *q)
{
struct mmc_queue *mq = q->queuedata;
+ struct request *req;
+ int ret;
+
+ if (!mq) {
+ printk(KERN_ERR "MMC: killing requests for dead queue\n");
+ while ((req = elv_next_request(q)) != NULL) {
+ do {
+ ret = end_that_request_chunk(req, 0,
+ req->current_nr_sectors << 9);
+ } while (ret);
+ }
+ return;
+ }
if (!mq->req)
wake_up(&mq->thread_wq);
@@ -179,6 +192,15 @@ EXPORT_SYMBOL(mmc_init_queue);
void mmc_cleanup_queue(struct mmc_queue *mq)
{
+ request_queue_t *q = mq->queue;
+ unsigned long flags;
+
+ /* Mark that we should start throwing out stragglers */
+ spin_lock_irqsave(q->queue_lock, flags);
+ q->queuedata = NULL;
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ /* Then terminate our worker thread */
mq->flags |= MMC_QUEUE_EXIT;
wake_up(&mq->thread_wq);
wait_for_completion(&mq->thread_complete);
More information about the Commits-kernel
mailing list