Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/drivers/mmc/mmc_queue.c | |
3 | * | |
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | */ | |
11 | #include <linux/module.h> | |
12 | #include <linux/blkdev.h> | |
87598a2b | 13 | #include <linux/kthread.h> |
1da177e4 LT |
14 | |
15 | #include <linux/mmc/card.h> | |
16 | #include <linux/mmc/host.h> | |
17 | #include "mmc_queue.h" | |
18 | ||
87598a2b | 19 | #define MMC_QUEUE_SUSPENDED (1 << 0) |
1da177e4 LT |
20 | |
21 | /* | |
22 | * Prepare a MMC request. Essentially, this means passing the | |
23 | * preparation off to the media driver. The media driver will | |
24 | * create a mmc_io_request in req->special. | |
25 | */ | |
26 | static int mmc_prep_request(struct request_queue *q, struct request *req) | |
27 | { | |
28 | struct mmc_queue *mq = q->queuedata; | |
29 | int ret = BLKPREP_KILL; | |
30 | ||
4aff5e23 | 31 | if (blk_special_request(req)) { |
1da177e4 LT |
32 | /* |
33 | * Special commands already have the command | |
34 | * blocks already setup in req->special. | |
35 | */ | |
36 | BUG_ON(!req->special); | |
37 | ||
38 | ret = BLKPREP_OK; | |
4aff5e23 | 39 | } else if (blk_fs_request(req) || blk_pc_request(req)) { |
1da177e4 LT |
40 | /* |
41 | * Block I/O requests need translating according | |
42 | * to the protocol. | |
43 | */ | |
44 | ret = mq->prep_fn(mq, req); | |
45 | } else { | |
46 | /* | |
47 | * Everything else is invalid. | |
48 | */ | |
49 | blk_dump_rq_flags(req, "MMC bad request"); | |
50 | } | |
51 | ||
52 | if (ret == BLKPREP_OK) | |
4aff5e23 | 53 | req->cmd_flags |= REQ_DONTPREP; |
1da177e4 LT |
54 | |
55 | return ret; | |
56 | } | |
57 | ||
58 | static int mmc_queue_thread(void *d) | |
59 | { | |
60 | struct mmc_queue *mq = d; | |
61 | struct request_queue *q = mq->queue; | |
1da177e4 LT |
62 | |
63 | /* | |
64 | * Set iothread to ensure that we aren't put to sleep by | |
65 | * the process freezing. We handle suspension ourselves. | |
66 | */ | |
67 | current->flags |= PF_MEMALLOC|PF_NOFREEZE; | |
68 | ||
1da177e4 | 69 | down(&mq->thread_sem); |
1da177e4 LT |
70 | do { |
71 | struct request *req = NULL; | |
72 | ||
73 | spin_lock_irq(q->queue_lock); | |
74 | set_current_state(TASK_INTERRUPTIBLE); | |
75 | if (!blk_queue_plugged(q)) |