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; }