RE: my driver is dropping characters

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

 



Can't it be because you are using size = 1byte in copy_from_user? Make it 'count'.

--
Thanks,
Nilesh

---------------------------------------------------------

From: kernelnewbies-bounce@xxxxxxxxxxxx [mailto:kernelnewbies-bounce@xxxxxxxxxxxx] On Behalf Of Bond
Sent: Wednesday, September 15, 2010 5:27 PM
To: kernelnewbies
Subject: my driver is dropping characters

I wrote my hello world type of character device driver.(First driver that I wrote)
I created a device as follows

mknod /dev/bond c 60 0
and then tried to write something to that device as follows
echo -n abcde > /dev/bond


cat /dev/bond
will show me the last
e of entered abcde
above but will drop abcd.
I can see the last character which was passed on to as argument to echo but not the previous characters.

Any idea what improvement should I make.
Here is the code.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */




/* Declaration of memory.c functions */
int bond_open(struct inode *inode, struct file *filp) { return 0;};
int bond_release(struct inode *inode, struct file *filp){ return 0;};
ssize_t bond_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
 
  /* Transfering data to user space */
  copy_to_user(buf,bond_buffer,1);


  /* Changing reading position as best suits */
  if (*f_pos == 0) {
    *f_pos+=1;
    return 1;
  } else {
    return 0;
  }
};




ssize_t bond_write(struct file *filp, char *buf, size_t count, loff_t *f_pos)
 {


  char *tmp;


  tmp=buf+count-1;
  copy_from_user(bond_buffer,tmp,1);
  return 1;
} ;
void bond_exit(void);
int bond_init(void);


/* Structure that declares the usual file */
/* access functions */
struct file_operations bond_fops = {
  read: bond_read,
  write: bond_write,
  open: bond_open,
  release: bond_release
};


/* Global variables of the driver */
/* Major number */
int bond_major = 60;
/* Buffer to store data */
char *bond_buffer;


static int bond_init(void) {
  printk("<1> Hello bond new driver!\n");
     int result;


      /* Registering device */
      result = register_chrdev(bond_major, "bond", &bond_fops);
      if (result < 0) {
        printk(
          "<1>memory: cannot obtain major number %d\n", bond_major);
        return result;
      }


      /* Allocating memory for the buffer */
      bond_buffer = kmalloc(1, GFP_KERNEL);
      if (!bond_buffer) {
        result = -ENOMEM;
        goto fail;
      }
      memset(bond_buffer, 0, 1);


      printk("<1>Inserting bond module\n");
      return 0;


      fail:
        bond_exit();
        return result;
      return 0;
 }


static void bond_exit(void) {
  printk("<1> Bye, bond world\n");
/* Freeing the major number */
  unregister_chrdev(bond_major, "bond");


  /* Freeing buffer memory */
  if (bond_buffer) {
    kfree(bond_buffer);
  }


  printk("<1>Removing bond module\n");




}


module_init(bond_init);
module_exit(bond_exit);



--
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