📄 block.c
字号:
/* * Mambo IDE Device Driver for PC * * First version by Ho Lee 2003/06/12 - 2003/06/13 */#include <linux/kernel.h>#include <linux/module.h>/*#ifdef CONFIG_MODVERSIONS#define MODVERSIONS#include <linux/modversions.h>#endif*/#include <linux/fs.h>#include <linux/vmalloc.h>#include <asm/uaccess.h>#include <linux/devfs_fs_kernel.h>#define DEVICE_NAME "MamboIDE" /* device name */#define DEVICE_FILENAME "mamboide" /* device node name */#define MAMBOIDE_MAXUNIT 2 /* 2 units : master / slave */#define MAMBOIDE_SHIFT 6 /* max 64 partitions */#define DEVICE_NUM (MAMBOIDE_MAXUNIT << MAMBOIDE_SHIFT)#define MAMBOIDE_BLOCKSIZE 4096 /* sizeof block */#define MAMBOIDE_SECTSIZE 512 /* sizeof sector */#define MAMBOIDE_RAHEAD 4 /* read ahead */extern int s_nMajor;#define MAJOR_NR s_nMajor // IDE2_MAJOR => hde/hdf, IDE3_MAJOR = hdg/hdh#define MAJOR_NAME "mhd"#define DEVICE_NR(device) (MINOR(device) >> MAMBOIDE_SHIFT)#define DEVICE_PARTNR(device) (MINOR(device) & ((1 << MAMBOIDE_SHIFT) - 1))#define DEVICE_ON(device) /* do nothing */#define DEVICE_OFF(device) /* do nothing */#define DEVICE_NO_RANDOM#include <linux/blk.h>#include <linux/blkpg.h>#include <linux/genhd.h>#include <linux/hdreg.h>#include "mum.h"#include "ide.h"/* * Globak Variables */static int s_nMajor = 0;static int s_kbsize[DEVICE_NUM]; /* size in blocks of 1024 bytes */static int s_blocksize[DEVICE_NUM]; /* size of 1024 byte block */static int s_hardsect[DEVICE_NUM]; /* sizeof real block in bytes */static devfs_handle_t devfs_handle;static int s_ide_map[MAX_DRIVES];static int s_ide_found = 0;/* * Function Prototypes */static int mamboide_open(struct inode *inodep, struct file *filp);static int mamboide_release(struct inode *inodep, struct file *filp);static int mamboide_revalidate(kdev_t i_rdev);static int mamboide_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg);static int mamboide_make_request(request_queue_t *q, int rw, struct buffer_head *sbh);//static void mamboide_request(request_queue_t *q);/* * Device Operations */static struct block_device_operations mamboide_fops = { owner : THIS_MODULE, open : mamboide_open, release : mamboide_release, ioctl : mamboide_ioctl, revalidate : mamboide_revalidate,};struct gendisk s_mamboide_gendisk = { // major : MAJOR_NR, major_name : MAJOR_NAME, minor_shift : MAMBOIDE_SHIFT, max_p : 1 << MAMBOIDE_SHIFT, fops : &mamboide_fops,};struct hd_struct s_mamboide_partitions[DEVICE_NUM];/* * Module startup/cleanup */int init_module(void){ static int s_major_list[] = { IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR, -1, }; int i, n, mask, map; printk("Loading Mambo Mambo IDE Driver v1.1.0\n"); // // Probing IDE devices // for (i = 0, mask = 0; mum_open(i) == 0; ++i) { mask |= (0x03 << (i * 2)); printk("Found Mambo device %d\n", i); } if (mask == 0) { printk("No Mambo device.\n"); return -ENODEV; } if ((s_ide_found = ide_probe(mask, 1)) == 0) { printk("No device on IDE bus.\n"); return -ENODEV; } else printk("Found %d IDE devices\n", s_ide_found); for (i = 0, n = 0; i < MAX_DRIVES; ++i) if (g_ideinfo[i].type != IDE_NONE) s_ide_map[n++] = i; for (; n < MAX_DRIVES; ++n) s_ide_map[n] = -1; // // register device files // for (i = 0; s_major_list[i] >= 0; ++i) { if ((s_nMajor = devfs_register_blkdev(s_major_list[i], DEVICE_NAME, &mamboide_fops)) >= 0) break; } if (s_nMajor < 0) { printk(DEVICE_NAME " : Driver registration failed (%d)\n", s_nMajor); return s_nMajor; } else s_nMajor = s_major_list[i]; printk(DEVICE_NAME " : Driver registered with Major Number = %d\n", MAJOR_NR); devfs_handle = devfs_mk_dir(NULL, DEVICE_FILENAME, NULL); devfs_register_series(devfs_handle, "%u", DEVICE_NUM, DEVFS_FL_DEFAULT, s_nMajor, 0, S_IFBLK | S_IRUGO | S_IWUGO, &mamboide_fops, NULL); // // setup information // for (i = 0; i < DEVICE_NUM; ++i) { s_blocksize[i] = MAMBOIDE_BLOCKSIZE; s_hardsect[i] = MAMBOIDE_SECTSIZE; } for (i = 0; i < MAX_DRIVES; ++i) { map = s_ide_map[i]; if (map >= 0 && g_ideinfo[map].type != IDE_NONE) { n = i << MAMBOIDE_SHIFT; s_kbsize[n] = g_ideinfo[map].nsectors >> 1; s_mamboide_partitions[n].nr_sects = g_ideinfo[map].nsectors; printk("Registered IDE %d : size = %dMB\n", i, s_kbsize[n] >> 10); } } blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), &mamboide_make_request); //blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mamboide_request); read_ahead[MAJOR_NR] = MAMBOIDE_RAHEAD; blk_size[MAJOR_NR] = s_kbsize; blksize_size[MAJOR_NR] = s_blocksize; hardsect_size[MAJOR_NR] = s_hardsect; s_mamboide_gendisk.major = MAJOR_NR; s_mamboide_gendisk.sizes = s_kbsize; s_mamboide_gendisk.part = s_mamboide_partitions; s_mamboide_gendisk.nr_real = MAMBOIDE_MAXUNIT; add_gendisk(&s_mamboide_gendisk); for (i = 0; i < MAMBOIDE_MAXUNIT; ++i) { map = s_ide_map[i]; register_disk(&s_mamboide_gendisk, MKDEV(MAJOR_NR, i << MAMBOIDE_SHIFT), MAMBOIDE_SHIFT, &mamboide_fops, g_ideinfo[map].nsectors); } return 0;}void cleanup_module(void){ int i; printk("Unloading Mambo IDE Module\n"); del_gendisk(&s_mamboide_gendisk); for (i = 0; i < DEVICE_NUM; ++i) destroy_buffers(MKDEV(MAJOR_NR, i)); /* flush the devices */ // blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); devfs_unregister(devfs_handle); devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME); read_ahead[MAJOR_NR] = 0; blk_size[MAJOR_NR] = NULL; blksize_size[MAJOR_NR] = NULL; hardsect_size[MAJOR_NR] = NULL; mum_closeall();}/* * Device Operations */int mamboide_open(struct inode *inodep, struct file *filp){ if (MINOR(inodep->i_rdev) >= DEVICE_NUM) return -ENXIO; MOD_INC_USE_COUNT; return 0;}int mamboide_release(struct inode *inodep, struct file *filp){ MOD_DEC_USE_COUNT; return 0;}int mamboide_revalidate(kdev_t i_rdev){ int i; int unit = DEVICE_NR(i_rdev); int part1 = (unit << MAMBOIDE_SHIFT) + 1; int npart = (1 << MAMBOIDE_SHIFT) - 1; memset(s_kbsize + part1, 0, npart * sizeof(int)); for (i = 0; i < npart; ++i) { s_mamboide_partitions[part1 + i].start_sect = 0; s_mamboide_partitions[part1 + i].nr_sects = 0; } grok_partitions(&s_mamboide_gendisk, unit, 1 << MAMBOIDE_SHIFT, s_kbsize[unit << MAMBOIDE_SHIFT]); return 0;}int mamboide_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg){ int minor = MINOR(inodep->i_rdev); int unit = DEVICE_NR(inodep->i_rdev); long devsize; switch (cmd) { case BLKGETSIZE : /* return device size */ devsize = s_mamboide_partitions[minor].nr_sects; // printk("BLKGETSIZE %d = %d\n", minor, devsize); return put_user(devsize, (long *) arg); case HDIO_GETGEO : { struct hd_geometry geo; int map = s_ide_map[unit]; geo.cylinders = g_ideinfo[map].cyls; geo.heads = g_ideinfo[map].heads; geo.sectors = g_ideinfo[map].sectors; geo.start = s_mamboide_partitions[minor].start_sect; // printk("GETGEO %d %d %d %d\n", geo.cylinders, geo.heads, geo.sectors, geo.start); copy_to_user((void *) arg, &geo, sizeof geo); return 0; } break; case BLKRRPART : // printk("BLKRRPART\n"); return mamboide_revalidate(inodep->i_rdev); case BLKROSET : case BLKROGET : case BLKRAGET : case BLKRASET : default : return blk_ioctl(inodep->i_rdev, cmd, arg); } return 0;}/* * Request Processing */ #if 1int mamboide_make_request(request_queue_t *q, int rw, struct buffer_head *sbh){ char *bdata; int minor = MINOR(sbh->b_rdev); int unit = DEVICE_NR(sbh->b_rdev); int map = s_ide_map[unit]; unsigned int block, nsector; block = sbh->b_rsector + s_mamboide_partitions[minor].start_sect; nsector = sbh->b_size / SECTOR_SIZE; bdata = bh_kmap(sbh); switch (rw) { case READ : case READA : // printk("read : %d, %d\n", block, nsector); ide_rw_block(1, 0, map, block, bdata, nsector); break; case WRITE : // printk("write : %d, %d\n", block, nsector); ide_rw_block(0, 0, map, block, bdata, nsector); break; default : goto fail; } sbh->b_end_io(sbh, 1); return 0; fail: sbh->b_end_io(sbh, 0); return 0;}#elsevoid mamboide_request(request_queue_t *q){ unsigned int block, nsector; for (;;) { INIT_REQUEST; block = CURRENT->sector; nsector = CURRENT->current_nr_sectors; switch (CURRENT->cmd) { case READ : // printk("READ : %d, %d\n", block, nsector); ide_rw_block(1, 0, 0, block, CURRENT->buffer, nsector); break; case WRITE : // printk("WRITE : %d, %d\n", block, nsector); ide_rw_block(0, 0, 0, block, CURRENT->buffer, nsector); break; } end_request(1); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -