#include // for printk()
#include // for register_chrdev()
#include // for put_user(), get_user()
#include // for inb(), outb()
char modname[] = "cmosram";// name of this kernel module
char devname[] = "cmos";// name for the device's file
intmy_major = 70;// major ID-number for driver
intcmos_size = 128;// total bytes of cmos memory
intwrite_max = 9;// largest 'writable' address
ssize_t my_read( struct file *file, char *buf, size_t len, loff_t *pos )
{
unsigned chardatum;
if ( *pos >= cmos_size ) return 0;
outb( *pos, 0x70 ); datum = inb( 0x71 );
if ( put_user( datum, buf ) ) return -EFAULT;
*pos += 1;
return1;
}
ssize_t my_write( struct file *file, const char *buf, size_t len, loff_t *pos )
{
unsigned chardatum;
if ( *pos >= cmos_size ) return 0;
if ( *pos > write_max ) return -EPERM;
if ( get_user( datum, buf ) ) return -EFAULT;
outb( *pos, 0x70 ); outb( datum, 0x71 );
*pos += 1;
return1;
}
loff_t my_llseek( struct file *file, loff_t pos, int whence )
{
loff_tnewpos = -1;
switch ( whence )
{
case 0:newpos = pos; break;// SEEK_SET
case 1: newpos = file->f_pos + pos; break;// SEEK_CUR
case 2: newpos = cmos_size + pos; break;// SEEK_END
}
if (( newpos < 0 )||( newpos > cmos_size )) return -EINVAL;
file->f_pos = newpos;
returnnewpos;
}
struct file_operations my_fops = {
owner:THIS_MODULE,
llseek:my_llseek,
write:my_write,
read:my_read,
};
static int __init my_init( void )
{
printk( "<1>nInstalling '%s' module ", devname );
printk( "(major=%d) n", my_major );
returnregister_chrdev( my_major, devname, &my_fops );
}
static void __exit my_exit(void )
{
unregister_chrdev( my_major, devname );
printk( "<1>Removing '%s' modulen", devname );
}
module_init( my_init );
module_exit( my_exit );
MODULE_LICENSE("GPL");