Reputation: 13330
I have
#define IOCTL_ALLOC_MSG _IO(MAJOR_NUM, 0)
#define IOCTL_DEALLOC_MSG _IO(MAJOR_NUM, 1)
in a header file.
and in the driver file I wrote:
struct file_operations memory_fops = {
unlocked_ioctl: device_ioctl,
open: memory_open,
release: memory_release
};
int memory_init(void) {
int result;
/* Registering device */
result = register_chrdev(MAJOR_NUM, "memory", &memory_fops);
if (result < 0) {
printk("<1>memory: cannot obtain major number %d\n", MAJOR_NUM);
return result;
}
allocfunc();
printk("<1>Inserting memory module\n");
return 0;
}
int device_ioctl(struct inode *inode, /* see include/linux/fs.h */
struct file *file, /* ditto */
unsigned int ioctl_num, /* number and param for ioctl */
unsigned long ioctl_param)
{
/*
* Switch according to the ioctl called
*/
printk ( "<l> inside ioctl \n" );
switch (ioctl_num) {
case IOCTL_ALLOC_MSG:
allocfunc();
break;
case IOCTL_DEALLOC_MSG:
deallocfunc();
break;
}
return 0;
}
I created the character file like
mknod /dev/memory c 60 0
the app call fails
int main(int argc, char *argv[]) {
FILE * memfile;
/* Opening the device parlelport */
memfile=fopen("memory","r+");
if ( memfile <0) {
printf ( " cant open file \n");
return -1;
}
/* We remove the buffer from the file i/o */
int ret_val;
if ( argc > 1 ) {
if ( strcmp (argv[1], "mem" ) ==0 ) {
ret_val = ioctl(memfile, IOCTL_ALLOC_MSG);
if (ret_val < 0) {
printf("ioctl failed. Return code: %d, meaning: %s\n", ret_val, strerror(errno));
return -1;
}
}
when i run the app i get "ioctl failed. Return code: -1, meaning: Invalid argument" in : strerror(errno)
printk:
Inserting memory module
fyi, I experimented with "/dev/memory" "memory" different names and major number combinations - but in vain.
Upvotes: 0
Views: 20462
Reputation: 98496
You are passing a FILE*
to the ioctl()
function, while it expects a file descriptor, that is an int
.
It should at the very least generate a big warning saying that you are converting a pointer to integer without a cast, doesn't it?
There are two obvious solutions:
fileno()
function to get the file descriptor from the FILE*
. It should be something like ioctl(fileno(memfile), IOCTL_ALLOC_MSG)
.open()
instead of fopen()
. This one is the preferred solution if you are writing low level code, as you avoid the additional abstraction layer that FILE*
imposes (all the buffering stuff and so).Upvotes: 5
Reputation: 2792
I'm going to postulate that changing fopen("memory")
to fopen("/dev/memory1")
will fix the initial problem with your code.
@SunEric also points out in a comment on your question that you have a call to allocFunc()
in your driver's initialization function (memory_init()
), and yet that seems to be what you want your IOCTL_ALLOC_MSG
to do. That may well be the next problem you need to straighten out.
Upvotes: 0