static bool __read_single_block(int fd, uint32_t args, int opcode, uint8_t *buf) { int ret = -1; int dev_fd = fd; struct mmc_ioc_cmd cmd_desc; memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.write_flag = MMC_DATA_READ; cmd_desc.opcode = opcode; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1; cmd_desc.blksz = DEFAULT_BLOCK_SIZE; cmd_desc.blocks = 1; mmc_ioc_cmd_set_data(cmd_desc, buf); ret = ioctl(dev_fd, MMC_IOC_CMD, &cmd_desc); if (ret) { perror("ioctl"); return false; } else { return true; } }
int mmc_send_write_prot_type(char *dev_path, uint32_t args) { int ret = 0; int dev_fd = 0; struct mmc_ioc_cmd cmd_desc; uint8_t buf[DEFAULT_BLOCK_SIZE]; dev_fd = open(dev_path, O_RDONLY); if(dev_fd == -1) { perror("open device: "); return -EINVAL; } memset(buf, 0xFF, DEFAULT_BLOCK_SIZE); memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.write_flag = MMC_DATA_READ; cmd_desc.opcode = MMC_SEND_WRITE_PROT_TYPE; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1B; mmc_ioc_cmd_set_data(cmd_desc, buf); ret = ioctl(dev_fd, MMC_IOC_CMD, &cmd_desc); if (ret) { perror("ioctl"); } else { dump_memory_u8(buf, DEFAULT_BLOCK_SIZE, stdout); } #ifdef DEBUG printf("response 0 is 0x%08X\n", cmd_desc.response[0]); printf("response 1 is 0x%08X\n", cmd_desc.response[1]); printf("response 2 is 0x%08X\n", cmd_desc.response[2]); printf("response 3 is 0x%08X\n", cmd_desc.response[3]); #endif if(close(dev_fd)) { perror("close deivce"); } return ret; }
int mmc_read_extcsd(int fd, __u8 *extcsd) { int ret = 0; struct mmc_ioc_cmd idata; memset(&idata, 0, sizeof(idata)); memset(extcsd, 0, sizeof(__u8) * 512); idata.write_flag = 0; idata.opcode = MMC_SEND_EXT_CSD; idata.arg = 0; idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; idata.blksz = 512; idata.blocks = 1; mmc_ioc_cmd_set_data(idata, extcsd); ret = ioctl(fd, MMC_IOC_CMD, &idata); return ret; }
int mmc_gen_cmd(int fd, __u32 arg, __u8 *data) { int ret = 0; struct mmc_ioc_cmd idata; memset(&idata, 0, sizeof(idata)); idata.write_flag = (arg & 1) ? 0 : 1; idata.opcode = MMC_GEN_CMD; idata.arg = arg; idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; idata.blksz = 512; idata.blocks = 1; mmc_ioc_cmd_set_data(idata, data); ret = ioctl(fd, MMC_IOC_CMD, &idata); return ret; }
int mmc_send_write_prot_type(int fd, __u32 address, __u64 *result) { int ret = 0; struct mmc_ioc_cmd idata; memset(&idata, 0, sizeof(idata)); memset(result, 0, sizeof(*result)); idata.opcode = MMC_SEND_WRITE_PROT_TYPE; idata.arg = address; idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; idata.blksz = sizeof(*result); idata.blocks = 1; mmc_ioc_cmd_set_data(idata, result); ret = ioctl(fd, MMC_IOC_CMD, &idata); return ret; }
int mmc_switch(char *dev_path, uint32_t args) { int ret = -1; int dev_fd = -1; dev_fd = open(dev_path, O_RDONLY); if(dev_fd == -1) { perror("open device: "); return -1; } uint8_t buf[64]; memset(buf, 0x0, 64); struct mmc_ioc_cmd cmd_desc; memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.write_flag = MMC_DATA_READ; cmd_desc.opcode = MMC_SWITCH; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1; cmd_desc.blksz = 64; cmd_desc.blocks = 1; mmc_ioc_cmd_set_data(cmd_desc, buf); dump_cmd_desc(&cmd_desc, stdout); ret = ioctl(dev_fd, MMC_IOC_CMD, &cmd_desc); if (ret) { perror("ioctl"); } dump_memory_u8(buf, 64, stdout); if(close(dev_fd)) { perror("close device: "); } return ret; }
int mmc_bus_test_r(char *dev_path, uint32_t args) { int ret = -1; // ddr mode #if 0 int dev_fd = -1; struct mmc_ioc_cmd cmd_desc; dev_fd = open(dev_path, O_RDONLY); if(dev_fd == -1) { perror("open device: "); return -1; } memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.opcode = MMC_BUS_TEST_R; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1; mmc_ioc_cmd_set_data(cmd_desc, ext_csd); ret = ioctl(dev_fd, MMC_IOC_CMD, &cmd_desc); if (ret) { perror("ioctl"); } #ifdef DEBUG printf("response 0 is 0x%08X\n", cmd_desc.response[0]); printf("response 1 is 0x%08X\n", cmd_desc.response[1]); printf("response 2 is 0x%08X\n", cmd_desc.response[2]); printf("response 3 is 0x%08X\n", cmd_desc.response[3]); #endif if(close(dev_fd)) { perror("close device: "); } #endif return ret; }
int __send_ext_csd(int fd, uint8_t *ext_csd) { int ret = 0; struct mmc_ioc_cmd cmd_desc; memset(&cmd_desc, 0, sizeof(cmd_desc)); memset(ext_csd, 0, sizeof(uint8_t) * EXT_CSD_SIZE); cmd_desc.write_flag = MMC_DATA_READ; cmd_desc.opcode = MMC_SEND_EXT_CSD; cmd_desc.arg = 0; cmd_desc.flags = MMC_RSP_R1 ; cmd_desc.blksz = EXT_CSD_SIZE; cmd_desc.blocks = 1; mmc_ioc_cmd_set_data(cmd_desc, ext_csd); ret = ioctl(fd, MMC_IOC_CMD, &cmd_desc); if (ret) perror("ioctl"); return ret; }
int rpmb_send(struct storage_msg *msg, const void *r, size_t req_len) { int rc; struct { struct mmc_ioc_multi_cmd multi; struct mmc_ioc_cmd cmd_buf[3]; } mmc = {}; struct mmc_ioc_cmd *cmd = mmc.multi.cmds; const struct storage_rpmb_send_req *req = r; if (req_len < sizeof(*req)) { ALOGW("malformed rpmb request: invalid length (%zu < %zu)\n", req_len, sizeof(*req)); msg->result = STORAGE_ERR_NOT_VALID; goto err_response; } size_t expected_len = sizeof(*req) + req->reliable_write_size + req->write_size; if (req_len != expected_len) { ALOGW("malformed rpmb request: invalid length (%zu != %zu)\n", req_len, expected_len); msg->result = STORAGE_ERR_NOT_VALID; goto err_response; } const uint8_t *write_buf = req->payload; if (req->reliable_write_size) { if ((req->reliable_write_size % MMC_BLOCK_SIZE) != 0) { ALOGW("invalid reliable write size %u\n", req->reliable_write_size); msg->result = STORAGE_ERR_NOT_VALID; goto err_response; } cmd->write_flag = MMC_WRITE_FLAG_RELW; cmd->opcode = MMC_WRITE_MULTIPLE_BLOCK; cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; cmd->blksz = MMC_BLOCK_SIZE; cmd->blocks = req->reliable_write_size / MMC_BLOCK_SIZE; mmc_ioc_cmd_set_data((*cmd), write_buf); #ifdef RPMB_DEBUG ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag); print_buf("request: ", write_buf, req->reliable_write_size); #endif write_buf += req->reliable_write_size; mmc.multi.num_of_cmds++; cmd++; } if (req->write_size) { if ((req->write_size % MMC_BLOCK_SIZE) != 0) { ALOGW("invalid write size %u\n", req->write_size); msg->result = STORAGE_ERR_NOT_VALID; goto err_response; } cmd->write_flag = MMC_WRITE_FLAG_W; cmd->opcode = MMC_WRITE_MULTIPLE_BLOCK; cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; cmd->blksz = MMC_BLOCK_SIZE; cmd->blocks = req->write_size / MMC_BLOCK_SIZE; mmc_ioc_cmd_set_data((*cmd), write_buf); #ifdef RPMB_DEBUG ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag); print_buf("request: ", write_buf, req->write_size); #endif write_buf += req->write_size; mmc.multi.num_of_cmds++; cmd++; } if (req->read_size) { if (req->read_size % MMC_BLOCK_SIZE != 0 || req->read_size > sizeof(read_buf)) { ALOGE("%s: invalid read size %u\n", __func__, req->read_size); msg->result = STORAGE_ERR_NOT_VALID; goto err_response; } cmd->write_flag = MMC_WRITE_FLAG_R; cmd->opcode = MMC_READ_MULTIPLE_BLOCK; cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC, cmd->blksz = MMC_BLOCK_SIZE; cmd->blocks = req->read_size / MMC_BLOCK_SIZE; mmc_ioc_cmd_set_data((*cmd), read_buf); #ifdef RPMB_DEBUG ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag); #endif mmc.multi.num_of_cmds++; cmd++; } rc = ioctl(rpmb_fd, MMC_IOC_MULTI_CMD, &mmc.multi); if (rc < 0) { ALOGE("%s: mmc ioctl failed: %d, %s\n", __func__, rc, strerror(errno)); msg->result = STORAGE_ERR_GENERIC; goto err_response; } #ifdef RPMB_DEBUG if (req->read_size) print_buf("response: ", read_buf, req->read_size); #endif if (msg->flags & STORAGE_MSG_FLAG_POST_COMMIT) { /* * Nothing todo for post msg commit request as MMC_IOC_MULTI_CMD * is fully synchronous in this implementation. */ } msg->result = STORAGE_NO_ERROR; return ipc_respond(msg, read_buf, req->read_size); err_response: return ipc_respond(msg, NULL, 0); }
int sd_read_single_block(char *dev_path, uint32_t args, char *out_file_path) { uint32_t blk_cnt = 1; struct mmc_ioc_cmd cmd_desc; uint32_t blk_size = SD_BLK_SIZE; char *buf = (char *)malloc(blk_size * blk_cnt); FILE *out_file = NULL; if(buf == NULL) { fprintf(stderr, "-%s: %d- fail to malloc memory", __FILE__, __LINE__); return -ENOMEM; } memset(buf, 0, blk_size * blk_cnt); memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.write_flag = SD_DATA_READ; cmd_desc.opcode = SD_CMD_READ_SINGLE_BLK; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1; cmd_desc.blksz = blk_size; cmd_desc.blocks = blk_cnt; mmc_ioc_cmd_set_data(cmd_desc, buf); if(issue_sd_cmd(dev_path, &cmd_desc)) { fprintf(stdout, "0x%08X\n", cmd_desc.response[0]); if(out_file_path == NULL) { return 0; } else { out_file = fopen(out_file_path, "w+"); } if(out_file) { if(fwrite(buf, 1, blk_size * blk_cnt, out_file) != blk_size) { fprintf(stderr, "error! write to file\n"); fclose(out_file); return -1; } else { fclose(out_file); return 0; } } else { perror("open file: "); return -1; } return 0; } else { fprintf(stderr, "cmd error\n"); return -1; } }
int mmc_cmd61(char *dev_path, uint32_t args, char *file_path) { int ret = 0; int dev_fd = 0; int file_fd = 0; char *buf = NULL; uint32_t blk_cnt = args & MMC_CMD61_BLK_CNT_MASK; struct mmc_ioc_cmd cmd_desc; struct stat file_stat; if(file_path == NULL) { printf("Please specify input file using \'i\' option\n"); return -EINVAL; } dev_fd = open(dev_path, O_RDONLY); if(dev_fd == -1) { perror("open device: "); return -EINVAL; } file_fd = open(file_path, O_RDONLY); if(file_fd == -1) { perror("open file: "); return -EINVAL; } fstat(file_fd, &file_stat); if(file_stat.st_size < (DEFAULT_BLOCK_SIZE * blk_cnt)) { printf("%s is too small to write\n",file_path); if(close(file_fd)) perror("close file: "); if(close(dev_fd)) perror("close device: "); return -EINVAL; } buf = mmap(NULL, (DEFAULT_BLOCK_SIZE * blk_cnt), PROT_READ, MAP_SHARED, file_fd ,0); if(buf == MAP_FAILED) { return -EINVAL; } memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.write_flag = MMC_DATA_WRITE; cmd_desc.opcode = MMC_CMD61; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1; cmd_desc.blksz = DEFAULT_BLOCK_SIZE; cmd_desc.blocks = blk_cnt; mmc_ioc_cmd_set_data(cmd_desc, buf); #ifdef DEBUG dump_cmd_desc(&cmd_desc, stdout); #endif ret = ioctl(dev_fd, MMC_IOC_CMD, &cmd_desc); if (ret) { perror("ioctl"); } if(close(dev_fd)) { perror("close deivce"); } if(close(file_fd)) { perror("close file"); } #ifdef DEBUG printf("response 0 is 0x%08X\n", cmd_desc.response[0]); printf("response 1 is 0x%08X\n", cmd_desc.response[1]); printf("response 2 is 0x%08X\n", cmd_desc.response[2]); printf("response 3 is 0x%08X\n", cmd_desc.response[3]); #endif return ret; }
int mmc_program_csd(char *dev_path, uint32_t args, char *file_path) { int ret = 0; int dev_fd = 0; int file_fd = 0; struct mmc_ioc_cmd cmd_desc; struct stat file_stat; uint8_t *buf; dev_fd = open(dev_path, O_RDONLY); if(dev_fd == -1) { perror("open device: "); return -EINVAL; } file_fd = open(file_path, O_RDONLY); if(file_fd == -1) { perror("open device: "); return -EINVAL; } fstat(file_fd, &file_stat); if(file_stat.st_size < DEFAULT_BLOCK_SIZE) { printf("%s is too small to write\n",file_path); if(close(file_fd)) perror("close file: "); if(close(dev_fd)) perror("close device: "); return -EINVAL; } buf = mmap(NULL, DEFAULT_BLOCK_SIZE, PROT_READ, MAP_SHARED, file_fd ,0); if(buf == MAP_FAILED) { return -EINVAL; } memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.write_flag = MMC_DATA_WRITE; cmd_desc.opcode = MMC_PROGRAM_CSD; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1B; cmd_desc.blksz = DEFAULT_BLOCK_SIZE; cmd_desc.blocks = 1; mmc_ioc_cmd_set_data(cmd_desc, buf); ret = ioctl(dev_fd, MMC_IOC_CMD, &cmd_desc); if (ret) { perror("ioctl"); } else { dump_memory_u8(buf, DEFAULT_BLOCK_SIZE, stdout); } #ifdef DEBUG printf("response 0 is 0x%08X\n", cmd_desc.response[0]); printf("response 1 is 0x%08X\n", cmd_desc.response[1]); printf("response 2 is 0x%08X\n", cmd_desc.response[2]); printf("response 3 is 0x%08X\n", cmd_desc.response[3]); #endif if(close(dev_fd)) { perror("close deivce"); } if(close(file_fd)) { perror("close file"); } return ret; }
int mmc_read_multiple_block(char *dev_path, uint32_t args, uint32_t blk_cnt, char *output_file_path) { int ret = 0; int dev_fd = -1; FILE *out_stream = NULL; struct mmc_ioc_cmd cmd_desc; if(blk_cnt < 1) { printf("Please specify block count using \'n\' option\n"); return -EINVAL; } if(output_file_path == NULL) { out_stream = stdout; } else { out_stream = fopen(output_file_path, "w+"); if(out_stream == NULL) { printf("Fail to open %s\n", output_file_path); return -EINVAL; } } dev_fd = open(dev_path, O_RDONLY); if(dev_fd == -1) { perror("open device: "); return -1; } uint8_t *buf = (uint8_t *)malloc(DEFAULT_BLOCK_SIZE * blk_cnt); memset(buf, 0, DEFAULT_BLOCK_SIZE * blk_cnt); memset(&cmd_desc, 0, sizeof(cmd_desc)); cmd_desc.write_flag = MMC_DATA_READ; cmd_desc.opcode = MMC_READ_MULTIPLE_BLOCK; cmd_desc.arg = args; cmd_desc.flags = MMC_RSP_R1; cmd_desc.blksz = DEFAULT_BLOCK_SIZE; cmd_desc.blocks = blk_cnt; mmc_ioc_cmd_set_data(cmd_desc, buf); ret = ioctl(dev_fd, MMC_IOC_CMD, &cmd_desc); if (ret) { perror("ioctl"); } else { dump_memory_u8(buf,DEFAULT_BLOCK_SIZE * blk_cnt, out_stream); } #ifdef DEBUG printf("response 0 is 0x%08X\n", cmd_desc.response[0]); printf("response 1 is 0x%08X\n", cmd_desc.response[1]); printf("response 2 is 0x%08X\n", cmd_desc.response[2]); printf("response 3 is 0x%08X\n", cmd_desc.response[3]); #endif fclose(out_stream); free(buf); if(close(dev_fd)) { perror("close device: "); } return ret; }