Re: my driver is dropping characters

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

 



Hi,

the problem is your bond_buffer and how you handle read and writes from it.
(see below)

2010/9/15 Bond <jamesbond.2k.g@xxxxxxxxx>:
> 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);
you just copy one byte to the buffer instead of count.

>
>
>   /* 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);
you just copy the last byte from buf (buf+count-1) to your
bond_buffer. you should copy count bytes, starting by buf.
>   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);
your bond buffer is just one byte big. you need a bigger one
(PAGE_SIZE maybe). beware that you check in your read and write
functions, that you don't copy more bytes then the bond_buffer can
hold...
>       if (!bond_buffer) {
>         result = -ENOMEM;
>         goto fail;
>       }
>       memset(bond_buffer, 0, 1);
set the whole buffer to zero.
>
>
>       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);
>
>
>
>



-- 
motzblog.wordpress.com

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