📄 nandsys.c
字号:
/* 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 + -