USB: cdc_acm: Fix memory leak after hangup
[safe/jmp/linux-2.6] / drivers / block / floppy.c
index 1e27ed9..5c01f74 100644 (file)
@@ -931,7 +931,7 @@ static inline void unlock_fdc(void)
        del_timer(&fd_timeout);
        cont = NULL;
        clear_bit(0, &fdc_busy);
-       if (elv_next_request(floppy_queue))
+       if (current_req || blk_peek_request(floppy_queue))
                do_fd_request(floppy_queue);
        spin_unlock_irqrestore(&floppy_lock, flags);
        wake_up(&fdc_wait);
@@ -2912,7 +2912,7 @@ static void redo_fd_request(void)
                        struct request *req;
 
                        spin_lock_irq(floppy_queue->queue_lock);
-                       req = elv_next_request(floppy_queue);
+                       req = blk_fetch_request(floppy_queue);
                        spin_unlock_irq(floppy_queue->queue_lock);
                        if (!req) {
                                do_floppy = NULL;
@@ -3327,7 +3327,10 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
                mutex_lock(&open_lock);
-               LOCK_FDC(drive, 1);
+               if (lock_fdc(drive, 1)) {
+                       mutex_unlock(&open_lock);
+                       return -EINTR;
+               }
                floppy_type[type] = *g;
                floppy_type[type].name = "user format";
                for (cnt = type << 2; cnt < (type << 2) + 4; cnt++)
@@ -3904,7 +3907,7 @@ static int floppy_revalidate(struct gendisk *disk)
        return res;
 }
 
-static struct block_device_operations floppy_fops = {
+static const struct block_device_operations floppy_fops = {
        .owner                  = THIS_MODULE,
        .open                   = floppy_open,
        .release                = floppy_release,
@@ -4148,6 +4151,29 @@ static void floppy_device_release(struct device *dev)
 {
 }
 
+static int floppy_resume(struct device *dev)
+{
+       int fdc;
+
+       for (fdc = 0; fdc < N_FDC; fdc++)
+               if (FDCS->address != -1)
+                       user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
+
+       return 0;
+}
+
+static struct dev_pm_ops floppy_pm_ops = {
+       .resume = floppy_resume,
+       .restore = floppy_resume,
+};
+
+static struct platform_driver floppy_driver = {
+       .driver = {
+               .name = "floppy",
+               .pm = &floppy_pm_ops,
+       },
+};
+
 static struct platform_device floppy_device[N_DRIVE];
 
 static struct kobject *floppy_find(dev_t dev, int *part, void *data)
@@ -4196,10 +4222,14 @@ static int __init floppy_init(void)
        if (err)
                goto out_put_disk;
 
+       err = platform_driver_register(&floppy_driver);
+       if (err)
+               goto out_unreg_blkdev;
+
        floppy_queue = blk_init_queue(do_fd_request, &floppy_lock);
        if (!floppy_queue) {
                err = -ENOMEM;
-               goto out_unreg_blkdev;
+               goto out_unreg_driver;
        }
        blk_queue_max_sectors(floppy_queue, 64);
 
@@ -4346,6 +4376,8 @@ out_flush_work:
 out_unreg_region:
        blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
        blk_cleanup_queue(floppy_queue);
+out_unreg_driver:
+       platform_driver_unregister(&floppy_driver);
 out_unreg_blkdev:
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 out_put_disk:
@@ -4566,6 +4598,7 @@ static void __exit floppy_module_exit(void)
 
        blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
        unregister_blkdev(FLOPPY_MAJOR, "fd");
+       platform_driver_unregister(&floppy_driver);
 
        for (drive = 0; drive < N_DRIVE; drive++) {
                del_timer_sync(&motor_off_timer[drive]);