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

📄 flsystem.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** *                                                                            * * 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$ *//* * includes */#include "tffsdrv.h"#include "flbase.h"#include "doch_sys.h"#include "hib.h"#ifdef TFFS_MESSAGES_ENABLEDint fl_debug = FL_DEBUG_DEF;module_param(fl_debug, int, (S_IRUGO | S_IWUSR));MODULE_PARM_DESC(fl_debug,"Print TrueFFS debug messages [0-7].");#endif/* For portability reasons, Linux drivers should use macros readXXX/writeXXX * when reading/writing hardware registers and transferring data from * devices. Command line parameter "tffs_memcpy=1" allows DiskOnChip driver * to use memcpy() library routine instead, which often greatly improves * driver's 'read' performance. * *     insmod tffs.o tffs_memcpy=1 */int tffs_memcpy = 0;module_param(tffs_memcpy, int, S_IRUGO);MODULE_PARM_DESC(tffs_memcpy, "Use memcpy() for DiskOnChip data transfers.");/* Command line parameter "tffs_addr=<physical_address>" allows user to tell * DiskOnChip driver where to look for DiskOnChip. For example, to instruct * driver to probe for DiskOnChip at physical address 0x14000000: * *     insmod tffs.o tffs_addr=0x14000000 */ulong tffs_addr[FL_SOCKETS] = { TFFS_PHYS_ADDR };static int __fl_sockets = FL_SOCKETS;  /* just for module_param_array() below */#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))  module_param_array(tffs_addr, ulong, __fl_sockets, S_IRUGO);#else  module_param_array(tffs_addr, ulong, &__fl_sockets, S_IRUGO);#endifMODULE_PARM_DESC(tffs_addr,"Physical address of DiskOnChip.");/* Command line parameter "tffs_skip_sleeps=<num>" instructs DiskOnChip driver * how often it should yield CPU during DiskOnChip 'write' operations. The * higher the <num>, the less frequently driver yield CPU, thus increasing * it's 'write' performance, but also increasing it's load on CPU.  * *     insmod tffs.o tffs_skip_sleep=3 */int tffs_skip_sleeps = 5;module_param(tffs_skip_sleeps, int, (S_IRUGO | S_IWUSR));MODULE_PARM_DESC(tffs_skip_sleeps,"How often to yield CPU during write operations.");unsigned int profiling[10] = {0};/* * static routines */static void TffsMapMem (SocketInfo *psoc, unsigned long phys_addr, unsigned long length);static void TffsUnmapMem (SocketInfo *psoc);static void irq_wait_timed_out (unsigned long arg);/* * static vars *//* semaphore used by TrueFFS: one per socket, plus one for dochVol.mutex */static struct semaphore  sems [FL_SOCKETS + 1];/* next TrueFFS semaphore to allocate (0..FL_SOCKETS-1) */static int  total_sems = 0;/*-----------------------------------------------------------------------* *                                                                       * *                       T f f s M a p M e m                             * *                                                                       * * Allocate physical memory region, and map it into kernel's address     * * space.                                                                * *                                                                       * * Parameters:                                                           * *      psoc          socket pointer                                     * *      phys_addr     starting address of physical memory region         * *      length        length (in bytes) of this physical memory region   * *                                                                       * *-----------------------------------------------------------------------*/staticvoid  TffsMapMem ( SocketInfo    * psoc,                   unsigned long   phys_addr,                   unsigned long   length ){    struct resource * rs;    /* no memory region has been obtained yet */    psoc->fMemRequested = 0;    psoc->dwPhysAddr    = 0;    psoc->dwMappedLen   = 0;    psoc->dwVirtAddr    = 0;    /* request physical memory region that DiskOnChip resides in */    if ((rs = request_mem_region(phys_addr, length, "tffs")) != NULL)    {        /* map this physical memory region to kernel's virtual addr. space */        if ((psoc->dwVirtAddr = (ulong)ioremap_nocache(phys_addr, length)) != 0)	{            psoc->fMemRequested = 1;            psoc->dwPhysAddr    = phys_addr;            psoc->dwMappedLen   = length;	}        else	{            PrintkDebug("ioremap_nocache(0x%lx,0x%lx) failed", phys_addr, length);            release_mem_region (phys_addr, length);	}    }    else        { PrintkDebug("request_mem_region(0x%lx,0x%lx) failed", phys_addr, length); }}/*-----------------------------------------------------------------------* *                                                                       * *                       T f f s U n m a p M e m                         * *                                                                       * * Unmap and free memory region previously allocated by TffsMapMem().    * *                                                                       * * Parameters:                                                           * *      psoc          socket pointer                                     * *                                                                       * *-----------------------------------------------------------------------*/staticvoid  TffsUnmapMem ( SocketInfo * psoc ){    if (psoc->dwVirtAddr != 0)        iounmap ((void *)psoc->dwVirtAddr);    if (psoc->fMemRequested == 1)        release_mem_region (psoc->dwPhysAddr, psoc->dwMappedLen);    psoc->fMemRequested = 0;    psoc->dwPhysAddr    = 0;    psoc->dwMappedLen   = 0;    psoc->dwVirtAddr    = 0;}void * TffsMalloc (unsigned long size){    return vmalloc (size + 4);}void  TffsFree (void * vptr){    vfree (vptr);}int LnxTffsPrint(const char *fmt, ...){	va_list args;	char buf[1024];			/* hopefully enough, kernel/printk.c thinks so */	int i;	va_start(args, fmt);	i = vsprintf(buf, fmt, args);	va_end(args);	buf[i] = '\0';	while(i>0)	{		if(buf[i-1]==0xd || buf[i-1]==0xa)		{			buf[--i]=0;		}		else			break;	}	printk(KERN_ERR TFFS_DEVICE_NAME": %s\n",buf);	return i;}/*-----------------------------------------------------------------------* *                                                                       * *                       t f f s _ r e a d w                             * *                                                                       * * This routine transfers data from RAM to DiskOnChip device in cases    * * when DMA is not used.                                                 * *                                                                       * * Parameters:                                                           * *      io_vaddr      virtual address of DiskOnChip's data port          * *      vbuf          buffer to transfer data from                       * *      words         number of 16-bit short words to transfer           * *                                                                       * *-----------------------------------------------------------------------*/void tffs_readw ( unsigned long io_vaddr, short * vbuf, int words ){    if (tffs_memcpy == 1) /* ugly hack: use memcpy() to transfer data */    {        register char * p = (char *) vbuf;        register int    n;        /* DiskOnChip's data port is aliased across 1024-bytes region */        for (words <<= 1; words > 0; words -= n, p += n)        {            n = ((words <= 1024) ? words : 1024);            memcpy (p, (void *)io_vaddr, n);	}      }    else /* standard Linux case: use readw/writew macros for portability */    {        while (words--)            *vbuf++ = readw (io_vaddr);    }}/*-----------------------------------------------------------------------* *                                                                       * *                       t f f s _ w r i t e w                           * *                                                                       * * This routine transfers data from DiskOnChip device to RAM in cases    * * when DMA is not used.                                                 * *                                                                       * * Parameters:                                                           * *      io_vaddr      virtual address of DiskOnChip's data port          * *      vbuf          buffer to transfer data to                         * *      words         number of 16-bit short words to transfer           * *                                                                       * *-----------------------------------------------------------------------*/void tffs_writew ( unsigned long io_vaddr, short * vbuf, int words ){    if (tffs_memcpy == 1) /* ugly hack: use memcpy() to transfer data */    {        register char * p = (char *) vbuf;        register int    n;        /* DiskOnChip's data port is aliased across 1024-bytes region */        for (words <<= 1; words > 0; words -= n, p += n)        {            n = ((words <= 1024) ? words : 1024);            memcpy ((void *)io_vaddr, p, n);	}      }    else /* standard Linux case: use readw/writew macros for portability */    {        while (words--)        {            writew (*vbuf, io_vaddr);            vbuf++;        }    }}/*-----------------------------------------------------------------------* *                                                                       * *                       d o c h b l k _ r e a d                         * *                                                                       * * This routine transfers data from DiskOnChip H3 device to RAM.         * *                                                                       * * Parameters:                                                           * *      vbuf          buffer to transfer data to                         * *      sectors       number of 512-byte sectors to transfer             * *                                                                       * *-----------------------------------------------------------------------*/int dochblk_read (void * vbuf, unsigned int sectors){    flReadEvenNumberOfBytes ((DOCHFlash), DOCH_DATA_PORT_AREA, vbuf, ((sectors) << 9));    return 0;}/*-----------------------------------------------------------------------* *                                                                       * *                       d o c h b l k _ w r i t e                       * *                                                                       * * This routine transfers data from RAM to DiskOnChip H3 device.         * *                                                                       * * Parameters:                                                           * *      vbuf          buffer to transfer data from                       * *      sectors       number of 512-byte sectors to transfer             * *                                                                       * *-----------------------------------------------------------------------*/int dochblk_write (void * vbuf, unsigned int sectors){    flWriteEvenNumberOfBytes ((DOCHFlash), DOCH_DATA_PORT_AREA, vbuf, ((sectors) << 9));    return 0;}void  flSysfunInit ( void ){    register int   iSoc;    unsigned long  win_size;  /* size of DiskOnChip window in bytes */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -