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

📄 sd_protocol.c

📁 spi driver code one marve
💻 C
📖 第 1 页 / 共 3 页
字号:
			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_SET_BUS_WIDTH, 0x2, MSS_RESPONSE_R1,					0);			if (ret)				return ret;			ret = sd_unpack_r1(cmd, &r1, sd_card);			if (ret)				return ret;			card->bus_width = MSS_BUSWIDTH_4BIT;		}	}	memset(llreq, 0x0, sizeof(struct mss_ll_request));	memset(cmd, 0x0, sizeof(struct mss_cmd));	memset(data, 0x0, sizeof(struct mss_data));		memcpy(&ios, &host->ios, sizeof(struct mss_ios));	if ((sd_card->ocr & SD_OCR_CCS)	&& host->high_capacity) {		ios.access_mode = MSS_ACCESS_MODE_SECTOR;		cmdarg = arg->block;		blklen = 512;	}	else {		if (arg->block_len != sd_card->block_len) {			ret = mss_send_simple_ll_req(host, llreq, cmd, 					SD_SET_BLOCKLEN, arg->block_len, 					MSS_RESPONSE_R1, 0);			if (ret)				return ret;			ret = sd_unpack_r1(cmd, &r1, sd_card);			if (ret)				return ret;			sd_card->block_len = arg->block_len;		}		cmdarg = arg->block * arg->block_len;		blklen = arg->block_len;	}	ios.clock = sd_tran_speed(sd_card->csd.tran_speed);	host->ops->set_ios(host, &ios);	read_write_entry:	memset(llreq, 0x0, sizeof(struct mss_ll_request));	memset(cmd, 0x0, sizeof(struct mss_cmd));	memset(data, 0x0, sizeof(struct mss_data));		llreq->cmd = cmd;	llreq->data = data;		if (arg->nob > 1) {		if (action == MSS_READ_MEM) {			opcode = SD_READ_MULTIPLE_BLOCK;			flags = MSS_DATA_READ | MSS_DATA_MULTI;		}		else {			opcode = SD_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, llreq);		if (!ret)			ret = sd_unpack_r1(cmd, &r1, sd_card);		sd_card->state = (action == MSS_WRITE_MEM) ? CARD_STATE_RCV : CARD_STATE_DATA;		if (ret) {			mss_send_simple_ll_req(host, llreq, cmd, 					SD_STOP_TRANSMISSION, 0, 					(action == MSS_WRITE_MEM) ? 					MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0);			sd_card->state = CARD_STATE_TRAN;			if (--retries) {				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);				goto read_write_entry;			}			return ret;		}		ret = mss_send_simple_ll_req(host, llreq, cmd, 				SD_STOP_TRANSMISSION, 0, 				(action == MSS_WRITE_MEM) ? 				MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0);		if (ret)			return ret;		ret = sd_unpack_r1(cmd, &r1, sd_card);		sd_card->state = CARD_STATE_TRAN;		if (ret	&& (sd_card->errno != SD_ERROR_OUT_OF_RANGE)) 			return ret;		ret = MSS_ERROR_NONE;	} else {		if (action == MSS_READ_MEM) {			opcode = SD_READ_SINGLE_BLOCK;			flags = MSS_DATA_READ;		}		else {			opcode = SD_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, llreq);		if (!ret)			ret = sd_unpack_r1(cmd, &r1, sd_card);		if (ret) {			if (--retries) {				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);				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;	result->bytes_xfered = data->bytes_xfered;	return MSS_ERROR_NONE;}#if 0static enum mss_result sd_lock_unlock_entry(struct mss_card_device *dev){	struct mss_io_request *t = dev->io_request;	struct sd_response_r1 r1;	u8 *buffer;	int status = 0;	int retval;	int cmd_backup;	buffer = NULL;	if ((retval = sd_get_status(dev, &status))) {		printk(KERN_INFO "can not get card status");		retval = MSS_LOCK_FAILED;		goto lock_error;	}	if(status & CARD_STATUS_WP) {		printk(KERN_INFO "card is write protection\n");		retval = MSS_WRITE_PROTECTED;		goto lock_error;	} 	if (dev->state == CARD_STATE_STBY) {		mss_simple_cmd( dev, SD_SELECT_CARD, (dev->slot->rca) << 16, RESPONSE_R1B, buffer );		if ((retval = sd_unpack_r1(dev->io_request, &r1, dev->state)))			goto lock_error;	}	dev->state = CARD_STATE_TRAN;	mss_simple_cmd(dev, SD_SET_BLOCKLEN, t->block_len, RESPONSE_R1, buffer);	if ((retval = sd_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, SD_LOCK_UNLOCK, 0, 1, t->block_len, RESPONSE_R1B, dev->io_request->buffer);	if ((retval = sd_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, SD_SEND_STATUS, (dev->slot->rca) << 16, RESPONSE_R1, buffer);	if ((retval = sd_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; }#endifstatic int sd_query_function(struct mss_card *card, struct io_swfunc_request *r, struct sw_func_status *status){	struct sd_card *sd_card = card->prot_card;	int i;	u32 arg = 0;	if (card->slot->host->sd_spec != MSS_SD_SPEC_20			|| sd_card->ver != MSS_SD_SPEC_20)		return MSS_ERROR_ACTION_UNSUPPORTED;	for (i = 5; i > 0; i--) {		arg |= ((r->args[i] & 0xF) << (i << 2));	}	return sd_send_cmd6(card, status, 0, arg);}static int sd_sw_function(struct mss_card *card, struct io_swfunc_request *r){	int ret, i;	u32 arg = 0;	struct sw_func_status status;	struct sd_card *sd_card = card->prot_card;		if (card->slot->host->sd_spec != MSS_SD_SPEC_20 			|| sd_card->ver != MSS_SD_SPEC_20)		return MSS_ERROR_ACTION_UNSUPPORTED;	for (i = 0; i < 6; i++) {		if (r->args[i] >= 0xF) {			goto switch_err;		}	}	/* Step 1: CMD6(mode = 0, func = 0xF(Don't Care) */	ret = sd_send_cmd6(card, &status, 0, 0xFFFFFF);	if (ret)		goto switch_err;		/* Step 2: Any Switch ? */	for (i = 0; i < 6; i++) {		if (!((status.func_support[i]) & (0x1 << (r->args[i])))) 			goto switch_err;	}	for (i = 0; i < 6; i++) {		if (status.group_status[i] != r->args[i]) {				break;		}	}	if (i == 6)		return 0;			/* Step 3: CMD6(mode = 0, func= funcX */	for (i = 5; i > 0; i--) {		arg |= ((r->args[i]) << (i << 2));	}	ret = sd_send_cmd6(card, &status, 0, arg);	if (ret)		goto switch_err;	if (status.current_consumption > r->current_acceptable) {		goto switch_err;	}	for (i = 0; i < 6; i++) {		if (status.group_status[i] != r->args[i]) {			goto switch_err;		}	}	ret = sd_send_cmd6(card, &status, 1, arg);	if (ret)		goto switch_err;	for (i = 0; i < 6; i++) {		if (status.group_status[i] != r->args[i]) {			goto switch_err;		}	}	return 0;switch_err:	sd_card->errno = SD_ERROR_SWFUNC;	return MSS_ERROR_ACTION_UNSUPPORTED;}/* count by 512 bytes */static int sd_get_capacity(struct mss_card *card, u32 *size){	struct sd_card *sd_card = card->prot_card;	int c_size = 0;	int c_size_mult = 0;	int blk_len = 0;	if (sd_card->csd.csd_structure == 0) {		c_size = sd_card->csd.csd.csd1.c_size;		c_size_mult = sd_card->csd.csd.csd1.c_size_mult;		blk_len = sd_card->csd.read_bl_len - 9;	}	/* (csize + 1) * 512 * 1024 bytes */	else if (sd_card->csd.csd_structure == 1) {		c_size = sd_card->csd.csd.csd2.c_size;		c_size_mult = 7;	       	blk_len = 1;	}	*size = (c_size + 1) << (2 + c_size_mult + blk_len);	dbg("capacity is :0x%x\n", *size);	return MSS_ERROR_NONE;}/***************************************************************************** * *   protocol driver interface functions * ****************************************************************************/static int sd_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result){	int ret;	u32 status;		if (action != MSS_RECOGNIZE_CARD && card->card_type != MSS_SD_CARD)		return MSS_ERROR_WRONG_CARD_TYPE;	switch (action) {		case MSS_RECOGNIZE_CARD:			ret = sd_recognize_card(card);			break;		case MSS_INIT_CARD:			ret = sd_card_init(card);			break;		case MSS_READ_MEM:		case MSS_WRITE_MEM:			if (!arg || !result)				return -EINVAL;			ret = sd_read_write_entry(card, action, arg, result);			break;	/*		case MSS_LOCK_UNLOCK:			ret = sd_lock_unlock_entry(dev);			break;	*/		case MSS_SD_QUERY_FUNC:			if (!arg || !result)				return -EINVAL;			ret = sd_query_function(card, arg, result);			break;		case MSS_SD_SW_FUNC:			if (!arg)				return -EINVAL;			ret = sd_sw_function(card, arg);				break;		case MSS_QUERY_CARD:			ret = sd_get_status(card, &status);			break;		case MSS_GET_CAPACITY:			ret = sd_get_capacity(card, result);			break;		default:			ret = MSS_ERROR_ACTION_UNSUPPORTED;			break;	}	return ret;}static int sd_prot_attach_card(struct mss_card *card){	struct sd_card *sd_card;#define ALIGN32(x)	(((x) + 31) & (~31))	sd_card = kzalloc(ALIGN32(ALIGN32(sizeof(struct sd_card))) + 512, 			GFP_KERNEL);	card->prot_card = sd_card;	if (sd_card) {		sd_card->buf = (char *)ALIGN32((unsigned int)&sd_card[1]);		return 0;	}	return -ENOMEM;}static void sd_prot_detach_card(struct mss_card *card){	kfree(card->prot_card);}static int sd_prot_get_errno(struct mss_card *card){	struct sd_card *sd_card = card->prot_card;		return sd_card->errno;}static struct mss_prot_driver sd_protocol = {	.name			=	SD_PROTOCOL,	.prot_entry		=	sd_prot_entry,	.attach_card		=	sd_prot_attach_card,	.detach_card		=	sd_prot_detach_card,	.get_errno		=	sd_prot_get_errno,};/***************************************************************************** * *   module init and exit functions * ****************************************************************************/static int sd_protocol_init(void){	register_mss_prot_driver(&sd_protocol);	return 0;}static void sd_protocol_exit(void){	unregister_mss_prot_driver(&sd_protocol);}module_init(sd_protocol_init);module_exit(sd_protocol_exit);MODULE_AUTHOR("Bridge Wu");MODULE_LICENSE("MIT");MODULE_DESCRIPTION("SD protocol driver");

⌨️ 快捷键说明

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