hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/drivers/block/paride/pcd.c
....@@ -137,7 +137,7 @@
137137 #include <linux/delay.h>
138138 #include <linux/cdrom.h>
139139 #include <linux/spinlock.h>
140
-#include <linux/blkdev.h>
140
+#include <linux/blk-mq.h>
141141 #include <linux/mutex.h>
142142 #include <linux/uaccess.h>
143143
....@@ -186,7 +186,8 @@
186186 static int pcd_detect(void);
187187 static void pcd_probe_capabilities(void);
188188 static void do_pcd_read_drq(void);
189
-static void do_pcd_request(struct request_queue * q);
189
+static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx,
190
+ const struct blk_mq_queue_data *bd);
190191 static void do_pcd_read(void);
191192
192193 struct pcd_unit {
....@@ -199,6 +200,8 @@
199200 char *name; /* pcd0, pcd1, etc */
200201 struct cdrom_device_info info; /* uniform cdrom interface */
201202 struct gendisk *disk;
203
+ struct blk_mq_tag_set tag_set;
204
+ struct list_head rq_list;
202205 };
203206
204207 static struct pcd_unit pcd[PCD_UNITS];
....@@ -230,7 +233,7 @@
230233 struct pcd_unit *cd = bdev->bd_disk->private_data;
231234 int ret;
232235
233
- check_disk_change(bdev);
236
+ bdev_check_media_change(bdev);
234237
235238 mutex_lock(&pcd_mutex);
236239 ret = cdrom_open(&cd->info, bdev, mode);
....@@ -272,6 +275,9 @@
272275 .open = pcd_block_open,
273276 .release = pcd_block_release,
274277 .ioctl = pcd_block_ioctl,
278
+#ifdef CONFIG_COMPAT
279
+ .compat_ioctl = blkdev_compat_ptr_ioctl,
280
+#endif
275281 .check_events = pcd_block_check_events,
276282 };
277283
....@@ -292,6 +298,10 @@
292298 CDC_CD_RW,
293299 };
294300
301
+static const struct blk_mq_ops pcd_mq_ops = {
302
+ .queue_rq = pcd_queue_rq,
303
+};
304
+
295305 static void pcd_init_units(void)
296306 {
297307 struct pcd_unit *cd;
....@@ -300,13 +310,20 @@
300310 pcd_drive_count = 0;
301311 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
302312 struct gendisk *disk = alloc_disk(1);
313
+
303314 if (!disk)
304315 continue;
305
- disk->queue = blk_init_queue(do_pcd_request, &pcd_lock);
306
- if (!disk->queue) {
316
+
317
+ disk->queue = blk_mq_init_sq_queue(&cd->tag_set, &pcd_mq_ops,
318
+ 1, BLK_MQ_F_SHOULD_MERGE);
319
+ if (IS_ERR(disk->queue)) {
320
+ disk->queue = NULL;
307321 put_disk(disk);
308322 continue;
309323 }
324
+
325
+ INIT_LIST_HEAD(&cd->rq_list);
326
+ disk->queue->queuedata = cd;
310327 blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
311328 cd->disk = disk;
312329 cd->pi = &cd->pia;
....@@ -329,6 +346,7 @@
329346 strcpy(disk->disk_name, cd->name); /* umm... */
330347 disk->fops = &pcd_bdops;
331348 disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
349
+ disk->events = DISK_EVENT_MEDIA_CHANGE;
332350 }
333351 }
334352
....@@ -708,9 +726,9 @@
708726 k = 0;
709727 if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
710728 cd = pcd;
711
- if (pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer,
712
- PI_PCD, verbose, cd->name)) {
713
- if (!pcd_probe(cd, -1, id) && cd->disk) {
729
+ if (cd->disk && pi_init(cd->pi, 1, -1, -1, -1, -1, -1,
730
+ pcd_buffer, PI_PCD, verbose, cd->name)) {
731
+ if (!pcd_probe(cd, -1, id)) {
714732 cd->present = 1;
715733 k++;
716734 } else
....@@ -721,11 +739,13 @@
721739 int *conf = *drives[unit];
722740 if (!conf[D_PRT])
723741 continue;
742
+ if (!cd->disk)
743
+ continue;
724744 if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD],
725745 conf[D_UNI], conf[D_PRO], conf[D_DLY],
726746 pcd_buffer, PI_PCD, verbose, cd->name))
727747 continue;
728
- if (!pcd_probe(cd, conf[D_SLV], id) && cd->disk) {
748
+ if (!pcd_probe(cd, conf[D_SLV], id)) {
729749 cd->present = 1;
730750 k++;
731751 } else
....@@ -736,8 +756,14 @@
736756 return 0;
737757
738758 printk("%s: No CD-ROM drive found\n", name);
739
- for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
759
+ for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
760
+ if (!cd->disk)
761
+ continue;
762
+ blk_cleanup_queue(cd->disk->queue);
763
+ cd->disk->queue = NULL;
764
+ blk_mq_free_tag_set(&cd->tag_set);
740765 put_disk(cd->disk);
766
+ }
741767 pi_unregister_driver(par_drv);
742768 return -1;
743769 }
....@@ -748,18 +774,18 @@
748774 static int set_next_request(void)
749775 {
750776 struct pcd_unit *cd;
751
- struct request_queue *q;
752777 int old_pos = pcd_queue;
753778
754779 do {
755780 cd = &pcd[pcd_queue];
756
- q = cd->present ? cd->disk->queue : NULL;
757781 if (++pcd_queue == PCD_UNITS)
758782 pcd_queue = 0;
759
- if (q) {
760
- pcd_req = blk_fetch_request(q);
761
- if (pcd_req)
762
- break;
783
+ if (cd->present && !list_empty(&cd->rq_list)) {
784
+ pcd_req = list_first_entry(&cd->rq_list, struct request,
785
+ queuelist);
786
+ list_del_init(&pcd_req->queuelist);
787
+ blk_mq_start_request(pcd_req);
788
+ break;
763789 }
764790 } while (pcd_queue != old_pos);
765791
....@@ -768,33 +794,41 @@
768794
769795 static void pcd_request(void)
770796 {
797
+ struct pcd_unit *cd;
798
+
771799 if (pcd_busy)
772800 return;
773
- while (1) {
774
- if (!pcd_req && !set_next_request())
775
- return;
776801
777
- if (rq_data_dir(pcd_req) == READ) {
778
- struct pcd_unit *cd = pcd_req->rq_disk->private_data;
779
- if (cd != pcd_current)
780
- pcd_bufblk = -1;
781
- pcd_current = cd;
782
- pcd_sector = blk_rq_pos(pcd_req);
783
- pcd_count = blk_rq_cur_sectors(pcd_req);
784
- pcd_buf = bio_data(pcd_req->bio);
785
- pcd_busy = 1;
786
- ps_set_intr(do_pcd_read, NULL, 0, nice);
787
- return;
788
- } else {
789
- __blk_end_request_all(pcd_req, BLK_STS_IOERR);
790
- pcd_req = NULL;
791
- }
792
- }
802
+ if (!pcd_req && !set_next_request())
803
+ return;
804
+
805
+ cd = pcd_req->rq_disk->private_data;
806
+ if (cd != pcd_current)
807
+ pcd_bufblk = -1;
808
+ pcd_current = cd;
809
+ pcd_sector = blk_rq_pos(pcd_req);
810
+ pcd_count = blk_rq_cur_sectors(pcd_req);
811
+ pcd_buf = bio_data(pcd_req->bio);
812
+ pcd_busy = 1;
813
+ ps_set_intr(do_pcd_read, NULL, 0, nice);
793814 }
794815
795
-static void do_pcd_request(struct request_queue *q)
816
+static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx,
817
+ const struct blk_mq_queue_data *bd)
796818 {
819
+ struct pcd_unit *cd = hctx->queue->queuedata;
820
+
821
+ if (rq_data_dir(bd->rq) != READ) {
822
+ blk_mq_start_request(bd->rq);
823
+ return BLK_STS_IOERR;
824
+ }
825
+
826
+ spin_lock_irq(&pcd_lock);
827
+ list_add_tail(&bd->rq->queuelist, &cd->rq_list);
797828 pcd_request();
829
+ spin_unlock_irq(&pcd_lock);
830
+
831
+ return BLK_STS_OK;
798832 }
799833
800834 static inline void next_request(blk_status_t err)
....@@ -802,8 +836,10 @@
802836 unsigned long saved_flags;
803837
804838 spin_lock_irqsave(&pcd_lock, saved_flags);
805
- if (!__blk_end_request_cur(pcd_req, err))
839
+ if (!blk_update_request(pcd_req, err, blk_rq_cur_bytes(pcd_req))) {
840
+ __blk_mq_end_request(pcd_req, err);
806841 pcd_req = NULL;
842
+ }
807843 pcd_busy = 0;
808844 pcd_request();
809845 spin_unlock_irqrestore(&pcd_lock, saved_flags);
....@@ -983,14 +1019,20 @@
9831019 pcd_probe_capabilities();
9841020
9851021 if (register_blkdev(major, name)) {
986
- for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
1022
+ for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
1023
+ if (!cd->disk)
1024
+ continue;
1025
+
1026
+ blk_cleanup_queue(cd->disk->queue);
1027
+ blk_mq_free_tag_set(&cd->tag_set);
9871028 put_disk(cd->disk);
1029
+ }
9881030 return -EBUSY;
9891031 }
9901032
9911033 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
9921034 if (cd->present) {
993
- register_cdrom(&cd->info);
1035
+ register_cdrom(cd->disk, &cd->info);
9941036 cd->disk->private_data = cd;
9951037 add_disk(cd->disk);
9961038 }
....@@ -1005,12 +1047,16 @@
10051047 int unit;
10061048
10071049 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
1050
+ if (!cd->disk)
1051
+ continue;
1052
+
10081053 if (cd->present) {
10091054 del_gendisk(cd->disk);
10101055 pi_release(cd->pi);
10111056 unregister_cdrom(&cd->info);
10121057 }
10131058 blk_cleanup_queue(cd->disk->queue);
1059
+ blk_mq_free_tag_set(&cd->tag_set);
10141060 put_disk(cd->disk);
10151061 }
10161062 unregister_blkdev(major, name);