]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/block/swim.c
swim: stop sharing request queue across multiple gendisks
[karo-tx-linux.git] / drivers / block / swim.c
index b5afd495d482e8971be1cc431bb7b0ea8b54cae2..3064be6cf3755a4017cbd2a30cda023977250cbf 100644 (file)
@@ -211,7 +211,7 @@ enum head {
 struct swim_priv {
        struct swim __iomem *base;
        spinlock_t lock;
-       struct request_queue *queue;
+       int fdc_queue;
        int floppy_count;
        struct floppy_state unit[FD_MAX_UNIT];
 };
@@ -525,12 +525,33 @@ static int floppy_read_sectors(struct floppy_state *fs,
        return 0;
 }
 
-static void redo_fd_request(struct request_queue *q)
+static struct request *swim_next_request(struct swim_priv *swd)
 {
+       struct request_queue *q;
+       struct request *rq;
+       int old_pos = swd->fdc_queue;
+
+       do {
+               q = swd->unit[swd->fdc_queue].disk->queue;
+               if (++swd->fdc_queue == swd->floppy_count)
+                       swd->fdc_queue = 0;
+               if (q) {
+                       rq = blk_fetch_request(q);
+                       if (rq)
+                               return rq;
+               }
+       } while (swd->fdc_queue != old_pos);
+
+       return NULL;
+}
+
+static void do_fd_request(struct request_queue *q)
+{
+       struct swim_priv *swd = q->queuedata;
        struct request *req;
        struct floppy_state *fs;
 
-       req = blk_fetch_request(q);
+       req = swim_next_request(swd);
        while (req) {
                int err = -EIO;
 
@@ -554,15 +575,10 @@ static void redo_fd_request(struct request_queue *q)
                }
        done:
                if (!__blk_end_request_cur(req, err))
-                       req = blk_fetch_request(q);
+                       req = swim_next_request(swd);
        }
 }
 
-static void do_fd_request(struct request_queue *q)
-{
-       redo_fd_request(q);
-}
-
 static struct floppy_struct floppy_type[4] = {
        {    0,  0, 0,  0, 0, 0x00, 0x00, 0x00, 0x00, NULL }, /* no testing   */
        {  720,  9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 360KB SS 3.5"*/
@@ -833,22 +849,25 @@ static int swim_floppy_init(struct swim_priv *swd)
                return -EBUSY;
        }
 
+       spin_lock_init(&swd->lock);
+
        for (drive = 0; drive < swd->floppy_count; drive++) {
                swd->unit[drive].disk = alloc_disk(1);
                if (swd->unit[drive].disk == NULL) {
                        err = -ENOMEM;
                        goto exit_put_disks;
                }
+               swd->unit[drive].disk->queue = blk_init_queue(do_fd_request,
+                                                             &swd->lock);
+               if (!swd->unit[drive].disk->queue) {
+                       err = -ENOMEM;
+                       put_disk(swd->unit[drive].disk);
+                       goto exit_put_disks;
+               }
+               swd->unit[drive].disk->queue->queuedata = swd;
                swd->unit[drive].swd = swd;
        }
 
-       spin_lock_init(&swd->lock);
-       swd->queue = blk_init_queue(do_fd_request, &swd->lock);
-       if (!swd->queue) {
-               err = -ENOMEM;
-               goto exit_put_disks;
-       }
-
        for (drive = 0; drive < swd->floppy_count; drive++) {
                swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE;
                swd->unit[drive].disk->major = FLOPPY_MAJOR;
@@ -856,7 +875,6 @@ static int swim_floppy_init(struct swim_priv *swd)
                sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
                swd->unit[drive].disk->fops = &floppy_fops;
                swd->unit[drive].disk->private_data = &swd->unit[drive];
-               swd->unit[drive].disk->queue = swd->queue;
                set_capacity(swd->unit[drive].disk, 2880);
                add_disk(swd->unit[drive].disk);
        }
@@ -943,13 +961,12 @@ static int swim_remove(struct platform_device *dev)
 
        for (drive = 0; drive < swd->floppy_count; drive++) {
                del_gendisk(swd->unit[drive].disk);
+               blk_cleanup_queue(swd->unit[drive].disk->queue);
                put_disk(swd->unit[drive].disk);
        }
 
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 
-       blk_cleanup_queue(swd->queue);
-
        /* eject floppies */
 
        for (drive = 0; drive < swd->floppy_count; drive++)