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

📄 tffs2lnx.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** *                                                                            * * 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 + -