亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專(zhuān)輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? mmc_media.c

?? spi driver for sd /mmc card
?? C
?? 第 1 頁(yè) / 共 2 頁(yè)
字號(hào):
/* * Block driver for media (i.e., flash cards) * * Copyright 2002 Hewlett-Packard Company * * Use consistent with the GNU GPL is permitted, * provided that this copyright notice is * preserved in its entirety in all copies and derived works. * * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS * FITNESS FOR ANY PARTICULAR PURPOSE. * * Many thanks to Alessandro Rubini and Jonathan Corbet! * * Author:  Andrew Christian *          28 May 2002 */ /* * Copyright 2004-2005 Motorola, Inc. All Rights Reserved. * Revision History:                    Modification     Changed by            Date             Description of Changes----------------   ------------      -------------------------Zhu Zhifu           05/27/2004         change for sync fs when close devicejiang lili          04/15/2005         change for ioctl*/ #include <linux/config.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/fs.h>     /* everything... */#include <linux/errno.h>  /* error codes */#include <linux/types.h>  /* size_t */#include <linux/fcntl.h>  /* O_ACCMODE */#include <linux/hdreg.h>  /* HDIO_GETGEO */#include <linux/init.h>#include <linux/devfs_fs_kernel.h>#include <linux/completion.h>#include <asm/system.h>#include <asm/uaccess.h>#include "mmc_core.h"#define MAJOR_NR mmc_major /* force definitions on in blk.h */static int mmc_major = 0xf3; /* must be declared before including blk.h *///#ifdef CONFIG_ARCH_EZX_E680/* add by w20598 for mmcsysif */static int mmcsysif_major = 0xf4;static int mmcsysif_usage = 0;extern int mmc_slot_enable;extern struct completion fatpanic_completion;extern unsigned short panicdev;#ifdef CONFIG_DEVFS_FSdevfs_handle_t mmcsysif_de;#endif/* add end *///#endif#define MMC_SHIFT           3             /* max 8 partitions per card */#define DEVICE_NR(device)   (MINOR(device)>>MMC_SHIFT)#define DEVICE_NAME         "mmc"         /* name for messaging */#define DEVICE_INTR         mmc_intrptr   /* pointer to the bottom half */#define DEVICE_NO_RANDOM                  /* no entropy to contribute */#define DEVICE_REQUEST      mmc_media_request#define DEVICE_OFF(d) /* do-nothing */#include <linux/blk.h>#include <linux/blkpg.h>static int rahead     = 8;static int maxsectors = 128;static unsigned long bh_pages = 0;MODULE_PARM(maxsectors,"i");MODULE_PARM_DESC(maxsectors,"Maximum number of sectors for a single request");MODULE_PARM(rahead,"i");MODULE_PARM_DESC(rahead,"Default sector read ahead");#define MMC_NDISK	(MMC_MAX_SLOTS << MMC_SHIFT)/*    Don't bother messing with blksize_size....it gets changed by various filesystems.   You're better off dealing with arbitrary blksize's*/ static int              mmc_blk[MMC_NDISK];  /* Used for hardsect_size - should be 512 bytes */static int              mmc_max[MMC_NDISK];  /* Used for max_sectors[] - limit size of individual request */static int              mmc_sizes[MMC_NDISK];        /* Used in gendisk - gives whole size of partition */static struct hd_struct mmc_partitions[MMC_NDISK];   /* Used in gendisk - gives particular partition information */static char             mmc_gendisk_flags;#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t   mmc_devfs_handle;#endif// There is one mmc_media_dev per inserted cardstruct mmc_media_dev {	int              usage;	struct mmc_slot *slot;	spinlock_t       lock;	int              changed;	long             nr_sects;   // In total number of sectors	int              read_block_len;      // Valid read block length	int              write_block_len;     // Valid write block length	unsigned char	 lock_param[258];  // Lock card data structure 	struct mmc_io_request io_request;};static struct mmc_media_dev   g_media_dev[MMC_MAX_SLOTS];static struct mmc_io_request  g_io_request;static int                    g_busy;static struct gendisk mmc_gendisk = { //modify by zhuzf       major:	        0,               /* major number dynamically assigned */        major:	        0xf3,	major_name:	DEVICE_NAME,	minor_shift:	MMC_SHIFT,	 /* shift to get device number */	max_p:	        1 << MMC_SHIFT,	 /* Number of partiions */	/* The remainder will be filled in dynamically */};/*************************************************************************//* TODO: O_EXCL, O_NDELAY, invalidate_buffers */static int mmc_media_open( struct inode *inode, struct file *filp ){	struct mmc_media_dev *dev;	int num = DEVICE_NR(inode->i_rdev);	int ro = 0;	DEBUG(1,": num=%d\n", num);//#ifdef CONFIG_ARCH_EZX_E680	/* add by w20598 */	if (!mmc_slot_enable)	    return -ENODEV;	/* add end *///#endif	if ( num >= MMC_MAX_SLOTS)		return -ENODEV;	dev = &g_media_dev[num];	if ( !dev->slot ) 		return -ENODEV;        	spin_lock(&dev->lock);	if (!dev->usage)		check_disk_change(inode->i_rdev);	dev->usage++;	MOD_INC_USE_COUNT;	if ( (dev->slot->dev->sdrive->is_wp && dev->slot->dev->sdrive->is_wp(dev->slot->id)) || 		dev->slot->csd.perm_write_protect || 		dev->slot->csd.tmp_write_protect) 		ro = 1;	set_device_ro(inode->i_rdev, ro);	spin_unlock(&dev->lock);	return 0;}static int mmc_media_release( struct inode *inode, struct file *filep ){	struct mmc_media_dev *dev = &g_media_dev[DEVICE_NR(inode->i_rdev)];	DEBUG(1,": num=%d\n", DEVICE_NR(inode->i_rdev));	spin_lock(&dev->lock);	dev->usage--;	/* Is this worth doing? */	/* add by w20598. force to sync filesystem *///	if (!dev->usage) {			fsync_dev(inode->i_rdev);		destroy_buffers(inode->i_rdev);//	}	MOD_DEC_USE_COUNT;	spin_unlock(&dev->lock);	return 0;}static int mmc_media_revalidate(kdev_t i_rdev){	int index, max_p, start, i;	struct mmc_media_dev *dev;	index = DEVICE_NR(i_rdev);	DEBUG(2,": index=%d\n", index);	max_p = mmc_gendisk.max_p;	start = index << MMC_SHIFT;	dev   = &g_media_dev[index];	for ( i = max_p - 1 ; i >= 0 ; i-- ) {		int item = start + i;		invalidate_device(MKDEV(mmc_major,item),1);		mmc_gendisk.part[item].start_sect = 0;		mmc_gendisk.part[item].nr_sects   = 0;		/* TODO: Fix the blocksize? */	}	register_disk(&mmc_gendisk, i_rdev, 1 << MMC_SHIFT, mmc_gendisk.fops, dev->nr_sects);	return 0;}static void mmc_media_wait_done ( struct mmc_io_request *req ){ 	complete(req->done_data);} static int mmc_media_ioctl (struct inode *inode, struct file *filp,			    unsigned int cmd, unsigned long arg){ 	DECLARE_COMPLETION(completion);	int num = DEVICE_NR(inode->i_rdev);	int size;	struct hd_geometry geo;	struct mmc_media_dev *dev;	struct mmc_slot *slot;	unsigned long status;	DEBUG(1," ioctl 0x%x 0x%lx\n", cmd, arg);//#ifdef CONFIG_ARCH_EZX_E680		/* add by w20598 */	if (!mmc_slot_enable)	    return -EFAULT;	/* add end *///#endif	dev	= &g_media_dev[num];	slot	= g_media_dev[num].slot;	switch(cmd) {	case BLKGETSIZE:		/* Return the device size, expressed in sectors */		/* Not really necessary, but this is faster than walking the gendisk list */		if (!access_ok(VERIFY_WRITE, arg, sizeof(long)))			return -EFAULT;		return put_user(mmc_partitions[MINOR(inode->i_rdev)].nr_sects, (long *)arg);	case BLKRRPART: /* re-read partition table */		if (!capable(CAP_SYS_ADMIN)) 			return -EACCES;		return mmc_media_revalidate(inode->i_rdev);	case HDIO_GETGEO:		if (!access_ok(VERIFY_WRITE, arg, sizeof(geo)))			return -EFAULT;		/* Grab the size from the 0 partition for this minor */                geo.cylinders = mmc_partitions[MINOR(inode->i_rdev)].nr_sects;                geo.heads     = 1;                geo.sectors   = 1;                geo.start     = mmc_partitions[MINOR(inode->i_rdev)].start_sect;                if (copy_to_user((void *) arg, &geo, sizeof(geo)))                        return -EFAULT;                return 0;       case IOCMMCSETCLKRATE:		if (!access_ok(VERIFY_READ, arg, sizeof(int)))			return -EFAULT;		if (MMC_NO_ERROR != slot->dev->sdrive->set_clock(arg) )			return -EINVAL;		return 0;        case IOCMMCGETCARDCID:                if (!access_ok(VERIFY_WRITE, arg, sizeof(struct mmc_cid)))                        return -EFAULT;                if (copy_to_user ((void *) arg, &(slot->cid), sizeof(struct mmc_cid)))                        return -EFAULT;                return 0;        case IOCMMCGETCARDCSD:                if (!access_ok(VERIFY_WRITE, arg, sizeof(struct mmc_csd)))                        return -EFAULT;                if (copy_to_user ((void *) arg, &(slot->csd), sizeof(struct mmc_csd)))                        return -EFAULT;                return 0;	case IOCMMCGETCARDSTATUS:		if (!access_ok(VERIFY_WRITE, arg, sizeof(int)))			return -EFAULT;		status = 0;		if (slot->dev->sdrive->is_wp && slot->dev->sdrive->is_wp(num))			status |= 0x1;		if (slot->flags & MMC_SLOT_FLAG_LOCKED)			status |= 0x2;		if (slot->flags & MMC_SLOT_FLAG_LOCK_FAILED) {			status |= 0x4;			slot->flags &= ~MMC_SLOT_FLAG_LOCK_FAILED;		}		if (!(slot->csd.ccc & 0x80)) /* dont support lock/ulock */		        status |= 0x8;		if (copy_to_user((void*) arg, & status, sizeof(unsigned long)))			return -EFAULT;				return 0;	case IOCMMCLOCKCARD:#if 0/* e680 dont support lock the card when the phone power on */		spin_lock(&dev->lock);		if (dev->usage > 1) {			spin_unlock(&dev->lock);			return -EBUSY;		}		spin_unlock(&dev->lock);#endif 		/*  class 7 support */		if ( !(slot->csd.ccc & 0x80) ) return -EINVAL;		/* card lock data structure */		if (!access_ok(VERIFY_READ, arg, 2)) return -EFAULT;		if (copy_from_user(dev->lock_param, (void*)arg, 2)) 			return -EFAULT;		size = dev->lock_param[1] + 2;		if (!access_ok(VERIFY_READ, arg, size)) return -EFAULT;		if (copy_from_user(dev->lock_param, (void*)arg, size))			return -EFAULT;		/* issue i/o request for lock/unlock */		dev->io_request.id 		= num;		dev->io_request.cmd 		= MMC_IO_LOCK;		dev->io_request.block_len  	= size;		dev->io_request.buffer     	= dev->lock_param;		dev->io_request.done_data	= &completion;		dev->io_request.done		= mmc_media_wait_done;		if (!mmc_handle_io_request(&dev->io_request))			return -EBUSY;		/* wait until done */		wait_for_completion(&completion);		return 0;//#ifdef CONFIG_ARCH_EZX_E680	case IOCMMCGETCARDTYPE:	       	if (!access_ok(VERIFY_WRITE, arg, sizeof(long)))			return -EFAULT;						return put_user(g_media_dev[num].slot->sd,(long *)arg);//#endif			default:		return blk_ioctl(inode->i_rdev, cmd, arg);	}	return -ENOTTY; /* should never get here */}static int mmc_media_check_change(kdev_t i_rdev) {	int                   index, retval;	struct mmc_media_dev *dev;	unsigned long         flags;	index = DEVICE_NR(i_rdev);	DEBUG(2," device=%d\n", index);	if (index >= MMC_MAX_SLOTS) 		return 0;	dev = &g_media_dev[index];	spin_lock_irqsave(&dev->lock, flags);	retval = (dev->changed ? 1 : 0);	dev->changed = 0;	spin_unlock_irqrestore(&dev->lock, flags);	return retval;}static struct mmc_media_dev * mmc_media_locate_device(const struct request *req){	int num = DEVICE_NR(req->rq_dev);	if ( num >= MMC_MAX_SLOTS) {		static int count = 0;		if (count++ < 5) /* print the message at most five times */			printk(KERN_WARNING "mmc: request for unknown device\n");		return NULL;	}	return &g_media_dev[num];}static int mmc_media_transfer( struct mmc_media_dev *dev, const struct request *req ){	int minor = MINOR(req->rq_dev);	unsigned long flags;	int cmd;	struct buffer_head *bh;	int nr_sectors;	unsigned char *buffer,*data;		DEBUG(2,": minor=%d\n", minor);	nr_sectors = 0;	bh = req->bh;	if (!bh_pages) {	    buffer = req->buffer;	    data = NULL;	}	else data = buffer = (u8*) bh_pages;        while(bh) {	    	    nr_sectors += bh->b_size >> 9;            if ( (req->cmd == WRITE) && data ) {	        memcpy(data, bh->b_data, bh->b_size);                data += bh->b_size;            }            if ( (!bh->b_reqnext) ||		 (bh->b_reqnext->b_rsector != (bh->b_rsector + (bh->b_size >> 9))) ||                 ((!data) && (bh->b_reqnext->b_page != bh->b_page)) )                 break;            bh = bh->b_reqnext;        }	    	if ( req->sector + nr_sectors > mmc_partitions[minor].nr_sects) {		static int count = 0;		if (count++ < 5)			printk(KERN_WARNING "%s: request past end of partition\n", __FUNCTION__);		return 0;	}	cmd = (req->cmd == READ) ? MMC_IO_READ : 		((req->cmd == WRITE) ? MMC_IO_WRITE : MMC_IO_UNKNOWN);	if (cmd == MMC_IO_UNKNOWN) {		printk(KERN_WARNING "%s : unknown request->cmd = %d\n",__FUNCTION__, req->cmd);		return 0;	}		spin_lock_irqsave(&dev->lock, flags);	g_io_request.id         = DEVICE_NR(req->rq_dev);	g_io_request.cmd        = cmd;	g_io_request.sector     = mmc_partitions[minor].start_sect + req->sector;	g_io_request.nr_sectors = nr_sectors;	g_io_request.block_len  = mmc_blk[minor];	g_io_request.buffer     = buffer;	DEBUG(2,": id=%d cmd=%d sector=%ld nr_sectors=%ld block_len=%ld buf=%p\n",	      g_io_request.id, g_io_request.cmd, g_io_request.sector, g_io_request.nr_sectors,	      g_io_request.block_len, g_io_request.buffer );	mmc_handle_io_request(&g_io_request);	spin_unlock_irqrestore(&dev->lock, flags);	return 1;}static void mmc_media_request( request_queue_t *q ){	struct mmc_media_dev *dev;	if ( g_busy )		return;	while(1) {		INIT_REQUEST;  /* returns when queue is empty *///#ifdef CONFIG_ARCH_EZX_E680				/* add by w20598 to prevent from flushing data when card is removed */		if (!mmc_slot_enable)		{		    if (READ == CURRENT->cmd)		    {		        DEBUG(3," card is removed.read cmd return error!\n");		        end_request(0);		    }		    else		    {		        DEBUG(3," card is removed.write cmd return ok!\n");		        end_request(1);		    }		    continue;		}		/* add end *///#endif

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人免费高清视频| 国产亚洲精品免费| 欧美区一区二区三区| 在线亚洲精品福利网址导航| 波多野结衣亚洲| 99久久久精品免费观看国产蜜| 国产成人综合视频| 国产a区久久久| 成人av影视在线观看| 东方aⅴ免费观看久久av| 国产69精品久久久久毛片| 国产剧情一区二区三区| 国产91精品免费| www.成人网.com| 色噜噜夜夜夜综合网| 欧美亚洲综合久久| 在线不卡a资源高清| 日韩三级在线观看| 久久久五月婷婷| 中文乱码免费一区二区| 国产精品美女久久久久久久| 亚洲视频一二三| 亚洲一区二区三区自拍| 日韩在线观看一区二区| 久草精品在线观看| 成人av中文字幕| 欧美日韩中字一区| 日韩亚洲欧美中文三级| 久久综合成人精品亚洲另类欧美 | 国产98色在线|日韩| 成人国产精品免费| 欧美探花视频资源| 精品少妇一区二区三区在线视频| 国产色一区二区| 亚洲欧美日韩精品久久久久| 丝袜亚洲另类欧美综合| 国产剧情在线观看一区二区| 92精品国产成人观看免费| 欧美日韩dvd在线观看| 精品国产免费视频| 最新国产成人在线观看| 日欧美一区二区| 粉嫩蜜臀av国产精品网站| 色狠狠桃花综合| 欧美刺激午夜性久久久久久久| 中文字幕第一区| 婷婷国产在线综合| 粉嫩蜜臀av国产精品网站| 欧美色男人天堂| 国产清纯在线一区二区www| 一区二区三区精品久久久| 激情五月播播久久久精品| 日本精品视频一区二区| 精品国内二区三区| 亚洲综合在线视频| 国产成人精品在线看| 欧美日韩国产一级片| 国产精品免费av| 人禽交欧美网站| 日本韩国精品一区二区在线观看| 欧美精品一区二| 亚洲成人午夜电影| 99久久精品一区| 久久久久国色av免费看影院| 亚洲丶国产丶欧美一区二区三区| 国产不卡视频一区| 日韩欧美国产电影| 亚洲欧美偷拍卡通变态| 国产在线视频不卡二| 中文字幕中文字幕在线一区 | 韩国v欧美v日本v亚洲v| 在线看一区二区| 国产精品理伦片| 国产一区二区三区不卡在线观看 | 久久久蜜桃精品| 免费成人av资源网| 欧美揉bbbbb揉bbbbb| ...av二区三区久久精品| 国内一区二区在线| 欧美一级片在线观看| 一区二区三区在线视频免费| 成人国产精品免费观看视频| 亚洲精品一区二区三区在线观看| 亚洲电影视频在线| 91福利在线观看| 中文字幕一区二区三区不卡在线| 国产在线精品一区在线观看麻豆| 欧美一区二区三区在线电影| 亚洲一区二区av在线| 99re亚洲国产精品| 亚洲欧美怡红院| 成人激情免费网站| 欧美国产精品一区二区三区| 国产美女久久久久| 欧美mv日韩mv| 加勒比av一区二区| 精品粉嫩超白一线天av| 久久成人av少妇免费| 日韩手机在线导航| 男女男精品网站| 日韩欧美国产综合一区 | 国产91色综合久久免费分享| 精品动漫一区二区三区在线观看| 蜜桃一区二区三区在线观看| 6080午夜不卡| 久久精品国产久精国产爱| 欧美一区二区啪啪| 免费的国产精品| 精品国产成人系列| 国产伦精品一区二区三区免费 | 国产色婷婷亚洲99精品小说| 国产在线国偷精品产拍免费yy| 欧美草草影院在线视频| 精品一区二区三区久久久| 日韩一区二区免费在线观看| 久久99久久精品| 国产日韩精品视频一区| aaa欧美日韩| 一区二区三区在线观看动漫| 欧美午夜电影在线播放| 丝袜脚交一区二区| 精品国产91乱码一区二区三区| 国产精品一品视频| 亚洲欧美一区二区三区国产精品| 欧美午夜影院一区| 麻豆freexxxx性91精品| 久久久久国色av免费看影院| av在线这里只有精品| 亚洲午夜久久久久久久久电影网| 欧美一区二区精品在线| 国产一区二区三区日韩| 亚洲三级免费电影| 欧美精品日韩综合在线| 另类综合日韩欧美亚洲| 国产日产欧美一区二区三区| 色噜噜狠狠一区二区三区果冻| 日韩和欧美一区二区| 久久久久久97三级| 91精品办公室少妇高潮对白| 日本aⅴ亚洲精品中文乱码| 久久亚洲欧美国产精品乐播| 99在线热播精品免费| 亚洲国产日韩一级| 久久久久久久久久久黄色| 99re热视频这里只精品| 男女性色大片免费观看一区二区 | 国产精品国产三级国产三级人妇| 欧美色综合网站| 国产在线日韩欧美| 一二三四区精品视频| 久久久亚洲午夜电影| 在线一区二区三区四区| 国内成人自拍视频| 亚洲永久精品国产| 久久精品网站免费观看| 欧美日韩中文字幕精品| 国产成人精品在线看| 婷婷夜色潮精品综合在线| 中文字幕第一区二区| 欧美高清视频www夜色资源网| 国产91露脸合集magnet| 日韩电影在线一区二区| 国产精品久久99| 欧美电影免费观看高清完整版在线 | 欧美精品久久久久久久久老牛影院| 国产一区二区在线看| 亚洲一区二区三区三| 欧美国产日本视频| 欧美成人三级电影在线| 日本高清成人免费播放| 国产精品一区二区黑丝 | 欧美日韩视频在线第一区| 国产白丝网站精品污在线入口| 日本 国产 欧美色综合| 亚洲自拍都市欧美小说| 国产精品免费人成网站| 久久综合网色—综合色88| 91精品久久久久久久99蜜桃 | 一区二区三区国产精品| 国产精品无人区| 欧美精品一区二区精品网| 欧美日韩一区二区三区高清| 不卡一区二区三区四区| 国产精品一二三四区| 毛片基地黄久久久久久天堂| 亚洲国产精品一区二区www在线| 国产精品色呦呦| 久久九九久久九九| 欧美大片日本大片免费观看| 欧美精品第一页| 欧美日韩一区高清| 在线一区二区三区四区五区| 一本久道久久综合中文字幕| 丁香激情综合国产| 国产精品一线二线三线精华| 美国毛片一区二区| 裸体在线国模精品偷拍| 日本一道高清亚洲日美韩| 日本亚洲最大的色成网站www| 天堂在线亚洲视频|