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

📄 tffs2lnx.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 4 页
字号:
        if (copy_to_user(tmp, &output, sizeof(output)))                           \            return -EFAULT;                                                       \        return 0;                                                                 \    }#define USR2KRN01(theHandle,typeOut,pSoc)                  \    USR2KRN_O_START(typeOut)                               \    ioreq.irHandle = theHandle;                            \    flIOctl(&ioreq);                                       \    USR2KRN_END#define USR2KRN11(theHandle,typeIn,typeOut,pSoc)           \    USR2KRN_IO_START(typeIn,typeOut)                       \    ioreq.irHandle = theHandle;                            \    flIOctl(&ioreq);                                       \    USR2KRN_END/* returns: 0 - OK, 1 - no TFFS ioctl, <0 - error */int TffsIoctl(DeviceInfo*pDevice,int cmd,unsigned long arg){#ifdef FL_IOCTL_INTERFACE	unsigned char bdtlVolume=pDevice->bHandle;	IOreq ioreq;	flIOctlRecord ioctlRecord;    static unsigned int handle_for_ioctls = 0xffff;    if ((cmd < FL_IOCTL_LNX) || (cmd > FL_IOCTL_IPL_HW_PROTECTION))        { PrintkError ("unknown IOCTL code %d passed to TrueFFS", cmd);  return 1; }	/* map flIOctlRecord */	if(!access_ok(VERIFY_WRITE|VERIFY_READ,(void*)arg,sizeof(flIOctlRecord)))		return -EFAULT;	if(copy_from_user(&ioctlRecord,(void*)arg,sizeof(flIOctlRecord)))		return -EFAULT;	ioreq.irData=&ioctlRecord;	ioreq.irFlags=cmd;	switch(cmd)	{	case FL_IOCTL_GET_INFO:		{			struct hd_geometry geometry;			USR2KRN_O_START(flDiskInfoOutput);                        ioreq.irHandle = bdtlVolume;                        flIOctl(&ioreq);			geometry.heads     = pDevice->bHead;			geometry.sectors   = pDevice->bSect;			geometry.cylinders = pDevice->wCyl;			((flDiskInfoOutput*)(ioctlRecord.outputRecord))->info.cylinders=geometry.cylinders;			((flDiskInfoOutput*)(ioctlRecord.outputRecord))->info.heads=geometry.heads;			((flDiskInfoOutput*)(ioctlRecord.outputRecord))->info.sectors=geometry.sectors;			USR2KRN_END;		}	case FL_IOCTL_DEFRAGMENT:		USR2KRN11(bdtlVolume,flDefragInput,flDefragOutput,pSoc);	case FL_IOCTL_MOUNT_VOLUME:		USR2KRN11(bdtlVolume,flMountInput,flOutputStatusRecord,pSoc);#ifdef BDK_ACCESS	case FL_IOCTL_BDK_OPERATION:	{		void*tmp1=NULL,*tmpIn=NULL;		flBDKOperationInput input;		flOutputStatusRecord output;		void*tmp;				if(!access_ok(VERIFY_READ|VERIFY_WRITE,ioctlRecord.inputRecord,sizeof(flBDKOperationInput)))		{			PrintkDebug("FL_IOCTL_BDK_OPERATION:access_ok(inputRecord)");			return -EFAULT;		}		if(copy_from_user(&input,ioctlRecord.inputRecord,sizeof(flBDKOperationInput)))		{			PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_from_user(inputRecord)");			return -EFAULT;		}		if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputStatusRecord)))		{			PrintkDebug("FL_IOCTL_BDK_OPERATION:access_ok(outputRecord)");			return -EFAULT;		}		tmp=ioctlRecord.outputRecord;		tmpIn=ioctlRecord.inputRecord;		ioctlRecord.inputRecord=&input;		ioctlRecord.outputRecord=&output;				if(input.bdkStruct.bdkBuffer!=NULL)		{			tmp1=input.bdkStruct.bdkBuffer;			input.bdkStruct.bdkBuffer=VMalloc(input.bdkStruct.length);			if(input.bdkStruct.bdkBuffer==NULL)			{				PrintkDebug("FL_IOCTL_BDK_OPERATION:vmalloc");				return -ENOMEM;			}			if(!access_ok(VERIFY_WRITE|VERIFY_READ,tmp1,input.bdkStruct.length))			{				vfree(input.bdkStruct.bdkBuffer);				PrintkDebug("FL_IOCTL_BDK_OPERATION:access_ok");				return -EFAULT;			}			if(copy_from_user(input.bdkStruct.bdkBuffer,tmp1,input.bdkStruct.length))			{				vfree(input.bdkStruct.bdkBuffer);				PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_from_user");				return -EFAULT;			}		}                ioreq.irHandle = handle_for_ioctls;                flIOctl(&ioreq);		if(input.bdkStruct.bdkBuffer!=NULL)		{			if(copy_to_user(tmp1,input.bdkStruct.bdkBuffer,input.bdkStruct.length))			{				PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_to_user(bdkBuffer)");				vfree(input.bdkStruct.bdkBuffer);				return -EFAULT;			}			vfree(input.bdkStruct.bdkBuffer);		}		/* copy flBDKOperationInput */		input.bdkStruct.bdkBuffer=tmp1;		if(copy_to_user(tmpIn,&input,sizeof(flBDKOperationInput)))		{			if(input.bdkStruct.bdkBuffer!=NULL)				vfree(input.bdkStruct.bdkBuffer);				PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_to_user(inputRecord)");			return -EFAULT;		}		if(copy_to_user(tmp,&output,sizeof(output)))			return -EFAULT;		return 0;	}#endif /* BDK_ACCESS */	case FL_IOCTL_DELETE_SECTORS:	case FL_IOCTL_READ_SECTORS:	case FL_IOCTL_WRITE_SECTORS:		return -EINVAL;	case FL_IOCTL_BDTL_HW_PROTECTION:	case FL_IOCTL_IPL_HW_PROTECTION:#ifdef BDK_ACCESS	case FL_IOCTL_BINARY_HW_PROTECTION:#endif#ifdef HW_PROTECTION        {   flProtectionInput  my_prot_in,  *usr_prot_in  = (flProtectionInput  *)ioctlRecord.inputRecord;            flProtectionOutput my_prot_out, *usr_prot_out = (flProtectionOutput *)ioctlRecord.outputRecord;	            if( !access_ok((VERIFY_WRITE | VERIFY_READ), usr_prot_in, sizeof(flProtectionInput)) )               return -EFAULT;            if( !access_ok(VERIFY_WRITE, usr_prot_out, sizeof(flProtectionOutput)))                return -EFAULT;            if( copy_from_user(&my_prot_in, usr_prot_in, sizeof(flProtectionInput)) )                return -EFAULT;            ioctlRecord.inputRecord  = &my_prot_in;            ioctlRecord.outputRecord = &my_prot_out;# ifdef BDK_ACCESS            if (cmd == FL_IOCTL_BINARY_HW_PROTECTION)                ioreq.irHandle = handle_for_ioctls;            else# endif                ioreq.irHandle = ((handle_for_ioctls != 0xffff) ? handle_for_ioctls : bdtlVolume);            flIOctl (&ioreq);            if( copy_to_user(usr_prot_in,  &my_prot_in, sizeof(flProtectionInput)) )                return -EFAULT;            if( copy_to_user(usr_prot_out, &my_prot_out,sizeof(flProtectionOutput)) )                return -EFAULT;            return 0;        }#else /* !HW_PROTECTION */        return -EINVAL;#endif	case FL_IOCTL_OTP:#ifdef HW_OTP	{		void*tmp1;		USR2KRN_IO_START(flOtpInput,flOutputStatusRecord);		tmp1=input.buffer;		input.buffer=KMalloc(input.length);		if(input.buffer==NULL)			return -ENOMEM;		if(!access_ok(VERIFY_WRITE|VERIFY_READ,tmp1,input.length))		{			kfree(input.buffer);			return -EFAULT;		}		if(copy_from_user(input.buffer,tmp1,input.length))		{			kfree(input.buffer);			return -EFAULT;		}                ioreq.irHandle = (bdtlVolume & 0x0f);                flIOctl(&ioreq);		if(copy_to_user(tmp1,input.buffer,input.length))		{			kfree(input.buffer);			return -EFAULT;		}		kfree(input.buffer);		USR2KRN_END;	}#else	/* HW_OTP */		return -EINVAL;#endif	/* HW_OTP */	case FL_IOCTL_CUSTOMER_ID:#ifdef HW_OTP		USR2KRN01(bdtlVolume&0x0f,flCustomerIdOutput,pSoc);#else	/* HW_OTP */		return -EINVAL;#endif	case FL_IOCTL_UNIQUE_ID:#ifdef HW_OTP		USR2KRN01(bdtlVolume&0x0f,flUniqueIdOutput,pSoc);#else	/* HW_OTP */		return -EINVAL;#endif	case FL_IOCTL_NUMBER_OF_PARTITIONS:		USR2KRN01(bdtlVolume&0x0f,flCountPartitionsOutput,pSoc);	case FL_IOCTL_WRITE_IPL:#ifndef NO_IPL_CODE	{		flIPLInput iplInput;		flOutputStatusRecord outputStatusRecord;		void*outputStatusRecordSave,*bBufPtrSave;		if(!access_ok(VERIFY_READ,ioctlRecord.inputRecord,sizeof(flIPLInput)))			return -EFAULT;		if(copy_from_user(&iplInput,ioctlRecord.inputRecord,sizeof(flIPLInput)))			return -EFAULT;		if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputStatusRecord)))			return -EFAULT;		outputStatusRecordSave=ioctlRecord.outputRecord;		ioctlRecord.inputRecord=&iplInput;		ioctlRecord.outputRecord=&outputStatusRecord;				bBufPtrSave=iplInput.bBufPtr;		iplInput.bBufPtr=KMalloc(iplInput.sdwLength);		if(iplInput.bBufPtr==NULL)			return -ENOMEM;		if(!access_ok(VERIFY_READ,bBufPtrSave,iplInput.sdwLength))		{			kfree(iplInput.bBufPtr);			return -EFAULT;		}		if(copy_from_user(iplInput.bBufPtr,bBufPtrSave,iplInput.sdwLength))		{			kfree(iplInput.bBufPtr);			return -EFAULT;		}		ioreq.irHandle=bdtlVolume&0x0f;		flIOctl (&ioreq);		kfree(iplInput.bBufPtr);		if(copy_to_user(outputStatusRecordSave,&outputStatusRecord,sizeof(flOutputStatusRecord)))			return -EFAULT;		return 0;	}#else /* NO_IPL_CODE */		return -EINVAL;#endif /* NO_IPL_CODE */	case FL_IOCTL_DEEP_POWER_DOWN_MODE:		USR2KRN11(bdtlVolume&0x0f,flPowerDownInput,flOutputStatusRecord,pSoc);	case FL_IOCTL_EXTENDED_ENVIRONMENT_VARIABLES:#ifdef FL_ENVIRONMENT_VARS		USR2KRN11(bdtlVolume,flExtendedEnvVarsInput,flExtendedEnvVarsOutput,pSoc);#else		return -EINVAL;#endif /* FL_ENVIRONMENT_VARS */	case FL_IOCTL_VERIFY_VOLUME:#ifdef VERIFY_VOLUME		USR2KRN11(bdtlVolume,flVerifyVolumeInput,flVerifyVolumeOutput,pSoc);#endif	case FL_IOCTL_SET_ACCESS_ROUTINE:		return -EINVAL;	case FL_IOCTL_GET_ACCESS_ROUTINE:		return -EINVAL;	case FL_IOCTL_IS_QUICK_MOUNT_VALID:# ifndef FL_NO_QUICK_MOUNT_FEATURE		USR2KRN01(bdtlVolume,flGetQuickMountOutput,pSoc);# else		return -EINVAL;# endif /* FL_NO_QUICK_MOUNT_FEATURE */	case FL_IOCTL_WRITE_QUICK_MOUNT_INFO:# ifndef FL_NO_QUICK_MOUNT_FEATURE		USR2KRN01(bdtlVolume,flOutputStatusRecord,pSoc);# else		return -EINVAL;# endif /* FL_NO_QUICK_MOUNT_FEATURE */	case FL_IOCTL_CLEAR_QUICK_MOUNT_INFO:# ifndef FL_NO_QUICK_MOUNT_FEATURE		USR2KRN01(bdtlVolume,flOutputStatusRecord,pSoc);# else		return -EINVAL;# endif /* FL_NO_QUICK_MOUNT_FEATURE */	case FL_IOCTL_FLASH_FORMAT:# ifndef FL_FORMAT_VOLUME            return -EINVAL;# else	{   FormatParams3                 formatParams3;            BDTLPartitionFormatParams3    bdtl_fp [FL_VOLUMES];#  ifdef BDK_ACCESS            BinaryPartitionFormatParams3  bin_fp [FL_BINARY_PARTITIONS];#  endif            flFlashFormatInput            flashFormatInput;            flOutputStatusRecord          outputStatusRecord;            void                        * user_outputStatusRecord;            int                           bdtls; /* BDTL partitions to create */            int                           bins;  /* binary partitions to create */            PrintkDebug("TffsIoctl:FL_IOCTL_FLASH_FORMAT");            if( !access_ok(VERIFY_WRITE, ioctlRecord.outputRecord, sizeof(flOutputStatusRecord)) )                return -EFAULT;            user_outputStatusRecord = ioctlRecord.outputRecord;            ioctlRecord.outputRecord = &outputStatusRecord;            if( !access_ok(VERIFY_READ, ioctlRecord.inputRecord, sizeof(flFlashFormatInput)) )                return -EFAULT;            if( copy_from_user(&flashFormatInput, ioctlRecord.inputRecord, sizeof(flFlashFormatInput)) )                return -EFAULT;            ioctlRecord.inputRecord  = &flashFormatInput;            if( !access_ok(VERIFY_READ, flashFormatInput.fpPtr, sizeof(FormatParams3)) )                return -EFAULT;            if( copy_from_user(&formatParams3, flashFormatInput.fpPtr, sizeof(FormatParams3)) )                return -EFAULT;            /* BDTL partitions layout */            bdtls = flashFormatInput.fpPtr->noOfBDTLPartitions;            if (bdtls > FL_VOLUMES)                return -EINVAL;            if( !access_ok(VERIFY_READ, flashFormatInput.fpPtr->BDTLPartitionInfo,                                        (sizeof(BDTLPartitionFormatParams3) * bdtls)) )                return -EFAULT;            if( copy_from_user(bdtl_fp, flashFormatInput.fpPtr->BDTLPartitionInfo,                                        (sizeof(BDTLPartitionFormatParams3) * bdtls)) )                return -EFAULT;            flashFormatInput.fpPtr->BDTLPartitionInfo = bdtl_fp;            /* binary partitions layout */            bins = flashFormatInput.fpPtr->noOfBinaryPartitions;            if (bins > 0)            {#  ifdef BDK_ACCESS                if( !access_ok(VERIFY_READ, flashFormatInput.fpPtr->binaryPartitionInfo,                                        (sizeof(BinaryPartitionFormatParams3) * bins)) )                    return -EFAULT;                if( copy_from_user(bin_fp, flashFormatInput.fpPtr->binaryPartitionInfo,                                        (sizeof(BinaryPartitionFormatParams3) * bins)) )                    return -EFAULT;

⌨️ 快捷键说明

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