On 21 December 2011 16:23, Girish K S <girish.shivananjappa@xxxxxxxxxx> wrote: > On 21 December 2011 13:09, Saugata Das <saugata.das@xxxxxxxxxxxxxx> wrote: >> From: Saugata Das <saugata.das@xxxxxxxxxx> >> >> MMC-4.5 data tag feature will be used to store the file system meta-data in the >> tagged region of eMMC. This will improve the write and subsequent read transfer >> time for the meta data. >> >> Signed-off-by: Saugata Das <saugata.das@xxxxxxxxxx> >> --- >> drivers/mmc/card/block.c | 17 +++++++++++++++-- >> drivers/mmc/core/mmc.c | 14 ++++++++++++++ >> include/linux/mmc/card.h | 2 ++ >> include/linux/mmc/mmc.h | 3 +++ >> 4 files changed, 34 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c >> index a1cb21f..af3b6c3 100644 >> --- a/drivers/mmc/card/block.c >> +++ b/drivers/mmc/card/block.c >> @@ -995,6 +995,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 >> @@ -1071,6 +1072,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, >> 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). >> * However, it is not sufficient to just send CMD23, >> @@ -1091,10 +1102,12 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, >> >> if ((md->flags & MMC_BLK_CMD23) && >> mmc_op_multi(brq->cmd.opcode) && >> - (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) { >> + (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; >> } >> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c >> index dbf421a..244049b 100644 >> --- a/drivers/mmc/core/mmc.c >> +++ b/drivers/mmc/core/mmc.c >> @@ -488,6 +488,20 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) >> ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 | >> ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | >> ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; >> + >> + if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) >> + card->ext_csd.data_sector_size = 4096; >> + else >> + card->ext_csd.data_sector_size = 512; >> + >> + if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) && >> + (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) { >> + card->ext_csd.data_tag_unit_size = >> + ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) * >> + (card->ext_csd.data_sector_size); >> + } else { >> + card->ext_csd.data_tag_unit_size = 0; >> + } >> } >> >> out: >> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h >> index 415f2db..a55668d 100644 >> --- a/include/linux/mmc/card.h >> +++ b/include/linux/mmc/card.h >> @@ -71,6 +71,8 @@ struct mmc_ext_csd { >> bool hpi_en; /* HPI enablebit */ >> bool hpi; /* HPI support bit */ >> unsigned int hpi_cmd; /* cmd used as HPI */ >> + unsigned int data_sector_size; /* 512Bytes or 4KB */ >> + unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ >> u8 raw_partition_support; /* 160 */ >> u8 raw_erased_mem_count; /* 181 */ >> u8 raw_ext_csd_structure; /* 194 */ >> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h >> index 0e71356..e076f7f 100644 >> --- a/include/linux/mmc/mmc.h >> +++ b/include/linux/mmc/mmc.h >> @@ -273,6 +273,7 @@ struct _mmc_csd { >> #define EXT_CSD_FLUSH_CACHE 32 /* W */ >> #define EXT_CSD_CACHE_CTRL 33 /* R/W */ >> #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ >> +#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */ >> #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ >> #define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ >> #define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ >> @@ -313,6 +314,8 @@ struct _mmc_csd { >> #define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ >> #define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ >> #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ >> +#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ >> +#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ >> #define EXT_CSD_HPI_FEATURES 503 /* RO */ >> >> /* > > TAG_RES_SIZE in the extended csd register mentions about the resource > size utilised by the device to keep data tag. > This can be used to avoid the data exhaustion case. > Once the tag resource is exhausted, the further tag data writes will be ignored by eMMC and those will be written to the non-tagged or default area of eMMC (ref to section 6.6.25 in 4.5 spec : "The data shall still be written to the device regardless of the resources exhaustion; however, it may not have the improved characteristics"). So, host driver need not do additional tracking of the amount of data written using tag option. >> -- >> 1.7.4.3 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html