| .. | .. |
|---|
| 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 | |
|---|