📄 zlg_fs.c
字号:
/****************************************Copyright (c)**************************************************** Guangzou ZLG-MCU Development Co.,LTD.** graduate school** http://www.zlgmcu.com****--------------File Info-------------------------------------------------------------------------------** File name: zlg_fs.c** Last modified Date: 2005-05-25** 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/FS . **------------------------------------------------------------------------------------------------------** Created by: Chenmingji** Created date: 2005-05-25** Version: 1.0** Descriptions: The original version****------------------------------------------------------------------------------------------------------** Modified by: Chenmingji** Modified date: 2005-05-25** Version: 1.01** Descriptions: Modified zlg_fs_cleanup()**********************************************************************************************************/#define IN_ZLG_FS#include "config.h"/******************************************************************************************************** function announce********************************************************************************************************/static int zlg_fs_open(struct inode *inode, struct file *filp);static int zlg_fs_release(struct inode *inode, struct file *filp); static int zlg_fs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param);static int check_zlg_fs_change(kdev_t dev);static int zlg_fs_revalidate(kdev_t dev);int zlg_fs_init(void);void zlg_fs_cleanup(void);/******************************************************************************************************** function announce********************************************************************************************************/#define MAJOR_NR major /* force definitions on in blk.h */#define DEVICE_NO_RANDOM /* no entropy to contribute */#define DEVICE_OFF(d) /* do-nothing */MODULE_PARM(major, "i");module_init(zlg_fs_init);module_exit(zlg_fs_cleanup);#define DEVICE_NR(device) (MINOR(device) >> ZLG_FS_SHIFT)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/FS");MODULE_AUTHOR("chenmingji");/*********************************************************************************************************** "全局和静态变量在这里定义" ** global variables and static variables define here********************************************************************************************************/static int major = ZLG_FS_MAJOR_NR; /* must be declared before including blk.h */#include <linux/blk.h>static int ZLG_FS_blocksizes[MAX_DISKS << ZLG_FS_SHIFT]; /* bytes per device */static int ZLG_FS_sizes[MAX_DISKS << ZLG_FS_SHIFT]; /* bytes per device's block */ /* must be (1 << n) */static unsigned int ZLG_FS_usage[MAX_DISKS]; /* device using count */fs_drivers *DiskInfo[MAX_DISKS];static struct hd_struct part[MAX_DISKS << ZLG_FS_SHIFT];struct gendisk zlg_fs_gendisk;/********************************************************************************************************/static struct block_device_operations zlg_fs_fops = /* driver info */{ owner: THIS_MODULE, open: zlg_fs_open, release: zlg_fs_release, ioctl: zlg_fs_ioctl, check_media_change: check_zlg_fs_change, revalidate: zlg_fs_revalidate,};/*********************************************************************************************************** Function name: zlg_fs_add_driver** Descriptions: add driver.** Input:info: driver info** Output 0: OK** other: not OK** Created by: Chenmingji** Created Date: 2005-05-25**-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/ int zlg_fs_add_driver(fs_drivers *info){ int i; for (i = 0; i < MAX_DISKS; i++) { if (DiskInfo[i] == NULL) { DiskInfo[i] = info; return 0; } } return -1; }/*********************************************************************************************************** Function name: zlg_fs_remove_driver** Descriptions: replace __make_request() in this module.** Descriptions: remove driver** Input:info: driver info** Output 0: OK** other: not OK** Created by: Chenmingji** Created Date: 2005-05-25**-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/ int zlg_fs_remove_driver(fs_drivers *info){ int i; for (i = 0; i < MAX_DISKS; i++) { if (DiskInfo[i] == info) { DiskInfo[i] = NULL; return 0; } } return -1;}/*********************************************************************************************************** Function name: zlg_fs_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-05-25**-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/ static int zlg_fs_make_request(request_queue_t *queue, int rw, struct buffer_head *bh){ u32 temp, SecSize; u32 size; int part, num, nr; Disk_RW_Parameter dp; fs_drivers *fs; num = DEVICE_NR(bh->b_rdev); nr = MINOR(bh->b_rdev); if (num >= MAX_DISKS) { 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; } fs = DiskInfo[num]; /* Figure out what we are doing */ dp.RsvdForLow = fs->RsvdForLow; SecSize = fs->BytesPerSec; dp.SectorIndex = bh->b_rsector + zlg_fs_gendisk.part[nr].start_sect; dp.Buf = bh->b_data; size = bh->b_size; if (bh->b_rsector + size / SecSize >= zlg_fs_gendisk.part[nr].nr_sects) { bh->b_end_io(bh, 0); return 0; } /* Do the transfer */ switch(rw) { case READ: case READA: /* Readahead */ while (size >= SecSize) { DiskInfo[num]->DiakCommand(DISK_READ_SECTOR, &dp); size = size - SecSize; dp.SectorIndex++; dp.Buf += SecSize; } bh->b_end_io(bh, 1); break; case WRITE: refile_buffer(bh); while (size >= SecSize) { DiskInfo[num]->DiakCommand(DISK_WRITE_SECTOR, &dp); 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_fs_queue** Descriptions: queue device** Input:q: queue** Output 0: OK** other: not OK** Created by: Chenmingji** Created Date: 2005-05-25**-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/#if 0 static int zlg_fs_queue(request_queue_t *q){ return 0; } #endif/*********************************************************************************************************** Function name: zlg_fs_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-05-25**-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/ static int zlg_fs_open(struct inode *inode, struct file *filp){ int num; unsigned long flag; Disk_RW_Parameter dp; num = DEVICE_NR(inode->i_rdev); if (num >= MAX_DISKS) { return -ENODEV; } if (DiskInfo[num] == NULL) { return -ENODEV; } //local_irq_save(flag); ZLG_FS_usage[num]++; if (ZLG_FS_usage[num] == 1) { dp.RsvdForLow = DiskInfo[num]->RsvdForLow; DiskInfo[num]->DiakCommand(DISK_INIT, &dp); if (DiskInfo[num]->open != NULL) { DiskInfo[num]->open(inode, filp); } zlg_fs_revalidate(inode->i_rdev); } //local_irq_restore(flag); MOD_INC_USE_COUNT; return 0; /* success */} /*********************************************************************************************************** Function name: zlg_fs_release** Descriptions: release device** Input:inode: information of device** filp: pointer of file** Output 0: OK** other: not OK** Created by: Chenmingji** Created Date: 2005-05-25**-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/ static int zlg_fs_release(struct inode *inode, struct file *filp) { int num; Disk_RW_Parameter dp; unsigned long flag; int part1, npart, i; num = DEVICE_NR(inode->i_rdev); if (num >= MAX_DISKS) { return -ENODEV;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -