diff options
Diffstat (limited to 'drivers/mmc/card/queue.c')
-rw-r--r-- | drivers/mmc/card/queue.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index c77eb49eda0..3b15884e435 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -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; } @@ -130,6 +130,18 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock 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; + } + } #ifdef CONFIG_MMC_BLOCK_BOUNCE if (host->max_hw_segs == 1) { |