.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* GD ROM driver for the SEGA Dreamcast |
---|
2 | 3 | * copyright Adrian McMenamin, 2007 |
---|
3 | 4 | * With thanks to Marcus Comstedt and Nathan Keynes |
---|
4 | 5 | * for work in reversing PIO and DMA |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License as published by |
---|
8 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - * (at your option) any later version. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | | - * |
---|
16 | | - * You should have received a copy of the GNU General Public License along |
---|
17 | | - * with this program; if not, write to the Free Software Foundation, Inc., |
---|
18 | | - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
---|
19 | | - * |
---|
20 | 6 | */ |
---|
21 | 7 | |
---|
22 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
31 | 17 | #include <linux/cdrom.h> |
---|
32 | 18 | #include <linux/genhd.h> |
---|
33 | 19 | #include <linux/bio.h> |
---|
34 | | -#include <linux/blkdev.h> |
---|
| 20 | +#include <linux/blk-mq.h> |
---|
35 | 21 | #include <linux/interrupt.h> |
---|
36 | 22 | #include <linux/device.h> |
---|
37 | 23 | #include <linux/mutex.h> |
---|
38 | 24 | #include <linux/wait.h> |
---|
39 | | -#include <linux/workqueue.h> |
---|
40 | 25 | #include <linux/platform_device.h> |
---|
41 | 26 | #include <scsi/scsi.h> |
---|
42 | 27 | #include <asm/io.h> |
---|
.. | .. |
---|
102 | 87 | static DECLARE_WAIT_QUEUE_HEAD(command_queue); |
---|
103 | 88 | static DECLARE_WAIT_QUEUE_HEAD(request_queue); |
---|
104 | 89 | |
---|
105 | | -static DEFINE_SPINLOCK(gdrom_lock); |
---|
106 | | -static void gdrom_readdisk_dma(struct work_struct *work); |
---|
107 | | -static DECLARE_WORK(work, gdrom_readdisk_dma); |
---|
108 | | -static LIST_HEAD(gdrom_deferred); |
---|
109 | | - |
---|
110 | 90 | struct gdromtoc { |
---|
111 | 91 | unsigned int entry[99]; |
---|
112 | 92 | unsigned int first, last; |
---|
.. | .. |
---|
122 | 102 | char disk_type; |
---|
123 | 103 | struct gdromtoc *toc; |
---|
124 | 104 | struct request_queue *gdrom_rq; |
---|
| 105 | + struct blk_mq_tag_set tag_set; |
---|
125 | 106 | } gd; |
---|
126 | 107 | |
---|
127 | 108 | struct gdrom_id { |
---|
.. | .. |
---|
332 | 313 | static int gdrom_get_last_session(struct cdrom_device_info *cd_info, |
---|
333 | 314 | struct cdrom_multisession *ms_info) |
---|
334 | 315 | { |
---|
335 | | - int fentry, lentry, track, data, tocuse, err; |
---|
| 316 | + int fentry, lentry, track, data, err; |
---|
| 317 | + |
---|
336 | 318 | if (!gd.toc) |
---|
337 | 319 | return -ENOMEM; |
---|
338 | | - tocuse = 1; |
---|
| 320 | + |
---|
339 | 321 | /* Check if GD-ROM */ |
---|
340 | 322 | err = gdrom_readtoc_cmd(gd.toc, 1); |
---|
341 | 323 | /* Not a GD-ROM so check if standard CD-ROM */ |
---|
342 | 324 | if (err) { |
---|
343 | | - tocuse = 0; |
---|
344 | 325 | err = gdrom_readtoc_cmd(gd.toc, 0); |
---|
345 | 326 | if (err) { |
---|
346 | 327 | pr_info("Could not get CD table of contents\n"); |
---|
.. | .. |
---|
498 | 479 | { |
---|
499 | 480 | int ret; |
---|
500 | 481 | |
---|
501 | | - check_disk_change(bdev); |
---|
| 482 | + bdev_check_media_change(bdev); |
---|
502 | 483 | |
---|
503 | 484 | mutex_lock(&gdrom_mutex); |
---|
504 | 485 | ret = cdrom_open(gd.cd_info, bdev, mode); |
---|
.. | .. |
---|
537 | 518 | .release = gdrom_bdops_release, |
---|
538 | 519 | .check_events = gdrom_bdops_check_events, |
---|
539 | 520 | .ioctl = gdrom_bdops_ioctl, |
---|
| 521 | +#ifdef CONFIG_COMPAT |
---|
| 522 | + .compat_ioctl = blkdev_compat_ptr_ioctl, |
---|
| 523 | +#endif |
---|
540 | 524 | }; |
---|
541 | 525 | |
---|
542 | 526 | static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id) |
---|
.. | .. |
---|
584 | 568 | * 9 -> sectors >> 8 |
---|
585 | 569 | * 10 -> sectors |
---|
586 | 570 | */ |
---|
587 | | -static void gdrom_readdisk_dma(struct work_struct *work) |
---|
| 571 | +static blk_status_t gdrom_readdisk_dma(struct request *req) |
---|
588 | 572 | { |
---|
589 | 573 | int block, block_cnt; |
---|
590 | 574 | blk_status_t err; |
---|
591 | 575 | struct packet_command *read_command; |
---|
592 | | - struct list_head *elem, *next; |
---|
593 | | - struct request *req; |
---|
594 | 576 | unsigned long timeout; |
---|
595 | 577 | |
---|
596 | | - if (list_empty(&gdrom_deferred)) |
---|
597 | | - return; |
---|
598 | 578 | read_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL); |
---|
599 | 579 | if (!read_command) |
---|
600 | | - return; /* get more memory later? */ |
---|
| 580 | + return BLK_STS_RESOURCE; |
---|
| 581 | + |
---|
601 | 582 | read_command->cmd[0] = 0x30; |
---|
602 | 583 | read_command->cmd[1] = 0x20; |
---|
603 | | - spin_lock(&gdrom_lock); |
---|
604 | | - list_for_each_safe(elem, next, &gdrom_deferred) { |
---|
605 | | - req = list_entry(elem, struct request, queuelist); |
---|
606 | | - spin_unlock(&gdrom_lock); |
---|
607 | | - block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET; |
---|
608 | | - block_cnt = blk_rq_sectors(req)/GD_TO_BLK; |
---|
609 | | - __raw_writel(virt_to_phys(bio_data(req->bio)), GDROM_DMA_STARTADDR_REG); |
---|
610 | | - __raw_writel(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG); |
---|
611 | | - __raw_writel(1, GDROM_DMA_DIRECTION_REG); |
---|
612 | | - __raw_writel(1, GDROM_DMA_ENABLE_REG); |
---|
613 | | - read_command->cmd[2] = (block >> 16) & 0xFF; |
---|
614 | | - read_command->cmd[3] = (block >> 8) & 0xFF; |
---|
615 | | - read_command->cmd[4] = block & 0xFF; |
---|
616 | | - read_command->cmd[8] = (block_cnt >> 16) & 0xFF; |
---|
617 | | - read_command->cmd[9] = (block_cnt >> 8) & 0xFF; |
---|
618 | | - read_command->cmd[10] = block_cnt & 0xFF; |
---|
619 | | - /* set for DMA */ |
---|
620 | | - __raw_writeb(1, GDROM_ERROR_REG); |
---|
621 | | - /* other registers */ |
---|
622 | | - __raw_writeb(0, GDROM_SECNUM_REG); |
---|
623 | | - __raw_writeb(0, GDROM_BCL_REG); |
---|
624 | | - __raw_writeb(0, GDROM_BCH_REG); |
---|
625 | | - __raw_writeb(0, GDROM_DSEL_REG); |
---|
626 | | - __raw_writeb(0, GDROM_INTSEC_REG); |
---|
627 | | - /* Wait for registers to reset after any previous activity */ |
---|
628 | | - timeout = jiffies + HZ / 2; |
---|
629 | | - while (gdrom_is_busy() && time_before(jiffies, timeout)) |
---|
630 | | - cpu_relax(); |
---|
631 | | - __raw_writeb(GDROM_COM_PACKET, GDROM_STATUSCOMMAND_REG); |
---|
632 | | - timeout = jiffies + HZ / 2; |
---|
633 | | - /* Wait for packet command to finish */ |
---|
634 | | - while (gdrom_is_busy() && time_before(jiffies, timeout)) |
---|
635 | | - cpu_relax(); |
---|
636 | | - gd.pending = 1; |
---|
637 | | - gd.transfer = 1; |
---|
638 | | - outsw(GDROM_DATA_REG, &read_command->cmd, 6); |
---|
639 | | - timeout = jiffies + HZ / 2; |
---|
640 | | - /* Wait for any pending DMA to finish */ |
---|
641 | | - while (__raw_readb(GDROM_DMA_STATUS_REG) && |
---|
642 | | - time_before(jiffies, timeout)) |
---|
643 | | - cpu_relax(); |
---|
644 | | - /* start transfer */ |
---|
645 | | - __raw_writeb(1, GDROM_DMA_STATUS_REG); |
---|
646 | | - wait_event_interruptible_timeout(request_queue, |
---|
647 | | - gd.transfer == 0, GDROM_DEFAULT_TIMEOUT); |
---|
648 | | - err = gd.transfer ? BLK_STS_IOERR : BLK_STS_OK; |
---|
649 | | - gd.transfer = 0; |
---|
650 | | - gd.pending = 0; |
---|
651 | | - /* now seek to take the request spinlock |
---|
652 | | - * before handling ending the request */ |
---|
653 | | - spin_lock(&gdrom_lock); |
---|
654 | | - list_del_init(&req->queuelist); |
---|
655 | | - __blk_end_request_all(req, err); |
---|
656 | | - } |
---|
657 | | - spin_unlock(&gdrom_lock); |
---|
| 584 | + block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET; |
---|
| 585 | + block_cnt = blk_rq_sectors(req)/GD_TO_BLK; |
---|
| 586 | + __raw_writel(virt_to_phys(bio_data(req->bio)), GDROM_DMA_STARTADDR_REG); |
---|
| 587 | + __raw_writel(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG); |
---|
| 588 | + __raw_writel(1, GDROM_DMA_DIRECTION_REG); |
---|
| 589 | + __raw_writel(1, GDROM_DMA_ENABLE_REG); |
---|
| 590 | + read_command->cmd[2] = (block >> 16) & 0xFF; |
---|
| 591 | + read_command->cmd[3] = (block >> 8) & 0xFF; |
---|
| 592 | + read_command->cmd[4] = block & 0xFF; |
---|
| 593 | + read_command->cmd[8] = (block_cnt >> 16) & 0xFF; |
---|
| 594 | + read_command->cmd[9] = (block_cnt >> 8) & 0xFF; |
---|
| 595 | + read_command->cmd[10] = block_cnt & 0xFF; |
---|
| 596 | + /* set for DMA */ |
---|
| 597 | + __raw_writeb(1, GDROM_ERROR_REG); |
---|
| 598 | + /* other registers */ |
---|
| 599 | + __raw_writeb(0, GDROM_SECNUM_REG); |
---|
| 600 | + __raw_writeb(0, GDROM_BCL_REG); |
---|
| 601 | + __raw_writeb(0, GDROM_BCH_REG); |
---|
| 602 | + __raw_writeb(0, GDROM_DSEL_REG); |
---|
| 603 | + __raw_writeb(0, GDROM_INTSEC_REG); |
---|
| 604 | + /* Wait for registers to reset after any previous activity */ |
---|
| 605 | + timeout = jiffies + HZ / 2; |
---|
| 606 | + while (gdrom_is_busy() && time_before(jiffies, timeout)) |
---|
| 607 | + cpu_relax(); |
---|
| 608 | + __raw_writeb(GDROM_COM_PACKET, GDROM_STATUSCOMMAND_REG); |
---|
| 609 | + timeout = jiffies + HZ / 2; |
---|
| 610 | + /* Wait for packet command to finish */ |
---|
| 611 | + while (gdrom_is_busy() && time_before(jiffies, timeout)) |
---|
| 612 | + cpu_relax(); |
---|
| 613 | + gd.pending = 1; |
---|
| 614 | + gd.transfer = 1; |
---|
| 615 | + outsw(GDROM_DATA_REG, &read_command->cmd, 6); |
---|
| 616 | + timeout = jiffies + HZ / 2; |
---|
| 617 | + /* Wait for any pending DMA to finish */ |
---|
| 618 | + while (__raw_readb(GDROM_DMA_STATUS_REG) && |
---|
| 619 | + time_before(jiffies, timeout)) |
---|
| 620 | + cpu_relax(); |
---|
| 621 | + /* start transfer */ |
---|
| 622 | + __raw_writeb(1, GDROM_DMA_STATUS_REG); |
---|
| 623 | + wait_event_interruptible_timeout(request_queue, |
---|
| 624 | + gd.transfer == 0, GDROM_DEFAULT_TIMEOUT); |
---|
| 625 | + err = gd.transfer ? BLK_STS_IOERR : BLK_STS_OK; |
---|
| 626 | + gd.transfer = 0; |
---|
| 627 | + gd.pending = 0; |
---|
| 628 | + |
---|
| 629 | + blk_mq_end_request(req, err); |
---|
658 | 630 | kfree(read_command); |
---|
| 631 | + return BLK_STS_OK; |
---|
659 | 632 | } |
---|
660 | 633 | |
---|
661 | | -static void gdrom_request(struct request_queue *rq) |
---|
| 634 | +static blk_status_t gdrom_queue_rq(struct blk_mq_hw_ctx *hctx, |
---|
| 635 | + const struct blk_mq_queue_data *bd) |
---|
662 | 636 | { |
---|
663 | | - struct request *req; |
---|
| 637 | + blk_mq_start_request(bd->rq); |
---|
664 | 638 | |
---|
665 | | - while ((req = blk_fetch_request(rq)) != NULL) { |
---|
666 | | - switch (req_op(req)) { |
---|
667 | | - case REQ_OP_READ: |
---|
668 | | - /* |
---|
669 | | - * Add to list of deferred work and then schedule |
---|
670 | | - * workqueue. |
---|
671 | | - */ |
---|
672 | | - list_add_tail(&req->queuelist, &gdrom_deferred); |
---|
673 | | - schedule_work(&work); |
---|
674 | | - break; |
---|
675 | | - case REQ_OP_WRITE: |
---|
676 | | - pr_notice("Read only device - write request ignored\n"); |
---|
677 | | - __blk_end_request_all(req, BLK_STS_IOERR); |
---|
678 | | - break; |
---|
679 | | - default: |
---|
680 | | - printk(KERN_DEBUG "gdrom: Non-fs request ignored\n"); |
---|
681 | | - __blk_end_request_all(req, BLK_STS_IOERR); |
---|
682 | | - break; |
---|
683 | | - } |
---|
| 639 | + switch (req_op(bd->rq)) { |
---|
| 640 | + case REQ_OP_READ: |
---|
| 641 | + return gdrom_readdisk_dma(bd->rq); |
---|
| 642 | + case REQ_OP_WRITE: |
---|
| 643 | + pr_notice("Read only device - write request ignored\n"); |
---|
| 644 | + return BLK_STS_IOERR; |
---|
| 645 | + default: |
---|
| 646 | + printk(KERN_DEBUG "gdrom: Non-fs request ignored\n"); |
---|
| 647 | + return BLK_STS_IOERR; |
---|
684 | 648 | } |
---|
685 | 649 | } |
---|
686 | 650 | |
---|
.. | .. |
---|
768 | 732 | return gdrom_init_dma_mode(); |
---|
769 | 733 | } |
---|
770 | 734 | |
---|
| 735 | +static const struct blk_mq_ops gdrom_mq_ops = { |
---|
| 736 | + .queue_rq = gdrom_queue_rq, |
---|
| 737 | +}; |
---|
| 738 | + |
---|
771 | 739 | /* |
---|
772 | 740 | * register this as a block device and as compliant with the |
---|
773 | 741 | * universal CD Rom driver interface |
---|
.. | .. |
---|
784 | 752 | |
---|
785 | 753 | /* Start the device */ |
---|
786 | 754 | if (gdrom_execute_diagnostic() != 1) { |
---|
787 | | - pr_warning("ATA Probe for GDROM failed\n"); |
---|
| 755 | + pr_warn("ATA Probe for GDROM failed\n"); |
---|
788 | 756 | return -ENODEV; |
---|
789 | 757 | } |
---|
790 | 758 | /* Print out firmware ID */ |
---|
.. | .. |
---|
809 | 777 | goto probe_fail_no_disk; |
---|
810 | 778 | } |
---|
811 | 779 | probe_gdrom_setupdisk(); |
---|
812 | | - if (register_cdrom(gd.cd_info)) { |
---|
| 780 | + if (register_cdrom(gd.disk, gd.cd_info)) { |
---|
813 | 781 | err = -ENODEV; |
---|
814 | 782 | goto probe_fail_cdrom_register; |
---|
815 | 783 | } |
---|
816 | 784 | gd.disk->fops = &gdrom_bdops; |
---|
| 785 | + gd.disk->events = DISK_EVENT_MEDIA_CHANGE; |
---|
817 | 786 | /* latch on to the interrupt */ |
---|
818 | 787 | err = gdrom_set_interrupt_handlers(); |
---|
819 | 788 | if (err) |
---|
820 | 789 | goto probe_fail_cmdirq_register; |
---|
821 | | - gd.gdrom_rq = blk_init_queue(gdrom_request, &gdrom_lock); |
---|
822 | | - if (!gd.gdrom_rq) { |
---|
823 | | - err = -ENOMEM; |
---|
| 790 | + |
---|
| 791 | + gd.gdrom_rq = blk_mq_init_sq_queue(&gd.tag_set, &gdrom_mq_ops, 1, |
---|
| 792 | + BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING); |
---|
| 793 | + if (IS_ERR(gd.gdrom_rq)) { |
---|
| 794 | + err = PTR_ERR(gd.gdrom_rq); |
---|
| 795 | + gd.gdrom_rq = NULL; |
---|
824 | 796 | goto probe_fail_requestq; |
---|
825 | 797 | } |
---|
| 798 | + |
---|
826 | 799 | blk_queue_bounce_limit(gd.gdrom_rq, BLK_BOUNCE_HIGH); |
---|
827 | 800 | |
---|
828 | 801 | err = probe_gdrom_setupqueue(); |
---|
.. | .. |
---|
839 | 812 | |
---|
840 | 813 | probe_fail_toc: |
---|
841 | 814 | blk_cleanup_queue(gd.gdrom_rq); |
---|
| 815 | + blk_mq_free_tag_set(&gd.tag_set); |
---|
842 | 816 | probe_fail_requestq: |
---|
843 | 817 | free_irq(HW_EVENT_GDROM_DMA, &gd); |
---|
844 | 818 | free_irq(HW_EVENT_GDROM_CMD, &gd); |
---|
.. | .. |
---|
850 | 824 | probe_fail_no_mem: |
---|
851 | 825 | unregister_blkdev(gdrom_major, GDROM_DEV_NAME); |
---|
852 | 826 | gdrom_major = 0; |
---|
853 | | - pr_warning("Probe failed - error is 0x%X\n", err); |
---|
| 827 | + pr_warn("Probe failed - error is 0x%X\n", err); |
---|
854 | 828 | return err; |
---|
855 | 829 | } |
---|
856 | 830 | |
---|
857 | 831 | static int remove_gdrom(struct platform_device *devptr) |
---|
858 | 832 | { |
---|
859 | | - flush_work(&work); |
---|
860 | 833 | blk_cleanup_queue(gd.gdrom_rq); |
---|
| 834 | + blk_mq_free_tag_set(&gd.tag_set); |
---|
861 | 835 | free_irq(HW_EVENT_GDROM_CMD, &gd); |
---|
862 | 836 | free_irq(HW_EVENT_GDROM_DMA, &gd); |
---|
863 | 837 | del_gendisk(gd.disk); |
---|