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