Reputation: 935
I am trying to implement ioctl in kernel space to write some date into the register, I am getting a crash in cmd of ioctl.
Below is my code:
Kernel side:
static struct file_operations fops = {
.compat_ioctl = device_ioctl
};
int device_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg)
{
int len = 200;
printk (KERN_INFO "In Device_ioctl !!\n");
switch(cmd)
{
case IOCTL_WRITE_REG:
write_ioctl((unsigned long *)arg);
break;
default:
printk (KERN_INFO "default\n");
return -ENOTTY;
}
printk (KERN_INFO "device_ioctl out\n");
return len;
}
User Side
#define IOCTL_WRITE_REG _IOW(MAJOR_NUM, 1, int *)
void write_to_device(int write_fd)
{
int retval;
unsigned int to_write1 = 1;
retval = ioctl(write_fd, IOCTL_WRITE_REG, &to_write1);
if(retval < 0)
{
printf("fd: %d, write error: %d\n", write_fd, errno);
exit(-1);
}
}
It is not entering into device_ioctl function, Where am I going wrong ?
Upvotes: 0
Views: 2014
Reputation: 49533
Few things I happen to notice:
unlocked_ioctl
instead of compat_ioctl
. compat_ioctl
is to allow 32-bit user space programs to invoke ioctl
calls on a 64-bit kernel.The signature of your ioctl handler function is incorrect (for unlocked_ioctl
). The expected signature is:
long (*unlocked_ioctl) (struct file * filep, unsigned int, unsigned long);
I haven't tried really compiling this code, but I think this should work:
static struct file_operations fops = {
.unlocked_ioctl = device_ioctl
};
long device_ioctl(struct file *filep,
unsigned int cmd,
unsigned long arg)
{
int len = 200;
printk (KERN_INFO "In Device_ioctl !!\n");
switch(cmd)
{
case IOCTL_WRITE_REG:
write_ioctl((unsigned long *)arg);
break;
default:
printk (KERN_INFO "default\n");
return -ENOTTY;
}
printk (KERN_INFO "device_ioctl out\n");
return len;
}
Upvotes: 3