IOCTL in Block-Device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux