关于MMC子系统添加CMD56获取金士顿数据写入量方案

本篇主要介绍在SDM450 Android9平台MMC子系统添加接口来获取金士顿EMMC数据写入量方案。

1、金士顿数据写入量获取流程
在这里插入图片描述
2、数据写入量结果计算方式
在这里插入图片描述
从金士顿提供的文档来看,整体流程如下:

1、首先发生CMD16设置blocklen为512字节

2、CMD16发送成功后,发送CMD56用于获取数据写入量

3、CMD56获取到的数据信息:

  bit15~bit12:written data unit size

  bit19~bit16:written data sector size

SDM450 Android10平台添加接口代码如下:

1、kernel/msm-4.9/drivers/mmc/core/mmc_ops.c文件添加获取写入量接口

#define HEX_STR_STEP             (3)
#define HEX_STR_SPLIT_DSPACE     (' ')
#define HEX_STR_SPLIT_SEMICOLON  (':')
#define HEX_STR_SPLIT_COMMA      (',')

static int starce_hex2str(uint8_t *byte, int byte_len, uint8_t *str, long str_len,uint8_t split_c)
{
    int i = 0;
    char *pos = (char*)str;
    long tmp_len = 0;
    tmp_len = HEX_STR_STEP*byte_len + 1;

    if(str_len < tmp_len){
        pr_err("ERROR: len error %ld,%ld\n",str_len,tmp_len);
        return -1;
    }

    for(i = 0; i < byte_len -1; i += 1){
        pos += sprintf(pos, "%02X%c", byte[i],split_c);
    }

    pos += sprintf(pos, "%02X", byte[byte_len - 1]);

    if(str_len != ((uint8_t *)pos - str + HEX_STR_STEP)){
        pr_err("ERROR: starce_hex2str str_len =%ld, sp len =%ld\n",str_len,((uint8_t *)pos - str + HEX_STR_STEP));
        return -1;
    }
    return 0;
}

uint8_t * trace_byte_to_str(uint8_t* trace_byte_data,int len)
{
    int trace_str_len = len*3+2;
    uint8_t *trace_str_data = NULL;
    int ret = 0;

    if(NULL == trace_byte_data){
        pr_err("tarce data is NULL\n");
        goto error;
    }

    pr_err("malloc trace_str_len=%d\n",trace_str_len);

    trace_str_data = (uint8_t *)kmalloc(trace_str_len,GFP_KERNEL);

    if(NULL != trace_str_data){
        memset(trace_str_data,0,trace_str_len);
        ret = starce_hex2str(trace_byte_data,len,trace_str_data,trace_str_len,HEX_STR_SPLIT_DSPACE);
        if(0 != ret){
            pr_err("error starce_hex2str fail %d\n",ret);
            goto error;
        }
    }else{
        pr_err("tarce str malloc trace_str_len=%d fail\n",trace_str_len);
        goto error;
    }
    return trace_str_data;
error:
    return NULL;
}

int mmc_get_wr_data(struct mmc_card *card, struct mmc_host *host, u32 *unit, u32 *sector)
{
    struct mmc_request mrq;
    struct mmc_command cmd;
    struct mmc_data data;
    struct scatterlist sg;
    char *data_buf;
    char* buf = NULL;
    int err = 0;

    err = mmc_set_blocklen(card, 512);
    pr_err("%s:%d: send CMD16 err = %d\n", __func__, __LINE__, err);

    memset(&mrq, 0, sizeof(struct mmc_request));
    memset(&cmd, 0, sizeof(struct mmc_command));
    memset(&data, 0, sizeof(struct mmc_data));

    data_buf = kmalloc(512, GFP_KERNEL);
    if (data_buf == NULL)
        return -ENOMEM;

    mrq.cmd = &cmd;
    mrq.data = &data;

    cmd.opcode = MMC_GEN_CMD;
    cmd.arg = 0x8D;
    cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
    data.blksz = 512;
    data.blocks = 1;
    data.flags = MMC_DATA_READ;
    data.sg = &sg;
    data.sg_len = 1;

    sg_init_one(&sg, data_buf, 512);
    mmc_wait_for_req(host, &mrq);
    pr_err("%s:%d: send CMD56 err = %d\n", __func__, __LINE__, cmd.error);
    if (cmd.error) {
        err = cmd.error;
    }
    else {
        buf = (char*)trace_byte_to_str(data_buf,512);
        if(NULL != buf){
            pr_err("data=%s\n",buf);
        }
        pr_err("%02x %02x %02x %02x\n",data_buf[15],data_buf[14],data_buf[13],data_buf[12]);
        pr_err("%02x %02x %02x %02x\n",data_buf[19],data_buf[18],data_buf[17],data_buf[16]);
        *unit = data_buf[15];
        *unit = *unit << 8 | data_buf[14];
        *unit = *unit << 8 | data_buf[13];
        *unit = *unit << 8 | data_buf[12];
        *sector = data_buf[19];
        *sector = *sector << 8 | data_buf[18];
        *sector = *sector << 8 | data_buf[17];
        *sector = *sector << 8 | data_buf[16];
    }
    kfree(data_buf);

    return err;
}

2、 kernel/msm-4.9 / drivers/mmc/core/mmc_ops.h

int mmc_get_wr_data(struct mmc_card *card, struct mmc_host *host, u32 *unit, u32 *sector);

3、 kernel/msm-4.9 / include/linux/mmc/card.h

struct mmc_card {

    ......

    u32 unit;
    u32 sector;

}

4、 kernel/msm-4.9 / drivers/mmc/core/mmc.c

static ssize_t mmc_wr_data_show(struct device *dev,
                struct device_attribute *attr,
                char *buf)
{
    struct mmc_card *card = mmc_dev_to_card(dev);

    return sprintf(buf, "unit=0x%x\nsector=0x%x\n", card->unit, card->sector);
}

static DEVICE_ATTR(data_size, S_IRUGO, mmc_wr_data_show, NULL);

static struct attribute *mmc_std_attrs[] = {

    ......

    &dev_attr_data_size.attr,

}

static int mmc_init_card(struct mmc_host *host, u32 ocr,
    struct mmc_card *oldcard)
{

    ......

    u32 unit = 0;
    u32 sector = 0;

 

    err = mmc_get_wr_data(card, host, &unit, &sector);
    if (err == 0) {
        card->unit = unit;
        card->sector = sector;
    }
    pr_err("%s:%d:unit = 0x%x, sector = 0x%x\n", __func__, __LINE__, unit, sector);

}

最终在/sys/bus/mmc/devices/mmc0:0001下生成data_size节点,用于查看数据写入量:如下
在这里插入图片描述
数据写入量计算结果:

数据写入量 = (unit*128 + sector)512/1024/1024/1024 = (90313128 + 913) * 512/1024/1024/1024 = 5.5GB

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值