Hello,
I want to provide an own ioctl in a block_device. Therefor I added my own ioctl-function in a gendisk. For testing I used a simple ramdisk found in one of the books I use to learn:
#include <linux/fs.h> #include <linux/module.h> #include <linux/init.h> #include <linux/blkdev.h>
#define BD_MAJOR 242 #define SIZE_IN_KBYTES 256
MODULE_LICENSE("GPL");
static struct gendisk *disk; static struct request_queue *bdqueue; static char *mempool; static spinlock_t bdlock = SPIN_LOCK_UNLOCKED;
static void bd_request( request_queue_t *q ) { [...] }
static int myioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { printk(KERN_ALERT "ioctl was called\n"); if (cmd == 3249) return 42; return -ENOTTY; }
static struct block_device_operations bdops = { .owner = THIS_MODULE, .ioctl = myioctl, };
static int __init mod_init(void) { if (register_blkdev(BD_MAJOR, "bdsample" )) { printk("blockdevice: Majornummer %d not free.", BD_MAJOR); return -EIO; } if( !(mempool=vmalloc(SIZE_IN_KBYTES*1024)) ) { printk("vmalloc failed ...\n"); goto out_no_mem; }
if( !(disk=alloc_disk(1)) ) {
printk("alloc_disk failed ...\n");
goto out;
}
disk->major = BD_MAJOR;
disk->first_minor = 0;
if( (bdqueue=blk_init_queue(&bd_request,&bdlock))==NULL )
goto out;
blk_queue_hardsect_size( bdqueue, 512 );
disk->queue = bdqueue;
sprintf(disk->disk_name, "bd0");
set_capacity( disk, (SIZE_IN_KBYTES * 1024)>>9 ); // in 512 Byte Bloecke
disk->fops = &bdops;
add_disk( disk );
return 0;
out:
vfree( mempool );
out_no_mem:
unregister_blkdev(BD_MAJOR, "bdsample" );
return -EIO;
}
static void __exit mod_exit(void) { del_gendisk(disk); put_disk( disk ); blk_cleanup_queue( bdqueue ); vfree( mempool ); unregister_blkdev(BD_MAJOR, "bdsample" ); }
module_init( mod_init ); module_exit( mod_exit );
Then I wrote my own Program to call the ioctl:
int main(int argc, char *argv[]) { int ret; int file_desc;
file_desc = open("/dev/bd0", 0); ret = ioctl(file_desc, 3249, 0); printf("result: %d\n", ret); }
/dev/bd0 is (242,0), what is the ramdisk. /proc/devices says after loading the module that bdsample is the driver for major 242. But calling the Programm results in the output:
result: -1
And in /var/log/messages no new entry of the ioctl is created. Only during insmod one entry "ioctl was called" was added. What is wrong with this?
If it is important: I use a i386-Architecture.
tschau
Sascha Effert fermat@xxxxxxxxxxxx Tel.:(0177) 6266652
-- Being evil means it can be christmas every day.
-- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/