diff options
author | Adrian Hunter <adrian.hunter@nokia.com> | 2010-08-11 17:17:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-12 11:43:30 -0400 |
commit | 4980454868af4b2f84f1f15f4b76512eecb37e1d (patch) | |
tree | c8480c25797558d44f39fdbec2e8a4b22f47c729 | |
parent | 8d57a98ccd0b4489003473979da8f5a1363ba7a3 (diff) |
mmc_block: add support for secure discard
Secure discard is implemented by Secure Trim if the discard is unaligned
or Secure Erase otherwise.
Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Acked-by: Jens Axboe <axboe@kernel.dk>
Cc: Kyungmin Park <kmpark@infradead.org>
Cc: Madhusudhan Chikkature <madhu.cr@ti.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ben Gardiner <bengardiner@nanometrics.ca>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/mmc/card/block.c | 46 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 3 |
2 files changed, 46 insertions, 3 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 03f96e975fe5..d545f79f6000 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -280,6 +280,42 @@ out: | |||
280 | return err ? 0 : 1; | 280 | return err ? 0 : 1; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, | ||
284 | struct request *req) | ||
285 | { | ||
286 | struct mmc_blk_data *md = mq->data; | ||
287 | struct mmc_card *card = md->queue.card; | ||
288 | unsigned int from, nr, arg; | ||
289 | int err = 0; | ||
290 | |||
291 | mmc_claim_host(card->host); | ||
292 | |||
293 | if (!mmc_can_secure_erase_trim(card)) { | ||
294 | err = -EOPNOTSUPP; | ||
295 | goto out; | ||
296 | } | ||
297 | |||
298 | from = blk_rq_pos(req); | ||
299 | nr = blk_rq_sectors(req); | ||
300 | |||
301 | if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) | ||
302 | arg = MMC_SECURE_TRIM1_ARG; | ||
303 | else | ||
304 | arg = MMC_SECURE_ERASE_ARG; | ||
305 | |||
306 | err = mmc_erase(card, from, nr, arg); | ||
307 | if (!err && arg == MMC_SECURE_TRIM1_ARG) | ||
308 | err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); | ||
309 | out: | ||
310 | spin_lock_irq(&md->lock); | ||
311 | __blk_end_request(req, err, blk_rq_bytes(req)); | ||
312 | spin_unlock_irq(&md->lock); | ||
313 | |||
314 | mmc_release_host(card->host); | ||
315 | |||
316 | return err ? 0 : 1; | ||
317 | } | ||
318 | |||
283 | static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) | 319 | static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) |
284 | { | 320 | { |
285 | struct mmc_blk_data *md = mq->data; | 321 | struct mmc_blk_data *md = mq->data; |
@@ -510,10 +546,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) | |||
510 | 546 | ||
511 | static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | 547 | static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) |
512 | { | 548 | { |
513 | if (req->cmd_flags & REQ_DISCARD) | 549 | if (req->cmd_flags & REQ_DISCARD) { |
514 | return mmc_blk_issue_discard_rq(mq, req); | 550 | if (req->cmd_flags & REQ_SECURE) |
515 | else | 551 | return mmc_blk_issue_secdiscard_rq(mq, req); |
552 | else | ||
553 | return mmc_blk_issue_discard_rq(mq, req); | ||
554 | } else { | ||
516 | return mmc_blk_issue_rw_rq(mq, req); | 555 | return mmc_blk_issue_rw_rq(mq, req); |
556 | } | ||
517 | } | 557 | } |
518 | 558 | ||
519 | static inline int mmc_blk_readonly(struct mmc_card *card) | 559 | static inline int mmc_blk_readonly(struct mmc_card *card) |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 3b15884e435c..e876678176be 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -141,6 +141,9 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
141 | mq->queue->limits.discard_alignment = | 141 | mq->queue->limits.discard_alignment = |
142 | card->erase_size << 9; | 142 | card->erase_size << 9; |
143 | } | 143 | } |
144 | if (mmc_can_secure_erase_trim(card)) | ||
145 | queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, | ||
146 | mq->queue); | ||
144 | } | 147 | } |
145 | 148 | ||
146 | #ifdef CONFIG_MMC_BLOCK_BOUNCE | 149 | #ifdef CONFIG_MMC_BLOCK_BOUNCE |