📄 tffs2lnx.c
字号:
}staticint release_socket (SocketInfo * pSoc){ register int iDev; for (iDev = 0; iDev < pSoc->wDevices; iDev++) release_disk (&pSoc->pDevices[iDev]); if (pSoc->pDevices != NULL) { kfree (pSoc->pDevices); pSoc->pDevices = NULL; } pSoc->wDevices = 0; /* free scatter/gather cache if was allocated */ if (pSoc->pCache != NULL) kfree (pSoc->pCache); return 0;}staticint release_disk (DeviceInfo *pDevice){#ifndef TFFS_ALLOW_UNFORMATTED if(pDevice->dwSize==0) return 0;#endif#ifdef USE_EXT_FILTER /* if we were using EXT filter, uninstall it */ if ((tffs_fs_filter == 1) && (pDevice->dwSize != 0)) { ExtFilterRelease(pDevice); }#endif if(!TffsCloseDevice(pDevice)) PrintkDebug("TffsCloseDevice() error"); pDevice->dwSize=0; tffsInfo.wDevices--; return 1;}unsigned char TffsOpenDevice (DeviceInfo * pDisk){ IOreq ioreq; FLStatus status = flDriveNotAvailable; if (pDisk->fAbsMounted == 0) { ioreq.irHandle = pDisk->bHandle; if ((status = flAbsMountVolume(&ioreq)) == flOK) pDisk->fAbsMounted = 1; else PrintkError("flAbsMountVolume() error %d", status); }#ifdef TFFS_ALLOW_UNFORMATTED if (pDisk->dwSize == 0) return 1;#endif return pDisk->fAbsMounted;}unsigned char TffsCloseDevice (DeviceInfo * pDevice){ IOreq ioreq; FLStatus stat = flDriveNotAvailable; if (pDevice->fAbsMounted != 0) { ioreq.irHandle = pDevice->bHandle; stat = flDismountVolume (&ioreq); pDevice->fAbsMounted = 0; if (stat != flOK) { PrintkDebug("flDismountVolume() error %d", stat); return 0; } } return 1;}#ifdef TFFS_STATISTICstaticvoid CountAl(DeviceInfo*pDevice,int block,int count,int dir){ int sector=block,sectors=count,noInShared; while(sectors) { noInShared=(((sector>>pDevice->wTffsHWSectorSizeShift)+1)<<pDevice->wTffsHWSectorSizeShift)-sector; if(noInShared>sectors) noInShared=sectors; if(noInShared==(1<<pDevice->wTffsHWSectorSizeShift)) { if(dir==READ) { pDevice->stat.dwAlReadShared++; pDevice->stat.dwAlReadSec+=noInShared; } else { pDevice->stat.dwAlWriteShared++; pDevice->stat.dwAlWriteSec+=noInShared; } } else { if(dir==READ) { pDevice->stat.dwUnalReadShared++; pDevice->stat.dwUnalReadSec+=noInShared; } else { pDevice->stat.dwUnalWriteShared++; pDevice->stat.dwUnalWriteSec+=noInShared; } } sectors-=noInShared; sector+=noInShared; }}#endif /* TFFS_STATISTIC */#ifdef TFFS_COUNT_REQ_SECTORSextern unsigned long dwRead,dwWritten;#endifunsigned char TffsRead(DeviceInfo*pDevice,void*data,int block,int count){ IOreq ioreq; FLStatus stat = flDriveNotAvailable;#ifdef TFFS_COUNT_REQ_SECTORS dwRead+=count;#endif#ifdef TFFS_STATISTIC pDevice->stat.dwAbsRead++; pDevice->stat.dwAbsReadSec+=count; CountAl(pDevice,block,count,READ);#endif ioreq.irHandle=pDevice->bHandle; ioreq.irData=data; ioreq.irLength=block; ioreq.irCount=count; if ((stat = flAbsRead(&ioreq)) == flOK) return 1; PrintkDebug("flAbsRead() error %d",stat); return 0;}/* Perform read or write of appropriate number of sectors from a DOC volume */unsigned char TffsWrite(DeviceInfo*pDevice,void*data,int block,int count){#ifndef TFFS_RO IOreq ioreq; FLStatus stat = flDriveNotAvailable;# ifdef TFFS_COUNT_REQ_SECTORS dwWritten+=count;# endif# ifdef TFFS_STATISTIC pDevice->stat.dwAbsWrite++; pDevice->stat.dwAbsWriteSec+=count; CountAl(pDevice,block,count,WRITE);# endif ioreq.irHandle=pDevice->bHandle; ioreq.irData=data; ioreq.irLength=block; ioreq.irCount=count;# ifdef USE_EXT_FILTER if (tffs_fs_filter == 1) /* use EXT filter */ ExtFilter (pDevice,data,block,count);# endif# ifdef USE_FAT_FILTER if (tffs_fs_filter == 2) /* use FAT filter */ ffCheckBeforeWrite (&ioreq);# endif if ((stat = flAbsWrite(&ioreq)) == flOK) return 1; PrintkError ("flAbsWrite error %d",stat);#endif /* TFFS_RO */ return 0;}/************************************************************************ * * * s o c k e t _ s t d _ f o r m a t * * * * Formats DiskOnChip socket with standard format parameters. * * WARNING: all existing data on DiskOnChip is destroyed ! * * * * Parameters: * * psoc : socket to format * * * * Returns: * * flOK on success, otherwise respective error code * * * ************************************************************************/static FLStatus socket_std_format (SocketInfo * psoc){ IOreq ioreq; FLStatus stat = flDriveNotAvailable; /* format socket using standard formatting parameters */static FormatParams3 std_fp3 = STD_FORMAT_PARAMS3;static BDTLPartitionFormatParams3 std_bdtl_fp3 = STD_BDTL_PARAMS3; std_fp3.BDTLPartitionInfo = &std_bdtl_fp3; ioreq.irHandle = psoc->bHandle; ioreq.irFlags = TL_NORMAL_FORMAT; ioreq.irData = &std_fp3; if ((stat = flFlashFormat(&ioreq)) != flOK) PrintkError("flFlashFormat error %d", stat); return stat;}/************************************************************************ * * * a t a _ p a s s t h r o u g h * * * * This routine implements ATA pass-through command for DiskOnChip H3 * * devices. * * * * Parameters: * * pdev : device * * ioctl_rec_ptr : kernel copy of user's flIOctlRecord * * lnx_inrec_ptr : kernel copy of user's flInputLnxRecord * * * * Returns: * * zero on success, otherwise -EFAULT or -ENOMEM * * * ************************************************************************/staticint ata_passthrough ( DeviceInfo * pdev, flIOctlRecord * ioctl_rec_ptr, flInputLnxRecord * lnx_inrec_ptr ){ flOutputLnxRecord lnx_outrec; flAtaPassthrough ata; char * buf = NULL; int rc = -EFAULT; /* copy struct flAtaPassthrough from user space */ if( access_ok(VERIFY_WRITE, (void *)(lnx_inrec_ptr->data), sizeof(ata)) == 0 ) return -EFAULT; if( copy_from_user(&ata, (void *)(lnx_inrec_ptr->data), sizeof(ata)) != 0 ) return -EFAULT; if ((ata.passThruOP == DOCH_PASSTHRU_DATA_OUT) || (ata.passThruOP == DOCH_PASSTHRU_DATA_IN)) { /* currently we don't allow more then 256 sectors in single transfer */ if (ata.userBuffSize > (256 * FL_SECTOR_SIZE)) return -ENOMEM; /* check if we can access user buffer */ if (ata.passThruOP == DOCH_PASSTHRU_DATA_OUT) { if( access_ok(VERIFY_READ, ata.userBuff, ata.userBuffSize) == 0 ) return -EFAULT; } else if (ata.passThruOP == DOCH_PASSTHRU_DATA_IN) { if( access_ok(VERIFY_WRITE, ata.userBuff, ata.userBuffSize) == 0 ) return -EFAULT; } /* allocate kernel buffer to hold user data */ if ((buf = vmalloc(ata.userBuffSize)) == NULL) return -ENOMEM; } /* For output (host -> DiskOnChip) operations, copy data from * user buffer 'ata.userBuff' to to kernel buffer 'buf' */ if (ata.passThruOP == DOCH_PASSTHRU_DATA_OUT) { if( copy_from_user(buf, ata.userBuff, ata.userBuffSize) != 0 ) goto quit;#if 0 /* andrayk May 12 2006: firmware checksum calculation to assist debugging */ { register unsigned long s; register int n = (ata.userBuffSize / sizeof(long)) - 1; unsigned long * p = (unsigned long *)buf; for (s = 0; n >= 0; n--) s ^= p[n]; PrintkDebug ("Firmware file checksum is 0x%lx", s); }#endif } /* Execute pass-through ATA command, and put it's status into * both 'flOutputLnxRecord.status' and 'flAtaPassthrough.status'. */ ata.status = lnx_outrec.status = DOCHAtaPassThrough (pdev->bHandle, /* not 'ata.socketNum', for security reasons */ ata.passThruOP, (DOCH_Registers *) &ata.in_regs, (DOCH_Registers *) &ata.out_regs, ata.secNum, buf, FALSE); /* don't use DiskOnChip interrupt */ /* For input (DiskOnChip -> host) operations, copy data from * kernel buffer 'buf' to user buffer 'ata.userBuff'. */ if (ata.passThruOP == DOCH_PASSTHRU_DATA_IN) { if( copy_to_user(ata.userBuff, buf, ata.userBuffSize) != 0 ) goto quit; } /* copy updated struct flAtaPassthrough back to user space */ if( copy_to_user((void *)(lnx_inrec_ptr->data), &ata, sizeof(ata)) != 0 ) goto quit; /* copy updated struct flOutputLnxRecord back to user space */ if( copy_to_user(ioctl_rec_ptr->outputRecord, &lnx_outrec, sizeof(lnx_outrec)) != 0 ) goto quit; rc = 0; /* success */ quit: if (buf != NULL) { memset (buf, 0, ata.userBuffSize); vfree (buf); } return rc;}#define USR2KRN_O_START(typeOut) \ { \ typeOut output; \ void *tmp; \ if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(typeOut))) \ return -EFAULT; \ tmp = ioctlRecord.outputRecord; \ ioctlRecord.outputRecord = &output;#define USR2KRN_IO_START(typeIn,typeOut) \ { \ typeIn input; \ typeOut output; \ void *tmp; \ if (!access_ok(VERIFY_READ,ioctlRecord.inputRecord,sizeof(typeIn))) \ return -EFAULT; \ if (copy_from_user(&input,ioctlRecord.inputRecord,sizeof(typeIn))) \ return -EFAULT; \ ioctlRecord.inputRecord = &input; \ if (!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(typeOut))) \ return -EFAULT; \ tmp = ioctlRecord.outputRecord; \ ioctlRecord.outputRecord = &output;#define USR2KRN_END \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -