.. | .. |
---|
152 | 152 | #include <linux/hdreg.h> |
---|
153 | 153 | #include <linux/cdrom.h> |
---|
154 | 154 | #include <linux/spinlock.h> |
---|
155 | | -#include <linux/blkdev.h> |
---|
| 155 | +#include <linux/blk-mq.h> |
---|
156 | 156 | #include <linux/blkpg.h> |
---|
157 | 157 | #include <linux/mutex.h> |
---|
158 | 158 | #include <linux/uaccess.h> |
---|
.. | .. |
---|
206 | 206 | #define ATAPI_WRITE_10 0x2a |
---|
207 | 207 | |
---|
208 | 208 | static int pf_open(struct block_device *bdev, fmode_t mode); |
---|
209 | | -static void do_pf_request(struct request_queue * q); |
---|
| 209 | +static blk_status_t pf_queue_rq(struct blk_mq_hw_ctx *hctx, |
---|
| 210 | + const struct blk_mq_queue_data *bd); |
---|
210 | 211 | static int pf_ioctl(struct block_device *bdev, fmode_t mode, |
---|
211 | 212 | unsigned int cmd, unsigned long arg); |
---|
212 | 213 | static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
---|
.. | .. |
---|
238 | 239 | int present; /* device present ? */ |
---|
239 | 240 | char name[PF_NAMELEN]; /* pf0, pf1, ... */ |
---|
240 | 241 | struct gendisk *disk; |
---|
| 242 | + struct blk_mq_tag_set tag_set; |
---|
| 243 | + struct list_head rq_list; |
---|
241 | 244 | }; |
---|
242 | 245 | |
---|
243 | 246 | static struct pf_unit units[PF_UNITS]; |
---|
.. | .. |
---|
273 | 276 | .open = pf_open, |
---|
274 | 277 | .release = pf_release, |
---|
275 | 278 | .ioctl = pf_ioctl, |
---|
| 279 | + .compat_ioctl = pf_ioctl, |
---|
276 | 280 | .getgeo = pf_getgeo, |
---|
277 | 281 | .check_events = pf_check_events, |
---|
| 282 | +}; |
---|
| 283 | + |
---|
| 284 | +static const struct blk_mq_ops pf_mq_ops = { |
---|
| 285 | + .queue_rq = pf_queue_rq, |
---|
278 | 286 | }; |
---|
279 | 287 | |
---|
280 | 288 | static void __init pf_init_units(void) |
---|
.. | .. |
---|
284 | 292 | |
---|
285 | 293 | pf_drive_count = 0; |
---|
286 | 294 | for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) { |
---|
287 | | - struct gendisk *disk = alloc_disk(1); |
---|
| 295 | + struct gendisk *disk; |
---|
| 296 | + |
---|
| 297 | + disk = alloc_disk(1); |
---|
288 | 298 | if (!disk) |
---|
289 | 299 | continue; |
---|
290 | | - disk->queue = blk_init_queue(do_pf_request, &pf_spin_lock); |
---|
291 | | - if (!disk->queue) { |
---|
| 300 | + |
---|
| 301 | + disk->queue = blk_mq_init_sq_queue(&pf->tag_set, &pf_mq_ops, |
---|
| 302 | + 1, BLK_MQ_F_SHOULD_MERGE); |
---|
| 303 | + if (IS_ERR(disk->queue)) { |
---|
| 304 | + disk->queue = NULL; |
---|
292 | 305 | put_disk(disk); |
---|
293 | | - return; |
---|
| 306 | + continue; |
---|
294 | 307 | } |
---|
| 308 | + |
---|
| 309 | + INIT_LIST_HEAD(&pf->rq_list); |
---|
| 310 | + disk->queue->queuedata = pf; |
---|
295 | 311 | blk_queue_max_segments(disk->queue, cluster); |
---|
296 | 312 | blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); |
---|
297 | 313 | pf->disk = disk; |
---|
.. | .. |
---|
304 | 320 | disk->first_minor = unit; |
---|
305 | 321 | strcpy(disk->disk_name, pf->name); |
---|
306 | 322 | disk->fops = &pf_fops; |
---|
| 323 | + disk->events = DISK_EVENT_MEDIA_CHANGE; |
---|
307 | 324 | if (!(*drives[unit])[D_PRT]) |
---|
308 | 325 | pf_drive_count++; |
---|
309 | 326 | } |
---|
.. | .. |
---|
746 | 763 | return 0; |
---|
747 | 764 | |
---|
748 | 765 | printk("%s: No ATAPI disk detected\n", name); |
---|
749 | | - for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) |
---|
| 766 | + for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { |
---|
| 767 | + if (!pf->disk) |
---|
| 768 | + continue; |
---|
| 769 | + blk_cleanup_queue(pf->disk->queue); |
---|
| 770 | + pf->disk->queue = NULL; |
---|
| 771 | + blk_mq_free_tag_set(&pf->tag_set); |
---|
750 | 772 | put_disk(pf->disk); |
---|
| 773 | + } |
---|
751 | 774 | pi_unregister_driver(par_drv); |
---|
752 | 775 | return -1; |
---|
753 | 776 | } |
---|
.. | .. |
---|
784 | 807 | static int set_next_request(void) |
---|
785 | 808 | { |
---|
786 | 809 | struct pf_unit *pf; |
---|
787 | | - struct request_queue *q; |
---|
788 | 810 | int old_pos = pf_queue; |
---|
789 | 811 | |
---|
790 | 812 | do { |
---|
791 | 813 | pf = &units[pf_queue]; |
---|
792 | | - q = pf->present ? pf->disk->queue : NULL; |
---|
793 | 814 | if (++pf_queue == PF_UNITS) |
---|
794 | 815 | pf_queue = 0; |
---|
795 | | - if (q) { |
---|
796 | | - pf_req = blk_fetch_request(q); |
---|
797 | | - if (pf_req) |
---|
798 | | - break; |
---|
| 816 | + if (pf->present && !list_empty(&pf->rq_list)) { |
---|
| 817 | + pf_req = list_first_entry(&pf->rq_list, struct request, |
---|
| 818 | + queuelist); |
---|
| 819 | + list_del_init(&pf_req->queuelist); |
---|
| 820 | + blk_mq_start_request(pf_req); |
---|
| 821 | + break; |
---|
799 | 822 | } |
---|
800 | 823 | } while (pf_queue != old_pos); |
---|
801 | 824 | |
---|
.. | .. |
---|
804 | 827 | |
---|
805 | 828 | static void pf_end_request(blk_status_t err) |
---|
806 | 829 | { |
---|
807 | | - if (pf_req && !__blk_end_request_cur(pf_req, err)) |
---|
| 830 | + if (!pf_req) |
---|
| 831 | + return; |
---|
| 832 | + if (!blk_update_request(pf_req, err, blk_rq_cur_bytes(pf_req))) { |
---|
| 833 | + __blk_mq_end_request(pf_req, err); |
---|
808 | 834 | pf_req = NULL; |
---|
| 835 | + } |
---|
809 | 836 | } |
---|
810 | 837 | |
---|
811 | 838 | static void pf_request(void) |
---|
.. | .. |
---|
842 | 869 | } |
---|
843 | 870 | } |
---|
844 | 871 | |
---|
845 | | -static void do_pf_request(struct request_queue *q) |
---|
| 872 | +static blk_status_t pf_queue_rq(struct blk_mq_hw_ctx *hctx, |
---|
| 873 | + const struct blk_mq_queue_data *bd) |
---|
846 | 874 | { |
---|
| 875 | + struct pf_unit *pf = hctx->queue->queuedata; |
---|
| 876 | + |
---|
| 877 | + spin_lock_irq(&pf_spin_lock); |
---|
| 878 | + list_add_tail(&bd->rq->queuelist, &pf->rq_list); |
---|
847 | 879 | pf_request(); |
---|
| 880 | + spin_unlock_irq(&pf_spin_lock); |
---|
| 881 | + |
---|
| 882 | + return BLK_STS_OK; |
---|
848 | 883 | } |
---|
849 | 884 | |
---|
850 | 885 | static int pf_next_buf(void) |
---|
.. | .. |
---|
998 | 1033 | pf_busy = 0; |
---|
999 | 1034 | |
---|
1000 | 1035 | if (register_blkdev(major, name)) { |
---|
1001 | | - for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) |
---|
| 1036 | + for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { |
---|
| 1037 | + if (!pf->disk) |
---|
| 1038 | + continue; |
---|
| 1039 | + blk_cleanup_queue(pf->disk->queue); |
---|
| 1040 | + blk_mq_free_tag_set(&pf->tag_set); |
---|
1002 | 1041 | put_disk(pf->disk); |
---|
| 1042 | + } |
---|
1003 | 1043 | return -EBUSY; |
---|
1004 | 1044 | } |
---|
1005 | 1045 | |
---|
.. | .. |
---|
1020 | 1060 | int unit; |
---|
1021 | 1061 | unregister_blkdev(major, name); |
---|
1022 | 1062 | for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { |
---|
1023 | | - if (!pf->present) |
---|
| 1063 | + if (!pf->disk) |
---|
1024 | 1064 | continue; |
---|
1025 | | - del_gendisk(pf->disk); |
---|
| 1065 | + |
---|
| 1066 | + if (pf->present) |
---|
| 1067 | + del_gendisk(pf->disk); |
---|
| 1068 | + |
---|
1026 | 1069 | blk_cleanup_queue(pf->disk->queue); |
---|
| 1070 | + blk_mq_free_tag_set(&pf->tag_set); |
---|
1027 | 1071 | put_disk(pf->disk); |
---|
1028 | | - pi_release(pf->pi); |
---|
| 1072 | + |
---|
| 1073 | + if (pf->present) |
---|
| 1074 | + pi_release(pf->pi); |
---|
1029 | 1075 | } |
---|
1030 | 1076 | } |
---|
1031 | 1077 | |
---|