IOCTL

Ioctl() is a system call to invoke input output controls to a device file. It takes an integer code which signifies the control operation and an argument as pointer to provide inputs for the operation. Same input pointer can be used to get the output from the operation. It returns zero on success and non-zero if some error happened or if this ioctl code is not implemented by kernel/driver.

IOCTL low layer

It passes argument buffer from user mode and jumps to kernel mode using software interrupt. Kernel calls driver ioctl routine. Driver copies argument to kernel buffer. Driver can do register manipulation if needed and copies return buffer to user mode. Driver can return error if ioctl code is not implemented in driver or argument is not in proper format. Kernel returns call and switch context to user mode and control returns back to user code.

PARPORT IOCTL codes

  • Data register
    • PPRDATA - read 8 bit data register
    • PPWDATA - write 8 bit data register
  • Data Direction
    • PPDATADIR mode=0 - Sets data direction bits to write mode
    • PPDATADIR mode=FFh/255 - Sets data direction bits to read mode
  • Control register
    • PPRCONTROL - Reads control register
    • PPWCONTROL - Writes to control register
    • PPFCONTROL - atomic modify control register(read write at once)
  • Status register
    • PPRSTATUS - Reads the status register

Source Code

Here is a small example to invoke ioctl to parallel port of PC. We have connected a LED to PIN 1 (strobe) of parallel port (LPT0) with a 1K resistor to ground. We are executing ioctl code PPFCONTROL to parallel port 0 with argument of strobe control bit. First we are giving strobe bit as 1 and then with some delay we are setting 0. This will create a sequence of on and off of the strobe LED.
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <asm/ioctl.h>
#include <linux/parport.h>
#include <linux/ppdev.h>
#define DEVICE "/dev/parport0"
int main(int argc, char **argv)
{
  struct ppdev_frob_struct frob;
  int fd;
  int mode;
                                                                            
  if((fd=open(DEVICE, O_RDWR)) < 0) {
    fprintf(stderr, "can not open %s\n", DEVICE);
    return 10;
  }
  if(ioctl(fd, PPCLAIM)) {
    perror("PPCLAIM");
    close(fd);
    return 10;
  }
  
  frob.mask = PARPORT_CONTROL_STROBE;  /* change only this pin ! */
  while(1) {
    frob.val = PARPORT_CONTROL_STROBE;  /* set STROBE PIN... */
    printf("LED is on\n");
    fflush(stdout);
    ioctl(fd, PPFCONTROL, &frob);
    usleep(500);
    frob.val = 0;        /* and clear STROBE PIN */
    printf("LED is off\n");
    fflush(stdout);
    ioctl(fd, PPFCONTROL, &frob);
    usleep(500);
  }
  ioctl(fd, PPRELEASE);
  close(fd);
  return 0;
}

About our authors: Team EQA

You have viewed 1 page out of 252. Your C learning is 0.00% complete. Login to check your learning progress.

#