📄 tffs2lnx.c
字号:
/****************************************************************************** * * * Project: DOC Driver for Linux 2.6 Block device driver for mDOC H3 family * * of devices under Linux kernel 2.6. * * * * Version: 1.0 * * Email questions to: oemsupport@sandisk.com * * Copyright (C) SanDisk IL Ltd. 1995 - 2007 * * SanDisk IL Ltd., 7 Atir Yeda Street, Kfar Saba 44425, Israel * * * ****************************************************************************** * * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation; either version 2 of the License, or any later version.* * This program is distributed in the hope that it will be useful, but WITHOUT* * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details, which is set forth in the readme.txt file. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., 51 * * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * * * This License does not grant you any right to use the trademarks, service * * marks or logos of SanDisk IL Ltd. or SanDisk Corporation. * * Subject to the foregoing, SanDisk IL Ltd., for itself and on behalf of its * * licensors, hereby reserves all intellectual property rights in the program,* * except for the rights expressly granted in this License. * * * ******************************************************************************//* * $Log$ */#include "tffsdrv.h"#include "tffs2lnx.h"#include "_tffsioct.h"#include "fatfilt.h"#include "flioctl.h"#include "blockdev.h"#include "doch_api.h"#include "defs.h"#define USE_FAT_FILTER /* allow runtime enabling/disabling of FAT filter */#define USE_EXT_FILTER /* allow runtime enabling/disabling of EXT filter */#include "extfiltr.h"/* * global vars */TffsInfo tffsInfo;/* * static routines */static int /* __init */ init_socket (SocketInfo *pSocket);static int /* __init */ init_disk (DeviceInfo *pDisk, SocketInfo *pSocket);static int release_socket (SocketInfo *pSoc);static int release_disk (DeviceInfo *pDevice);static void set_disk_geometry (DeviceInfo *pDevice);static FLStatus socket_std_format (SocketInfo *psoc);static int ata_passthrough (DeviceInfo *pdev, flIOctlRecord *ioctl_rec_ptr, flInputLnxRecord *lnx_inrec_ptr);#if 0 /* andrayk June 23 2006: added for H3 burst */ static int set_burst (SocketInfo * psoc);#endif#if 0 /* andrayk June 23 2006: added for H3 burst */ int tffs_burst = FALSE; module_param(tffs_burst, int, S_IRUGO); MODULE_PARM_DESC(tffs_burst, "enable burst (0 or 1)."); int tffs_burst_length = 4; module_param(tffs_burst_length, int, S_IRUGO); MODULE_PARM_DESC(tffs_burst_length, "burst length (4, 8, 16 or 32)."); int tffs_burst_latency = 0; module_param(tffs_burst_latency, int, S_IRUGO); MODULE_PARM_DESC(tffs_burst_latency, "burst latency."); int tffs_burst_hold = 1; module_param(tffs_burst_hold, int, S_IRUGO); MODULE_PARM_DESC(tffs_burst_hold, "burst hold time (1 or 2)."); int tffs_burst_ws = 1; module_param(tffs_burst_ws, int, S_IRUGO); MODULE_PARM_DESC(tffs_burst_ws, "burst wait states.");#endif/* Command line parameter "tffs_hardsect=<size>", when specified as non-zero, * forces DiskOnChip driver to use this hardsector size rather then obtain it * from the DiskOnChip. The <size> must be either zero (default - obtain * hardsector from DiskOnChip), or power of 2 in the range [512..4096]. */static int tffs_hardsect = 0; /* zero - obtain hardsector from DiskOnChip */module_param(tffs_hardsect, int, S_IRUGO);MODULE_PARM_DESC(tffs_hardsect, "Size (in bytes) of hardware sector for all devices.");/* Command line parameter "tffs_format=<socket_no>" allows user to perform * low-level formatting of specified DiskOnChip socket when driver starts up. * For example: * * insmod tffs.o tffs_format=0 * * will re-format DiskOnchip socket #0. */static int tffs_format = 0xff; /* 0xff: don't format anything */module_param(tffs_format, int, S_IRUGO);MODULE_PARM_DESC(tffs_format, "Format DiskOnChip socket.");/* Command line parameter "tffs_pio=<num>", when specified as non-zero, * forces DiskOnChip driver to use multi-sector polled I/O transfers with * DiskOnChip H3 devices. The <num> must be in range [0..256]; it specifies * maximum number of sectors that can be written to or read from DiskOnChip * H3 device in a single transfer. Default value is zero (use single-sector * polled I/O mode). */static unsigned int tffs_pio = 0; /* zero for single-sector polled I/O */module_param(tffs_pio, int, S_IRUGO);MODULE_PARM_DESC(tffs_pio, "Multi-sector polled I/O mode.");#if defined(USE_FAT_FILTER) || defined(USE_EXT_FILTER) /* Command line parameter "tffs_fs_filter=<mode>" allows user to enable/disable * various file system filters at runtime. Allowed values for <mode> are zero * (default - don't use filters), '1' (use EXT filter), and '2' (use FAT filter). */ static int tffs_fs_filter = 0; /* zero - don't use file system filters */ module_param(tffs_fs_filter, int, S_IRUGO); MODULE_PARM_DESC(tffs_fs_filter, "Enable FAT (tffs_fs_filter=1) or EXT (tffs_fs_filter=2) file system filters.");#endifunsigned char TffsIsWriteProtected (DeviceInfo *pDevice){#ifdef HW_PROTECTION IOreq ioreq; FLStatus stat; ioreq.irHandle = pDevice->bHandle; if ((stat = flIdentifyProtection(&ioreq)) == flOK) { if ((ioreq.irFlags & WRITE_PROTECTED) && !(ioreq.irFlags & KEY_INSERTED)) return 1; } else { if ((stat != flFeatureNotSupported) && (stat != flNotProtected)) { PrintkDebug ("flIdentifyProtection() error %d", stat); } }#endif /* HW_PROTECTION */ return 0;}/******************************************************************************* * * * T f f s I n i t * * * * Initialize TrueFFS, and find all disks on all DiskOnChip sockets. * * * * Parameters: none * * * * Returns: total number of disks found on all DiskOnChip sockets (zero if * * none found), or -1 if error occurred. * * * *******************************************************************************/int /* __init */ TffsInit (void){ register int iSoc; FLStatus stat; tffsInfo.wDevices = 0; memset (tffsInfo.ppDevices, 0, sizeof(tffsInfo.ppDevices)); /* initialize TrueFFS, and find all DiskOnChip sockets */ if ((stat = flInit()) != flOK) { PrintkDebug ("flInit() error %d", stat); return -1; } /* find all disks on all DiskOnChip sockets */ for (iSoc = 0; iSoc < FL_SOCKETS; iSoc++) init_socket (&tffsInfo.sockets[iSoc]); /* return total number of disks on all DiskOnChip sockets */ return tffsInfo.wDevices;}/******************************************************************************* * * * T f f s C l e a n u p * * * * Uninitialize TrueFFS, and shut it down. * * * * Parameters: none * * * * Returns: always zero (success). * * * *******************************************************************************/int TffsCleanup (void){ register int iSoc; for (iSoc = 0; iSoc < FL_SOCKETS; iSoc++) release_socket (&tffsInfo.sockets[iSoc]); memset (tffsInfo.ppDevices, 0, sizeof(tffsInfo.ppDevices)); tffsInfo.wDevices = 0;#ifdef FL_EXIT flExit();#endif return 0;}staticint /* __init */ init_socket (SocketInfo *pSoc){ IOreq ioreq; FLStatus stat; register int iDev; SocketInfo*pS;#ifdef TFFS_USE_RAM pSoc->fFound=1;#endif /* if socket wasn't found, abort */ if (pSoc->fFound == 0) { pSoc->bHandle = 0xff; return 0; } for(pS=tffsInfo.sockets;pS!=pSoc;pS++) { if(pSoc->bHandle==pS->bHandle) pSoc->bHandle++; } PrintkInfo("Socket %u in addr 0x%lx",pSoc->bHandle,pSoc->dwPhysAddr); /* if requested, format socket using standard formatting parameters */ if (pSoc->bHandle == tffs_format) { PrintkInfo("format socket %d", tffs_format); if( (stat = socket_std_format(pSoc)) != flOK ) { PrintkError ("format failed on socket %d, error %d", tffs_format, stat); return 0; } PrintkInfo("formatting successful"); } /* find out how many disks are on this DiskOnChip socket */ ioreq.irHandle = pSoc->bHandle; stat = flCountVolumes(&ioreq); if ((stat != flOK) || (ioreq.irFlags == 0)) { PrintkDebug("flCountVolumes error %d irFlags %lu", (int)stat, ioreq.irFlags);#ifdef TFFS_ALLOW_UNFORMATTED pSoc->wDevices = 1;#else pSoc->wDevices = 0;#endif } else pSoc->wDevices = ioreq.irFlags; if (pSoc->wDevices == 0) { /* There are no any disk on this socket; probably this * socket has never been formatted. */ return 0; } if ((pSoc->pDevices = KMalloc(pSoc->wDevices * sizeof(DeviceInfo))) == NULL) { pSoc->wDevices = 0; return 0; } for (iDev = 0; iDev < pSoc->wDevices; iDev++) init_disk (&pSoc->pDevices[iDev], pSoc); /* If configured, allocate scatter/gather buffer. Align size * of scatter/gather buffer up to multiple of PAGE_SIZE. */ if (tffs_sg_bufsize > 0) { tffs_sg_bufsize = (((tffs_sg_bufsize - 1) / PAGE_SIZE) + 1) * PAGE_SIZE; if ((pSoc->pCache = KMalloc(tffs_sg_bufsize)) == NULL) { PrintkError ("can't allocate scatter/gather buffer"); tffs_sg_bufsize = 0; } }#if 0 /* enable h/w DMA in DiskOnChip */ ioreq.irHandle = pSoc->bHandle; ioreq.irFlags = FL_DMA_TYPE; ioreq.irLength = FL_DMA_HW_ENABLED; flHwConfig (&ioreq);#endif /* set single- or multi-sector polled I/O mode */ TffsSetPIO (pSoc);#if 0 /* andrayk June 23 2006: added for H3 burst */ set_burst (pSoc);#endif return (pSoc->wDevices != 0);}/* defice still dismounted after init */staticint /* __init */ init_disk (DeviceInfo * pDisk, SocketInfo * pSocket){ unsigned char bDevice; pDisk->bHandle=pSocket->bHandle+((pDisk-pSocket->pDevices)<<4); pDisk->pSocket=(SocketInfo*)pSocket; pDisk->wTffsHWSectorSizeShift=0; while( (1<<pDisk->wTffsHWSectorSizeShift) != 8 ) pDisk->wTffsHWSectorSizeShift++; if(tffs_hardsect > 0) pDisk->wHWSectorSize=tffs_hardsect; else pDisk->wHWSectorSize=512<<(TFFS_MAXHW_SECTOR_SIZE_BITS<pDisk->wTffsHWSectorSizeShift?TFFS_MAXHW_SECTOR_SIZE_BITS:pDisk->wTffsHWSectorSizeShift); if(pDisk->wHWSectorSize>4096) pDisk->wHWSectorSize=4096; pDisk->dwSize=0; pDisk->fAbsMounted=0; if(TffsOpenDevice(pDisk)) { IOreq ioreq; FLStatus stat; ioreq.irHandle=pDisk->bHandle; if ((stat = flSectorsInVolume(&ioreq)) == flOK) pDisk->dwSize=ioreq.irLength; else PrintkDebug("flSectorsInVolume error %d",stat); } else PrintkDebug("TffsOpenDevice error");#ifndef TFFS_ALLOW_UNFORMATTED if(pDisk->dwSize > 0) {#endif for(bDevice=0; (tffsInfo.ppDevices[bDevice] != NULL) && (bDevice < FL_VOLUMES); bDevice++) ; if (bDevice >= FL_VOLUMES) return 0; tffsInfo.ppDevices[bDevice]=pDisk; tffsInfo.wDevices++; pDisk->diskNo=bDevice;#ifndef TFFS_ALLOW_UNFORMATTED } else return 0;#endif#ifdef USE_EXT_FILTER /* if we are going to use EXT filter, install it */ if ((tffs_fs_filter == 1) && (pDisk->dwSize != 0)) { ExtFilterInit (pDisk); }#endif set_disk_geometry (pDisk); PrintkInfo ("Device 0x%x: %ld 512-byte sectors, h/w sector %d bytes", pDisk->diskNo, pDisk->dwSize, pDisk->wHWSectorSize); return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -