diff options
author | Jens Axboe <axboe@kernel.dk> | 2018-10-15 10:38:52 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-10-15 22:08:07 -0400 |
commit | 89c6b16509693332fe13d4bb6b812134de56c16f (patch) | |
tree | 5d48f858cd9b6f323d3fbfa70d70df3151e3b26d /drivers/block/paride | |
parent | fab1adcf9503ccf191aec9ee42580f7dc1eb6237 (diff) |
paride: convert pcd to blk-mq
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/paride')
-rw-r--r-- | drivers/block/paride/pcd.c | 88 |
1 files changed, 56 insertions, 32 deletions
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index a026211afb51..96670eefaeb2 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c | |||
@@ -137,7 +137,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY}; | |||
137 | #include <linux/delay.h> | 137 | #include <linux/delay.h> |
138 | #include <linux/cdrom.h> | 138 | #include <linux/cdrom.h> |
139 | #include <linux/spinlock.h> | 139 | #include <linux/spinlock.h> |
140 | #include <linux/blkdev.h> | 140 | #include <linux/blk-mq.h> |
141 | #include <linux/mutex.h> | 141 | #include <linux/mutex.h> |
142 | #include <linux/uaccess.h> | 142 | #include <linux/uaccess.h> |
143 | 143 | ||
@@ -186,7 +186,8 @@ static int pcd_packet(struct cdrom_device_info *cdi, | |||
186 | static int pcd_detect(void); | 186 | static int pcd_detect(void); |
187 | static void pcd_probe_capabilities(void); | 187 | static void pcd_probe_capabilities(void); |
188 | static void do_pcd_read_drq(void); | 188 | 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); | ||
190 | static void do_pcd_read(void); | 191 | static void do_pcd_read(void); |
191 | 192 | ||
192 | struct pcd_unit { | 193 | struct pcd_unit { |
@@ -199,6 +200,8 @@ struct pcd_unit { | |||
199 | char *name; /* pcd0, pcd1, etc */ | 200 | char *name; /* pcd0, pcd1, etc */ |
200 | struct cdrom_device_info info; /* uniform cdrom interface */ | 201 | struct cdrom_device_info info; /* uniform cdrom interface */ |
201 | struct gendisk *disk; | 202 | struct gendisk *disk; |
203 | struct blk_mq_tag_set tag_set; | ||
204 | struct list_head rq_list; | ||
202 | }; | 205 | }; |
203 | 206 | ||
204 | static struct pcd_unit pcd[PCD_UNITS]; | 207 | static struct pcd_unit pcd[PCD_UNITS]; |
@@ -292,6 +295,10 @@ static const struct cdrom_device_ops pcd_dops = { | |||
292 | CDC_CD_RW, | 295 | CDC_CD_RW, |
293 | }; | 296 | }; |
294 | 297 | ||
298 | static const struct blk_mq_ops pcd_mq_ops = { | ||
299 | .queue_rq = pcd_queue_rq, | ||
300 | }; | ||
301 | |||
295 | static void pcd_init_units(void) | 302 | static void pcd_init_units(void) |
296 | { | 303 | { |
297 | struct pcd_unit *cd; | 304 | struct pcd_unit *cd; |
@@ -300,13 +307,19 @@ static void pcd_init_units(void) | |||
300 | pcd_drive_count = 0; | 307 | pcd_drive_count = 0; |
301 | for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { | 308 | for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { |
302 | struct gendisk *disk = alloc_disk(1); | 309 | struct gendisk *disk = alloc_disk(1); |
310 | |||
303 | if (!disk) | 311 | if (!disk) |
304 | continue; | 312 | continue; |
305 | disk->queue = blk_init_queue(do_pcd_request, &pcd_lock); | 313 | |
306 | if (!disk->queue) { | 314 | disk->queue = blk_mq_init_sq_queue(&cd->tag_set, &pcd_mq_ops, |
307 | put_disk(disk); | 315 | 1, BLK_MQ_F_SHOULD_MERGE); |
316 | if (IS_ERR(disk->queue)) { | ||
317 | disk->queue = NULL; | ||
308 | continue; | 318 | continue; |
309 | } | 319 | } |
320 | |||
321 | INIT_LIST_HEAD(&cd->rq_list); | ||
322 | disk->queue->queuedata = cd; | ||
310 | blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); | 323 | blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); |
311 | cd->disk = disk; | 324 | cd->disk = disk; |
312 | cd->pi = &cd->pia; | 325 | cd->pi = &cd->pia; |
@@ -748,18 +761,18 @@ static int pcd_queue; | |||
748 | static int set_next_request(void) | 761 | static int set_next_request(void) |
749 | { | 762 | { |
750 | struct pcd_unit *cd; | 763 | struct pcd_unit *cd; |
751 | struct request_queue *q; | ||
752 | int old_pos = pcd_queue; | 764 | int old_pos = pcd_queue; |
753 | 765 | ||
754 | do { | 766 | do { |
755 | cd = &pcd[pcd_queue]; | 767 | cd = &pcd[pcd_queue]; |
756 | q = cd->present ? cd->disk->queue : NULL; | ||
757 | if (++pcd_queue == PCD_UNITS) | 768 | if (++pcd_queue == PCD_UNITS) |
758 | pcd_queue = 0; | 769 | pcd_queue = 0; |
759 | if (q) { | 770 | if (cd->present && !list_empty(&cd->rq_list)) { |
760 | pcd_req = blk_fetch_request(q); | 771 | pcd_req = list_first_entry(&cd->rq_list, struct request, |
761 | if (pcd_req) | 772 | queuelist); |
762 | break; | 773 | list_del_init(&pcd_req->queuelist); |
774 | blk_mq_start_request(pcd_req); | ||
775 | break; | ||
763 | } | 776 | } |
764 | } while (pcd_queue != old_pos); | 777 | } while (pcd_queue != old_pos); |
765 | 778 | ||
@@ -768,33 +781,41 @@ static int set_next_request(void) | |||
768 | 781 | ||
769 | static void pcd_request(void) | 782 | static void pcd_request(void) |
770 | { | 783 | { |
784 | struct pcd_unit *cd; | ||
785 | |||
771 | if (pcd_busy) | 786 | if (pcd_busy) |
772 | return; | 787 | return; |
773 | while (1) { | ||
774 | if (!pcd_req && !set_next_request()) | ||
775 | return; | ||
776 | 788 | ||
777 | if (rq_data_dir(pcd_req) == READ) { | 789 | if (!pcd_req && !set_next_request()) |
778 | struct pcd_unit *cd = pcd_req->rq_disk->private_data; | 790 | return; |
779 | if (cd != pcd_current) | 791 | |
780 | pcd_bufblk = -1; | 792 | cd = pcd_req->rq_disk->private_data; |
781 | pcd_current = cd; | 793 | if (cd != pcd_current) |
782 | pcd_sector = blk_rq_pos(pcd_req); | 794 | pcd_bufblk = -1; |
783 | pcd_count = blk_rq_cur_sectors(pcd_req); | 795 | pcd_current = cd; |
784 | pcd_buf = bio_data(pcd_req->bio); | 796 | pcd_sector = blk_rq_pos(pcd_req); |
785 | pcd_busy = 1; | 797 | pcd_count = blk_rq_cur_sectors(pcd_req); |
786 | ps_set_intr(do_pcd_read, NULL, 0, nice); | 798 | pcd_buf = bio_data(pcd_req->bio); |
787 | return; | 799 | pcd_busy = 1; |
788 | } else { | 800 | ps_set_intr(do_pcd_read, NULL, 0, nice); |
789 | __blk_end_request_all(pcd_req, BLK_STS_IOERR); | ||
790 | pcd_req = NULL; | ||
791 | } | ||
792 | } | ||
793 | } | 801 | } |
794 | 802 | ||
795 | static void do_pcd_request(struct request_queue *q) | 803 | static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx, |
804 | const struct blk_mq_queue_data *bd) | ||
796 | { | 805 | { |
806 | struct pcd_unit *cd = hctx->queue->queuedata; | ||
807 | |||
808 | if (rq_data_dir(bd->rq) != READ) { | ||
809 | blk_mq_start_request(bd->rq); | ||
810 | return BLK_STS_IOERR; | ||
811 | } | ||
812 | |||
813 | spin_lock_irq(&pcd_lock); | ||
814 | list_add_tail(&bd->rq->queuelist, &cd->rq_list); | ||
797 | pcd_request(); | 815 | pcd_request(); |
816 | spin_unlock_irq(&pcd_lock); | ||
817 | |||
818 | return BLK_STS_OK; | ||
798 | } | 819 | } |
799 | 820 | ||
800 | static inline void next_request(blk_status_t err) | 821 | static inline void next_request(blk_status_t err) |
@@ -802,8 +823,10 @@ static inline void next_request(blk_status_t err) | |||
802 | unsigned long saved_flags; | 823 | unsigned long saved_flags; |
803 | 824 | ||
804 | spin_lock_irqsave(&pcd_lock, saved_flags); | 825 | spin_lock_irqsave(&pcd_lock, saved_flags); |
805 | if (!__blk_end_request_cur(pcd_req, err)) | 826 | if (!blk_update_request(pcd_req, err, blk_rq_cur_bytes(pcd_req))) { |
827 | __blk_mq_end_request(pcd_req, err); | ||
806 | pcd_req = NULL; | 828 | pcd_req = NULL; |
829 | } | ||
807 | pcd_busy = 0; | 830 | pcd_busy = 0; |
808 | pcd_request(); | 831 | pcd_request(); |
809 | spin_unlock_irqrestore(&pcd_lock, saved_flags); | 832 | spin_unlock_irqrestore(&pcd_lock, saved_flags); |
@@ -1011,6 +1034,7 @@ static void __exit pcd_exit(void) | |||
1011 | unregister_cdrom(&cd->info); | 1034 | unregister_cdrom(&cd->info); |
1012 | } | 1035 | } |
1013 | blk_cleanup_queue(cd->disk->queue); | 1036 | blk_cleanup_queue(cd->disk->queue); |
1037 | blk_mq_free_tag_set(&cd->tag_set); | ||
1014 | put_disk(cd->disk); | 1038 | put_disk(cd->disk); |
1015 | } | 1039 | } |
1016 | unregister_blkdev(major, name); | 1040 | unregister_blkdev(major, name); |