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

📄 nandsys.c

📁 linux下的nandflash驱动程序,这是从国外网站上下载来的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*      Flash Disk Driver Interface for Linux    Written by Vova Lifliand*//*  Includes  */#include <linux/module.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/timer.h>#include <linux/genhd.h>#include <linux/hdreg.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/devfs_fs_kernel.h>#include <linux/malloc.h>#include <asm/system.h>#include <asm/io.h>#include <asm/uaccess.h>#include <asm/delay.h>/*  Macros for correct linux/blk.h inclusion  */#define MAJOR_NR	    254#define DEVICE_NAME         "nand"#define DEVICE_REQUEST	    do_flash_request#define DEVICE_NR(device)   (MINOR(device) >> 6)#define DEVICE_ON(device)#define DEVICE_OFF(device)#include <linux/blk.h>#include <linux/blkpg.h>/*  I/O Controls  */#define CL_FLASH_IOC_MAGIC          'f'#define CL_FLASH_IO_GET_PARAM        _IOWR (CL_FLASH_IOC_MAGIC, 1, 12)#define CL_FLASH_IO_DIRECT_ACCESS    _IOWR (CL_FLASH_IOC_MAGIC, 2, 524)#define MAX_FLASHN                  2/*  The following macro enables flash activity indication by LEDs  */#undef USE_LEDS/*  Macro to enable or disable trace logs  */#if 0#define cl_trace_log(param)	cl_error_log param#else#define cl_trace_log(param)#endif/*  CrFlash driver interface  */#define FLASH_PLATFORM_LINUX#define TARGET_786_CORE#include "CL_Logic.h"/*  Forward functions declaration  */static int flash_open (struct inode *inode,struct file *file);static void do_flash_request (request_queue_t * q);static int flash_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);static int flash_release (struct inode *inode, struct file *file);static void cl_timer_proc (void* unused);static void cl_flush_proc (void* unused);static int flash_check_media_change (kdev_t dev);static int flash_revalidate (kdev_t dev);/*  Global variables declaration  */static struct hd_struct flash_struct[MAX_FLASHN << 6];static int flash_sizes[MAX_FLASHN << 6];static int flash_blocksizes[MAX_FLASHN << 6];/*  Global variables for Nand flash driver control  */static cl_logic flogic[MAX_FLASHN] = {  NULL, NULL  };static unsigned long last_end_write_cmd = 0;/* The task queue structure for this task, from tqueue.h   */static struct tq_struct timerTask ={    routine:	cl_timer_proc};static struct tq_struct flushTask ={    routine:	cl_flush_proc};/* This is used by cleanup, to prevent the module from  * being unloaded while intrpt_routine is still in  * the task queue */static int StopLaunchTimer = 0;static DECLARE_WAIT_QUEUE_HEAD(WaitQ);static DECLARE_MUTEX (flash_sem);int format = 0;int flashdisableintr = 1;/*MODULE_PARM(format, "i");MODULE_PARM(flashdisableintr, "i");*/static int __init flirqen(char *str){	flashdisableintr = simple_strtol(str, NULL, 0);	return 1;}__setup("fl_irq=", flirqen);int ignore_ata_var = 0;static int __init ignore_ata(char *str){	ignore_ata_var = simple_strtol(str, NULL, 0);	return 1;}__setup("ignore_ata=", ignore_ata);static struct block_device_operations flash_fops ={    open: flash_open,    release: flash_release,    ioctl: flash_ioctl,    check_media_change: flash_check_media_change,    revalidate: flash_revalidate};static struct gendisk flash_gendisk ={    MAJOR_NR,	    /* Major number */    DEVICE_NAME,    /* Major name */    6,		    /* Bits to shift to get real from partition */    1 << 6,	    /* Number of partitions per real */    flash_struct,   /* hd struct */    flash_sizes,    /* block sizes */    MAX_FLASHN,     /* number */    NULL,	    /* internal */    NULL,	    /* next */    &flash_fops,    /* file operations */};static devfs_handle_t devfs_handle = NULL;/*  Definitions  *//*  Global variables  */static int ChipSelectCounter = 0;static int IntrDisabled = 0;static unsigned long IntrFlags;void cl_error_log (const char* format, ...){    char full_msg[300];    va_list marker;    va_start(marker, format);    vsprintf(full_msg, format, marker);    printk(full_msg);    va_end(marker);}/*  Defining functions needed for flash driver  */void* cl_nand_mem_alloc (unsigned long size){    return kmalloc (size, GFP_KERNEL);}void cl_nand_mem_free (void* ptr){    kfree (ptr);}void cl_zero_mem (void* ptr, long size){    memset (ptr, 0, size);}void cl_ff_mem (void* ptr, long size){    memset (ptr, 0xff, size);}void cl_mem_copy (void* dest, const void* src, long size){    memcpy (dest, src, size);}int cl_mem_compare (void* mem1, const void* mem2, long size){    return memcmp (mem1, mem2, size);}unsigned long cl_nand_get_max_cache_time (void){    return HZ * 30;       /*  30 seconds in cache maximum  */}unsigned long cl_get_jiffies (void){    return jiffies;}/*  Internally used functions  */static void do_nothing (void){}static void FlashDisableIntr (void){    if (IntrDisabled)        return;    __save_flags (IntrFlags);    __cli ();    IntrDisabled = 1;}static void FlashEnableIntr (void){    if (IntrDisabled)    {        __restore_flags (IntrFlags);        IntrDisabled = 0;    }}static unsigned long PciReadRegisterDWord (unsigned char reg,                                    unsigned char bus,                                    unsigned char device,                                    unsigned char function){    unsigned long flags;    unsigned long pci_cfg = 0x8000, prev;    __save_flags (flags);    __cli ();    pci_cfg |= bus;    pci_cfg <<= 5;    pci_cfg |= device;    pci_cfg <<= 3;    pci_cfg |= function;    pci_cfg <<= 8;    pci_cfg |= reg;    prev = inl (0xcf8);    outl (pci_cfg, 0xcf8);    pci_cfg = inl (0xcfc);    outl (prev, 0xcf8);    __restore_flags (flags);    return pci_cfg;}static unsigned long PciWriteRegisterDWord (unsigned char reg,                                     unsigned long data,                                     unsigned char bus,                                     unsigned char device,                                     unsigned char function){    unsigned long flags;    unsigned long pci_cfg = 0x8000, prev;    __save_flags (flags);    __cli ();    pci_cfg |= bus;    pci_cfg <<= 5;    pci_cfg |= device;    pci_cfg <<= 3;    pci_cfg |= function;    pci_cfg <<= 8;    pci_cfg |= reg;    prev = inl (0xcf8);    outl (pci_cfg, 0xcf8);    outl (data, 0xcfc);    outl (prev, 0xcf8);    __restore_flags (flags);    return pci_cfg;}static unsigned short GetGpioBaseAddr (void){    static unsigned short GpioBaseAddr = 0;    if (!GpioBaseAddr)        GpioBaseAddr = PciReadRegisterDWord (0x58, 0, 31, 0) & 0xfffc;    return GpioBaseAddr;}static void FlashDeviceSelect (int device_id){	static int last_selected_device = -1;    unsigned long reg;	if (last_selected_device == device_id)		return;	/*  GPIO22 is connected to multiplexer that selects one of        two NAND Flashes  */	FlashDisableIntr ();    reg = inl (GetGpioBaseAddr() + 0xC);    if (device_id)        reg |= (1L << 22L);    else reg &= ~(1L << 22L);    outl (reg, GetGpioBaseAddr() + 0xC);	FlashEnableIntr ();    cl_trace_log (("NAND Flash %d selected.\n", device_id));}static void FlashInitRoutine (void){#ifdef USE_LEDS    unsigned long reg;    reg = inl (GetGpioBaseAddr() + 0x0C);    reg |= (1L << 27);    outl (reg, GetGpioBaseAddr() + 0x0C);#endif}static void FlashChipSelect_Universal (int on, int device){    if (on)    {        if(ChipSelectCounter++)            return;		FlashDeviceSelect (device);        /*  Disable interrupts  */		if (flashdisableintr)			FlashDisableIntr ();        /*  Enable secondary IDE decode  */        PciWriteRegisterDWord (0x40,                   PciReadRegisterDWord (0x40, 0, 31, 1) | 0x80000000L,                    0, 31, 1);    }    else    {        if(--ChipSelectCounter)            return;        /*  Disable secondary IDE decode  */        PciWriteRegisterDWord (0x40,                    PciReadRegisterDWord (0x40, 0, 31, 1) & 0x7FFFFFFFL,                    0, 31, 1);        /*  Restore interrupts  */		if (flashdisableintr)	        FlashEnableIntr ();    }}static void Flash1_ChipSelect (int on){    FlashChipSelect_Universal (on, 0);}static void Flash2_ChipSelect (int on){    FlashChipSelect_Universal (on, 1);}static unsigned char FlashReadByte (unsigned char offset){    return inb (0x170 + offset);}static void FlashWriteByte (unsigned char offset, unsigned char data){    outb (data, 0x170 + offset);}static void FlashBlockRead (unsigned char* data, int count){    while (count--)        *data++ = inb (0x170);}static void FlashBlockWrite (const unsigned char* data, int count){    while (count--)        outb (*data++, 0x170);}/*  Flashes 486Core leds to see activity when accessing flashes  *//*  For each variable: (-1) leave as is, (0) off, (1) on  */static void FlashCoreLeds (short operation, short reclaim){#ifdef USE_LEDS    unsigned long reg;    reg = inl (GetGpioBaseAddr() + 0xC);    if (operation == 1)        reg &= ~(1L << 27L);    if (operation == 0)        reg |= (1L << 27L);    if (reclaim == 1)        reg &= ~(1L << 28L);    if (reclaim == 0)        reg |= (1L << 28);    outl (reg, GetGpioBaseAddr() + 0xC);#endif}static void mk_delay (unsigned long microsec){    microsec *= 200;    microsec /= 50;    while (microsec--)        inb (0xb3);}static cl_nand_map_if cl_nand_linux[MAX_FLASHN] ={    {

⌨️ 快捷键说明

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