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

📄 core.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/drivers/mmc/core/core.c * *  Copyright (C) 2003-2004 Russell King, All Rights Reserved. *  SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. *  Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. *  MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/module.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/completion.h>#include <linux/device.h>#include <linux/delay.h>#include <linux/pagemap.h>#include <linux/err.h>#include <asm/scatterlist.h>#include <linux/scatterlist.h>#include <linux/mmc/card.h>#include <linux/mmc/host.h>#include <linux/mmc/mmc.h>#include <linux/mmc/sd.h>#include "core.h"#include "sysfs.h"#include "mmc_ops.h"#include "sd_ops.h"#include "sdio_ops.h"extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr);extern int mmc_attach_sd(struct mmc_host *host, u32 ocr);extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr);/** *	mmc_request_done - finish processing an MMC request *	@host: MMC host which completed request *	@mrq: MMC request which request * *	MMC drivers should call this function when they have completed *	their processing of a request. */void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq){	struct mmc_command *cmd = mrq->cmd;	int err = cmd->error;	pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n",		 mmc_hostname(host), cmd->opcode, err,		 mrq->data ? mrq->data->error : 0,		 mrq->stop ? mrq->stop->error : 0,		 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);	if (err && cmd->retries) {		cmd->retries--;		cmd->error = 0;		host->ops->request(host, mrq);	} else if (mrq->done) {		mrq->done(mrq);	}}EXPORT_SYMBOL(mmc_request_done);/** *	mmc_start_request - start a command on a host *	@host: MMC host to start command on *	@mrq: MMC request to start * *	Queue a command on the specified host.  We expect the *	caller to be holding the host lock with interrupts disabled. */voidmmc_start_request(struct mmc_host *host, struct mmc_request *mrq){	pr_debug("%s: starting CMD%u arg %08x flags %08x\n",		 mmc_hostname(host), mrq->cmd->opcode,		 mrq->cmd->arg, mrq->cmd->flags);	WARN_ON(!host->claimed);	mrq->cmd->error = 0;	mrq->cmd->mrq = mrq;	if (mrq->data) {		BUG_ON(mrq->data->blksz > host->max_blk_size);		BUG_ON(mrq->data->blocks > host->max_blk_count);		BUG_ON(mrq->data->blocks * mrq->data->blksz >			host->max_req_size);		mrq->cmd->data = mrq->data;		mrq->data->error = 0;		mrq->data->mrq = mrq;		if (mrq->stop) {			mrq->data->stop = mrq->stop;			mrq->stop->error = 0;			mrq->stop->mrq = mrq;		}	}	host->ops->request(host, mrq);}EXPORT_SYMBOL(mmc_start_request);static void mmc_wait_done(struct mmc_request *mrq){	complete(mrq->done_data);}int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq){	DECLARE_COMPLETION_ONSTACK(complete);	mrq->done_data = &complete;	mrq->done = mmc_wait_done;	mmc_start_request(host, mrq);	wait_for_completion(&complete);	return 0;}EXPORT_SYMBOL(mmc_wait_for_req);/** *	mmc_wait_for_cmd - start a command and wait for completion *	@host: MMC host to start command *	@cmd: MMC command to start *	@retries: maximum number of retries * *	Start a new MMC command for a host, and wait for the command *	to complete.  Return any error that occurred while the command *	was executing.  Do not attempt to parse the response. */int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries){	struct mmc_request mrq;	BUG_ON(!host->claimed);	memset(&mrq, 0, sizeof(struct mmc_request));	memset(cmd->resp, 0, sizeof(cmd->resp));	cmd->retries = retries;	mrq.cmd = cmd;	cmd->data = NULL;	mmc_wait_for_req(host, &mrq);	return cmd->error;}EXPORT_SYMBOL(mmc_wait_for_cmd);/** *	mmc_set_data_timeout - set the timeout for a data command *	@data: data phase for command *	@card: the MMC card associated with the data transfer *	@write: flag to differentiate reads from writes */void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,			  int write){	unsigned int mult;	/*	 * SD cards use a 100 multiplier rather than 10	 */	mult = mmc_card_sd(card) ? 100 : 10;	/*	 * Scale up the multiplier (and therefore the timeout) by	 * the r2w factor for writes.	 */	if (write)		mult <<= card->csd.r2w_factor;	data->timeout_ns = card->csd.tacc_ns * mult;	data->timeout_clks = card->csd.tacc_clks * mult;	/*	 * SD cards also have an upper limit on the timeout.	 */	if (mmc_card_sd(card)) {		unsigned int timeout_us, limit_us;		timeout_us = data->timeout_ns / 1000;		timeout_us += data->timeout_clks * 1000 /			(card->host->ios.clock / 1000);		if (write)			limit_us = 250000;		else			limit_us = 100000;		/*		 * SDHC cards always use these fixed values.		 */		if (timeout_us > limit_us || mmc_card_blockaddr(card)) {			data->timeout_ns = limit_us * 1000;			data->timeout_clks = 0;		}	}}EXPORT_SYMBOL(mmc_set_data_timeout);/** *	__mmc_claim_host - exclusively claim a host *	@host: mmc host to claim *	@card: mmc card to claim host for * *	Claim a host for a set of operations.  If a valid card *	is passed and this wasn't the last card selected, select *	the card before returning. * *	Note: you should use mmc_card_claim_host or mmc_claim_host. */void mmc_claim_host(struct mmc_host *host){	DECLARE_WAITQUEUE(wait, current);	unsigned long flags;	add_wait_queue(&host->wq, &wait);	spin_lock_irqsave(&host->lock, flags);	while (1) {		set_current_state(TASK_UNINTERRUPTIBLE);		if (!host->claimed)			break;		spin_unlock_irqrestore(&host->lock, flags);		schedule();		spin_lock_irqsave(&host->lock, flags);	}	set_current_state(TASK_RUNNING);	host->claimed = 1;	spin_unlock_irqrestore(&host->lock, flags);	remove_wait_queue(&host->wq, &wait);}EXPORT_SYMBOL(mmc_claim_host);/** *	mmc_release_host - release a host *	@host: mmc host to release * *	Release a MMC host, allowing others to claim the host *	for their operations. */void mmc_release_host(struct mmc_host *host){	unsigned long flags;	BUG_ON(!host->claimed);	spin_lock_irqsave(&host->lock, flags);	host->claimed = 0;	spin_unlock_irqrestore(&host->lock, flags);	wake_up(&host->wq);}EXPORT_SYMBOL(mmc_release_host);/* * Internal function that does the actual ios call to the host driver, * optionally printing some debug output. */static inline void mmc_set_ios(struct mmc_host *host){	struct mmc_ios *ios = &host->ios;	pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u "		"width %u timing %u\n",		 mmc_hostname(host), ios->clock, ios->bus_mode,		 ios->power_mode, ios->chip_select, ios->vdd,		 ios->bus_width, ios->timing);	host->ops->set_ios(host, ios);}/* * Control chip select pin on a host. */void mmc_set_chip_select(struct mmc_host *host, int mode){	host->ios.chip_select = mode;	mmc_set_ios(host);}/* * Sets the host clock to the highest possible frequency that * is below "hz". */void mmc_set_clock(struct mmc_host *host, unsigned int hz){	WARN_ON(hz < host->f_min);	if (hz > host->f_max)		hz = host->f_max;	host->ios.clock = hz;	mmc_set_ios(host);}/* * Change the bus mode (open drain/push-pull) of a host. */void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode){	host->ios.bus_mode = mode;	mmc_set_ios(host);}/* * Change data bus width of a host. */void mmc_set_bus_width(struct mmc_host *host, unsigned int width){	host->ios.bus_width = width;	mmc_set_ios(host);}/* * Mask off any voltages we don't support and select * the lowest voltage */u32 mmc_select_voltage(struct mmc_host *host, u32 ocr){	int bit;	ocr &= host->ocr_avail;	bit = ffs(ocr);	if (bit) {		bit -= 1;		ocr &= 3 << bit;		host->ios.vdd = bit;		mmc_set_ios(host);	} else {		ocr = 0;	}	return ocr;}/* * Select timing parameters for host. */void mmc_set_timing(struct mmc_host *host, unsigned int timing){	host->ios.timing = timing;

⌨️ 快捷键说明

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