simple character device driver

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

 



Hi all,

I have modified a simple character device driver as an exercise from the 
Cooperstein's Linux Device Drivers book.

It seems to work fine except that when I "cat /dev/mycdrv" it provides garbage. 

This is a trimmed down version of the code:

#include <linux/module.h>       /* for modules */
#include <linux/fs.h>           /* file_operations */
#include <linux/uaccess.h>      /* copy_(to,from)_user */
#include <linux/init.h>         /* module_init, module_exit */
#include <linux/slab.h>         /* kmalloc */
#include <linux/cdev.h>         /* cdev utilities */

#define MYDEV_NAME "mycdrv"
#define KBUF_SIZE (size_t)( PAGE_SIZE ) 

static char *kbuf;
static dev_t first;
static unsigned int count = 1;
static int my_major = 700, my_minor = 0;
static struct cdev *my_cdev;
static int counter = 0;

static int mycdrv_open (struct inode *inode, struct file *file)
{
    printk( KERN_INFO " open #%d\n", ++counter );
    kbuf = kmalloc (KBUF_SIZE, GFP_KERNEL);
    memset( kbuf, '\0', KBUF_SIZE ); 
    return 0;
}

static int mycdrv_release (struct inode *inode, struct file *file)
{
    printk (KERN_INFO " CLOSING device: %s:\n\n", MYDEV_NAME);
    kfree( kbuf );
    --counter;
    return 0;
}

static ssize_t
mycdrv_read (struct file *file, char __user * buf, size_t lbuf, loff_t * ppos)
{
    int nbytes, maxbytes, bytes_to_do;
    maxbytes = KBUF_SIZE - *ppos;
    bytes_to_do = lbuf <= maxbytes ? lbuf : maxbytes;
    nbytes = lbuf - copy_to_user (buf, kbuf + *ppos, bytes_to_do);
    *ppos += nbytes;
    printk (KERN_INFO "\n READING function, nbytes=%d, pos=%d\n", nbytes,
            (int)*ppos);
    return nbytes;
}

static const struct file_operations mycdrv_fops = {
    .owner = THIS_MODULE,
    .read = mycdrv_read,
    .write = mycdrv_write,
    .open = mycdrv_open,
    .release = mycdrv_release,
    .llseek = mycdrv_llseek
};

static int __init my_init (void)
{
    first = MKDEV (my_major, my_minor);
    alloc_chrdev_region( &first, 0, count, MYDEV_NAME );
    printk ( KERN_INFO "Device %s: MAJOR %d, MINOR %d\n", MYDEV_NAME, MAJOR( 
first ), MINOR( first ) );
    my_cdev = cdev_alloc ();
    cdev_init (my_cdev, &mycdrv_fops);
    cdev_add (my_cdev, first, count);
    printk (KERN_INFO "\nSucceeded in registering character device %s\n",
            MYDEV_NAME);
    return 0;
}

static void __exit my_exit (void)
{
    cdev_del (my_cdev);
    unregister_chrdev_region (first, count);
    printk (KERN_INFO "\ndevice unregistered\n");
}

module_init (my_init);
module_exit (my_exit);

Please, could someone explain why the readings of the device return garbage 
data instead of NULL characters as I have set with memset()?

Thanks in advance.

fabio

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at 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