📄 mmc_protocol.c
字号:
return ret; ret = mmc_unpack_r4(cmd, &r4, mmc_card); if (ret) { return ret; } status = r4.read_reg_contents; } while((status & 0x40) != 0x40 && retries--); if (!retries) return MSS_ERROR_TIMEOUT; mmc_card->state = CARD_STATE_TRAN; goto exit;no_ceata:#endif if (arg->nob > 1) { if (action == MSS_READ_MEM) { opcode = MMC_READ_MULTIPLE_BLOCK; flags = MSS_DATA_READ | MSS_DATA_MULTI; } else { opcode = MMC_WRITE_MULTIPLE_BLOCK; flags = MSS_DATA_WRITE | MSS_DATA_MULTI; } MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, arg->sg, 0); ret = mss_send_ll_req(host, &mmc_card->llreq); if (!ret) ret = mmc_unpack_r1(cmd, &r1, mmc_card); mmc_card->state = (action == MSS_WRITE_MEM) ? CARD_STATE_RCV : CARD_STATE_DATA; if (ret) { mss_send_simple_ll_req(host, llreq, cmd, MMC_STOP_TRANSMISSION, 0, (action == MSS_WRITE_MEM) ? MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); mmc_card->state = CARD_STATE_TRAN; if (--retries) { clock = host->ios.clock; clock = clock >> 1; if (clock < MMC_CARD_CLOCK_SLOW && retries == 1) clock = MMC_CARD_CLOCK_SLOW; mss_set_clock(host, clock); goto read_write_entry; } return ret; } ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_STOP_TRANSMISSION, 0, (action == MSS_WRITE_MEM) ? MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); if (ret) return ret; ret = mmc_unpack_r1(cmd, &r1, mmc_card); mmc_card->state = CARD_STATE_TRAN; if (ret && (mmc_card->errno != MMC_ERROR_OUT_OF_RANGE)) return ret; } else { if (action == MSS_READ_MEM) { opcode = MMC_READ_SINGLE_BLOCK; flags = MSS_DATA_READ; } else { opcode = MMC_WRITE_BLOCK; flags = MSS_DATA_WRITE; } MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, arg->sg, 0); ret = mss_send_ll_req(host, &mmc_card->llreq); if (!ret) ret = mmc_unpack_r1(cmd, &r1, mmc_card); if (ret) { if (--retries) { clock = host->ios.clock; clock = clock >> 1; if (clock < MMC_CARD_CLOCK_SLOW && retries == 1) clock = MMC_CARD_CLOCK_SLOW; mss_set_clock(host, clock); goto read_write_entry; } return ret; } } /* Deselect the card */ /*mmc_simple_ll_req(host, mmc_card, MMC_SELECT_CARD, 0, MSS_RESPONSE_NONE, 0); if (ret) return ret; ret = mmc_unpack_r1(&mmc_card->cmd, &r1, mmc_card); mmc_card->state = CARD_STATE_STBY; if (ret) return ret;*/exit: result->bytes_xfered = data->bytes_xfered; return MSS_ERROR_NONE;}#if 0static int mmc_lock_unlock_entry(struct mss_card *card, int action, struct mss_lock_arg *arg){ struct mmc_response_r1 r1; struct mmc_card *mmc_card = card->prot_card; int ret; u32 status = 0; ret = mmc_get_status(card, &status) if (ret) { /*printk(KERN_INFO "can not get card status"); retval = MSS_LOCK_FAILED; goto lock_error;*/ return ret; } if (mmc_card->state == CARD_STATE_STBY) { ret = mmc_simple_ll_req(host, mmc_card, MMC_SELECT_CARD, (host->slot->rca) << 16, RESPONSE_R1B, 0); if (ret) return ret; ret = mmc_unpack_r1(&mmc_card->cmd, &r1, mmc_card->state); if (ret) return ret; } mmc_card->state = CARD_STATE_TRAN; mmc_fix_request_block_len(arg); ret = mmc_simple_ll_req(host, mmc_card, MMC_SET_BLOCKLEN, arg->block_len, RESPONSE_R1, 0); ret = mmc_unpack_r1(&mmc_card->cmd, &r1, mmc_card->state); if (ret) return ret; /* mss_simple_cmd(dev, MMC_SET_BLOCKLEN, t->block_len, RESPONSE_R1, buffer); if ((retval = mmc_unpack_r1(dev->io_request, &r1, dev->state))) goto lock_error; cmd_backup = dev->cmd_flag; dev->cmd_flag = MSS_WRITE;*/ mss_send_cmd(dev, MMC_LOCK_UNLOCK, 0, 1, t->block_len, RESPONSE_R1B, dev->io_request->buffer); if ((retval = mmc_unpack_r1(dev->io_request, &r1, dev->state))) { dev->flags |= MSS_SLOT_FLAG_LOCK_FAILED; goto lock_error; } dev->cmd_flag = cmd_backup; mss_simple_cmd(dev, MMC_SEND_STATUS, (dev->slot->rca) << 16, RESPONSE_R1, buffer); if ((retval = mmc_unpack_r1( dev->io_request, &r1, dev->state))) goto lock_error; dev->flags &= ~MSS_SLOT_FLAG_LOCK_FAILED; if ( r1.status & R1_CARD_IS_LOCKED ) dev->flags |= MSS_SLOT_FLAG_LOCKED; else dev->flags &= ~MSS_SLOT_FLAG_LOCKED; mss_finish_io_request(dev, 1); return MSS_SUCCESS;lock_error: dev->flags |= MSS_SLOT_FLAG_LOCK_FAILED; mss_finish_io_request(dev, 0); return retval; return 0; }#endif/* count by 512 bytes */static int mmc_get_capacity(struct mss_card *card, u32 *size){ int c_size = 0; int c_size_mult = 0; struct mmc_card *mmc_card = card->prot_card; struct mss_host *host = card->slot->host; if (mmc_card->access_mode == MMC_ACCESS_MODE_SECTOR && host->high_capacity) *size = mmc_card->ext_csd.sec_count; else { c_size = mmc_card->csd.c_size; c_size_mult = mmc_card->csd.c_size_mult; *size = (c_size + 1) << (2 + c_size_mult + mmc_card->csd.read_bl_len - 9); }#ifdef CONFIG_MMC_CEATA if (card->card_type == MSS_CEATA_CARD) *size = 4 * 2* 1024 * 1024; /* FIXME: Consider it as 4GB card */#endif dbg("the capacity :0x%x", *size); return MSS_ERROR_NONE;}/***************************************************************************** * * protocol driver interface functions * ****************************************************************************/static int mmc_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result){ u32 status; int ret; if (action != MSS_RECOGNIZE_CARD && (card->card_type != MSS_MMC_CARD && card->card_type != MSS_CEATA_CARD)) return MSS_ERROR_WRONG_CARD_TYPE; switch (action) { case MSS_RECOGNIZE_CARD: ret = mmc_recognize_card(card); break; case MSS_INIT_CARD: ret = mmc_card_init(card); break; case MSS_READ_MEM: case MSS_WRITE_MEM: if (!arg) return -EINVAL; ret = mmc_read_write_entry(card, action, arg, result); break;#if 0 case MSS_SELECT_CARD: case MSS_DESELECT_CARD: ret = mmc_select_deselect_entry(dev); break; case MSS_SUSPEND_CARD: ret = mmc_suspend_entry(dev); break;#endif/* case MSS_LOCK_UNLOCK: ret = mmc_lock_unlock_entry(dev); break;*/ case MSS_QUERY_CARD: ret = mmc_get_status(card, &status); break; case MSS_GET_CAPACITY: ret = mmc_get_capacity(card, result); break; default: ret = MSS_ERROR_ACTION_UNSUPPORTED; //debug("Unknown protocol action!\n"); break; } /* dbg("mmc protocol entry exit, ret: %d, action: %d\n", ret, action);*/ return ret;}static int mmc_prot_attach_card(struct mss_card *card){ struct mmc_card *mmc_card;#define ALIGN32(x) (((x) + 31) & (~31)) mmc_card = kzalloc(ALIGN32(ALIGN32(sizeof(struct mmc_card))) + 512, GFP_KERNEL); card->prot_card = mmc_card; if (mmc_card) { mmc_card->buf = (char *)ALIGN32((unsigned int)&mmc_card[1]); return 0; } return -ENOMEM;}static void mmc_prot_detach_card(struct mss_card *card){ kfree(card->prot_card);}static int mmc_prot_get_errno(struct mss_card *card){ struct mmc_card *mmc_card = card->prot_card; return mmc_card->errno;}#if 0static int mmc_protocol_proc_read_device(char *page, char **start, off_t off, int count, int *eof, void *data){ struct mss_card_device *dev = (struct mss_card_device *)data; struct mmc_card_info *card = (struct mmc_card_info *)dev->card; char *p = page; int len = 0; if (!dev) return 0; p += sprintf(p, "Slot #%d\n", dev->slotid); p += sprintf(p, " State %s (%d)\n", mmc_state_to_string(dev->state), dev->state); if ( dev->state != CARD_STATE_EMPTY ) { p += sprintf(p, " Media %s\n", (dev->dev.driver ? dev->dev.driver->name : "unknown")); if(dev->card_type==MMC_CARD){ p += sprintf(p, " MMC card\n"); p += sprintf(p, " CID mid=%d\n", card->card_cid.mid); p += sprintf(p, " oid=%d\n", card->card_cid.oid); p += sprintf(p, " pnm=%s\n", card->card_cid.pnm); p += sprintf(p, " prv=%d.%d\n", card->card_cid.prv>>4, card->card_cid.prv&0xf); p += sprintf(p, " psn=0x%08x\n", card->card_cid.psn); p += sprintf(p, " mdt=%d/%d\n", card->card_cid.mdt>>4, (card->card_cid.mdt&0xf)+1997); p += sprintf(p, " CSD csd_structure=%d\n", card->card_csd.csd_structure); p += sprintf(p, " spec_vers=%d\n", card->card_csd.spec_vers); p += sprintf(p, " taac=0x%02x\n", card->card_csd.taac); p += sprintf(p, " nsac=0x%02x\n", card->card_csd.nsac); p += sprintf(p, " tran_speed=0x%02x\n", card->card_csd.tran_speed); p += sprintf(p, " ccc=0x%04x\n", card->card_csd.ccc); p += sprintf(p, " read_bl_len=%d\n", card->card_csd.read_bl_len); p += sprintf(p, " read_bl_partial=%d\n", card->card_csd.read_bl_partial); p += sprintf(p, " write_blk_misalign=%d\n", card->card_csd.write_blk_misalign); p += sprintf(p, " read_blk_misalign=%d\n", card->card_csd.read_blk_misalign); p += sprintf(p, " dsr_imp=%d\n", card->card_csd.dsr_imp); p += sprintf(p, " c_size=%d\n", card->card_csd.c_size); p += sprintf(p, " vdd_r_curr_min=%d\n", card->card_csd.vdd_r_curr_min); p += sprintf(p, " vdd_r_curr_max=%d\n", card->card_csd.vdd_r_curr_max); p += sprintf(p, " vdd_w_curr_min=%d\n", card->card_csd.vdd_w_curr_min); p += sprintf(p, " vdd_w_curr_max=%d\n", card->card_csd.vdd_w_curr_max); p += sprintf(p, " c_size_mult=%d\n", card->card_csd.c_size_mult); p += sprintf(p, " wp_grp_size=%d\n", card->card_csd.wp_grp_size); p += sprintf(p, " wp_grp_enable=%d\n", card->card_csd.wp_grp_enable); p += sprintf(p, " default_ecc=%d\n", card->card_csd.default_ecc); p += sprintf(p, " r2w_factor=%d\n", card->card_csd.r2w_factor); p += sprintf(p, " write_bl_len=%d\n", card->card_csd.write_bl_len); p += sprintf(p, " write_bl_partial=%d\n", card->card_csd.write_bl_partial); p += sprintf(p, " file_format_grp=%d\n", card->card_csd.file_format_grp); p += sprintf(p, " copy=%d\n", card->card_csd.copy); p += sprintf(p, " perm_write_protect=%d\n", card->card_csd.perm_write_protect); p += sprintf(p, " tmp_write_protect=%d\n", card->card_csd.tmp_write_protect); p += sprintf(p, " file_format=%d\n", card->card_csd.file_format); p += sprintf(p, " ecc=%d\n", card->card_csd.ecc); switch (card->card_csd.csd_structure) { case CSD_STRUCT_VER_1_0: case CSD_STRUCT_VER_1_1: p += sprintf(p, " sector_size=%d\n", card->card_csd.erase.v22.sector_size); p += sprintf(p, " erase_grp_size=%d\n", card->card_csd.erase.v22.erase_grp_size); break; case CSD_STRUCT_VER_1_2: default: p += sprintf(p, " erase_grp_size=%d\n", card->card_csd.erase.v31.erase_grp_size); p += sprintf(p, " erase_grp_mult=%d\n", card->card_csd.erase.v31.erase_grp_mult); break; } } } len = (p - page) - off; *start = page + off; return len;}#endifstatic struct mss_prot_driver mmc_protocol = { .name = MMC_PROTOCOL, .prot_entry = mmc_prot_entry, .attach_card = mmc_prot_attach_card, .detach_card = mmc_prot_detach_card, .get_errno = mmc_prot_get_errno,};static int mmc_protocol_init(void){ register_mss_prot_driver(&mmc_protocol); return 0;}static void mmc_protocol_exit(void){ unregister_mss_prot_driver(&mmc_protocol);}module_init(mmc_protocol_init);module_exit(mmc_protocol_exit);MODULE_AUTHOR("Bridge Wu");MODULE_LICENSE("GPL");MODULE_DESCRIPTION("MMC protocol driver");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -