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

📄 sd_protocol.c

📁 spi driver code one marve
💻 C
📖 第 1 页 / 共 3 页
字号:
			scr->data_stat_after_erase, scr->sd_security, 			scr->sd_bus_width);	return 0;}	static int sd_get_status(struct mss_card *card, int *status){	struct sd_response_r1 r1;	struct sd_card *sd_card = card->prot_card;	struct mss_host *host = card->slot->host;	int clock, ret, retries = 4;	clock = sd_tran_speed(sd_card->csd.tran_speed);	mss_set_clock(card->slot->host, clock);	while (retries--) {		ret = mss_send_simple_ll_req(host, &sd_card->llreq, 				&sd_card->cmd, SD_SEND_STATUS, 				sd_card->rca << 16, MSS_RESPONSE_R1, 0);		if (ret && !retries)			return ret;		else if (!ret) {			ret = sd_unpack_r1(&sd_card->cmd, &r1, sd_card);			if (ret) {				if (sd_card->errno == SD_ERROR_STATE_MISMATCH) {					sd_card->state = R1_CURRENT_STATE(r1.status);					sd_card->errno = SD_ERROR_NONE;				}				else					return ret;			}			else 				break;		}		clock = host->ios.clock;		clock = clock >> 1;		if (clock < SD_CARD_CLOCK_SLOW || retries == 1)			clock = SD_CARD_CLOCK_SLOW;		mss_set_clock(host, clock);	}	*status = r1.status;		return MSS_ERROR_NONE; }/** *  The blocks requested by the kernel may or may not match what we can do.   *  Unfortunately, filesystems play fast and loose with block sizes, so we're  *  stuck with this. */static void sd_fix_request_block_len(struct mss_card *card, int action, struct mss_rw_arg *arg){	u16 block_len = 0;	struct sd_card *sd_card = card->prot_card;	struct mss_host *host = card->slot->host;	switch(action) {		case MSS_DATA_READ:			block_len = 1 << sd_card->csd.read_bl_len;			break;		case MSS_DATA_WRITE:			block_len = 1 << sd_card->csd.write_bl_len;			break;		default:			return;	}	if (host->high_capacity	&& (sd_card->ocr & SD_OCR_CCS))		block_len = 512;		if (block_len < arg->block_len) {		int scale = arg->block_len / block_len;		arg->block_len	= block_len;		arg->block *= scale;		arg->nob *= scale;	}}static int sd_send_cmd6(struct mss_card *card, struct sw_func_status *status, int mode, u32 funcs){	struct sd_response_r1 r1;	struct sd_card *sd_card = card->prot_card;	struct mss_ll_request *llreq = &sd_card->llreq;	struct mss_cmd *cmd = &sd_card->cmd;	struct mss_data *data = &sd_card->data;	struct mss_host *host= card->slot->host;	struct scatterlist sg;	char *g_buffer = sd_card->buf;	int ret;	/* Set the argumens for CMD6. */	/* [31]: Mode 	 * [30:24]: reserved (all 0s)	 * [23:20]: group 6	 * [19:16]: group 5	 * [15:12]: group 4	 * [11:8]: group 3	 * [7:4]: group 2	 * [3:0]: group 1	 */	sg.page = virt_to_page(g_buffer);	sg.offset = offset_in_page(g_buffer);	sg.length = 8;		memset(llreq, 0x0, sizeof(struct mss_ll_request));	memset(cmd, 0x0, sizeof(struct mss_cmd));	memset(data, 0x0, sizeof(struct mss_data));	MSS_INIT_CMD(cmd, SD_SW_FUNC, (funcs | ((mode & 0x1) << 31)), 0, 			MSS_RESPONSE_R1);	MSS_INIT_DATA(data, 1, 32, MSS_DATA_READ, 1, &sg, 0);	llreq->cmd = cmd;	llreq->data = data;		ret = mss_send_ll_req(host, llreq);	if (ret)		return ret;	ret = sd_unpack_r1(cmd, &r1, sd_card);	if (ret)		return ret;	sd_unpack_swfuncstatus(g_buffer, status);		return 0;}/***************************************************************************** * *   protocol entry functions * ****************************************************************************/static int sd_recognize_card(struct mss_card *card){	struct sd_response_r1 r1;	struct sd_response_r3 r3;	struct sd_response_r7 r7;	int ret;	struct sd_card *sd_card = (struct sd_card *)card->prot_card;	struct mss_ios ios;	struct mss_host *host = card->slot->host;	struct mss_ll_request *llreq = &sd_card->llreq;	struct mss_cmd *cmd = &sd_card->cmd;	card->state = CARD_STATE_IDLE;	card->bus_width = MSS_BUSWIDTH_1BIT;	memcpy(&ios, &host->ios, sizeof(struct mss_ios)); 	ios.bus_mode = MSS_BUSMODE_OPENDRAIN;	ios.clock = host->f_min;	ios.bus_width = MSS_BUSWIDTH_1BIT;	host->ops->set_ios(host, &ios);	card->card_type = MSS_UNKNOWN_CARD;		ret = mss_send_simple_ll_req(host, llreq, cmd, 		       SD_GO_IDLE_STATE, 0, MSS_RESPONSE_NONE, MSS_CMD_INIT);	if (ret)		return ret;	if (host->sd_spec == MSS_SD_SPEC_20) {		if (!(host->vdd & MSS_VDD_27_36))			return MSS_ERROR_NO_PROTOCOL; 		ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_IF_COND,			       	0x1AA, MSS_RESPONSE_R7, 0);		if (ret == MSS_ERROR_TIMEOUT) {			sd_card->ver = MSS_SD_SPEC_11;			goto next;		}		else if (ret)			return ret;		ret = sd_unpack_r7(cmd, &r7, 0x1AA, sd_card);		if (!ret) {			sd_card->ver = MSS_SD_SPEC_20;			goto next;		}		else 			return ret;	}	next:	ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, 			MSS_RESPONSE_R1, 0);	if (ret)		return ret;	ret = sd_unpack_r1(cmd, &r1, sd_card);	if (ret && !(sd_card->errno == SD_ERROR_ILLEGAL_COMMAND 			&& sd_card->ver == MSS_SD_SPEC_11))		return ret;		ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SD_SEND_OP_COND, 0,		MSS_RESPONSE_R3, 0);	if (ret)		return ret;	ret = sd_unpack_r3(cmd, &r3, sd_card);		if (ret)		return ret;		if (r3.ocr & host->vdd) {		card->card_type = MSS_SD_CARD;	}	else		card->card_type = MSS_UNCOMPATIBLE_CARD;	return MSS_ERROR_NONE;}/** *  sd_card_init *  @dev: mss_card_device * *  return value: 0: success, -1: failed */static int sd_card_init(struct mss_card *card){	struct sd_response_r1 r1;	struct sd_response_r3 r3;	struct sd_response_r6 r6;	struct sd_response_r7 r7;	struct sd_cid cid;	int ret;	struct sd_card * sd_card= (struct sd_card *)card->prot_card;	struct mss_ios ios;	struct mss_host *host = card->slot->host;	struct mss_ll_request *llreq = &sd_card->llreq;	struct mss_cmd *cmd = &sd_card->cmd;	int hcs = 0;	sd_card->state = CARD_STATE_IDLE;	card->bus_width = MSS_BUSWIDTH_1BIT;	sd_card->rca = 0;	memcpy(&ios, &host->ios, sizeof(struct mss_ios));	ios.bus_mode = MSS_BUSMODE_OPENDRAIN;	ios.bus_width = MSS_BUSWIDTH_1BIT;	ios.clock = host->f_min;	host->ops->set_ios(host, &ios);	ret = mss_send_simple_ll_req(host, llreq, cmd, SD_GO_IDLE_STATE, 0, 			MSS_RESPONSE_NONE, MSS_CMD_INIT);	if (ret)		return ret;	/* 	 * We have to send cmd 8 to 2.0 card. It will tell the card that the 	 * host support 2.0 spec.	 */	if (sd_card->ver == MSS_SD_SPEC_20 && host->sd_spec == MSS_SD_SPEC_20) {		ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_IF_COND, 				0x1AA, MSS_RESPONSE_R7, 0);		if (ret)			return ret;		ret = sd_unpack_r7(cmd, &r7, 0x1AA, sd_card);		if (ret)			return ret;		if (host->high_capacity)			hcs = 1;	}	ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, 			MSS_RESPONSE_R1, 0);	if (ret)		return ret;	ret = sd_unpack_r1(cmd, &r1, sd_card);	if (ret)		return ret;	ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SD_SEND_OP_COND, 			hcs << 30 | host->vdd, MSS_RESPONSE_R3, 0);	if (ret)		return ret;	ret = sd_unpack_r3(cmd, &r3, sd_card);	if (ret)		return ret;	while (!(r3.ocr & SD_OCR_CARD_BUSY)) {		mdelay(20);		ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, 				MSS_RESPONSE_R1, 0);		if (ret)			return ret;		ret = sd_unpack_r1(cmd, &r1, sd_card);		if (ret)			return ret;		ret = mss_send_simple_ll_req(host, llreq, cmd, 				SD_SD_SEND_OP_COND, hcs << 30 | host->vdd,			       	MSS_RESPONSE_R3, 0);		if (ret)			return ret;		ret = sd_unpack_r3(cmd, &r3, sd_card);		if (ret)			return ret;	}	memcpy(&sd_card->ocr, &r3.ocr, sizeof(r3.ocr));	sd_card->state = CARD_STATE_READY;	ret = mss_send_simple_ll_req(host, llreq, cmd, SD_ALL_SEND_CID, 0, 			MSS_RESPONSE_R2_CID, 0);	if (ret)		return ret;	memset(&cid, 0x0, sizeof(struct sd_cid));	ret = sd_unpack_cid(cmd, &cid, sd_card);	if (ret)		return ret;		if (sd_card->cid.mid != 0) {		if (sd_card->cid.mid != cid.mid || sd_card->cid.oid != cid.oid				|| sd_card->cid.prv != cid.prv 				|| sd_card->cid.psn != cid.psn				|| sd_card->cid.mdt != cid.mdt				|| memcmp(sd_card->cid.pnm, cid.pnm, 6))			return MSS_ERROR_MISMATCH_CARD;		if (memcmp(&cid, &sd_card->cid, sizeof(struct sd_cid)))			return MSS_ERROR_MISMATCH_CARD;	}	else		memcpy(&sd_card->cid, &cid, sizeof(struct sd_cid));		sd_card->state = CARD_STATE_IDENT;	ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_RELATIVE_ADDR, 			0, MSS_RESPONSE_R6, 0);	if (ret)		return ret;	ret = sd_unpack_r6(cmd, &r6, sd_card);	if (ret)		return ret;	sd_card->state = CARD_STATE_STBY;	sd_card->rca = r6.rca;	ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_CSD, 		       sd_card->rca << 16, MSS_RESPONSE_R2_CSD, 0);	if (ret)		return ret;	ret = sd_unpack_csd(cmd, &sd_card->csd, sd_card);	if (ret)		return ret;		if (host->ops->is_slot_wp && host->ops->is_slot_wp(card->slot))		card->state |= MSS_CARD_WP;			return MSS_ERROR_NONE;}static int sd_read_write_entry(struct mss_card *card, int action, struct mss_rw_arg *arg, struct mss_rw_result *result){	struct sd_response_r1 r1;	struct mss_host *host = card->slot->host;	struct mss_ios ios;	int ret, retries = 4;	struct sd_card *sd_card = (struct sd_card *)card->prot_card;	struct mss_ll_request *llreq = &sd_card->llreq;	struct mss_cmd *cmd = &sd_card->cmd;	struct mss_data *data = &sd_card->data;	struct scatterlist sg;	char *g_buffer = sd_card->buf;	int status;	u32 clock;	u32 cmdarg, blklen, opcode, flags;	dbg("block:%d, nob:%d, blok_len:%d", arg->block, arg->nob, 			arg->block_len);		ret = sd_get_status(card, &status);	if (ret)		return ret;	if (status & R1_CARD_IS_LOCKED)		return MSS_ERROR_LOCKED;	if (action == MSS_WRITE_MEM && host->ops->is_slot_wp && 			host->ops->is_slot_wp(card->slot))		return MSS_ERROR_WP;		if (sd_card->state == CARD_STATE_STBY) {		ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SELECT_CARD,				sd_card->rca << 16, MSS_RESPONSE_R1B, 0);		if (ret)			return ret;		ret = sd_unpack_r1(cmd, &r1, sd_card);		if (ret)			return ret;	}	sd_card->state = CARD_STATE_TRAN;			sd_fix_request_block_len(card, action, arg);	if (!sd_card->scr.init) {		ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD,				sd_card->rca << 16, MSS_RESPONSE_R1, 0);		if (ret)			return ret;				sg.page = virt_to_page(g_buffer);		sg.offset = offset_in_page(g_buffer);		sg.length = 8;				memset(llreq, 0x0, sizeof(struct mss_ll_request));		memset(cmd, 0x0, sizeof(struct mss_cmd));		memset(data, 0x0, sizeof(struct mss_data));		MSS_INIT_CMD(cmd, SD_SEND_SCR, 0, 0, MSS_RESPONSE_R1);		MSS_INIT_DATA(data, 1, 8, MSS_DATA_READ, 1, &sg, 0);		llreq->cmd = cmd;		llreq->data = data;		ret = mss_send_ll_req(host, llreq);		if (ret)			return ret;		ret = sd_unpack_scr(g_buffer, &sd_card->scr);		if (ret)			return ret;	}	if (sd_card->scr.sd_bus_width == SCR_BUSWIDTH_1BIT) {		mss_set_buswidth(host, MSS_BUSWIDTH_1BIT);		card->bus_width = MSS_BUSWIDTH_1BIT;	}	else {		if (card->bus_width == MSS_BUSWIDTH_1BIT 				&& host->bus_width == MSS_BUSWIDTH_4BIT) {			mss_set_buswidth(host, MSS_BUSWIDTH_4BIT);			card->bus_width = MSS_BUSWIDTH_4BIT;			ret = mss_send_simple_ll_req(host, llreq, cmd, 					SD_APP_CMD, sd_card->rca << 16, 					MSS_RESPONSE_R1, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -