summaryrefslogtreecommitdiffstats
path: root/drivers/block/paride
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2018-10-15 10:38:52 -0400
committerJens Axboe <axboe@kernel.dk>2018-10-15 22:08:07 -0400
commit89c6b16509693332fe13d4bb6b812134de56c16f (patch)
tree5d48f858cd9b6f323d3fbfa70d70df3151e3b26d /drivers/block/paride
parentfab1adcf9503ccf191aec9ee42580f7dc1eb6237 (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.c88
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,
186static int pcd_detect(void); 186static int pcd_detect(void);
187static void pcd_probe_capabilities(void); 187static void pcd_probe_capabilities(void);
188static void do_pcd_read_drq(void); 188static void do_pcd_read_drq(void);
189static void do_pcd_request(struct request_queue * q); 189static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx,
190 const struct blk_mq_queue_data *bd);
190static void do_pcd_read(void); 191static void do_pcd_read(void);
191 192
192struct pcd_unit { 193struct 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
204static struct pcd_unit pcd[PCD_UNITS]; 207static 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
298static const struct blk_mq_ops pcd_mq_ops = {
299 .queue_rq = pcd_queue_rq,
300};
301
295static void pcd_init_units(void) 302static 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;
748static int set_next_request(void) 761static 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
769static void pcd_request(void) 782static 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
795static void do_pcd_request(struct request_queue *q) 803static 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
800static inline void next_request(blk_status_t err) 821static 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);