📄 tffs2lnx.c
字号:
flashFormatInput.fpPtr->binaryPartitionInfo = bin_fp;# else return -EINVAL;# endif } /* set to NULL not mapped pointers */ flashFormatInput.fpPtr->progressCallback = NULL; flashFormatInput.fpPtr->embeddedCIS = NULL; flashFormatInput.fpPtr->embeddedCISlength = 0; ioreq.irHandle = (bdtlVolume & 0x0f); flIOctl (&ioreq); if( copy_to_user(user_outputStatusRecord, &outputStatusRecord, sizeof(outputStatusRecord))) return -EFAULT; return 0; }# endif /* FL_FORMAT_VOLUME */ case FL_IOCTL_ERASE_BD:# ifdef FL_FORMAT_VOLUME PrintkDebug("TffsIoctl:FL_IOCTL_ERASE_BD"); USR2KRN11(bdtlVolume,flEraseBDInput,flOutputStatusRecord,pSoc);# else /* FL_FORMAT_VOLUME */ return -EINVAL;# endif /* FL_FORMAT_VOLUME */ case FL_IOCTL_FLASH_UNFORMAT:# ifdef FL_FORMAT_VOLUME USR2KRN11(bdtlVolume,flFlashUnformatInput,flOutputStatusRecord,pSoc);# else /* FL_FORMAT_VOLUME */ return -EINVAL;# endif /* FL_FORMAT_VOLUME */#if defined(TFFS_USE_G4) && defined(HW_OTP) case FL_IOCTL_MCOTP: { flMCOtpInput mcotpInput; flOutputStatusRecord outputStatusRecord; void*outputStatusRecordSave,*bufferSave=NULL,*mcotpInputSave; if(!access_ok(VERIFY_READ|VERIFY_WRITE,ioctlRecord.inputRecord,sizeof(flMCOtpInput))) return -EFAULT; if(copy_from_user(&mcotpInput,ioctlRecord.inputRecord,sizeof(flMCOtpInput))) return -EFAULT; if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputStatusRecord))) return -EFAULT; outputStatusRecordSave=ioctlRecord.outputRecord; mcotpInputSave=ioctlRecord.inputRecord; ioctlRecord.inputRecord=&mcotpInput; ioctlRecord.outputRecord=&outputStatusRecord; if(mcotpInput.length!=0) { bufferSave=mcotpInput.buffer; mcotpInput.buffer=VMalloc(mcotpInput.length); if(mcotpInput.buffer==NULL) return -ENOMEM; if(!access_ok(VERIFY_READ|VERIFY_WRITE,mcotpInput.buffer,mcotpInput.length)) return -EFAULT; if(copy_from_user(mcotpInput.buffer,bufferSave,sizeof(mcotpInput.length))) return -EFAULT; } ioreq.irHandle = bdtlVolume&0x0f; flIOctl (&ioreq); if(mcotpInput.length!=0) { if(copy_to_user(bufferSave,mcotpInput.buffer,sizeof(mcotpInput.length))) return -EFAULT; vfree(mcotpInput.buffer); mcotpInput.buffer=bufferSave; } if(copy_to_user(mcotpInputSave,&mcotpInput,sizeof(flMCOtpInput))) return -EFAULT; if(copy_to_user(outputStatusRecordSave,&outputStatusRecord,sizeof(flMCOtpInput))) return -EFAULT; }#endif /* defined(TFFS_USE_G4) && defined(HW_OTP) */ case FL_IOCTL_LNX: { flInputLnxRecord inRec; flOutputLnxRecord outRec; 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 TrueFFS handle for future IOCTLs */ { handle_for_ioctls = inRec.data; outRec.status = flOK; if(copy_to_user(ioctlRecord.outputRecord, &outRec, sizeof(flOutputLnxRecord))) return -EFAULT; return 0; }#if defined(TFFS_DEBUG_DRIVER) && !defined(TFFS_RO) case 3: /* print no of used sectors on device */ { ioreq.irHandle=pDevice->bHandle; ioreq.irLength=0; outRec.status =flDefragmentVolume (&ioreq); outRec.data=ioreq.irLength; if(copy_to_user(ioctlRecord.outputRecord,&outRec,sizeof(flOutputLnxRecord))) return -EFAULT; return 0; }#endif /* TFFS_DEBUG_DRIVER */ case 5: /* ATA pass-through command */ return ata_passthrough (pDevice, &ioctlRecord, &inRec); } } default: PrintkDebug("TffsIoctl: no Tffs ioctl"); return -EINVAL; } /* do not check error code - it sended by outRec->status */ flIOctl (&ioreq); return 0;#else /* FL_IOCTL_INTERFACE */ return 1;#endif /* FL_IOCTL_INTERFACE */}/******************************************************************************* * * * T f f s E n a b l e I R Q * * * * This routine enables DiskOnChip interrupt generation upon completion of * * flash erase/write operation. Works with all types of DiskOnChip devices. * * * * Parameters: * * * * psoc socket pointer * * * * Returns: * * * * always zero (success) * * * *******************************************************************************/int TffsEnableIRQ (SocketInfo * psoc){ IOreq ioreq; ioreq.irHandle = psoc->bHandle; ioreq.irFlags = FL_IRQ_RB_TYPE; ioreq.irLength = (FL_INT_RB_ENABLED | /* FL_IRQ_EDGE_TYPE */ FL_IRQ_LEVEL_TYPE); flHwConfig (&ioreq); return 0;}/******************************************************************************* * * * T f f s S e t P I O * * * * If requested, this routine sets multi-sector polled I/O mode in DiskOnChip * * H3 devices. It has no effect on H1/G4/G3 DiskOnChip devices. * * * * Parameters: * * * * psoc socket pointer * * * * Returns: * * * * zero if success otherwise respective error code * * * *******************************************************************************/int TffsSetPIO (SocketInfo * psoc){ IOreq ioreq; DOCH_Error rc = DOCH_OK; if (tffs_pio > 0) /* multi-sector polled I/O mode requested */ { /* If we are going to use intermediate DMA buffer (which is one MMU page * in size), we must make sure that multi-sector PIO won't overrun it. */ if( (tffs_dma_mode > 0) && !(tffs_dma_mode & 0x4) && ((tffs_pio * FL_SECTOR_SIZE) > PAGE_SIZE) ) { PrintkError ("Multi-sector polled I/O overruns DMA buffer, disabled"); tffs_pio = 0; return -1; } /* Set multi-sector polled I/O mode to transfer up to * 'tffs_pio_mode' (but no more then 256) sectors at once. */ ioreq.irHandle = psoc->bHandle; ioreq.irCount = DOCH_DATA_XFER_MODE_MULT; ioreq.irLength = ((tffs_pio <= 255) ? tffs_pio : 0); if ((rc = flDOCHSetDataTransferMode(&ioreq)) != DOCH_OK) { PrintkError ("Can't set multi-sector polled I/O, error %d", rc); tffs_pio = 0; return -1; } } else /* single-sector polled I/O mode requested */ { /* DiskOnChip H3 devices default to single-sector polled I/O mode * upon reset, so we don't have to do anything here. */ } return (int)rc;}#if 0 /* andrayk June 23 2006: added for H3 burst *//* * Check various burst-related parameters for sanity. * This routine is specific to DiskOnChip H3 devices. */staticint set_burst (SocketInfo * psoc){ /* check DiskOnChip H3 burst settings for sanity */ if (tffs_burst == TRUE) { switch (tffs_burst_length) { case 4: tffs_burst_length = 0x0000; break; /* DOCH_BURST_LEN_4_CYC */ case 8: tffs_burst_length = 0x0800; break; /* DOCH_BURST_LEN_8_CYC */ case 16: tffs_burst_length = 0x1000; break; /* DOCH_BURST_LEN_16_CYC */ case 32: tffs_burst_length = 0x1800; break; /* DOCH_BURST_LEN_32_CYC */ default: PrintkError ("Bad burst length (%d), burst disabled", tffs_burst_length); tffs_burst = 0; return -1; } switch (tffs_burst_hold) { case 1: tffs_burst_hold = 0x0000; break; /* DOCH_BURST_HOLD_1_CLK */ case 2: tffs_burst_hold = 0x2000; break; /* DOCH_BURST_HOLD_2_CYC */ default: PrintkError ("Bad burst hold (%d), burst disabled", tffs_burst_hold); tffs_burst = 0; return -1; } } return 0;}#endif /* 1 *//******************************************************************************* * * * T f f s S u s p e n d * * * * Power down DiskOnChip socket. * * * * Parameters: * * * * psoc socket pointer * * * * Returns: * * * * always zero (success) * * * *******************************************************************************/int TffsSuspend (SocketInfo * psoc){ IOreq ioreq; ioreq.irHandle = psoc->bHandle; ioreq.irFlags = DEEP_POWER_DOWN; flDeepPowerDownMode (&ioreq); return 0;}/******************************************************************************* * * * T f f s R e s u m e * * * * Power up (previously powered down) DiskOnChip socket. * * * * Parameters: * * * * psoc socket pointer * * * * Returns: * * * * always zero (success) * * * *******************************************************************************/int TffsResume (SocketInfo * psoc){ IOreq ioreq; ioreq.irHandle = psoc->bHandle; ioreq.irFlags = EXIT_DEEP_POWER_DOWN; flDeepPowerDownMode (&ioreq); return 0;}staticvoid set_disk_geometry (DeviceInfo *pDevice){ /* Limitations for old BIOSes: no. of heads : 8 bits - max 255 no. of cylinders: 10 bits - max 1023 no. of sectors per track: 6 bits - max 63 */ unsigned long dwSectors,dwRest; unsigned long dwMinSec,dwMaxSec,dwSec; unsigned long dwMinCyl,dwCyl; if(pDevice->dwSize==0) { pDevice->wCyl=1; pDevice->bHead=1; pDevice->bSect=1; return; } dwRest=dwSectors = (pDevice->dwSize >> pDevice->wTffsHWSectorSizeShift); /* use shared sector size instead kernel HW sector size - the same geometry for any harsect */ dwMinSec=dwSectors/(1023*255); if(dwSectors!=dwMinSec*1023*255) dwMinSec++; dwMaxSec=63>>pDevice->wTffsHWSectorSizeShift; dwMinCyl=dwSectors/(dwMaxSec*255); if(dwSectors!=dwMinCyl*dwMaxSec*255) dwMinCyl++; for(dwSec=dwMaxSec;dwSec>=dwMinSec;dwSec--) { unsigned long dwMinHead,dwMaxHead,dwHead; dwMinHead=dwSectors/(dwSec*1023); if(dwSectors!=dwMinHead*dwSec*1023) dwMinHead++; /* if(dwMinHead%16) dwMinHead=((dwMinHead>>4)+1)<<4; */ dwMaxHead=dwSectors/(dwSec*dwMinCyl); if(dwMaxHead>255) dwMaxHead=255; for(dwHead=dwMinHead;dwHead<=dwMaxHead;dwHead++ /*=16*/ ) { unsigned long tmp; dwCyl=dwSectors/(dwSec*dwHead); tmp=dwSectors-dwCyl*dwSec*dwHead; if(dwRest>tmp) { pDevice->wCyl=dwCyl; pDevice->bHead=dwHead; pDevice->bSect=dwSec<<pDevice->wTffsHWSectorSizeShift; if(tmp==0) { PrintkDebug("C/H/S (0) %u %u %u",pDevice->wCyl,pDevice->bHead,pDevice->bSect); return; } dwRest=tmp; } } } PrintkError("C/H/S %u %u %u",pDevice->wCyl,pDevice->bHead,pDevice->bSect);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -