Skip to main content.

5.7.3. The ioctl system call

API example:


#define DIGIO_IOC_MAGIC         'C'

/* parameter for DIGIO_SET_VAL ioctl */
struct digio_par {
   unsigned int pinnr;
   unsigned int val;
};

/*
 * ioctl definitions
 */
#define DIGIO_GET_VAL   _IOR(DIGIO_IOC_MAGIC, 0, struct digio_par *)
#define DIGIO_SET_VAL   _IOW(DIGIO_IOC_MAGIC, 1, struct digio_par *)
#define DIGIO_RESET_ALL _IO(SCULL_IOC_MAGIC, 2)
#define DIGIO_IOC_MAXNR 2

static int digio_ioctl (struct inode *inode, struct file *file, uint cmd, unsigned long arg)
{
   int err;
   struct digio_par par;

   /* sanity checks */
   if(_IOC_TYPE(cmd) != DIGIO_IOC_MAGIC) return -ENOTTY;
   if(_IOC_NR(cmd) > DIGIO_IOC_MAXNR) return -ENOTTY;

   switch(cmd) {
   case DIGIO_GET_VAL:
      if((err = digio_get_pin(par.pinnr, &par.val)) < 0)
         goto out;

      if(copy_to_user((unsigned int *)arg, &par, sizeof(struct digio_par)) != 0) {
         printk(KERN_CRIT "%s: copy_to_user failed", __FUNCTION__);
         err = -EFAULT;
         goto out;
      }
      break;

   case DIGIO_SET_VAL:
      if(copy_from_user(&par, (unsigned int *)arg, sizeof(struct digio_par))) {
         err = -EFAULT;
         printk(KERN_CRIT "%s: copy_from_user failed", __FUNCTION__);
         goto out;
      }

      digio_set_pin(par.pinnr, par.val);
      break;

   case DIGIO_RESET_ALL:
      digio_reset_all();
      break;

   default:
      /* this is defined by POSIX */
      return -ENOTTY;
   }
   
   /* all ok */
   err = 0;
   
 out:
   return err;
}
5.7.2. The proc file system 1. Denx Training Topics 5.7.4. Concurrency and Race Conditions
Prev Home Next