⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc_protocol.c

📁 spi driver code one marve
💻 C
📖 第 1 页 / 共 4 页
字号:
			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 + -