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 /drivers/mmc/card/block.c | |
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>
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r-- | drivers/mmc/card/block.c | 46 |
1 files changed, 43 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) |