📄 zlg_ffs_uclinx.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: zlg_ffs_uClinux.c
** Last modified Date: 2005-03-23
** Last Version: 1.0
** Descriptions: This is a Kernel module for uClinux 2.4.x .** This module let uClinux 2.4.x can use ZLG/FFS .
**------------------------------------------------------------------------------------------------------
** Created by: Chenmingji
** Created date: 2005-03-23
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#define IN_ZLG_FFS_UCLINUX#include "config.h"/********************************************************************************************************
function announce********************************************************************************************************/
static int zlg_ffs_open(struct inode *inode, struct file *filp);static int zlg_ffs_release(struct inode *inode, struct file *filp); static int zlg_ffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param);static int check_zlg_ffs_change(kdev_t dev);static int zlg_ffs_revalidate(kdev_t dev);int zlg_ffs_init(void);void zlg_ffs_cleanup(void);/********************************************************************************************************
function announce********************************************************************************************************/
#define MAJOR_NR major /* force definitions on in blk.h */#define DEVICE_NR(device) MINOR(device) /* has no partition bits */#define DEVICE_NO_RANDOM /* no entropy to contribute */#define DEVICE_OFF(d) /* do-nothing */MODULE_PARM(major, "i");module_init(zlg_ffs_init);module_exit(zlg_ffs_cleanup);MODULE_LICENSE("Proprietary");MODULE_DESCRIPTION("Guangzou ZLG-MCU Development Co.,LTD.\ngraduate school\nhttp://www.zlgmcu.com");MODULE_SUPPORTED_DEVICE("uClinux2.4.x LPC2200 ZLG/FFS");MODULE_AUTHOR("chenmingji");/*********************************************************************************************************
** "全局和静态变量在这里定义"
** global variables and static variables define here
********************************************************************************************************/
static int major = ZLG_FFS_MAJOR_NR; /* must be declared before including blk.h */#include <linux/blk.h>static int ZLG_FFS_blocksizes[MAX_DRIVES]; /* bytes per device */static int ZLG_FFS_sizes[MAX_DRIVES]; /* bytes per device's block */ /* must be (1 << n) */static FFSDisk FFSDiskInfo[MAX_DRIVES]; /* ZLG/FFS device's info */static unsigned int ZLG_FFS_usage[MAX_DRIVES]; /* device using count *//********************************************************************************************************/
static struct block_device_operations zlg_ffs_fops = /* driver info */{ owner: THIS_MODULE, open: zlg_ffs_open, release: zlg_ffs_release, ioctl: zlg_ffs_ioctl, check_media_change: check_zlg_ffs_change, revalidate: zlg_ffs_revalidate,};/*********************************************************************************************************
** Function name: zlg_ffs_make_request
** Descriptions: replace __make_request() in this module.
** Input:queue: request queue
** rw: command(read or write)
** bh: information of block
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-3-23
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int zlg_ffs_make_request(request_queue_t *queue, int rw, struct buffer_head *bh){ uint32 temp, SecSize; int32 size; unsigned long flag; Disk_RW_Parameter dp; FFSDisk *fdp; temp = MINOR(bh->b_rdev); if (temp >= MAX_DRIVES) { static int count = 0; if (count++ < 5) { printk(KERN_WARNING DEVICE_NAME ": request past end of device\n"); } bh->b_end_io(bh, 0); return 0; } /* Figure out what we are doing */ fdp = FFSDiskInfo + temp; dp.RsvdForLow = fdp; SecSize = fdp->Drive->BytsPerSec; dp.SectorIndex = bh->b_rsector; dp.Buf = bh->b_data; size = bh->b_size; /* Do the transfer */ switch(rw) { case READ: case READA: /* Readahead */ while (size >= SecSize) { local_irq_save(flag); ZLG_FFS(DISK_READ_SECTOR, &dp); local_irq_restore(flag); size = size - SecSize; dp.SectorIndex++; dp.Buf += SecSize; } bh->b_end_io(bh, 1); break; case WRITE: refile_buffer(bh); while (size >= SecSize) { local_irq_save(flag); ZLG_FFS(DISK_WRITE_SECTOR, &dp); local_irq_restore(flag); size = size - SecSize; dp.SectorIndex++; dp.Buf += SecSize; } mark_buffer_uptodate(bh, 1); bh->b_end_io(bh, 1); break; default: /* can't happen */ bh->b_end_io(bh, 0); break; } /* Nonzero return means we're done */ return 0; }/*********************************************************************************************************
** Function name: zlg_ffs_open
** Descriptions: open device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-3-23
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int zlg_ffs_open(struct inode *inode, struct file *filp){ int num; unsigned long flag; Disk_RW_Parameter dp; num = MINOR(inode->i_rdev); if (num >= MAX_DRIVES) { return -ENODEV; } local_irq_save(flag); ZLG_FFS_usage[num]++; if (ZLG_FFS_usage[num] == 1) { FFSDiskInfo[num].Drive = &(FlashDriverInfo[num]); dp.RsvdForLow = FFSDiskInfo + num; ZLG_FFS(DISK_INIT, &dp); ZLG_FFS_sizes[num] = FFSDiskInfo[num].BlockSum * FlashDriverInfo[num].BytsPerSec * FlashDriverInfo[num].SecsPreBlock / 1024; ZLG_FFS_blocksizes[num] = FlashDriverInfo[num].BytsPerSec; register_disk(NULL, MKDEV(MAJOR_NR, num), 1, &zlg_ffs_fops, FFSDiskInfo[num].BlockSum * FlashDriverInfo[num].SecsPreBlock); } local_irq_restore(flag); MOD_INC_USE_COUNT; return 0; /* success */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -