title: Linux Char Driver: blocking ioctl call
body: <p>I am new to driver development, and I am trying to write a simple char driver that has ioctl that allows user process to get the time(timespec) that my char driver took on last read and write.
  </p>
  
  <pre class="lang-c prettyprint-override"><code>long charmem_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
      struct charmem_dev *dev = filp-&gt;private_data;
  
      if (down_interruptible(&amp;dev-&gt;sem)) {
          printk(KERN_WARNING "I got booted!!\n");
          return -ERESTARTSYS;
      }
  
      printk(KERN_WARNING "charmem: in ioctl; cmd = %d, arg = %d\n", (int)cmd, (int)arg);
      switch(cmd) {
          case IOCTL_GET_LAST_READ_TIME:
              printk("charmem_ioctl: returning last read time delta, exiting...\n");
              up(&amp;dev-&gt;sem);
              return dev-&gt;last_read_delta.tv_nsec;
              break;
  
          case IOCTL_GET_LAST_WRITE_TIME:
              printk("charmem_ioctl: returning last write time delta, exiting...\n");
              up(&amp;dev-&gt;sem);
              return dev-&gt;last_write_delta.tv_nsec;
              break;
  
          case IOCTL_RESET_READ: /*return read-pointer to the start of buffer*/
              dev-&gt;rp = dev-&gt;buffer;
              break;
          case IOCTL_RESET_WRITE: /*return write-pointer to the start of buffer*/
              dev-&gt;wp = dev-&gt;buffer;
              break;
          case IOCTL_LOAD_BUFFER_TO_CACHE:
              load_buffer_to_cache(dev-&gt;buffer, dev-&gt;buffer_size);
              break;
          default:
              printk("charmem_ioctl: invalid ioctl command, exiting...\n");
              up(&amp;dev-&gt;sem);
              return -EFAULT;
      }
  
      up(&amp;dev-&gt;sem);
      return 0;
  }
  
  struct file_operations charmem_fops = {
      .owner = THIS_MODULE,
      .llseek = no_llseek,
      .read = charmem_read,
      .write = charmem_write,
      .unlocked_ioctl = charmem_ioctl,
      .open = charmem_open,
      .release = charmem_release,
  };
  </code></pre>
  
  <p><code>main.c</code> -- user program that tests my char device:</p>
  
  <pre class="lang-c prettyprint-override"><code>int fd = 0, ret = 0;
  fd = open("/dev/charmem0", O_RDWR);
  if (fd &lt; 0) {
      printf("/dev/charmem0  unable to access (fd = %d)... EXITING\n", fd);
      return -1;
  }
  
  ret = write(fd,msg1,10);
  ret = read(fd,user_buffer,10);
  read_delta = ioctl(fd, IOCTL_GET_LAST_READ_TIME);
  printf("read_delta : %d\n ", read_delta);
  write_delta = ioctl(fd, IOCTL_GET_LAST_WRITE_TIME);
  printf("write_delta : %d\n ", write_delta);
  </code></pre>
  
  <p><code>main.c</code> is the program that tests my char device; the program blocks after printing out <code>read_delta</code> value, and I am assuming that it blocks on ioctl. What am I doing wrong in my code?</p>