/* Give the current message to the calling
* process - the parameter we got is a pointer, fill it. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
i = device_read(file, (char*)ioctl_param, 99, 0);
#else
i = device_read(inode, file, (char*)ioctl_param, 99);
#endif
/* Warning - we assume here the buffer length is
* 100. If it's less than that we might overflow
* the buffer, causing the process to core dump.
*
* The reason we only allow up to 99 characters is
* that the NULL which terminates the string also needs room. */
/* Put a zero at the end of the buffer, so it will be properly terminated */
put_user('\0', (char*)ioctl_param+i);
break;
case IOCTL_GET_NTH_BYTE:
/* This ioctl is both input (ioctl_param) and
* output (the return value of this function) */
return Message[ioctl_param];
break;
}
return SUCCESS;
}
/* Module Declarations *************************** */
/* This structure will hold the functions to be called
* when a process does something to the device we
* created. Since a pointer to this structure is kept in
* the devices table, it can't be local to
* init_module. NULL is for unimplemented functions. */
struct file_operations Fops = {
NULL, /* seek */
device_read,
device_write,
NULL, /* readdir */
NULL, /* select */
device_ioctl, /* ioctl */
NULL, /* mmap */
device_open,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
NULL, /* flush */
#endif
device_release /* a.k.a. close */
};
/* Initialize the module - Register the character device */
int init_module() {
int ret_val;
/* Register the character device (atleast try) */
ret_val = module_register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
/* Negative values signify an error */
if (ret_val < 0) {
printk("%s failed with %d\n", "Sorry, registering the character device ", ret_val);
return ret_val;
}
printk("%s The major device number is %d.\n", "Registeration is a success", MAJOR_NUM);
printk("If you want to talk to the device driver,\n");
printk ("you'll have to create a device file. \n");
printk ("We suggest you use:\n");
printk ("mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
printk ("The device file name is important, because\n");
printk ("the ioctl program assumes that's the\n");
printk ("file you'll use.\n");
return 0;
}
/* Cleanup - unregister the appropriate file from /proc */
void cleanup_module() {
int ret;
/* Unregister the device */
ret = module_unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
/* If there's an error, report it */
if (ret < 0) printk("Error in module_unregister_chrdev: %d\n", ret);
}
/* chardev.h - the header file with the ioctl definitions.
*