aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2012-05-18 07:50:25 -0400
committerJiri Kosina <jkosina@suse.cz>2012-05-18 09:19:10 -0400
commit070ad7e793dc6ff753ee682ef7790b3373b471f6 (patch)
tree2e11acf8dacf2b29bc4722c0cc614afd271eb59f
parent0b7877d4eea3f93e3dd941999522bbd8c538cb53 (diff)
floppy: convert to delayed work and single-thread wq
There are several races in floppy driver between bottom half (scheduled_work) and timers (fd_timeout, fd_timer). Due to slowness of the actual floppy devices, those races are never (at least to my knowledge) triggered on a bare floppy metal. However on virtualized (emulated) floppy drives, which are of course magnitudes faster than the real ones, these races trigger reliably. They usually exhibit themselves as NULL pointer dereferences during DMA setup, such as BUG: unable to handle kernel NULL pointer dereference at 0000000a [ ... snip ... ] EIP: 0060:[<c02053d5>] EFLAGS: 00010293 CPU: 0 EAX: ffffe000 EBX: 0000000a ECX: 00000000 EDX: 0000000a ESI: c05d2718 EDI: 00000000 EBP: 00000000 ESP: f540fe44 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 Process swapper (pid: 0, ti=f540e000 task=c082d5a0 task.ti=c0826000) Stack: ffffe000 00001ffc 00000000 00000000 00000000 c05d2718 c0708b40 f540fe80 c020470f c05d2718 c0708b40 00000000 f540fe80 0000000a f540fee4 00000000 c0708b40 f540fee4 00000000 00000000 c020526b 00000000 c05d2718 c0708b40 Call Trace: [<c020470f>] dump_trace+0xaf/0x110 [<c020526b>] show_trace_log_lvl+0x4b/0x60 [<c0205298>] show_trace+0x18/0x20 [<c05c5811>] dump_stack+0x6d/0x72 [<c0248527>] warn_slowpath_common+0x77/0xb0 [<c02485f3>] warn_slowpath_fmt+0x33/0x40 [<f7ec593c>] setup_DMA+0x14c/0x210 [floppy] [<f7ecaa95>] setup_rw_floppy+0x105/0x190 [floppy] [<c0256d08>] run_timer_softirq+0x168/0x2a0 [<c024e762>] __do_softirq+0xc2/0x1c0 [<c02042ed>] do_softirq+0x7d/0xb0 [<f54d8a00>] 0xf54d89ff but other instances can be easily seen as well. This can be observed at least under VMWare, VirtualBox and KVM. This patch converts all the timers and bottom halfs to be processed in a single workqueue. This aproach has been already discussed back in 2010 if I remember correctly, and Acked by Linus [1], but it then never made it to the tree. This all is based on original idea and code of Stephen Hemminger. I have ported original Stepen's code to the current state of the floppy driver, and performed quite some testing (on real hardware), which didn't reveal any issues (this includes not only writing and reading data, but also formatting (unfortunately I didn't find any Double-Density disks any more)). Ability to handle errors properly (supplying known bad floppies) has also been verified. [1] http://kerneltrap.org/mailarchive/linux-kernel/2010/6/11/4582092 Based-on-patch-by: Stephen Hemminger <shemminger@vyatta.com> Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/block/floppy.c143
1 files changed, 73 insertions, 70 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index b0b00d70c166..48e1d70740dc 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -551,7 +551,7 @@ static void floppy_ready(void);
551static void floppy_start(void); 551static void floppy_start(void);
552static void process_fd_request(void); 552static void process_fd_request(void);
553static void recalibrate_floppy(void); 553static void recalibrate_floppy(void);
554static void floppy_shutdown(unsigned long); 554static void floppy_shutdown(struct work_struct *);
555 555
556static int floppy_request_regions(int); 556static int floppy_request_regions(int);
557static void floppy_release_regions(int); 557static void floppy_release_regions(int);
@@ -588,6 +588,8 @@ static int buffer_max = -1;
588static struct floppy_fdc_state fdc_state[N_FDC]; 588static struct floppy_fdc_state fdc_state[N_FDC];
589static int fdc; /* current fdc */ 589static int fdc; /* current fdc */
590 590
591static struct workqueue_struct *floppy_wq;
592
591static struct floppy_struct *_floppy = floppy_type; 593static struct floppy_struct *_floppy = floppy_type;
592static unsigned char current_drive; 594static unsigned char current_drive;
593static long current_count_sectors; 595static long current_count_sectors;
@@ -629,16 +631,15 @@ static inline void set_debugt(void) { }
629static inline void debugt(const char *func, const char *msg) { } 631static inline void debugt(const char *func, const char *msg) { }
630#endif /* DEBUGT */ 632#endif /* DEBUGT */
631 633
632typedef void (*timeout_fn)(unsigned long);
633static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0);
634 634
635static DECLARE_DELAYED_WORK(fd_timeout, floppy_shutdown);
635static const char *timeout_message; 636static const char *timeout_message;
636 637
637static void is_alive(const char *func, const char *message) 638static void is_alive(const char *func, const char *message)
638{ 639{
639 /* this routine checks whether the floppy driver is "alive" */ 640 /* this routine checks whether the floppy driver is "alive" */
640 if (test_bit(0, &fdc_busy) && command_status < 2 && 641 if (test_bit(0, &fdc_busy) && command_status < 2 &&
641 !timer_pending(&fd_timeout)) { 642 !delayed_work_pending(&fd_timeout)) {
642 DPRINT("%s: timeout handler died. %s\n", func, message); 643 DPRINT("%s: timeout handler died. %s\n", func, message);
643 } 644 }
644} 645}
@@ -666,15 +667,18 @@ static int output_log_pos;
666 667
667static void __reschedule_timeout(int drive, const char *message) 668static void __reschedule_timeout(int drive, const char *message)
668{ 669{
670 unsigned long delay;
671
669 if (drive == current_reqD) 672 if (drive == current_reqD)
670 drive = current_drive; 673 drive = current_drive;
671 del_timer(&fd_timeout); 674
672 if (drive < 0 || drive >= N_DRIVE) { 675 if (drive < 0 || drive >= N_DRIVE) {
673 fd_timeout.expires = jiffies + 20UL * HZ; 676 delay = 20UL * HZ;
674 drive = 0; 677 drive = 0;
675 } else 678 } else
676 fd_timeout.expires = jiffies + UDP->timeout; 679 delay = UDP->timeout;
677 add_timer(&fd_timeout); 680
681 queue_delayed_work(floppy_wq, &fd_timeout, delay);
678 if (UDP->flags & FD_DEBUG) 682 if (UDP->flags & FD_DEBUG)
679 DPRINT("reschedule timeout %s\n", message); 683 DPRINT("reschedule timeout %s\n", message);
680 timeout_message = message; 684 timeout_message = message;
@@ -872,7 +876,7 @@ static int lock_fdc(int drive, bool interruptible)
872 876
873 command_status = FD_COMMAND_NONE; 877 command_status = FD_COMMAND_NONE;
874 878
875 __reschedule_timeout(drive, "lock fdc"); 879 reschedule_timeout(drive, "lock fdc");
876 set_fdc(drive); 880 set_fdc(drive);
877 return 0; 881 return 0;
878} 882}
@@ -880,23 +884,15 @@ static int lock_fdc(int drive, bool interruptible)
880/* unlocks the driver */ 884/* unlocks the driver */
881static void unlock_fdc(void) 885static void unlock_fdc(void)
882{ 886{
883 unsigned long flags;
884
885 raw_cmd = NULL;
886 if (!test_bit(0, &fdc_busy)) 887 if (!test_bit(0, &fdc_busy))
887 DPRINT("FDC access conflict!\n"); 888 DPRINT("FDC access conflict!\n");
888 889
889 if (do_floppy) 890 raw_cmd = NULL;
890 DPRINT("device interrupt still active at FDC release: %pf!\n",
891 do_floppy);
892 command_status = FD_COMMAND_NONE; 891 command_status = FD_COMMAND_NONE;
893 spin_lock_irqsave(&floppy_lock, flags); 892 __cancel_delayed_work(&fd_timeout);
894 del_timer(&fd_timeout); 893 do_floppy = NULL;
895 cont = NULL; 894 cont = NULL;
896 clear_bit(0, &fdc_busy); 895 clear_bit(0, &fdc_busy);
897 if (current_req || set_next_request())
898 do_fd_request(current_req->q);
899 spin_unlock_irqrestore(&floppy_lock, flags);
900 wake_up(&fdc_wait); 896 wake_up(&fdc_wait);
901} 897}
902 898
@@ -968,26 +964,24 @@ static DECLARE_WORK(floppy_work, NULL);
968 964
969static void schedule_bh(void (*handler)(void)) 965static void schedule_bh(void (*handler)(void))
970{ 966{
967 WARN_ON(work_pending(&floppy_work));
968
971 PREPARE_WORK(&floppy_work, (work_func_t)handler); 969 PREPARE_WORK(&floppy_work, (work_func_t)handler);
972 schedule_work(&floppy_work); 970 queue_work(floppy_wq, &floppy_work);
973} 971}
974 972
975static DEFINE_TIMER(fd_timer, NULL, 0, 0); 973static DECLARE_DELAYED_WORK(fd_timer, NULL);
976 974
977static void cancel_activity(void) 975static void cancel_activity(void)
978{ 976{
979 unsigned long flags;
980
981 spin_lock_irqsave(&floppy_lock, flags);
982 do_floppy = NULL; 977 do_floppy = NULL;
983 PREPARE_WORK(&floppy_work, (work_func_t)empty); 978 cancel_delayed_work_sync(&fd_timer);
984 del_timer(&fd_timer); 979 cancel_work_sync(&floppy_work);
985 spin_unlock_irqrestore(&floppy_lock, flags);
986} 980}
987 981
988/* this function makes sure that the disk stays in the drive during the 982/* this function makes sure that the disk stays in the drive during the
989 * transfer */ 983 * transfer */
990static void fd_watchdog(void) 984static void fd_watchdog(struct work_struct *arg)
991{ 985{
992 debug_dcl(DP->flags, "calling disk change from watchdog\n"); 986 debug_dcl(DP->flags, "calling disk change from watchdog\n");
993 987
@@ -997,21 +991,20 @@ static void fd_watchdog(void)
997 cont->done(0); 991 cont->done(0);
998 reset_fdc(); 992 reset_fdc();
999 } else { 993 } else {
1000 del_timer(&fd_timer); 994 cancel_delayed_work(&fd_timer);
1001 fd_timer.function = (timeout_fn)fd_watchdog; 995 PREPARE_DELAYED_WORK(&fd_timer, fd_watchdog);
1002 fd_timer.expires = jiffies + HZ / 10; 996 queue_delayed_work(floppy_wq, &fd_timer, HZ / 10);
1003 add_timer(&fd_timer);
1004 } 997 }
1005} 998}
1006 999
1007static void main_command_interrupt(void) 1000static void main_command_interrupt(void)
1008{ 1001{
1009 del_timer(&fd_timer); 1002 cancel_delayed_work(&fd_timer);
1010 cont->interrupt(); 1003 cont->interrupt();
1011} 1004}
1012 1005
1013/* waits for a delay (spinup or select) to pass */ 1006/* waits for a delay (spinup or select) to pass */
1014static int fd_wait_for_completion(unsigned long delay, timeout_fn function) 1007static int fd_wait_for_completion(unsigned long expires, work_func_t function)
1015{ 1008{
1016 if (FDCS->reset) { 1009 if (FDCS->reset) {
1017 reset_fdc(); /* do the reset during sleep to win time 1010 reset_fdc(); /* do the reset during sleep to win time
@@ -1020,11 +1013,10 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function)
1020 return 1; 1013 return 1;
1021 } 1014 }
1022 1015
1023 if (time_before(jiffies, delay)) { 1016 if (time_before(jiffies, expires)) {
1024 del_timer(&fd_timer); 1017 cancel_delayed_work(&fd_timer);
1025 fd_timer.function = function; 1018 PREPARE_DELAYED_WORK(&fd_timer, function);
1026 fd_timer.expires = delay; 1019 queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies);
1027 add_timer(&fd_timer);
1028 return 1; 1020 return 1;
1029 } 1021 }
1030 return 0; 1022 return 0;
@@ -1342,7 +1334,7 @@ static int fdc_dtr(void)
1342 */ 1334 */
1343 FDCS->dtr = raw_cmd->rate & 3; 1335 FDCS->dtr = raw_cmd->rate & 3;
1344 return fd_wait_for_completion(jiffies + 2UL * HZ / 100, 1336 return fd_wait_for_completion(jiffies + 2UL * HZ / 100,
1345 (timeout_fn)floppy_ready); 1337 (work_func_t)floppy_ready);
1346} /* fdc_dtr */ 1338} /* fdc_dtr */
1347 1339
1348static void tell_sector(void) 1340static void tell_sector(void)
@@ -1447,7 +1439,7 @@ static void setup_rw_floppy(void)
1447 int flags; 1439 int flags;
1448 int dflags; 1440 int dflags;
1449 unsigned long ready_date; 1441 unsigned long ready_date;
1450 timeout_fn function; 1442 work_func_t function;
1451 1443
1452 flags = raw_cmd->flags; 1444 flags = raw_cmd->flags;
1453 if (flags & (FD_RAW_READ | FD_RAW_WRITE)) 1445 if (flags & (FD_RAW_READ | FD_RAW_WRITE))
@@ -1461,9 +1453,9 @@ static void setup_rw_floppy(void)
1461 */ 1453 */
1462 if (time_after(ready_date, jiffies + DP->select_delay)) { 1454 if (time_after(ready_date, jiffies + DP->select_delay)) {
1463 ready_date -= DP->select_delay; 1455 ready_date -= DP->select_delay;
1464 function = (timeout_fn)floppy_start; 1456 function = (work_func_t)floppy_start;
1465 } else 1457 } else
1466 function = (timeout_fn)setup_rw_floppy; 1458 function = (work_func_t)setup_rw_floppy;
1467 1459
1468 /* wait until the floppy is spinning fast enough */ 1460 /* wait until the floppy is spinning fast enough */
1469 if (fd_wait_for_completion(ready_date, function)) 1461 if (fd_wait_for_completion(ready_date, function))
@@ -1493,7 +1485,7 @@ static void setup_rw_floppy(void)
1493 inr = result(); 1485 inr = result();
1494 cont->interrupt(); 1486 cont->interrupt();
1495 } else if (flags & FD_RAW_NEED_DISK) 1487 } else if (flags & FD_RAW_NEED_DISK)
1496 fd_watchdog(); 1488 fd_watchdog(NULL);
1497} 1489}
1498 1490
1499static int blind_seek; 1491static int blind_seek;
@@ -1802,20 +1794,22 @@ static void show_floppy(void)
1802 pr_info("do_floppy=%pf\n", do_floppy); 1794 pr_info("do_floppy=%pf\n", do_floppy);
1803 if (work_pending(&floppy_work)) 1795 if (work_pending(&floppy_work))
1804 pr_info("floppy_work.func=%pf\n", floppy_work.func); 1796 pr_info("floppy_work.func=%pf\n", floppy_work.func);
1805 if (timer_pending(&fd_timer)) 1797 if (delayed_work_pending(&fd_timer))
1806 pr_info("fd_timer.function=%pf\n", fd_timer.function); 1798 pr_info("delayed work.function=%p expires=%ld\n",
1807 if (timer_pending(&fd_timeout)) { 1799 fd_timer.work.func,
1808 pr_info("timer_function=%pf\n", fd_timeout.function); 1800 fd_timer.timer.expires - jiffies);
1809 pr_info("expires=%lu\n", fd_timeout.expires - jiffies); 1801 if (delayed_work_pending(&fd_timeout))
1810 pr_info("now=%lu\n", jiffies); 1802 pr_info("timer_function=%p expires=%ld\n",
1811 } 1803 fd_timeout.work.func,
1804 fd_timeout.timer.expires - jiffies);
1805
1812 pr_info("cont=%p\n", cont); 1806 pr_info("cont=%p\n", cont);
1813 pr_info("current_req=%p\n", current_req); 1807 pr_info("current_req=%p\n", current_req);
1814 pr_info("command_status=%d\n", command_status); 1808 pr_info("command_status=%d\n", command_status);
1815 pr_info("\n"); 1809 pr_info("\n");
1816} 1810}
1817 1811
1818static void floppy_shutdown(unsigned long data) 1812static void floppy_shutdown(struct work_struct *arg)
1819{ 1813{
1820 unsigned long flags; 1814 unsigned long flags;
1821 1815
@@ -1868,7 +1862,7 @@ static int start_motor(void (*function)(void))
1868 1862
1869 /* wait_for_completion also schedules reset if needed. */ 1863 /* wait_for_completion also schedules reset if needed. */
1870 return fd_wait_for_completion(DRS->select_date + DP->select_delay, 1864 return fd_wait_for_completion(DRS->select_date + DP->select_delay,
1871 (timeout_fn)function); 1865 (work_func_t)function);
1872} 1866}
1873 1867
1874static void floppy_ready(void) 1868static void floppy_ready(void)
@@ -2821,7 +2815,6 @@ do_request:
2821 spin_lock_irq(&floppy_lock); 2815 spin_lock_irq(&floppy_lock);
2822 pending = set_next_request(); 2816 pending = set_next_request();
2823 spin_unlock_irq(&floppy_lock); 2817 spin_unlock_irq(&floppy_lock);
2824
2825 if (!pending) { 2818 if (!pending) {
2826 do_floppy = NULL; 2819 do_floppy = NULL;
2827 unlock_fdc(); 2820 unlock_fdc();
@@ -2898,13 +2891,15 @@ static void do_fd_request(struct request_queue *q)
2898 current_req->cmd_flags)) 2891 current_req->cmd_flags))
2899 return; 2892 return;
2900 2893
2901 if (test_bit(0, &fdc_busy)) { 2894 if (test_and_set_bit(0, &fdc_busy)) {
2902 /* fdc busy, this new request will be treated when the 2895 /* fdc busy, this new request will be treated when the
2903 current one is done */ 2896 current one is done */
2904 is_alive(__func__, "old request running"); 2897 is_alive(__func__, "old request running");
2905 return; 2898 return;
2906 } 2899 }
2907 lock_fdc(MAXTIMEOUT, false); 2900 command_status = FD_COMMAND_NONE;
2901 __reschedule_timeout(MAXTIMEOUT, "fd_request");
2902 set_fdc(0);
2908 process_fd_request(); 2903 process_fd_request();
2909 is_alive(__func__, ""); 2904 is_alive(__func__, "");
2910} 2905}
@@ -4159,10 +4154,16 @@ static int __init floppy_init(void)
4159 goto out_put_disk; 4154 goto out_put_disk;
4160 } 4155 }
4161 4156
4157 floppy_wq = alloc_ordered_workqueue("floppy", 0);
4158 if (!floppy_wq) {
4159 err = -ENOMEM;
4160 goto out_put_disk;
4161 }
4162
4162 disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); 4163 disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock);
4163 if (!disks[dr]->queue) { 4164 if (!disks[dr]->queue) {
4164 err = -ENOMEM; 4165 err = -ENOMEM;
4165 goto out_put_disk; 4166 goto out_destroy_workq;
4166 } 4167 }
4167 4168
4168 blk_queue_max_hw_sectors(disks[dr]->queue, 64); 4169 blk_queue_max_hw_sectors(disks[dr]->queue, 64);
@@ -4213,7 +4214,7 @@ static int __init floppy_init(void)
4213 use_virtual_dma = can_use_virtual_dma & 1; 4214 use_virtual_dma = can_use_virtual_dma & 1;
4214 fdc_state[0].address = FDC1; 4215 fdc_state[0].address = FDC1;
4215 if (fdc_state[0].address == -1) { 4216 if (fdc_state[0].address == -1) {
4216 del_timer_sync(&fd_timeout); 4217 cancel_delayed_work(&fd_timeout);
4217 err = -ENODEV; 4218 err = -ENODEV;
4218 goto out_unreg_region; 4219 goto out_unreg_region;
4219 } 4220 }
@@ -4224,7 +4225,7 @@ static int __init floppy_init(void)
4224 fdc = 0; /* reset fdc in case of unexpected interrupt */ 4225 fdc = 0; /* reset fdc in case of unexpected interrupt */
4225 err = floppy_grab_irq_and_dma(); 4226 err = floppy_grab_irq_and_dma();
4226 if (err) { 4227 if (err) {
4227 del_timer_sync(&fd_timeout); 4228 cancel_delayed_work(&fd_timeout);
4228 err = -EBUSY; 4229 err = -EBUSY;
4229 goto out_unreg_region; 4230 goto out_unreg_region;
4230 } 4231 }
@@ -4281,13 +4282,13 @@ static int __init floppy_init(void)
4281 user_reset_fdc(-1, FD_RESET_ALWAYS, false); 4282 user_reset_fdc(-1, FD_RESET_ALWAYS, false);
4282 } 4283 }
4283 fdc = 0; 4284 fdc = 0;
4284 del_timer_sync(&fd_timeout); 4285 cancel_delayed_work(&fd_timeout);
4285 current_drive = 0; 4286 current_drive = 0;
4286 initialized = true; 4287 initialized = true;
4287 if (have_no_fdc) { 4288 if (have_no_fdc) {
4288 DPRINT("no floppy controllers found\n"); 4289 DPRINT("no floppy controllers found\n");
4289 err = have_no_fdc; 4290 err = have_no_fdc;
4290 goto out_flush_work; 4291 goto out_release_dma;
4291 } 4292 }
4292 4293
4293 for (drive = 0; drive < N_DRIVE; drive++) { 4294 for (drive = 0; drive < N_DRIVE; drive++) {
@@ -4302,7 +4303,7 @@ static int __init floppy_init(void)
4302 4303
4303 err = platform_device_register(&floppy_device[drive]); 4304 err = platform_device_register(&floppy_device[drive]);
4304 if (err) 4305 if (err)
4305 goto out_flush_work; 4306 goto out_release_dma;
4306 4307
4307 err = device_create_file(&floppy_device[drive].dev, 4308 err = device_create_file(&floppy_device[drive].dev,
4308 &dev_attr_cmos); 4309 &dev_attr_cmos);
@@ -4320,13 +4321,14 @@ static int __init floppy_init(void)
4320 4321
4321out_unreg_platform_dev: 4322out_unreg_platform_dev:
4322 platform_device_unregister(&floppy_device[drive]); 4323 platform_device_unregister(&floppy_device[drive]);
4323out_flush_work: 4324out_release_dma:
4324 flush_work_sync(&floppy_work);
4325 if (atomic_read(&usage_count)) 4325 if (atomic_read(&usage_count))
4326 floppy_release_irq_and_dma(); 4326 floppy_release_irq_and_dma();
4327out_unreg_region: 4327out_unreg_region:
4328 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); 4328 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
4329 platform_driver_unregister(&floppy_driver); 4329 platform_driver_unregister(&floppy_driver);
4330out_destroy_workq:
4331 destroy_workqueue(floppy_wq);
4330out_unreg_blkdev: 4332out_unreg_blkdev:
4331 unregister_blkdev(FLOPPY_MAJOR, "fd"); 4333 unregister_blkdev(FLOPPY_MAJOR, "fd");
4332out_put_disk: 4334out_put_disk:
@@ -4397,7 +4399,7 @@ static int floppy_grab_irq_and_dma(void)
4397 * We might have scheduled a free_irq(), wait it to 4399 * We might have scheduled a free_irq(), wait it to
4398 * drain first: 4400 * drain first:
4399 */ 4401 */
4400 flush_work_sync(&floppy_work); 4402 flush_workqueue(floppy_wq);
4401 4403
4402 if (fd_request_irq()) { 4404 if (fd_request_irq()) {
4403 DPRINT("Unable to grab IRQ%d for the floppy driver\n", 4405 DPRINT("Unable to grab IRQ%d for the floppy driver\n",
@@ -4488,9 +4490,9 @@ static void floppy_release_irq_and_dma(void)
4488 pr_info("motor off timer %d still active\n", drive); 4490 pr_info("motor off timer %d still active\n", drive);
4489#endif 4491#endif
4490 4492
4491 if (timer_pending(&fd_timeout)) 4493 if (delayed_work_pending(&fd_timeout))
4492 pr_info("floppy timer still active:%s\n", timeout_message); 4494 pr_info("floppy timer still active:%s\n", timeout_message);
4493 if (timer_pending(&fd_timer)) 4495 if (delayed_work_pending(&fd_timer))
4494 pr_info("auxiliary floppy timer still active\n"); 4496 pr_info("auxiliary floppy timer still active\n");
4495 if (work_pending(&floppy_work)) 4497 if (work_pending(&floppy_work))
4496 pr_info("work still pending\n"); 4498 pr_info("work still pending\n");
@@ -4560,8 +4562,9 @@ static void __exit floppy_module_exit(void)
4560 put_disk(disks[drive]); 4562 put_disk(disks[drive]);
4561 } 4563 }
4562 4564
4563 del_timer_sync(&fd_timeout); 4565 cancel_delayed_work_sync(&fd_timeout);
4564 del_timer_sync(&fd_timer); 4566 cancel_delayed_work_sync(&fd_timer);
4567 destroy_workqueue(floppy_wq);
4565 4568
4566 if (atomic_read(&usage_count)) 4569 if (atomic_read(&usage_count))
4567 floppy_release_irq_and_dma(); 4570 floppy_release_irq_and_dma();