hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/drivers/block/swim.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Driver for SWIM (Sander Woz Integrated Machine) floppy controller
34 *
....@@ -7,11 +8,6 @@
78 * based on SWIM3 driver (c) Paul Mackerras, 1996
89 * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
910 *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public License
12
- * as published by the Free Software Foundation; either version
13
- * 2 of the License, or (at your option) any later version.
14
- *
1511 * 2004-08-21 (lv) - Initial implementation
1612 * 2008-10-30 (lv) - Port to 2.6
1713 */
....@@ -19,7 +15,7 @@
1915 #include <linux/module.h>
2016 #include <linux/fd.h>
2117 #include <linux/slab.h>
22
-#include <linux/blkdev.h>
18
+#include <linux/blk-mq.h>
2319 #include <linux/mutex.h>
2420 #include <linux/hdreg.h>
2521 #include <linux/kernel.h>
....@@ -190,6 +186,7 @@
190186 int ref_count;
191187
192188 struct gendisk *disk;
189
+ struct blk_mq_tag_set tag_set;
193190
194191 /* parent controller */
195192
....@@ -211,7 +208,6 @@
211208 struct swim_priv {
212209 struct swim __iomem *base;
213210 spinlock_t lock;
214
- int fdc_queue;
215211 int floppy_count;
216212 struct floppy_state unit[FD_MAX_UNIT];
217213 };
....@@ -331,7 +327,7 @@
331327 swim_select(base, RELAX);
332328 if (swim_readbit(base, MOTOR_ON))
333329 break;
334
- current->state = TASK_INTERRUPTIBLE;
330
+ set_current_state(TASK_INTERRUPTIBLE);
335331 schedule_timeout(1);
336332 }
337333 } else if (action == OFF) {
....@@ -350,7 +346,7 @@
350346 swim_select(base, RELAX);
351347 if (!swim_readbit(base, DISK_IN))
352348 break;
353
- current->state = TASK_INTERRUPTIBLE;
349
+ set_current_state(TASK_INTERRUPTIBLE);
354350 schedule_timeout(1);
355351 }
356352 swim_select(base, RELAX);
....@@ -374,7 +370,7 @@
374370
375371 for (wait = 0; wait < HZ; wait++) {
376372
377
- current->state = TASK_INTERRUPTIBLE;
373
+ set_current_state(TASK_INTERRUPTIBLE);
378374 schedule_timeout(1);
379375
380376 swim_select(base, RELAX);
....@@ -525,58 +521,36 @@
525521 return 0;
526522 }
527523
528
-static struct request *swim_next_request(struct swim_priv *swd)
524
+static blk_status_t swim_queue_rq(struct blk_mq_hw_ctx *hctx,
525
+ const struct blk_mq_queue_data *bd)
529526 {
530
- struct request_queue *q;
531
- struct request *rq;
532
- int old_pos = swd->fdc_queue;
527
+ struct floppy_state *fs = hctx->queue->queuedata;
528
+ struct swim_priv *swd = fs->swd;
529
+ struct request *req = bd->rq;
530
+ blk_status_t err;
531
+
532
+ if (!spin_trylock_irq(&swd->lock))
533
+ return BLK_STS_DEV_RESOURCE;
534
+
535
+ blk_mq_start_request(req);
536
+
537
+ if (!fs->disk_in || rq_data_dir(req) == WRITE) {
538
+ err = BLK_STS_IOERR;
539
+ goto out;
540
+ }
533541
534542 do {
535
- q = swd->unit[swd->fdc_queue].disk->queue;
536
- if (++swd->fdc_queue == swd->floppy_count)
537
- swd->fdc_queue = 0;
538
- if (q) {
539
- rq = blk_fetch_request(q);
540
- if (rq)
541
- return rq;
542
- }
543
- } while (swd->fdc_queue != old_pos);
543
+ err = floppy_read_sectors(fs, blk_rq_pos(req),
544
+ blk_rq_cur_sectors(req),
545
+ bio_data(req->bio));
546
+ } while (blk_update_request(req, err, blk_rq_cur_bytes(req)));
547
+ __blk_mq_end_request(req, err);
544548
545
- return NULL;
546
-}
549
+ err = BLK_STS_OK;
550
+out:
551
+ spin_unlock_irq(&swd->lock);
552
+ return err;
547553
548
-static void do_fd_request(struct request_queue *q)
549
-{
550
- struct swim_priv *swd = q->queuedata;
551
- struct request *req;
552
- struct floppy_state *fs;
553
-
554
- req = swim_next_request(swd);
555
- while (req) {
556
- blk_status_t err = BLK_STS_IOERR;
557
-
558
- fs = req->rq_disk->private_data;
559
- if (blk_rq_pos(req) >= fs->total_secs)
560
- goto done;
561
- if (!fs->disk_in)
562
- goto done;
563
- if (rq_data_dir(req) == WRITE && fs->write_protected)
564
- goto done;
565
-
566
- switch (rq_data_dir(req)) {
567
- case WRITE:
568
- /* NOT IMPLEMENTED */
569
- break;
570
- case READ:
571
- err = floppy_read_sectors(fs, blk_rq_pos(req),
572
- blk_rq_cur_sectors(req),
573
- bio_data(req->bio));
574
- break;
575
- }
576
- done:
577
- if (!__blk_end_request_cur(req, err))
578
- req = swim_next_request(swd);
579
- }
580554 }
581555
582556 static struct floppy_struct floppy_type[4] = {
....@@ -664,7 +638,8 @@
664638 return 0;
665639
666640 if (mode & (FMODE_READ|FMODE_WRITE)) {
667
- check_disk_change(bdev);
641
+ if (bdev_check_media_change(bdev) && fs->disk_in)
642
+ fs->ejected = 0;
668643 if ((mode & FMODE_WRITE) && fs->write_protected) {
669644 err = -EROFS;
670645 goto out;
....@@ -761,24 +736,6 @@
761736 return fs->ejected ? DISK_EVENT_MEDIA_CHANGE : 0;
762737 }
763738
764
-static int floppy_revalidate(struct gendisk *disk)
765
-{
766
- struct floppy_state *fs = disk->private_data;
767
- struct swim __iomem *base = fs->swd->base;
768
-
769
- swim_drive(base, fs->location);
770
-
771
- if (fs->ejected)
772
- setup_medium(fs);
773
-
774
- if (!fs->disk_in)
775
- swim_motor(base, OFF);
776
- else
777
- fs->ejected = 0;
778
-
779
- return !fs->disk_in;
780
-}
781
-
782739 static const struct block_device_operations floppy_fops = {
783740 .owner = THIS_MODULE,
784741 .open = floppy_unlocked_open,
....@@ -786,7 +743,6 @@
786743 .ioctl = floppy_ioctl,
787744 .getgeo = floppy_getgeo,
788745 .check_events = floppy_check_events,
789
- .revalidate_disk = floppy_revalidate,
790746 };
791747
792748 static struct kobject *floppy_find(dev_t dev, int *part, void *data)
....@@ -823,6 +779,10 @@
823779 return 0;
824780 }
825781
782
+static const struct blk_mq_ops swim_mq_ops = {
783
+ .queue_rq = swim_queue_rq,
784
+};
785
+
826786 static int swim_floppy_init(struct swim_priv *swd)
827787 {
828788 int err;
....@@ -852,20 +812,25 @@
852812 spin_lock_init(&swd->lock);
853813
854814 for (drive = 0; drive < swd->floppy_count; drive++) {
815
+ struct request_queue *q;
816
+
855817 swd->unit[drive].disk = alloc_disk(1);
856818 if (swd->unit[drive].disk == NULL) {
857819 err = -ENOMEM;
858820 goto exit_put_disks;
859821 }
860
- swd->unit[drive].disk->queue = blk_init_queue(do_fd_request,
861
- &swd->lock);
862
- if (!swd->unit[drive].disk->queue) {
863
- err = -ENOMEM;
822
+
823
+ q = blk_mq_init_sq_queue(&swd->unit[drive].tag_set, &swim_mq_ops,
824
+ 2, BLK_MQ_F_SHOULD_MERGE);
825
+ if (IS_ERR(q)) {
826
+ err = PTR_ERR(q);
864827 goto exit_put_disks;
865828 }
829
+
830
+ swd->unit[drive].disk->queue = q;
866831 blk_queue_bounce_limit(swd->unit[drive].disk->queue,
867832 BLK_BOUNCE_HIGH);
868
- swd->unit[drive].disk->queue->queuedata = swd;
833
+ swd->unit[drive].disk->queue->queuedata = &swd->unit[drive];
869834 swd->unit[drive].swd = swd;
870835 }
871836
....@@ -875,6 +840,7 @@
875840 swd->unit[drive].disk->first_minor = drive;
876841 sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
877842 swd->unit[drive].disk->fops = &floppy_fops;
843
+ swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE;
878844 swd->unit[drive].disk->private_data = &swd->unit[drive];
879845 set_capacity(swd->unit[drive].disk, 2880);
880846 add_disk(swd->unit[drive].disk);
....@@ -895,6 +861,7 @@
895861 blk_cleanup_queue(disk->queue);
896862 disk->queue = NULL;
897863 }
864
+ blk_mq_free_tag_set(&swd->unit[drive].tag_set);
898865 put_disk(disk);
899866 }
900867 } while (drive--);
....@@ -970,6 +937,7 @@
970937 for (drive = 0; drive < swd->floppy_count; drive++) {
971938 del_gendisk(swd->unit[drive].disk);
972939 blk_cleanup_queue(swd->unit[drive].disk->queue);
940
+ blk_mq_free_tag_set(&swd->unit[drive].tag_set);
973941 put_disk(swd->unit[drive].disk);
974942 }
975943