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

📄 tffsdrv2.c

📁 Linux下msys公司提供的doc2000的驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "flcustom.h"#include "tffsdrv.h"#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))#include "tffs2lnx.h"#include "extfiltr.h"#define SHUTDOWN_SIGS		(sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGQUIT)) /* 9|2|15|3 == 15 */#include <linux/config.h>			/* CONFIG_DEVFS_FS */#include <asm/io.h>					/* isa_write...() */#include <linux/ioport.h>			/* request_mem_reqion() */#include <linux/delay.h>			/* udelay() */#include <linux/init.h>				/* __initdata */#include <linux/sched.h>#include <linux/kernel.h>			/* printk() */#include <linux/slab.h>				/* kmalloc() */#include <linux/vmalloc.h>#include <linux/fs.h>				/* everything... */#include <linux/errno.h>			/* error codes */#include <linux/timer.h>#include <linux/fcntl.h>			/* O_ACCMODE */#include <linux/hdreg.h>			/* HDIO_GETGEO */#include <linux/devfs_fs_kernel.h>	/* devfs_handle_t */#include <linux/smp_lock.h>			/* lock_kernel() */#include <asm/system.h>				/* cli(), *_flags */#include <asm/uaccess.h>			/* verify_area() */#ifdef CONFIG_SMP#include <asm/spinlock.h>#endif/* definitions for blk.h */#include <linux/major.h>int majorReal;	/* our major device number */#define MAJOR_NR			majorReal#define DEVICE_ON#define DEVICE_OFF(d)		#define DEVICE_NR(device)	(MINOR(device)>>DEV2PART_SHIFT)#define DEVICE_NO_RANDOM#include <linux/blk.h>#include <linux/blkpg.h>	/* blk_ioctl() *//* end of blk.h definitions *//* module parameters */#ifdef MODULEMODULE_AUTHOR("yurid@msys.com");MODULE_DESCRIPTION("TrueFFS driver");#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)MODULE_LICENSE("Proprietary");#endifMODULE_SUPPORTED_DEVICE(TFFS_SUPPORTED_DEVICE);#endifstatic int __initdata major=TFFS_MAJOR;#ifdef MODULEMODULE_PARM(major,"i");		/* set to zero to get dynamic major */MODULE_PARM_DESC(major, "Major device number to use.");#endifstatic int __initdata rahead=TFFS_RAHEAD_DEF;#ifdef MODULEMODULE_PARM(rahead,"i");MODULE_PARM_DESC(rahead, "Set readahead flag for driver.");#endifstatic int __initdata hardsect=TFFS_HARDSECT_DEF;#ifdef MODULEMODULE_PARM(hardsect,"i");MODULE_PARM_DESC(hardsect, "The size of the hardware sector for all devices, in bytes.");#endifstatic int __initdata blksize=0;#ifdef MODULEMODULE_PARM(blksize,"i");MODULE_PARM_DESC(blksize, "The size of the block for all devices, in bytes.");#endif#ifndef DO_NOT_YIELD_CPUstatic int __initdata prio=TFFS_PRIO_DEF;	/* max -20, min 19 */# ifdef MODULEMODULE_PARM(prio,"i");MODULE_PARM_DESC(prio,"Kernel thread priority.");# endif#endif#define GetSocket(pDev)	((SocketInfo*)(pDev)->pSocket)static int*fl_blksize_size=NULL;static int*fl_hardsect_size=NULL;static int*fl_blk_size=NULL;static struct hd_struct*hdStruct=NULL;static TheDiskInfo diskInfo;static unsigned char bSockets;static spinlock_t o_c_lock;/* function declarations */int tffs_init(void);void* __init ckmalloc(int size,int mode);void __init lkfree(void**ptr);int Open(struct inode*inode,struct file *filp);int Ioctl(struct inode*inode, struct file *filp, unsigned int cmd, unsigned long arg);int Revalidate(kdev_t i_rdev);int Release(struct inode*inode, struct file*filp);#ifndef DO_NOT_YIELD_CPUstatic int IoKernelThread(void*socket);#endifstatic void DeviceRequest(request_queue_t*q);static void TransferRequests(void);static int TransferRequest(DeviceInfo*pDevice,struct request*pRequest);static struct block_device_operations blockDeviceOper ={	open:				Open,	release:			Release,	ioctl:				Ioctl,	check_media_change:	NULL,	revalidate:			NULL,};static struct gendisk theGendisk ={	0,							/* major		Major number, assigned at runtime */	TFFS_DEVICE_NAME,				/* major_name	Major name */	DEV2PART_SHIFT,				/* minor_shift	Bits to shift to get real from partition */	1<<DEV2PART_SHIFT,			/* max_p		Number of partitions per real */	NULL,						/* hd struct */	NULL,						/* block sizes */	0,							/* nr_real		maximum number of real, assigned at runtime */	NULL,						/* internal */	NULL,						/* next         linked list (not used for modules) */	&blockDeviceOper,	NULL,	NULL};#ifdef MODULE# define tffs_init init_module#endif/* Initialize the driver, register major and link into gendisk_list. */int tffs_init(void){	int result;	unsigned int socket,device,partition;	DeviceInfo*pDevice;	PrintkInfo("TrueFFS driver %d.%d",TFFS_SVER/100,TFFS_DRV_VER);	PrintkDebug("\"%s\" (pid %i)",current->comm,current->pid);	majorReal=major;		/* 100 by default */	/* Init TrueFFS */	TffsInit(&diskInfo);	if(diskInfo.noOfDevices==0)	{		PrintkError("Cannot find any TrueFFS devices");		goto fl_init_error;	}	theGendisk.nr_real=diskInfo.noOfDevices;	ExtFilterInit(&diskInfo);	PrintkDebug("tffs_init: TffsInit OK");	PrintkInfo("%d device(s) found",diskInfo.noOfDevices);	bSockets=(diskInfo.pDevices[diskInfo.noOfDevices-1].handle&0xf)+1;	PrintkDebug("%d socket(s) found",bSockets);	/* partition array must be allocated here, setup_dev() accesses it before calling fl_genit() */	/* allocate per device dynamic structures, these are done here so we can release ckmalloc() */	if (!(fl_blksize_size=ckmalloc((theGendisk.nr_real<<DEV2PART_SHIFT) * sizeof(int),GFP_KERNEL)))	{		PrintkDebug("tffs_init: ckmalloc(fl_blksize_size) failed");		goto fail_malloc;	}	if(!(fl_hardsect_size=ckmalloc((theGendisk.nr_real<<DEV2PART_SHIFT) * sizeof(int),GFP_KERNEL)))	{		PrintkDebug("tffs_init: ckmalloc(fl_hardsect_size) failed");		goto fail_malloc;	}	if(!(fl_blk_size=ckmalloc((theGendisk.nr_real<<DEV2PART_SHIFT) * sizeof(int),GFP_KERNEL)))	{		PrintkDebug("tffs_init: ckmalloc(fl_blk_size) failed");		goto fail_malloc;	}	if(!(hdStruct=ckmalloc((theGendisk.nr_real<<DEV2PART_SHIFT)*sizeof(struct hd_struct),GFP_KERNEL)))	{		PrintkDebug("tffs_init: ckmalloc(hdStruct) failed");		goto fail_malloc;	}	spin_lock_init(&o_c_lock);	/* init sockets */	for(socket=0;socket<bSockets;socket++)	{		SocketInfo*pSocket=diskInfo.pSockets+socket;		if(!pSocket->threadInit)		{#ifndef DO_NOT_YIELD_CPU			spin_lock_init(&pSocket->ioLock);		/* init available */			spin_unlock(&pSocket->ioLock);			sema_init(&pSocket->threadSemaphore,0);		/* init down */			init_waitqueue_head(&pSocket->waitQueueHead);			pSocket->threadInit=1;			kernel_thread(IoKernelThread,(void*)pSocket,0);			down_interruptible(&pSocket->threadSemaphore);	/* wait to thread */			PrintkDebug("tffs_init: after kernel_thread");#endif		}	}	/* init devices */	for(device=0;device<theGendisk.nr_real;device++)	{		int hardSecSize,blockSize;		pDevice=diskInfo.pDevices+device;		if(hardsect)			hardSecSize=hardsect;		else			hardSecSize=pDevice->sectorSize;/*		if(hardSecSize<pDevice->sectorSize)			hardSecSize=pDevice->sectorSize; */		if(hardSecSize>PAGE_SIZE) /* sector can't be great then block */			hardSecSize=PAGE_SIZE;		if(blksize)		{			blockSize=blksize;			if(blockSize<hardSecSize)				hardSecSize=blockSize;		}		else		{			blockSize=pDevice->sectorSize;			if(blockSize<BLOCK_SIZE)	/* Set default value. It's better than 512 */				blockSize=BLOCK_SIZE;			if(blockSize<hardSecSize)				blockSize=hardSecSize;		}		if(blockSize>PAGE_SIZE)	/* kernel limit: blksize_size can't be more then PAGE_SIZE */			blockSize=PAGE_SIZE;		pDevice->usage=0;		fl_blk_size[device<<DEV2PART_SHIFT]=pDevice->size>>10;		for(partition=device<<DEV2PART_SHIFT;partition<((device+1)<<DEV2PART_SHIFT);partition++)		{			fl_blksize_size[partition]=blockSize;			fl_hardsect_size[partition]=hardSecSize;		}		hdStruct[device<<DEV2PART_SHIFT].nr_sects=diskInfo.pDevices[device].size>>9;	}	/* Register your major, and/or accept a dynamic number */	if((result=devfs_register_blkdev(majorReal,TFFS_DEVICE_NAME,&blockDeviceOper)) < 0)	{		PrintkError("Can't get major %d",majorReal);		goto fail_malloc;	}	/* save major if we are using a dynamic major */	if (majorReal==0)	{		majorReal=result;			/* dynamic */	}	PrintkInfo("Registered module at major %d",majorReal);	/* setup gendisk structure with partition information */	theGendisk.part=hdStruct;	theGendisk.major=majorReal;	theGendisk.sizes=fl_blk_size;	blk_size[majorReal]=fl_blk_size;	blksize_size[majorReal]=fl_blksize_size;	hardsect_size[majorReal]=fl_hardsect_size;	read_ahead[majorReal]=rahead;	/* register request method */	blk_init_queue(BLK_DEFAULT_QUEUE(majorReal),DeviceRequest);	PrintkDebug("tffs_init: init_queue OK");	/* link into global gendisk list */	add_gendisk(&theGendisk);	PrintkDebug("tffs_init: add_gendisk OK");	/* grab blk_size information and spit out some info */	for(device=0;device<theGendisk.nr_real;device++)	{		pDevice = diskInfo.pDevices+device;		/* call resetup/register_disk for each physical device */		if(pDevice->size#ifdef TFFS_ALLOW_UNFORMATTED			|| (pDevice->pSocket->fDummy && ((pDevice->handle&0xf0)==0))	/* allow 1 dummy device per socket */#endif			)		{			PrintkDebug("tffs_init: register_disk real %d, device %d, size 0x%lx",majorReal,device<<DEV2PART_SHIFT,hdStruct[device<<DEV2PART_SHIFT].nr_sects);			register_disk(&theGendisk,MKDEV(majorReal,device<<DEV2PART_SHIFT),theGendisk.max_p,theGendisk.fops,hdStruct[device<<DEV2PART_SHIFT].nr_sects);			PrintkDebug("tffs_init: register_disk OK");		}		PrintkInfo("Device 0x%x size 0x%lx hardsect_size 0x%x",(unsigned short)(device<<DEV2PART_SHIFT),diskInfo.pDevices[device].size,(unsigned short)fl_hardsect_size[device<<DEV2PART_SHIFT]);		for(partition=(int)(device<<DEV2PART_SHIFT)+1; partition < (int)((device+1)<<DEV2PART_SHIFT);partition++)		{			ExtFilterAddPartition(partition,theGendisk.part[partition].start_sect,theGendisk.part[partition].nr_sects);			fl_blk_size[partition] = ((long)(theGendisk.part[partition].nr_sects))>>1;			if(fl_blk_size[partition]>0)			{				PrintkInfo("    partition 0x%x size 0x%lx start offset 0x%lx",partition,(long)fl_blk_size[partition]*1024,theGendisk.part[partition].start_sect<<9);			}		}	}	PrintkDebug("tffs_init: returns 0");	return 0;fail_malloc:	PrintkDebug("tffs_init: fails");	/* Failed, free any memory that was allocated and set pointers to NULL */	read_ahead[majorReal]=0;	lkfree((void **)&fl_blksize_size);	lkfree((void **)&fl_hardsect_size);	lkfree((void **)&fl_blk_size);	lkfree((void **)&hdStruct);	blk_size[majorReal]=NULL;	blksize_size[majorReal]=NULL;	hardsect_size[majorReal]=NULL;	ExtFilterRelease();fl_init_error:	TffsCleanup(&diskInfo);	return 1;}#ifdef MODULEvoid cleanup_module(void){	unsigned char bSocket;	int minor;	PrintkDebug("cleanup_module");	/* first of all, flush it all and reset all the data structures */	for(minor=0;minor<(theGendisk.nr_real<<DEV2PART_SHIFT);minor++)	{		ExtFilterRemovePartition(minor);		fsync_dev(MKDEV(majorReal,minor));	/* flush the devices */	}	ExtFilterRelease();	for(bSocket=0;bSocket<bSockets;bSocket++)	{		if(diskInfo.pSockets[bSocket].threadInit)		{#ifndef DO_NOT_YIELD_CPU			wake_up(&diskInfo.pSockets[bSocket].waitQueueHead);			PrintkDebug("cleanup_module: queue waked, socket %d",bSocket);#endif			diskInfo.pSockets[bSocket].threadInit=0;#ifndef DO_NOT_YIELD_CPU			down_interruptible(&diskInfo.pSockets[bSocket].threadSemaphore); /* wait for last request end */			PrintkDebug("cleanup_module: semaphore down, socket %d",bSocket);#endif		}	}	PrintkDebug("cleanup_module: before TffsCleanup");	TffsCleanup(&diskInfo);	blk_cleanup_queue(BLK_DEFAULT_QUEUE(majorReal));	/* unregister our device */	devfs_unregister_blkdev(majorReal,TFFS_DEVICE_NAME);	del_gendisk(&theGendisk);	/* reset global blk array entries */	read_ahead[majorReal] = 0;	blk_size[majorReal] = NULL;	blksize_size[majorReal] = NULL;	hardsect_size[majorReal] = NULL;	/* free our data structures */	lkfree((void **)&fl_blk_size);	lkfree((void **)&fl_blksize_size);	lkfree((void **)&fl_hardsect_size);	lkfree((void **)&hdStruct);}#endif	/* MODULE */void* __init ckmalloc(int size, int mode){	void *ptr;	if ((ptr = kmalloc(size, mode)))		memset(ptr, 0, size);	return ptr;}void __init lkfree(void **ptr){

⌨️ 快捷键说明

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