]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/mmc/card/queue.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[karo-tx-linux.git] / drivers / mmc / card / queue.c
index c77eb49eda0ea9825be7f92bf68b89c25c9b6a39..9c0b42bfe0898be59cb8210b6e57dcc6a47ec448 100644 (file)
@@ -30,9 +30,9 @@
 static int mmc_prep_request(struct request_queue *q, struct request *req)
 {
        /*
-        * We only like normal block requests.
+        * We only like normal block requests and discards.
         */
-       if (req->cmd_type != REQ_TYPE_FS) {
+       if (req->cmd_type != REQ_TYPE_FS && !(req->cmd_flags & REQ_DISCARD)) {
                blk_dump_rq_flags(req, "MMC bad request");
                return BLKPREP_KILL;
        }
@@ -128,8 +128,22 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
        mq->req = NULL;
 
        blk_queue_prep_rq(mq->queue, mmc_prep_request);
-       blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN);
        queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
+       if (mmc_can_erase(card)) {
+               queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mq->queue);
+               mq->queue->limits.max_discard_sectors = UINT_MAX;
+               if (card->erased_byte == 0)
+                       mq->queue->limits.discard_zeroes_data = 1;
+               if (!mmc_can_trim(card) && is_power_of_2(card->erase_size)) {
+                       mq->queue->limits.discard_granularity =
+                                                       card->erase_size << 9;
+                       mq->queue->limits.discard_alignment =
+                                                       card->erase_size << 9;
+               }
+               if (mmc_can_secure_erase_trim(card))
+                       queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD,
+                                               mq->queue);
+       }
 
 #ifdef CONFIG_MMC_BLOCK_BOUNCE
        if (host->max_hw_segs == 1) {