LJ Archive
int skel_major = 0;    /* default: dynamic */
int skel_base  = 0;    /* default: autodetect */
int skel_irq   = -1;   /* default: autodetect */
Static int skel_boards = 0; /* how many of them are there */
typedef struct Skel_Hw {
  int base;     /* I/O port */
  int irq;      /* IRQ being used */
  int hwirq;    /* The detected one */
  int irqcount;
  int usecount;
  /* .... */
} Skel_Hw;
Skel_Hw skel_hw[SKEL_MAX_BOARDS];
#define PORT0(board) ((board)->base+0)
#define PORT1(board) ((board)->base+1)
/* ... */
Static file_operations skel_fops; /* defined later on */
int init_module (void)
{
  int base, err, i;
  /* Look for a major */
  err = register_chrdev (skel_major, "skel", ∓skel_fops);
  if (err < 0) {
      printk(KERN_NOTICE "skel init: error %d\n", -err);
      return err;
  }
  if (skel_major==0) skel_major=err; /* dynamic */
  /*
   * Look for ports: PORT_MIN, PORT_STEP, PORT_MAX define
   * the range of (consecutive) addresses supported by the board
   */
  base = skel_base ? skel_base : PORT_MIN;
  do {
      if (check_region(base, PORT_STEP) != 0)
          continue; /* in use */
      request_region(base, PORT_STEP, "skel");
      skel_hw[skel_boards].base=base;
      if ( (err=skel_find(skel_hw+skel_boards)) == 0) {
          /* found one */
          skel_boards++;
          continue;
      }
      release_region(base, PORT_STEP);
  }
  /* if autodetecting skel_base is 0, otherwise, do it only once */
  while (skel_base==0 && (base+=PORT_STEP) < PORT_MAX);
  if (skel_boards==0) {
      printk(KERN_NOTICE "skel init: no boards found\n");
      return -ENODEV;
  }
  /* do other initialization here */
  if ( (err=request_resource_1()) != 0 )
      goto fail_resource_1:
  if ( (err=request_resource_2()) != 0 )
      goto fail_resource_2:
  if ( (err=request_resource_3()) != 0 )
      goto fail_resource_3:
  return 0; /* success */
  fail_resource_3: free_resource_2()
  fail_resource_2: free_resource_1()
  fail_resource_1: printk(KERN_NOTICE "skel init: error %i\n",
  -err);
  /* release your boards */
  for (i=0; i<skel_boards; i++)
      release_region(skel_hw[i].base, PORT_STEP);
  return err; /* failure */
}
void cleanup_module (void)
{
  int b;
  if (MOD_IN_USE)
      return /* -EBUSY */;
  printk(KERN_INFO "skel driver unloaded\n");
  for (b=0; b<skel_boards; b++) {
      /* shutdown the board.... */
      release_region(skel_hw[b].base, PORT_STEP);
      if (skel_hw[b].irq >= 0)
          free_irq(skel_hw[b].irq);
  }
  unregister_chrdev(skel_major, "skel");
  return;
}
LJ Archive