]> git.hungrycats.org Git - linux/commitdiff
[PATCH] floppy cleanup timers/resources on unload
authorAndrew Morton <akpm@osdl.org>
Sun, 21 Sep 2003 08:40:42 +0000 (01:40 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Sun, 21 Sep 2003 08:40:42 +0000 (01:40 -0700)
From: Zwane Mwaikambo <zwane@linuxpower.ca>

The floppy driver currently can leave pending timers after unloading
itself.

This bug has a corresponding bugzilla entry at;

http://bugme.osdl.org/show_bug.cgi?id=1061

drivers/block/floppy.c

index b25acb42542ea0e9df3ddd430f34a5cd397324de..de963ccf001517a404c400f39fb68cdb48ff7ea8 100644 (file)
@@ -219,6 +219,7 @@ static int use_virtual_dma;
  */
 
 static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED;
+static struct completion device_release;
 
 static unsigned short virtual_dma_port=0x3f0;
 irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
@@ -4203,9 +4204,17 @@ static int __init floppy_setup(char *str)
 
 static int have_no_fdc= -ENODEV;
 
+static void floppy_device_release(struct device *dev)
+{
+       complete(&device_release);
+}
+
 static struct platform_device floppy_device = {
        .name           = "floppy",
        .id             = 0,
+       .dev            = {
+                       .release = floppy_device_release,
+       }
 };
 
 static struct kobject *floppy_find(dev_t dev, int *part, void *data)
@@ -4576,11 +4585,15 @@ int init_module(void)
 void cleanup_module(void)
 {
        int drive;
-               
+
+       init_completion(&device_release);
        platform_device_unregister(&floppy_device);
        blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
        unregister_blkdev(FLOPPY_MAJOR, "fd");
+
        for (drive = 0; drive < N_DRIVE; drive++) {
+               del_timer_sync(&motor_off_timer[drive]);
+
                if ((allowed_drive_mask & (1 << drive)) &&
                    fdc_state[FDC(drive)].version != FDC_NONE) {
                        del_gendisk(disks[drive]);
@@ -4590,9 +4603,17 @@ void cleanup_module(void)
        }
        devfs_remove("floppy");
 
+       del_timer_sync(&fd_timeout);
+       del_timer_sync(&fd_timer);
        blk_cleanup_queue(floppy_queue);
+
+       if (usage_count)
+               floppy_release_irq_and_dma();
+
        /* eject disk, if any */
        fd_eject(0);
+
+       wait_for_completion(&device_release);
 }
 
 MODULE_PARM(floppy,"s");