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

📄 mmc_core.c

📁 pxa270下的sd卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	printk("\n\n\n \t\t Wangzheng cid->mdt 0x%.8x\n", cid->mdt);		DEBUG(2," mid=%d oid=%d pnm=%s prv=%d.%d psn=%08x mdt=%d/%d\n",	      cid->mid, cid->oid, cid->pnm, 	      (cid->prv>>4), (cid->prv&0xf), 	      cid->psn, (cid->mdt>>4), (cid->mdt&0xf)+2000);	if ( buf[0] != 0x3f )  return MMC_ERROR_HEADER_MISMATCH;       	return 0;}int mmc_unpack_r3( struct mmc_request *request, struct mmc_response_r3 *r3 ){	u8 *buf = request->response;	if ( request->result ) return request->result;	r3->ocr = PARSE_U32(buf,1);	DEBUG(2," ocr=%08x\n", r3->ocr);	if ( buf[0] != 0x3f )  return MMC_ERROR_HEADER_MISMATCH;	return 0;}/**************************************************************************/#define KBPS 1#define MBPS 1000static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 };static u32 ts_mul[] = { 0,    1000, 1200, 1300, 1500, 2000, 2500, 3000, 			3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 };u32 mmc_tran_speed( u8 ts ){	u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3];	if ( rate <= 0 ) {		DEBUG(0, ": error - unrecognized speed 0x%02x\n", ts);		return 1;	}	return rate;}/**************************************************************************/void mmc_send_cmd( struct mmc_dev *dev, int cmd, u32 arg, 		   u16 nob, u16 block_len, enum mmc_rsp_t rtype ){	dev->request.cmd       = cmd;	dev->request.arg       = arg;	dev->request.rtype     = rtype;	dev->request.nob       = nob;	dev->request.block_len = block_len;	dev->request.buffer    = NULL;	/* dev->request.sd = dev->slot[0].sd; */ /* Wangzheng used for 1 bit or 4 bit */	if ( nob && dev->io_request )		dev->request.buffer = dev->io_request->buffer;	dev->state  |= STATE_CMD_ACTIVE;	dev->sdrive->send_cmd(&dev->request);}void mmc_finish_io_request( struct mmc_dev *dev, int result ){	struct mmc_io_request *t = dev->io_request;	struct mmc_slot *slot = dev->slot + t->id;	dev->io_request = NULL;     // Remove the old request (the media driver may requeue)	if ( slot->media_driver )		slot->media_driver->io_request_done( t, result );}/* Only call this when there is no pending request - it unloads the media driver */int mmc_check_eject( struct mmc_dev *dev ){	unsigned long   flags;	int             state;	int             i;	DEBUG(2," dev state=%x\n", dev->state);	local_irq_save(flags);	state = dev->state;	dev->state = state & ~STATE_EJECT;	local_irq_restore(flags);	if ( !(state & STATE_EJECT) )		return 0;	for ( i = 0 ; i < dev->num_slots ; i++ ) {		struct mmc_slot *slot = dev->slot + i;		if ( slot->flags & MMC_SLOT_FLAG_EJECT ) {			slot->state = CARD_STATE_EMPTY;			if ( slot->media_driver ) {				slot->media_driver->unload( slot );				slot->media_driver = NULL;			}			slot->flags &= ~MMC_SLOT_FLAG_EJECT;			run_sbin_mmc_hotplug(dev,i,0);		}	}	return 1;}int mmc_check_insert( struct mmc_dev *dev ){	unsigned long   flags;	int             state;	int             i;	int             card_count = 0;	DEBUG(2," dev state=%x\n", dev->state);	local_irq_save(flags);	state = dev->state;	dev->state = state & ~STATE_INSERT;	local_irq_restore(flags);	if ( !(state & STATE_INSERT) ) 		return 0;	for ( i = 0 ; i < dev->num_slots ; i++ ) {		struct mmc_slot *slot = dev->slot + i;		if ( slot->flags & MMC_SLOT_FLAG_INSERT ) {			if  (!dev->sdrive->is_empty(i)) {				slot->state = CARD_STATE_IDLE;				card_count++;			}			slot->flags &= ~MMC_SLOT_FLAG_INSERT;		}	}	return card_count;}/****************************************************************** * * Hotplug callback card insertion/removal * ******************************************************************/ #if !defined(CONFIG_OMAP_INNOVATOR) && !defined(CONFIG_MACH_OMAP_PERSEUS2)#ifdef CONFIG_HOTPLUGextern char hotplug_path[];extern int call_usermodehelper(char *path, char **argv, char **envp);static void run_sbin_hotplug(struct mmc_dev *dev, int id, int insert){	int i;	char *argv[3], *envp[8];	char media[64], slotnum[16];	if (!hotplug_path[0])		return;	DEBUG(0,": hotplug_path=%s id=%d insert=%d\n", hotplug_path, id, insert);	i = 0;	argv[i++] = hotplug_path;	argv[i++] = "mmc";	argv[i] = 0;	/* minimal command environment */	i = 0;	envp[i++] = "HOME=/";	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";		/* other stuff we want to pass to /sbin/hotplug */	sprintf(slotnum, "SLOT=%d", id );	if ( dev->slot[id].media_driver && dev->slot[id].media_driver->name )		sprintf(media, "MEDIA=%s", dev->slot[id].media_driver->name );	else		sprintf(media, "MEDIA=unknown");	envp[i++] = slotnum;	envp[i++] = media;	if (insert)		envp[i++] = "ACTION=add";	else		envp[i++] = "ACTION=remove";	envp[i] = 0;	call_usermodehelper (argv [0], argv, envp);}static void mmc_hotplug_task_handler( void *nr ){	int insert = ((int) nr) & 0x01;	int id     = ((int) nr) >> 1;	DEBUG(2," id=%d insert=%d\n", id, insert );	run_sbin_hotplug(&g_mmc_dev, id, insert );}static struct tq_struct mmc_hotplug_task = {	routine:  mmc_hotplug_task_handler};void run_sbin_mmc_hotplug(struct mmc_dev *dev, int id, int insert ){	mmc_hotplug_task.data = (void *) ((id << 1) | insert);	schedule_task( &mmc_hotplug_task );}#elsevoid run_sbin_mmc_hotplug(struct mmc_dev *sdev, int id, int insert) { }#endif /* CONFIG_HOTPLUG */#elsevoid run_sbin_mmc_hotplug(struct mmc_dev *sdev,  int id, int insert) { }#endif/****************************************************************** * Common processing tasklet * Everything gets serialized through this ******************************************************************/static void mmc_tasklet_action(unsigned long data){	struct mmc_dev *dev = (struct mmc_dev *)data;	unsigned long   flags;	int             state;	DEBUG(2,": dev=%p flags=%02x\n", dev, dev->state);	/* Grab the current working state */	local_irq_save(flags);	state = dev->state;	if ( state & STATE_CMD_DONE )		dev->state = state & ~(STATE_CMD_DONE | STATE_CMD_ACTIVE);	local_irq_restore(flags);	/* If there is an active command, don't do anything */	if ( (state & STATE_CMD_ACTIVE) && !(state & STATE_CMD_DONE) )		return;	if ( dev->protocol )		dev->protocol(dev,state);}/****************************************************************** * Callbacks from low-level driver * These run at interrupt time ******************************************************************/void mmc_cmd_complete(struct mmc_request *request){	DEBUG(2,": request=%p retval=%d\n", request, request->result);	g_mmc_dev.state |= STATE_CMD_DONE;	if ( !g_mmc_dev.suspended )		tasklet_schedule(&g_mmc_dev.task);}void mmc_insert(int slot){	DEBUG(2,": %d\n", slot);	g_mmc_dev.state |= STATE_INSERT;	g_mmc_dev.slot[slot].flags |= MMC_SLOT_FLAG_INSERT;	if ( !g_mmc_dev.suspended )		tasklet_schedule(&g_mmc_dev.task);}void mmc_eject(int slot){	DEBUG(2,": %d\n", slot);	g_mmc_dev.state |= STATE_EJECT;	g_mmc_dev.slot[slot].flags |= MMC_SLOT_FLAG_EJECT;	if ( !g_mmc_dev.suspended )		tasklet_schedule(&g_mmc_dev.task);}EXPORT_SYMBOL(mmc_cmd_complete);EXPORT_SYMBOL(mmc_insert);EXPORT_SYMBOL(mmc_eject);/****************************************************************** * Called from the media handler ******************************************************************/void mmc_handle_io_request( struct mmc_io_request *t ){	DEBUG(2," id=%d cmd=%d sector=%ld nr_sectors=%ld block_len=%ld buf=%p\n",	      t->id, t->cmd, t->sector, t->nr_sectors, t->block_len, t->buffer);		if ( g_mmc_dev.io_request ) {		DEBUG(0,": error! io_request in progress\n");		return;	}		g_mmc_dev.io_request = t;	tasklet_schedule(&g_mmc_dev.task);}EXPORT_SYMBOL(mmc_handle_io_request);/****************************************************************** *  Media handlers *  Allow different drivers to register a media handler ******************************************************************/static LIST_HEAD(mmc_media_drivers);int mmc_match_media_driver( struct mmc_slot *slot ){	struct list_head *item;	DEBUG(2,": slot=%p\n", slot);	for ( item = mmc_media_drivers.next ; item != &mmc_media_drivers ; item = item->next ) {		struct mmc_media_driver *drv = list_entry(item, struct mmc_media_driver, node );		if ( drv->probe(slot) ) {			slot->media_driver = drv;			drv->load(slot);			return 1;		}	}	return 0;}int mmc_register_media_driver( struct mmc_media_driver *drv ){	list_add_tail( &drv->node, &mmc_media_drivers );	return 0;}void mmc_unregister_media_driver( struct mmc_media_driver *drv ){	list_del(&drv->node);}EXPORT_SYMBOL(mmc_register_media_driver);EXPORT_SYMBOL(mmc_unregister_media_driver);/******************************************************************/int mmc_register_slot_driver( struct mmc_slot_driver *sdrive, int num_slots ){	int i;	int retval;	DEBUG(2," max=%d ocr=0x%08x\n", num_slots, sdrive->ocr);	if ( num_slots > MMC_MAX_SLOTS ) {		printk(KERN_CRIT "%s: illegal num of slots %d\n", __FUNCTION__, num_slots);		return -ENOMEM;	}	if ( g_mmc_dev.sdrive ) {		printk(KERN_ALERT "%s:: slot in use\n", __FUNCTION__);		return -EBUSY;	}	g_mmc_dev.sdrive    = sdrive;	g_mmc_dev.num_slots = num_slots;	for ( i = 0 ; i < num_slots ; i++ ) {		struct mmc_slot *slot = &g_mmc_dev.slot[i];		memset(slot,0,sizeof(struct mmc_slot));		slot->id = i;		slot->state = CARD_STATE_EMPTY;	}	retval = sdrive->init();	if ( retval )		return retval;	/* Generate insert events for cards */	for ( i = 0 ; i < num_slots ; i++ )		if ( !sdrive->is_empty(i) )			mmc_insert(i);	return 0;}

⌨️ 快捷键说明

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