ioctl problems when copying to user space

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

 




I'm having problems getting my ioctl function to write to user-space.

I call it from user space with this code:

/*======================*/

  time_stamp ts;

  if(   ioctl(fd, ioct_num, &ts) )
    {
       printf("ioctl error %d %d\n", errno, sizeof(ts));
       
    }
/*======================*/
  

My driver keeps failing at __generic_copy_to_user in the code below.
I don't see why it should not be able to copy to that address.

/*================================================*/

#define DEV_IOC_GET_TIMES    _IOWR(DEV_IOCTL_TYPE, 1, time_stamp)

typedef struct _time_stamp
{
   struct timeval write_last;
   struct timeval write_now;
   struct timeval irq_last;
   struct timeval irq_now;
}time_stamp;

int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                unsigned long arg)
{

  int ret = 0;
  int index1 = 0;
  int index2 = 0;
  int prev1 = 0;
  int prev2 = 0;
  time_stamp ts;
  char * arg_ptr = (char *) arg;

  if(_IOC_TYPE(cmd) != DEV_IOCTL_TYPE) return -ENOTTY;
  if(_IOC_NR(cmd) > DEV_IOCTL_MAXNUM) return -ENOTTY;

  switch(cmd)
    {
    case DEV_IOC_GET_TIMES:
      /*
       * return the last 2 times a usb irq was recieved
       * and a write request was recieved
       */
      if(arg_ptr == NULL)
       {
         printk("pointer is null\n");
         return -EFAULT;
       }
     
      index1 = atomic_read(&wr_times_indx);
      index2 = atomic_read(&irq_times_indx);
      prev1 = prev_pos[index1];
      prev2 = prev_pos[index2];

      ts.write_now = write_times[index1];
      ts.write_last= write_times[prev1];
      ts.irq_now = irq_times[index2];
      ts.irq_last= irq_times[prev2];

      if( ret = __generic_copy_to_user(arg_ptr, ts,
                                       sizeof(time_stamp)))
        {
            printk("copy to user failed %d %d\n", ret,
                    sizeof(time_stamp));
            ret = -EFAULT;

        }
      break;

    default:
      
      return -ENOTTY;

    }

  return ret;

}

/*========================================================*/
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           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