|
@@ -1080,6 +1080,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
|
|
|
struct mmc_blk_request *brq = &mqrq->brq;
|
|
|
struct request *req = mqrq->req;
|
|
|
struct mmc_blk_data *md = mq->data;
|
|
|
+ bool do_data_tag;
|
|
|
|
|
|
/*
|
|
|
* Reliable writes are used to implement Forced Unit Access and
|
|
@@ -1155,6 +1156,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
|
|
|
if (do_rel_wr)
|
|
|
mmc_apply_rel_rw(brq, card, req);
|
|
|
|
|
|
+ /*
|
|
|
+ * Data tag is used only during writing meta data to speed
|
|
|
+ * up write and any subsequent read of this meta data
|
|
|
+ */
|
|
|
+ do_data_tag = (card->ext_csd.data_tag_unit_size) &&
|
|
|
+ (req->cmd_flags & REQ_META) &&
|
|
|
+ (rq_data_dir(req) == WRITE) &&
|
|
|
+ ((brq->data.blocks * brq->data.blksz) >=
|
|
|
+ card->ext_csd.data_tag_unit_size);
|
|
|
+
|
|
|
/*
|
|
|
* Pre-defined multi-block transfers are preferable to
|
|
|
* open ended-ones (and necessary for reliable writes).
|
|
@@ -1173,13 +1184,13 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
|
|
|
* We'll avoid using CMD23-bounded multiblock writes for
|
|
|
* these, while retaining features like reliable writes.
|
|
|
*/
|
|
|
-
|
|
|
- if ((md->flags & MMC_BLK_CMD23) &&
|
|
|
- mmc_op_multi(brq->cmd.opcode) &&
|
|
|
- (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
|
|
|
+ if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq->cmd.opcode) &&
|
|
|
+ (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
|
|
|
+ do_data_tag)) {
|
|
|
brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
|
|
|
brq->sbc.arg = brq->data.blocks |
|
|
|
- (do_rel_wr ? (1 << 31) : 0);
|
|
|
+ (do_rel_wr ? (1 << 31) : 0) |
|
|
|
+ (do_data_tag ? (1 << 29) : 0);
|
|
|
brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
|
|
brq->mrq.sbc = &brq->sbc;
|
|
|
}
|