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

📄 mmc_core.c

📁 mmc_qspi.tar.gz mmc block driver code for uClinux
💻 C
📖 第 1 页 / 共 2 页
字号:
	{			check_disk_change (inode->i_rdev);	}/*	else	{		retval = -EBUSY;		goto exit;	}*/	dev->mode = file->f_pos;	dev->open_count++;	MOD_INC_USE_COUNT;exit :	return retval;}static int mmc_blk_release (struct inode *inode, struct file *file){	int device_num = MINOR(inode->i_rdev) >> DEVICE_SHIFT;	struct mmc_blk *dev;	int retval = 0;		dbg("enter %s", __FUNCTION__);	if ((device_num < 0) ||	    (device_num >= nb_dev))	{		err("%s : DEV for minor %d don't exits", 				__FUNCTION__, device_num);		return -ENODEV;	}	dev = (struct mmc_blk *) (mmc_blk_dev + device_num);		if (dev->open_count <= 0)	{		err("%s - device not opened", __FUNCTION__);		return -ENODEV;	}	/* decrement our usage count for the device */	--dev->open_count;	MOD_DEC_USE_COUNT;	return retval;}static int mmc_blk_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	int minor = MINOR(inode->i_rdev);	int device_num = minor >> PAGE_SHIFT;	long size;	struct hd_geometry geo;		if ((device_num < 0) ||	    (device_num >= nb_dev))	{		err("%s : DEV for minor %d don't exits", 				__FUNCTION__, device_num);		return -ENODEV;	}	switch (cmd)	{		/* return device size in sector */		case BLKGETSIZE :						dbg("%s - get size command", __FUNCTION__);			                	if (!access_ok (VERIFY_WRITE, (void *) arg, sizeof (unsigned long)))				return -EFAULT;			//size = mmc_blk_gendisk.part[minor].nr_sects;						size =  mmc_blk_size[minor] * 				mmc_blk_blocksizes[minor] / 				mmc_blk_sectorsizes[minor];						dbg("(device %d - minor %d) size in sector = %ld", 					device_num, minor, size);			if (copy_to_user ((unsigned long *) arg, &size, sizeof (unsigned long)))				return (-EFAULT);			return (0);		/* read again partion table */		case BLKRRPART :			return (mmc_blk_revalidate (inode->i_rdev));				/* return the device geometry */		case HDIO_GETGEO :			dbg("%s - get the geom", __FUNCTION__);                	if (!access_ok (VERIFY_WRITE, (void *) arg, sizeof (unsigned long)))				return -EFAULT;			// size = mmc_blk_gendisk.part[device_num].nr_sects;			size =  mmc_blk_size[device_num] * 				mmc_blk_blocksizes[device_num] / 				mmc_blk_sectorsizes[device_num];						geo.cylinders = (size & ~0x3f) >> 6;			geo.heads = 4;			geo.sectors = 16;			geo.start = 4;			dbg("geom.cylinders = %d", geo.cylinders);			dbg("(device %d - minor %d) size in sector = %ld", 					device_num, minor, size);			if (copy_to_user ((struct hd_geometry *) arg, &geo, 					sizeof (struct hd_geometry)))				return (-EFAULT);			return (0);		/* let the kernel handle for us the unkown command */		default :			dbg("%s - let the kernel handle this ioctl :)", __FUNCTION__);			return (blk_ioctl (inode->i_rdev, cmd, arg));	}	return (-ENOTTY);}/* initialize the MMC and set device global variables (such as block size... etc) */static int init_mmc(int device_num, struct mmc_blk *dev){	int part, retval = 0;	char *csd_tmp = NULL;	char *cid_tmp = NULL;	long mmc_size, c_size, c_size_mult, read_block_len, mult, block_len, block_nr;	/* TODO : handle multiple devices */	if (device_num != 0)		return (-ENODEV);	retval = open_mmc ();	if (retval < 0)	{		err("%s : unable to open mmc device", 				__FUNCTION__);		/* attempt to let the qspi driver 		 * in a proper state */		release_mmc ();		return (retval);	}	dbg("%s - success to open the mmc device %d", 			__FUNCTION__, device_num);	/* get the MMC CID register (Card Specific Data) */	cid_tmp = get_cid ();	if (cid_tmp == NULL)	{		err("%s - unable to get CID register",			__FUNCTION__);	}	else	{		memcpy (dev->cid, cid_tmp, CID_SIZE);		kfree (cid_tmp);	}		/* get the MMC CSD register (Card Specific Data) */	csd_tmp = get_csd ();	if (csd_tmp == NULL)	{		err("%s - unable to get CSD register : use default settings",			__FUNCTION__);		dev->size = DFLT_BLK_SIZE;	}	else	{		memcpy (dev->csd, csd_tmp, CSD_SIZE);		c_size = ((long) (csd_tmp[6]&0x03)) << 10;		c_size += ((long) (csd_tmp[7]&0xff) << 2) + 			((long)(csd_tmp[8]&0xff)>>6);		c_size_mult = (long) (((csd_tmp[9] & 0x03) << 1) + 				((csd_tmp[10] & 0x80) >> 7));		read_block_len = (long) (csd_tmp[5] & 0x000f);		block_len = (long) (1 << read_block_len);		mult = (long) (1 << (c_size_mult + 2));		block_nr = (c_size + 1) * mult;		mmc_size = block_len * block_nr;		dev->size = (unsigned int) (mmc_size / DFLT_BLKSIZE_SIZE);			kfree (csd_tmp);	}	dev->sector_size = DFLT_HARDSECT_SIZE;	dev->block_size = DFLT_BLKSIZE_SIZE;	mmc_blk_size[device_num << DEVICE_SHIFT] = dev->size;	for (part = 0; part < (1 << DEVICE_SHIFT); part++)	{		mmc_blk_blocksizes[(device_num << DEVICE_SHIFT) + part] = 			dev->block_size;		mmc_blk_sectorsizes[(device_num << DEVICE_SHIFT) + part] = 			dev->sector_size;	}	info("%s - mmc_size : %ld(KB) - block_len : %ld - block_nr : %ld",			__FUNCTION__, dev->size, 			dev->block_size, dev->size);	return (0);}static int __init mmc_blk_init(void){	int result, device_num, device_found = 0, retval = 0;	if ((result = register_blkdev (mmc_blk_major, DEVICE_NAME, 					&mmc_blk_ops)) < 0)	{		dbg(" driver : unable to register chrdev");		return (-1);		}	if (mmc_blk_major == 0)		mmc_blk_major = result;		mmc_blk_gendisk.major = mmc_blk_major;	/* allocate our device private structure */	if (!(mmc_blk_dev = (struct mmc_blk *) 		kmalloc (nb_dev * sizeof (struct mmc_blk), GFP_KERNEL)))	{		retval = -ENOMEM;		err("%s - unable to allocate memory", __FUNCTION__);		goto alloc_dev_error_exit;	}	memset (mmc_blk_dev, 0, sizeof (struct mmc_blk));	memset (mmc_blk_size, 0, sizeof (mmc_blk_size));	memset (mmc_blk_blocksizes, 0, sizeof (mmc_blk_blocksizes));	memset (mmc_blk_sectorsizes, 0, sizeof (mmc_blk_sectorsizes));	/* mmc initialization */	for (device_num = 0; device_num < nb_dev; device_num++)	{		if (init_mmc (device_num, &mmc_blk_dev[device_num]) == 0)		{			device_found++;		}	}	if (!device_found)	{		retval = -ENODEV;		err("%s - unable to found MMC device", __FUNCTION__);		goto alloc_dev_error_exit;	}	blk_size[mmc_blk_major] = mmc_blk_gendisk.sizes = mmc_blk_size;	blksize_size[mmc_blk_major] = mmc_blk_blocksizes;	hardsect_size[mmc_blk_major] = mmc_blk_sectorsizes;	read_ahead[mmc_blk_major] = DFLT_RAHEAD;		/* allocate the partition array. */	mmc_blk_partitions = kmalloc ((nb_dev << DEVICE_SHIFT) 			* sizeof (struct hd_struct), GFP_KERNEL);	if (!mmc_blk_partitions)		goto alloc_partition_error_exit;	memset(mmc_blk_partitions, 0, (nb_dev << DEVICE_SHIFT) 			* sizeof(struct hd_struct));		    	/* device settings (partition later) */	for (device_num = 0; device_num < nb_dev; device_num++)	{		mmc_blk_partitions[device_num << DEVICE_SHIFT].nr_sects =			mmc_blk_size[device_num << DEVICE_SHIFT] 			* mmc_blk_blocksizes[device_num << DEVICE_SHIFT] 			/ mmc_blk_sectorsizes[device_num << DEVICE_SHIFT];	}	mmc_blk_gendisk.part = mmc_blk_partitions;	mmc_blk_gendisk.nr_real = nb_dev;	/* Put our gendisk structure on the list *///	add_gendisk (&mmc_blk_gendisk);	/* register the gentisk structure for older kernel */	mmc_blk_gendisk.next = gendisk_head;	gendisk_head = &mmc_blk_gendisk;	blk_queue_make_request (BLK_DEFAULT_QUEUE(mmc_blk_major), 			mmc_blk_make_request);	info("(device %d) check partition", device_num);	for (device_num = 0; device_num < nb_dev; device_num++)	{		register_disk (&mmc_blk_gendisk, 			MKDEV(mmc_blk_major, (device_num << DEVICE_SHIFT)), 			DEVICE_SHIFT, &mmc_blk_ops, 			mmc_blk_partitions[device_num << DEVICE_SHIFT].nr_sects);  	}	info("%s - MMC is now ready to use", __FUNCTION__);			return (0);alloc_partition_error_exit :	kfree (mmc_blk_dev);	alloc_dev_error_exit :	unregister_blkdev (mmc_blk_major, DEVICE_NAME);	return (retval);}void __exit mmc_blk_exit(void){	int device_num;	struct gendisk **gdp;	for (device_num = 0; device_num < nb_dev; device_num++)	{		fsync_dev (MKDEV(mmc_blk_major, device_num));	}	kfree (mmc_blk_dev);	kfree (mmc_blk_partitions);	unregister_blkdev (mmc_blk_major, DEVICE_NAME);	/* clean global array */	blk_size[mmc_blk_major] = NULL;	blksize_size[mmc_blk_major] = NULL;	hardsect_size[mmc_blk_major] = NULL;	read_ahead[mmc_blk_major] = 0;	/* Get our gendisk structure off the list */	//del_gendisk (&mmc_blk_gendisk);	    	/* unregister the gentisk structure for older kernel */	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))	{		if (*gdp == &mmc_blk_gendisk) 		{			*gdp = (*gdp)->next;			break;		}	}	if (release_mmc () < 0)		err("unable to release MMC");	info("MMC support disabled");	return;}module_init (mmc_blk_init);module_exit (mmc_blk_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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