/* * The cleanup function is used to handle initialization failures as well. * Thefore, it must be careful to work correctly even if some of the items * have not been initialized */ void scull_cleanup_module(void) { int i; dev_t devno = MKDEV(scull_major, scull_minor); /* Get rid of our char dev entries */ if (scull_devices) { for (i = 0; i < scull_nr_devs; i++) { scull_trim(scull_devices + i); cdev_del(&scull_devices[i].cdev); } kfree(scull_devices); } #ifdef SCULL_DEBUG /* use proc only if debugging */ scull_remove_proc(); #endif /* cleanup_module is never called if registering failed */ unregister_chrdev_region(devno, scull_nr_devs); /* and call the cleanup functions for friend devices */ scull_p_cleanup(); scull_access_cleanup(); }
/* * The cleanup function is used to handle initialization failures as well. * Thefore, it must be careful to work correctly even if some of the items * have not been initialized */ void scull_cleanup_module(void) { int i; #ifndef CONFIG_DEVFS_FS /* cleanup_module is never called if registering failed */ unregister_chrdev(scull_major, "scull"); #endif scull_remove_proc(); if (scull_devices) { for (i=0; i<scull_nr_devs; i++) { scull_trim(scull_devices+i); /* the following line is only used for devfs */ devfs_unregister(scull_devices[i].handle); } kfree(scull_devices); } /* and call the cleanup functions for friend devices */ scull_p_cleanup(); scull_access_cleanup(); /* once again, only for devfs */ devfs_unregister(scull_devfs_dir); }
int init_module(void) { int result, i; /* * Register your major, and accept a dynamic number */ result = register_chrdev(scull_major, "scull", &scull_fops); if (result < 0) { printk(KERN_WARNING "scull: can't get major %d\n",scull_major); return result; } if (scull_major == 0) scull_major = result; /* dynamic */ /* * allocate the devices -- we can't have them static, as the number * can be specified at load time */ scull_devices = kmalloc(scull_nr_devs * sizeof (Scull_Dev), GFP_KERNEL); if (!scull_devices) { result = -ENOMEM; goto fail_malloc; } memset(scull_devices, 0, scull_nr_devs * sizeof (Scull_Dev)); for (i=0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; scull_devices[i].qset = scull_qset; } /* At this point call the init function for any friend device */ if ( (result = scull_p_init()) ) goto fail_pipe; if ( (result = scull_access_init()) ) goto fail_access; /* ... */ #ifndef SCULL_DEBUG REGISTER_SYMTAB(NULL); /* otherwise, leave global symbols visible */ #endif #ifdef SCULL_USE_PROC /* only when available */ /* this is the last line in init_module */ proc_register_dynamic(&proc_root, &scull_proc_entry); #endif return 0; /* succeed */ fail_access: scull_p_cleanup(); fail_pipe: kfree(scull_devices); fail_malloc: unregister_chrdev(scull_major, "scull"); return result; }
void cleanup_module(void) { int i; unregister_chrdev(scull_major, "scull"); #ifdef SCULL_USE_PROC proc_unregister(&proc_root, scull_proc_entry.low_ino); #endif for (i=0; i<scull_nr_devs; i++) scull_trim(scull_devices+i); kfree(scull_devices); /* and call the cleanup functions for friend devices */ scull_p_cleanup(); scull_access_cleanup(); }
/* * The cleanup function is used to handle initialization failures as well. * Thefore, it must be careful to work correctly even if some of the items * have not been initialized */ void scull_cleanup_module(void) { int i; dev_t devno = MKDEV(scull_major, scull_minor); /* Get rid of our char dev entries */ if (scull_devices) { for (i = 0; i < scull_nr_devs; i++) { scull_trim(scull_devices + i); cdev_del(&scull_devices[i].cdev); } kfree(scull_devices); } /* cleanup_module is never called if registering failed */ unregister_chrdev_region(devno, scull_nr_devs); /* and call the cleanup functions for friend devices */ scull_p_cleanup(); }