aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/floppy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/floppy.c')
-rw-r--r--drivers/block/floppy.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index cf04c1b234ed..aa42e7766c6a 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -258,8 +258,8 @@ static int irqdma_allocated;
258#include <linux/completion.h> 258#include <linux/completion.h>
259 259
260static struct request *current_req; 260static struct request *current_req;
261static struct request_queue *floppy_queue;
262static void do_fd_request(struct request_queue *q); 261static void do_fd_request(struct request_queue *q);
262static int set_next_request(void);
263 263
264#ifndef fd_get_dma_residue 264#ifndef fd_get_dma_residue
265#define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) 265#define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA)
@@ -413,6 +413,7 @@ static struct gendisk *disks[N_DRIVE];
413static struct block_device *opened_bdev[N_DRIVE]; 413static struct block_device *opened_bdev[N_DRIVE];
414static DEFINE_MUTEX(open_lock); 414static DEFINE_MUTEX(open_lock);
415static struct floppy_raw_cmd *raw_cmd, default_raw_cmd; 415static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
416static int fdc_queue;
416 417
417/* 418/*
418 * This struct defines the different floppy types. 419 * This struct defines the different floppy types.
@@ -890,8 +891,8 @@ static void unlock_fdc(void)
890 del_timer(&fd_timeout); 891 del_timer(&fd_timeout);
891 cont = NULL; 892 cont = NULL;
892 clear_bit(0, &fdc_busy); 893 clear_bit(0, &fdc_busy);
893 if (current_req || blk_peek_request(floppy_queue)) 894 if (current_req || set_next_request())
894 do_fd_request(floppy_queue); 895 do_fd_request(current_req->q);
895 spin_unlock_irqrestore(&floppy_lock, flags); 896 spin_unlock_irqrestore(&floppy_lock, flags);
896 wake_up(&fdc_wait); 897 wake_up(&fdc_wait);
897} 898}
@@ -2243,8 +2244,8 @@ static void floppy_end_request(struct request *req, int error)
2243 * logical buffer */ 2244 * logical buffer */
2244static void request_done(int uptodate) 2245static void request_done(int uptodate)
2245{ 2246{
2246 struct request_queue *q = floppy_queue;
2247 struct request *req = current_req; 2247 struct request *req = current_req;
2248 struct request_queue *q;
2248 unsigned long flags; 2249 unsigned long flags;
2249 int block; 2250 int block;
2250 char msg[sizeof("request done ") + sizeof(int) * 3]; 2251 char msg[sizeof("request done ") + sizeof(int) * 3];
@@ -2258,6 +2259,8 @@ static void request_done(int uptodate)
2258 return; 2259 return;
2259 } 2260 }
2260 2261
2262 q = req->q;
2263
2261 if (uptodate) { 2264 if (uptodate) {
2262 /* maintain values for invalidation on geometry 2265 /* maintain values for invalidation on geometry
2263 * change */ 2266 * change */
@@ -2811,6 +2814,28 @@ static int make_raw_rw_request(void)
2811 return 2; 2814 return 2;
2812} 2815}
2813 2816
2817/*
2818 * Round-robin between our available drives, doing one request from each
2819 */
2820static int set_next_request(void)
2821{
2822 struct request_queue *q;
2823 int old_pos = fdc_queue;
2824
2825 do {
2826 q = disks[fdc_queue]->queue;
2827 if (++fdc_queue == N_DRIVE)
2828 fdc_queue = 0;
2829 if (q) {
2830 current_req = blk_fetch_request(q);
2831 if (current_req)
2832 break;
2833 }
2834 } while (fdc_queue != old_pos);
2835
2836 return current_req != NULL;
2837}
2838
2814static void redo_fd_request(void) 2839static void redo_fd_request(void)
2815{ 2840{
2816 int drive; 2841 int drive;
@@ -2822,17 +2847,17 @@ static void redo_fd_request(void)
2822 2847
2823do_request: 2848do_request:
2824 if (!current_req) { 2849 if (!current_req) {
2825 struct request *req; 2850 int pending;
2851
2852 spin_lock_irq(&floppy_lock);
2853 pending = set_next_request();
2854 spin_unlock_irq(&floppy_lock);
2826 2855
2827 spin_lock_irq(floppy_queue->queue_lock); 2856 if (!pending) {
2828 req = blk_fetch_request(floppy_queue);
2829 spin_unlock_irq(floppy_queue->queue_lock);
2830 if (!req) {
2831 do_floppy = NULL; 2857 do_floppy = NULL;
2832 unlock_fdc(); 2858 unlock_fdc();
2833 return; 2859 return;
2834 } 2860 }
2835 current_req = req;
2836 } 2861 }
2837 drive = (long)current_req->rq_disk->private_data; 2862 drive = (long)current_req->rq_disk->private_data;
2838 set_fdc(drive); 2863 set_fdc(drive);
@@ -4165,6 +4190,13 @@ static int __init floppy_init(void)
4165 goto out_put_disk; 4190 goto out_put_disk;
4166 } 4191 }
4167 4192
4193 disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock);
4194 if (!disks[dr]->queue) {
4195 err = -ENOMEM;
4196 goto out_put_disk;
4197 }
4198
4199 blk_queue_max_hw_sectors(disks[dr]->queue, 64);
4168 disks[dr]->major = FLOPPY_MAJOR; 4200 disks[dr]->major = FLOPPY_MAJOR;
4169 disks[dr]->first_minor = TOMINOR(dr); 4201 disks[dr]->first_minor = TOMINOR(dr);
4170 disks[dr]->fops = &floppy_fops; 4202 disks[dr]->fops = &floppy_fops;
@@ -4183,13 +4215,6 @@ static int __init floppy_init(void)
4183 if (err) 4215 if (err)
4184 goto out_unreg_blkdev; 4216 goto out_unreg_blkdev;
4185 4217
4186 floppy_queue = blk_init_queue(do_fd_request, &floppy_lock);
4187 if (!floppy_queue) {
4188 err = -ENOMEM;
4189 goto out_unreg_driver;
4190 }
4191 blk_queue_max_hw_sectors(floppy_queue, 64);
4192
4193 blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE, 4218 blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
4194 floppy_find, NULL, NULL); 4219 floppy_find, NULL, NULL);
4195 4220
@@ -4317,7 +4342,6 @@ static int __init floppy_init(void)
4317 4342
4318 /* to be cleaned up... */ 4343 /* to be cleaned up... */
4319 disks[drive]->private_data = (void *)(long)drive; 4344 disks[drive]->private_data = (void *)(long)drive;
4320 disks[drive]->queue = floppy_queue;
4321 disks[drive]->flags |= GENHD_FL_REMOVABLE; 4345 disks[drive]->flags |= GENHD_FL_REMOVABLE;
4322 disks[drive]->driverfs_dev = &floppy_device[drive].dev; 4346 disks[drive]->driverfs_dev = &floppy_device[drive].dev;
4323 add_disk(disks[drive]); 4347 add_disk(disks[drive]);
@@ -4333,8 +4357,6 @@ out_flush_work:
4333 floppy_release_irq_and_dma(); 4357 floppy_release_irq_and_dma();
4334out_unreg_region: 4358out_unreg_region:
4335 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); 4359 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
4336 blk_cleanup_queue(floppy_queue);
4337out_unreg_driver:
4338 platform_driver_unregister(&floppy_driver); 4360 platform_driver_unregister(&floppy_driver);
4339out_unreg_blkdev: 4361out_unreg_blkdev:
4340 unregister_blkdev(FLOPPY_MAJOR, "fd"); 4362 unregister_blkdev(FLOPPY_MAJOR, "fd");
@@ -4342,6 +4364,8 @@ out_put_disk:
4342 while (dr--) { 4364 while (dr--) {
4343 del_timer(&motor_off_timer[dr]); 4365 del_timer(&motor_off_timer[dr]);
4344 put_disk(disks[dr]); 4366 put_disk(disks[dr]);
4367 if (disks[dr]->queue)
4368 blk_cleanup_queue(disks[dr]->queue);
4345 } 4369 }
4346 return err; 4370 return err;
4347} 4371}
@@ -4550,11 +4574,11 @@ static void __exit floppy_module_exit(void)
4550 platform_device_unregister(&floppy_device[drive]); 4574 platform_device_unregister(&floppy_device[drive]);
4551 } 4575 }
4552 put_disk(disks[drive]); 4576 put_disk(disks[drive]);
4577 blk_cleanup_queue(disks[drive]->queue);
4553 } 4578 }
4554 4579
4555 del_timer_sync(&fd_timeout); 4580 del_timer_sync(&fd_timeout);
4556 del_timer_sync(&fd_timer); 4581 del_timer_sync(&fd_timer);
4557 blk_cleanup_queue(floppy_queue);
4558 4582
4559 if (atomic_read(&usage_count)) 4583 if (atomic_read(&usage_count))
4560 floppy_release_irq_and_dma(); 4584 floppy_release_irq_and_dma();