#include #include #include #include #include #define BD_MAJOR 242 #define SIZE_IN_KBYTES (8*1024) MODULE_LICENSE("GPL"); static struct gendisk *disk; static struct request_queue *bdqueue; static char *DiscSpace; static struct block_device_operations bdops = { .owner = THIS_MODULE, }; static int bdMakeRequest( request_queue_t *q, struct bio *bio ) { char *kaddr, *maddr; struct bio_vec *bvec; int segnr, BytesTransferred=0; blk_queue_bounce( q, &bio ); bio_for_each_segment( bvec, bio, segnr ) { kaddr = bio_data(bio); maddr = DiscSpace + (512 * bio->bi_sector); BytesTransferred += bio->bi_size; if( bio_data_dir( bio )==READ || bio_data_dir( bio )==READA ) { memcpy( kaddr, maddr, bio->bi_size ); } else { memcpy( maddr, kaddr, bio->bi_size ); } } bio_endio( bio, BytesTransferred, 0 ); return 0; } static int __init ModInit(void) { if( register_blkdev(BD_MAJOR, "bdsample" )) { printk("blockdevice: Majornummer %d not free.", BD_MAJOR); return -EIO; } if( !(DiscSpace=vmalloc(SIZE_IN_KBYTES*1024)) ) { printk("vmalloc failed ...\n"); goto out_no_mem; } bdqueue = blk_alloc_queue( GFP_KERNEL ); blk_queue_make_request( bdqueue, bdMakeRequest ); disk = alloc_disk(1); if( !disk ) { printk("alloc_disk failed ...\n"); goto out; } disk->major = BD_MAJOR; disk->first_minor = 0; disk->fops = &bdops; disk->queue = bdqueue; sprintf(disk->disk_name, "bd0"); set_capacity( disk, (SIZE_IN_KBYTES*1024)>>9 ); // in 512 Byte Bloecke add_disk( disk ); return 0; out: vfree( DiscSpace ); out_no_mem: unregister_blkdev(BD_MAJOR, "bdsample" ); return -EIO; } static void __exit ModExit(void) { unregister_blkdev(BD_MAJOR, "bdsample" ); del_gendisk(disk); put_disk( disk ); blk_cleanup_queue( bdqueue ); vfree( DiscSpace ); } module_init( ModInit ); module_exit( ModExit );