LJ Archive
typedef struct Skel_Clientdata {
  Skel_Hw *board;
  int flags;
  /* .... */
} Skel_Clientdata;
struct file_operations skel_fops;
struct file_operations skel_raw_fops;
int skel_open (struct inode *inode, struct file *filp)
{
  Skel_Hw *board;
  Skel_Clientdata *data;
  int err;
  if (SKEL_BOARD(inode->i_rdev) >= skel_boards)  return -ENODEV;
  board = skel_hw + BOARDNO(inode->i_rdev);
  switch (SKEL_MODE(inode->i_rdev)) /* node selection */
      {
      case 0: break;                             /* normal mode */
      case 1: filp->f_op = skel_raw_fops; break; /* raw mode */
      default: return -ENODEV;
      }
  data = kmalloc(sizeof(Skel_Clientdata), GFP_KERNEL);
  if (!data) return -ENOMEM;
  filp->private_data = data;
  data->board = board;
  data->flags = SKEL_DEFAULT_FLAGS;
  fill_any_further_field
  if (board->usecount == 0) { /* first open */
      if (board->hwirq >= 0) {
          if ( (err=request_irq(board->hwirq,skel_interrupt,0,"skel")) !=
          0) {
              kfree(data);
              return err; /* or go on, at your will */
          }
          board->irq=board->hwirq;
      }
      skel_initialize_the_board();
  }
  board->usecount++;
  MOD_INC_USE_COUNT;
  return 0;
}
void skel_close (struct inode *inode, struct file *filp)
{
  Skel_Clientdata *data=filp->private_data;
  Skel_Board *board=data->board;
  if (board->usecount == 1) { /* last close */
      if (board->irq) {
          free_irq(board->irq);
          board->irq = -1;
      }
      skel_shutdown_board
  }
  kfree(data);
  filp->private_data=NULL;
  board->usecount--;
  MOD_DEC_USE_COUNT;
  return;
}

LJ Archive