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

📄 sd_ops.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
字号:
/* *  linux/drivers/mmc/sd_ops.h * *  Copyright 2006-2007 Pierre Ossman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */#include <linux/types.h>#include <asm/scatterlist.h>#include <linux/scatterlist.h>#include <linux/mmc/host.h>#include <linux/mmc/card.h>#include <linux/mmc/mmc.h>#include <linux/mmc/sd.h>#include "core.h"#include "sd_ops.h"/** *	mmc_wait_for_app_cmd - start an application command and wait for 			       completion *	@host: MMC host to start command *	@rca: RCA to send MMC_APP_CMD to *	@cmd: MMC command to start *	@retries: maximum number of retries * *	Sends a MMC_APP_CMD, checks the card response, sends the command *	in the parameter and waits for it to complete. Return any error *	that occurred while the command was executing.  Do not attempt to *	parse the response. */int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,	struct mmc_command *cmd, int retries){	struct mmc_request mrq;	int i, err;	BUG_ON(!cmd);	BUG_ON(retries < 0);	err = MMC_ERR_INVALID;	/*	 * We have to resend MMC_APP_CMD for each attempt so	 * we cannot use the retries field in mmc_command.	 */	for (i = 0;i <= retries;i++) {		memset(&mrq, 0, sizeof(struct mmc_request));		err = mmc_app_cmd(host, card);		if (err != MMC_ERR_NONE)			continue;		memset(&mrq, 0, sizeof(struct mmc_request));		memset(cmd->resp, 0, sizeof(cmd->resp));		cmd->retries = 0;		mrq.cmd = cmd;		cmd->data = NULL;		mmc_wait_for_req(host, &mrq);		err = cmd->error;		if (cmd->error == MMC_ERR_NONE)			break;	}	return err;}EXPORT_SYMBOL(mmc_wait_for_app_cmd);int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card){	int err;	struct mmc_command cmd;	BUG_ON(!host);	BUG_ON(card && (card->host != host));	cmd.opcode = MMC_APP_CMD;	if (card) {		cmd.arg = card->rca << 16;		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;	} else {		cmd.arg = 0;		cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR;	}	err = mmc_wait_for_cmd(host, &cmd, 0);	if (err != MMC_ERR_NONE)		return err;	/* Check that card supported application commands */	if (!(cmd.resp[0] & R1_APP_CMD))		return MMC_ERR_FAILED;	return MMC_ERR_NONE;}int mmc_app_set_bus_width(struct mmc_card *card, int width){	int err;	struct mmc_command cmd;	BUG_ON(!card);	BUG_ON(!card->host);	memset(&cmd, 0, sizeof(struct mmc_command));	cmd.opcode = SD_APP_SET_BUS_WIDTH;	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;	switch (width) {	case MMC_BUS_WIDTH_1:		cmd.arg = SD_BUS_WIDTH_1;		break;	case MMC_BUS_WIDTH_4:		cmd.arg = SD_BUS_WIDTH_4;		break;	default:		return MMC_ERR_INVALID;	}	err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);	if (err != MMC_ERR_NONE)		return err;	return MMC_ERR_NONE;}int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr){	struct mmc_command cmd;	int i, err = 0;	BUG_ON(!host);	memset(&cmd, 0, sizeof(struct mmc_command));	cmd.opcode = SD_APP_OP_COND;	cmd.arg = ocr;	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;	for (i = 100; i; i--) {		err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);		if (err != MMC_ERR_NONE)			break;		if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)			break;		err = MMC_ERR_TIMEOUT;		mmc_delay(10);	}	if (rocr)		*rocr = cmd.resp[0];	return err;}int mmc_send_if_cond(struct mmc_host *host, u32 ocr){	struct mmc_command cmd;	int err;	static const u8 test_pattern = 0xAA;	/*	 * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND	 * before SD_APP_OP_COND. This command will harmlessly fail for	 * SD 1.0 cards.	 */	cmd.opcode = SD_SEND_IF_COND;	cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;	cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;	err = mmc_wait_for_cmd(host, &cmd, 0);	if (err != MMC_ERR_NONE)		return err;	if ((cmd.resp[0] & 0xFF) != test_pattern)		return MMC_ERR_FAILED;	return MMC_ERR_NONE;}int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca){	int err;	struct mmc_command cmd;	BUG_ON(!host);	BUG_ON(!rca);	memset(&cmd, 0, sizeof(struct mmc_command));	cmd.opcode = SD_SEND_RELATIVE_ADDR;	cmd.arg = 0;	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);	if (err != MMC_ERR_NONE)		return err;	*rca = cmd.resp[0] >> 16;	return MMC_ERR_NONE;}int mmc_app_send_scr(struct mmc_card *card, u32 *scr){	int err;	struct mmc_request mrq;	struct mmc_command cmd;	struct mmc_data data;	struct scatterlist sg;	BUG_ON(!card);	BUG_ON(!card->host);	BUG_ON(!scr);	err = mmc_app_cmd(card->host, card);	if (err != MMC_ERR_NONE)		return err;	memset(&mrq, 0, sizeof(struct mmc_request));	memset(&cmd, 0, sizeof(struct mmc_command));	memset(&data, 0, sizeof(struct mmc_data));	mrq.cmd = &cmd;	mrq.data = &data;	cmd.opcode = SD_APP_SEND_SCR;	cmd.arg = 0;	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;	data.blksz = 8;	data.blocks = 1;	data.flags = MMC_DATA_READ;	data.sg = &sg;	data.sg_len = 1;	sg_init_one(&sg, scr, 8);	mmc_set_data_timeout(&data, card, 0);	mmc_wait_for_req(card->host, &mrq);	if (cmd.error != MMC_ERR_NONE)		return cmd.error;	if (data.error != MMC_ERR_NONE)		return data.error;	scr[0] = ntohl(scr[0]);	scr[1] = ntohl(scr[1]);	return MMC_ERR_NONE;}int mmc_sd_switch(struct mmc_card *card, int mode, int group,	u8 value, u8 *resp){	struct mmc_request mrq;	struct mmc_command cmd;	struct mmc_data data;	struct scatterlist sg;	BUG_ON(!card);	BUG_ON(!card->host);	mode = !!mode;	value &= 0xF;	memset(&mrq, 0, sizeof(struct mmc_request));	memset(&cmd, 0, sizeof(struct mmc_command));	memset(&data, 0, sizeof(struct mmc_data));	mrq.cmd = &cmd;	mrq.data = &data;	cmd.opcode = SD_SWITCH;	cmd.arg = mode << 31 | 0x00FFFFFF;	cmd.arg &= ~(0xF << (group * 4));	cmd.arg |= value << (group * 4);	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;	data.blksz = 64;	data.blocks = 1;	data.flags = MMC_DATA_READ;	data.sg = &sg;	data.sg_len = 1;	sg_init_one(&sg, resp, 64);	mmc_set_data_timeout(&data, card, 0);	mmc_wait_for_req(card->host, &mrq);	if (cmd.error != MMC_ERR_NONE)		return cmd.error;	if (data.error != MMC_ERR_NONE)		return data.error;	return MMC_ERR_NONE;}

⌨️ 快捷键说明

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