📄 tffs2lnx.c
字号:
/* check that is Tffs ioctl */ PrintkDebug("TffsIoctl: handle 0x%x, cmd 0x%x",pDevice->handle,cmd); if(cmd<FL_IOCTL_LNX || cmd>TFFS_LAST_IOCTL) { PrintkDebug("TffsIoctl: no Tffs ioctl"); 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: USR2KRN01(bdtlVolume,flDiskInfoOutput);#ifdef DEFRAGMENT_VOLUME case FL_IOCTL_DEFRAGMENT: USR2KRN11(bdtlVolume,flDefragInput,flDefragOutput);#endif case FL_IOCTL_WRITE_PROTECT: USR2KRN11(bdtlVolume,flWriteProtectInput,flOutputStatusRecord); case FL_IOCTL_MOUNT_VOLUME: USR2KRN11(bdtlVolume,flMountInput,flOutputStatusRecord);#ifdef FORMAT_VOLUME case FL_IOCTL_FORMAT_VOLUME: USR2KRN_IO_START(flFormatInput,flOutputStatusRecord); /* set to NULL not mapped pointers */ ((flFormatPhysicalInput*)ioctlRecord.inputRecord)->fp.progressCallback=NULL; ((flFormatPhysicalInput*)ioctlRecord.inputRecord)->fp.embeddedCIS=NULL; ((flFormatPhysicalInput*)ioctlRecord.inputRecord)->fp.embeddedCISlength=0; USR2KRN_IOCTL(bdtlVolume); USR2KRN_END;#endif case FL_IOCTL_BDK_OPERATION: { void*tmp1=NULL; USR2KRN_IO_START(flBDKOperationInput,flOutputStatusRecord); 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; } } USR2KRN_IOCTL(bdkVolume); if(input.bdkStruct.bdkBuffer!=NULL) { if(copy_to_user(tmp1,input.bdkStruct.bdkBuffer,input.bdkStruct.length)) { vfree(input.bdkStruct.bdkBuffer); return -EFAULT; } vfree(input.bdkStruct.bdkBuffer); } USR2KRN_END; } case FL_IOCTL_DELETE_SECTORS: USR2KRN11(bdtlVolume,flDeleteSectorsInput,flOutputStatusRecord); case FL_IOCTL_READ_SECTORS: { void*tmp1; USR2KRN_IO_START(flReadWriteInput,flReadWriteOutput); tmp1=input.buf; input.buf=vmalloc(input.numberOfSectors*512); if(input.buf==NULL) { PrintkDebug("TffsIoctl:FL_IOCTL_READ_SECTORS:kmalloc"); return -ENOMEM; } USR2KRN_IOCTL(bdtlVolume); if(copy_to_user(tmp1,input.buf,input.numberOfSectors*512)) { PrintkDebug("TffsIoctl:FL_IOCTL_READ_SECTORS:copy_to_user"); vfree(input.buf); return -EFAULT; } vfree(input.buf); USR2KRN_END; } case FL_IOCTL_WRITE_SECTORS: { void*tmp1; USR2KRN_IO_START(flReadWriteInput,flReadWriteOutput); tmp1=input.buf; input.buf=vmalloc(input.numberOfSectors*512); if(input.buf==NULL) return -ENOMEM; if(copy_from_user(input.buf,tmp1,input.numberOfSectors*512)) { vfree(input.buf); return -EFAULT; } USR2KRN_IOCTL(bdtlVolume); vfree(input.buf); USR2KRN_END; }#ifdef FORMAT_VOLUME case FL_IOCTL_FORMAT_PHYSICAL_DRIVE: {#ifdef WRITE_EXB_IMAGE void*tmp1;#endif BDTLPartitionFormatParams bdtlPartitionFormatParams[4]; BinaryPartitionFormatParams binaryPartitionFormatParams[BINARY_PARTITIONS]; PrintkDebug("TffsIoctl:FL_IOCTL_FORMAT_PHYSICAL_DRIVE"); USR2KRN_IO_START(flFormatPhysicalInput,flOutputStatusRecord); PrintkDebug("%d %d",input.fp.noOfBinaryPartitions,input.fp.noOfBDTLPartitions); if(!access_ok(VERIFY_READ,input.fp.BDTLPartitionInfo,sizeof(BDTLPartitionFormatParams)*input.fp.noOfBDTLPartitions)) { PrintkDebug("TffsIoctl:FL_IOCTL_FORMAT_PHYSICAL_DRIVE:access_ok"); return -EFAULT; } if(copy_from_user(bdtlPartitionFormatParams,input.fp.BDTLPartitionInfo,sizeof(BDTLPartitionFormatParams)*input.fp.noOfBDTLPartitions)) { PrintkDebug("TffsIoctl:FL_IOCTL_FORMAT_PHYSICAL_DRIVE:copy_from_user"); return -EFAULT; } input.fp.BDTLPartitionInfo=bdtlPartitionFormatParams; PrintkDebug("%ld",bdtlPartitionFormatParams[0].length); if(input.fp.noOfBinaryPartitions!=0) { if(!access_ok(VERIFY_READ,input.fp.binaryPartitionInfo,sizeof(BinaryPartitionFormatParams)*input.fp.noOfBDTLPartitions)) { PrintkDebug("TffsIoctl:FL_IOCTL_FORMAT_PHYSICAL_DRIVE:access_ok"); return -EFAULT; } if(copy_from_user(binaryPartitionFormatParams,input.fp.binaryPartitionInfo,sizeof(BinaryPartitionFormatParams)*input.fp.noOfBinaryPartitions)) { PrintkDebug("TffsIoctl:FL_IOCTL_FORMAT_PHYSICAL_DRIVE:copy_from_user"); return -EFAULT; } input.fp.binaryPartitionInfo=binaryPartitionFormatParams; }#ifdef WRITE_EXB_IMAGE if(!access_ok(VERIFY_READ,input.fp.exbBuffer,input.fp.exbBufferLen)) { PrintkDebug("TffsIoctl:FL_IOCTL_FORMAT_PHYSICAL_DRIVE:access_ok"); return -EFAULT; } tmp1=kmalloc(input.fp.exbBufferLen,GFP_KERNEL); if(tmp1==NULL) return -ENOMEM; if(copy_from_user(tmp1,input.fp.exbBuffer,input.fp.exbBufferLen)) { kfree(tmp1); return -EFAULT; } input.fp.exbBuffer=tmp1;#endif /* set to NULL not mapped pointers */ ((flFormatPhysicalInput*)ioctlRecord.inputRecord)->fp.progressCallback=NULL; ((flFormatPhysicalInput*)ioctlRecord.inputRecord)->fp.embeddedCIS=NULL; ((flFormatPhysicalInput*)ioctlRecord.inputRecord)->fp.embeddedCISlength=0; USR2KRN_IOCTL(bdtlVolume&0x0f);#ifdef WRITE_EXB_IMAGE kfree(tmp1);#endif USR2KRN_END; }#endif /* FORMAT_VOLUME */#ifdef FORMAT_VOLUME case FL_IOCTL_FORMAT_LOGICAL_DRIVE: USR2KRN11(bdtlVolume,flFormatLogicalInput,flOutputStatusRecord);#endif#ifdef HW_PROTECTION case FL_IOCTL_BDTL_HW_PROTECTION: PrintkDebug("TffsIoctl FL_IOCTL_BDTL_HW_PROTECTION"); USR2KRN11(bdtlVolume,flProtectionInput,flProtectionOutput);#endif#ifdef HW_PROTECTION case FL_IOCTL_BINARY_HW_PROTECTION: USR2KRN11(bdkVolume,flProtectionInput,flProtectionOutput);#endif#ifdef HW_OTP case FL_IOCTL_OTP: { void*tmp1; USR2KRN_IO_START(flOtpInput,flOutputStatusRecord); tmp1=input.buffer; input.buffer=kmalloc(input.length,GFP_KERNEL); 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; } USR2KRN_IOCTL(bdtlVolume&0x0f); 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 */#ifdef HW_OTP case FL_IOCTL_CUSTOMER_ID: USR2KRN01(bdtlVolume&0x0f,flCustomerIdOutput);#endif#ifdef HW_OTP case FL_IOCTL_UNIQUE_ID: USR2KRN01(bdtlVolume&0x0f,flUniqueIdOutput);#endif case FL_IOCTL_NUMBER_OF_PARTITIONS: USR2KRN01(bdtlVolume&0x0f,flCountPartitionsOutput); case FL_IOCTL_INQUIRE_CAPABILITIES: USR2KRN11(0,flCapabilityInput,flCapabilityOutput); case FL_IOCTL_SET_ENVIRONMENT_VARIABLES:#if (TFFS_SVER >= 60000) return -EINVAL;#else /* TODO */#endif case FL_IOCTL_PLACE_EXB_BY_BUFFER:#ifdef WRITE_EXB_IMAGE { void*tmp1; USR2KRN_IO_START(flPlaceExbInput,flOutputStatusRecord); tmp1=input.buf; input.buf=vmalloc(input.bufLen); if(input.buf==NULL) return -ENOMEM; if(!access_ok(VERIFY_READ,tmp1,input.bufLen)) { kfree(input.buf); return -EFAULT; } if(copy_from_user(input.buf,tmp1,input.bufLen)) { kfree(input.buf); return -EFAULT; } USR2KRN_IOCTL(bdtlVolume&0x0f); vfree(input.buf); USR2KRN_END; }#endif case FL_IOCTL_WRITE_IPL:#if (TFFS_SVER >= 60000) return -EINVAL;#else /* TODO */ break;#endif case FL_IOCTL_DEEP_POWER_DOWN_MODE: USR2KRN11(bdtlVolume&0x0f,flPowerDownInput,flOutputStatusRecord);#ifdef ENVIRONMENT_VARS case FL_IOCTL_EXTENDED_ENVIRONMENT_VARIABLES: USR2KRN11(bdtlVolume,flExtendedEnvVarsInput,flExtendedEnvVarsOutput);#endif /* ENVIRONMENT_VARS */ case FL_IOCTL_VERIFY_VOLUME:#ifdef VERIFY_VOLUME USR2KRN11(bdtlVolume,flVerifyVolumeInput,flVerifyVolumeOutput);#endif case FL_IOCTL_SET_ACCESS_ROUTINE: return -EINVAL; case FL_IOCTL_GET_ACCESS_ROUTINE: return -EINVAL; case FL_IOCTL_EXTENDED_WRITE_IPL: { void*tmp1; USR2KRN_IO_START(flIplInput,flOutputStatusRecord); tmp1=input.buf; input.buf=kmalloc(input.bufLen,GFP_KERNEL); if(input.buf==NULL) return -ENOMEM; if(!access_ok(VERIFY_READ,tmp1,input.bufLen)) { kfree(input.buf); return -EFAULT; } if(copy_from_user(input.buf,tmp1,input.bufLen)) { kfree(input.buf); return -EFAULT; } USR2KRN_IOCTL(bdtlVolume&0x0f); kfree(input.buf); USR2KRN_END; }#if (TFFS_SVER >= 61000)#ifdef RUGGEDIZED case FL_IOCTL_OPEN_TRANSACTION: USR2KRN11(bdtlVolume,flRuggedizeInput,flRuggedizeOutput);#endif#ifdef RUGGEDIZED case FL_IOCTL_COMMIT_TRANSACTION: USR2KRN11(bdtlVolume,flRuggedizeInput,flRuggedizeOutput);#endif#ifdef RUGGEDIZED case FL_IOCTL_IS_VOLUME_RUGGEDIZED: return 0;#endif case FL_IOCTL_IS_QUICK_MOUNT_VALID: USR2KRN01(bdtlVolume,flGetQuickMountOutput); case FL_IOCTL_WRITE_QUICK_MOUNT_INFO: USR2KRN01(bdtlVolume,flOutputStatusRecord); case FL_IOCTL_CLEAR_QUICK_MOUNT_INFO: USR2KRN01(bdtlVolume,flOutputStatusRecord); case FL_IOCTL_COMPLETE_OPERATION: USR2KRN01(bdtlVolume,flOutputStatusRecord);#endif /* (TFFS_SVER >= 610) */ case FL_IOCTL_LNX: { flInputLnxRecord inRec; flOutputLnxRecord outRec; PrintkDebug("TffsIoctl FL_IOCTL_LNX"); if(!access_ok(VERIFY_READ,ioctlRecord.inputRecord,sizeof(flInputLnxRecord))) return -EFAULT; if(copy_from_user(&inRec,ioctlRecord.inputRecord,sizeof(flInputLnxRecord))) return -EFAULT; if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputLnxRecord))) return -EFAULT; switch(inRec.command) { case 0: /* set BKD volume */ bdkVolume=inRec.data; PrintkDebug("TffsIoctl FL_IOCTL_LNX: BDK volume number set to %x",bdkVolume); outRec.status=flOK; if(copy_to_user(ioctlRecord.outputRecord,&outRec,sizeof(flOutputLnxRecord))) return -EFAULT; return 0;#ifdef DRIVER_STATISTIC case 1: /* reset statistic */ PrintkDebug("TffsIoctl FL_IOCTL_LNX:reset"); dwReadCount=0; dwWriteCount=0; outRec.status=flOK; if(copy_to_user(ioctlRecord.outputRecord,&outRec,sizeof(flOutputLnxRecord))) return -EFAULT; return 0; case 2: /* print statistic */ PrintkInfo("Sectors readed %ld, written %ld",dwReadCount,dwWriteCount); outRec.status=flOK; if(copy_to_user(ioctlRecord.outputRecord,&outRec,sizeof(flOutputLnxRecord))) return -EFAULT; return 0;#endif /* DRIVER_STATISTIC */ default: outRec.status=flBadParameter; if(copy_to_user(&outRec,ioctlRecord.outputRecord,sizeof(flOutputLnxRecord))) return -EFAULT; return -EINVAL; } } default: PrintkDebug("TffsIoctl: no Tffs ioctl"); return -EINVAL; } /* do not check error code - it sended by outRec->status */ TffsPowerUp(pDevice->pSocket); flIOctl(&ioreq); TffsPowerDown(pDevice->pSocket); return 0;}#endif /* #ifdef IOCTL_INTERFACE */void TffsGetDriveGeometry(unsigned long dwSectorsPerDevice,unsigned long dwMaxCylinders,unsigned char*pHeads,unsigned char*pSectors,unsigned int*pCylinders){ /* Limitations for old BIOS: no. of heads per cyl: 8 bits no. of cylinders: 10 bits no. of sectors per cyl: 6 bits */ /* by Amir Ban */ unsigned long temp; *pCylinders = dwMaxCylinders; *pHeads = 16; temp = *pCylinders * (*pHeads); *pSectors = dwSectorsPerDevice / temp; if (dwSectorsPerDevice % temp) { (*pSectors)++; temp = *pCylinders * (*pSectors); *pHeads = dwSectorsPerDevice / temp; if (dwSectorsPerDevice % temp) { (*pHeads)++; temp = *pHeads * (*pSectors); *pCylinders = (unsigned long) (dwSectorsPerDevice / temp); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -