.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * sr.c Copyright (C) 1992 David Giller |
---|
3 | 4 | * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale |
---|
.. | .. |
---|
37 | 38 | #include <linux/kernel.h> |
---|
38 | 39 | #include <linux/mm.h> |
---|
39 | 40 | #include <linux/bio.h> |
---|
| 41 | +#include <linux/compat.h> |
---|
40 | 42 | #include <linux/string.h> |
---|
41 | 43 | #include <linux/errno.h> |
---|
42 | 44 | #include <linux/cdrom.h> |
---|
43 | 45 | #include <linux/interrupt.h> |
---|
44 | 46 | #include <linux/init.h> |
---|
45 | 47 | #include <linux/blkdev.h> |
---|
| 48 | +#include <linux/blk-pm.h> |
---|
46 | 49 | #include <linux/mutex.h> |
---|
47 | 50 | #include <linux/slab.h> |
---|
48 | 51 | #include <linux/pm_runtime.h> |
---|
49 | 52 | #include <linux/uaccess.h> |
---|
| 53 | + |
---|
| 54 | +#include <asm/unaligned.h> |
---|
50 | 55 | |
---|
51 | 56 | #include <scsi/scsi.h> |
---|
52 | 57 | #include <scsi/scsi_dbg.h> |
---|
.. | .. |
---|
76 | 81 | CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \ |
---|
77 | 82 | CDC_MRW|CDC_MRW_W|CDC_RAM) |
---|
78 | 83 | |
---|
79 | | -static DEFINE_MUTEX(sr_mutex); |
---|
80 | 84 | static int sr_probe(struct device *); |
---|
81 | 85 | static int sr_remove(struct device *); |
---|
82 | | -static int sr_init_command(struct scsi_cmnd *SCpnt); |
---|
| 86 | +static blk_status_t sr_init_command(struct scsi_cmnd *SCpnt); |
---|
83 | 87 | static int sr_done(struct scsi_cmnd *); |
---|
84 | 88 | static int sr_runtime_suspend(struct device *dev); |
---|
85 | 89 | |
---|
.. | .. |
---|
344 | 348 | case ILLEGAL_REQUEST: |
---|
345 | 349 | if (!(SCpnt->sense_buffer[0] & 0x90)) |
---|
346 | 350 | break; |
---|
347 | | - error_sector = (SCpnt->sense_buffer[3] << 24) | |
---|
348 | | - (SCpnt->sense_buffer[4] << 16) | |
---|
349 | | - (SCpnt->sense_buffer[5] << 8) | |
---|
350 | | - SCpnt->sense_buffer[6]; |
---|
| 351 | + error_sector = |
---|
| 352 | + get_unaligned_be32(&SCpnt->sense_buffer[3]); |
---|
351 | 353 | if (SCpnt->request->bio != NULL) |
---|
352 | 354 | block_sectors = |
---|
353 | 355 | bio_sectors(SCpnt->request->bio); |
---|
.. | .. |
---|
385 | 387 | return good_bytes; |
---|
386 | 388 | } |
---|
387 | 389 | |
---|
388 | | -static int sr_init_command(struct scsi_cmnd *SCpnt) |
---|
| 390 | +static blk_status_t sr_init_command(struct scsi_cmnd *SCpnt) |
---|
389 | 391 | { |
---|
390 | 392 | int block = 0, this_count, s_size; |
---|
391 | 393 | struct scsi_cd *cd; |
---|
392 | 394 | struct request *rq = SCpnt->request; |
---|
393 | | - int ret; |
---|
| 395 | + blk_status_t ret; |
---|
394 | 396 | |
---|
395 | | - ret = scsi_init_io(SCpnt); |
---|
396 | | - if (ret != BLKPREP_OK) |
---|
397 | | - goto out; |
---|
398 | | - WARN_ON_ONCE(SCpnt != rq->special); |
---|
| 397 | + ret = scsi_alloc_sgtables(SCpnt); |
---|
| 398 | + if (ret != BLK_STS_OK) |
---|
| 399 | + return ret; |
---|
399 | 400 | cd = scsi_cd(rq->rq_disk); |
---|
400 | | - |
---|
401 | | - /* from here on until we're complete, any goto out |
---|
402 | | - * is used for a killable error condition */ |
---|
403 | | - ret = BLKPREP_KILL; |
---|
404 | 401 | |
---|
405 | 402 | SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, |
---|
406 | 403 | "Doing sr request, block = %d\n", block)); |
---|
.. | .. |
---|
496 | 493 | SCpnt->sdb.length = this_count * s_size; |
---|
497 | 494 | } |
---|
498 | 495 | |
---|
499 | | - SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; |
---|
500 | | - SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; |
---|
501 | | - SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; |
---|
502 | | - SCpnt->cmnd[5] = (unsigned char) block & 0xff; |
---|
| 496 | + put_unaligned_be32(block, &SCpnt->cmnd[2]); |
---|
503 | 497 | SCpnt->cmnd[6] = SCpnt->cmnd[9] = 0; |
---|
504 | | - SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; |
---|
505 | | - SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; |
---|
| 498 | + put_unaligned_be16(this_count, &SCpnt->cmnd[7]); |
---|
506 | 499 | |
---|
507 | 500 | /* |
---|
508 | 501 | * We shouldn't disconnect in the middle of a sector, so with a dumb |
---|
.. | .. |
---|
512 | 505 | SCpnt->transfersize = cd->device->sector_size; |
---|
513 | 506 | SCpnt->underflow = this_count << 9; |
---|
514 | 507 | SCpnt->allowed = MAX_RETRIES; |
---|
| 508 | + SCpnt->cmd_len = 10; |
---|
515 | 509 | |
---|
516 | 510 | /* |
---|
517 | | - * This indicates that the command is ready from our end to be |
---|
518 | | - * queued. |
---|
| 511 | + * This indicates that the command is ready from our end to be queued. |
---|
519 | 512 | */ |
---|
520 | | - ret = BLKPREP_OK; |
---|
| 513 | + return BLK_STS_OK; |
---|
521 | 514 | out: |
---|
522 | | - return ret; |
---|
| 515 | + scsi_free_sgtables(SCpnt); |
---|
| 516 | + return BLK_STS_IOERR; |
---|
| 517 | +} |
---|
| 518 | + |
---|
| 519 | +static void sr_revalidate_disk(struct scsi_cd *cd) |
---|
| 520 | +{ |
---|
| 521 | + struct scsi_sense_hdr sshdr; |
---|
| 522 | + |
---|
| 523 | + /* if the unit is not ready, nothing more to do */ |
---|
| 524 | + if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) |
---|
| 525 | + return; |
---|
| 526 | + sr_cd_check(&cd->cdi); |
---|
| 527 | + get_sectorsize(cd); |
---|
523 | 528 | } |
---|
524 | 529 | |
---|
525 | 530 | static int sr_block_open(struct block_device *bdev, fmode_t mode) |
---|
.. | .. |
---|
534 | 539 | |
---|
535 | 540 | sdev = cd->device; |
---|
536 | 541 | scsi_autopm_get_device(sdev); |
---|
537 | | - check_disk_change(bdev); |
---|
| 542 | + if (bdev_check_media_change(bdev)) |
---|
| 543 | + sr_revalidate_disk(cd); |
---|
538 | 544 | |
---|
539 | | - mutex_lock(&sr_mutex); |
---|
| 545 | + mutex_lock(&cd->lock); |
---|
540 | 546 | ret = cdrom_open(&cd->cdi, bdev, mode); |
---|
541 | | - mutex_unlock(&sr_mutex); |
---|
| 547 | + mutex_unlock(&cd->lock); |
---|
542 | 548 | |
---|
543 | 549 | scsi_autopm_put_device(sdev); |
---|
544 | 550 | if (ret) |
---|
.. | .. |
---|
551 | 557 | static void sr_block_release(struct gendisk *disk, fmode_t mode) |
---|
552 | 558 | { |
---|
553 | 559 | struct scsi_cd *cd = scsi_cd(disk); |
---|
554 | | - mutex_lock(&sr_mutex); |
---|
| 560 | + |
---|
| 561 | + mutex_lock(&cd->lock); |
---|
555 | 562 | cdrom_release(&cd->cdi, mode); |
---|
| 563 | + mutex_unlock(&cd->lock); |
---|
| 564 | + |
---|
556 | 565 | scsi_cd_put(cd); |
---|
557 | | - mutex_unlock(&sr_mutex); |
---|
558 | 566 | } |
---|
559 | 567 | |
---|
560 | 568 | static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, |
---|
.. | .. |
---|
565 | 573 | void __user *argp = (void __user *)arg; |
---|
566 | 574 | int ret; |
---|
567 | 575 | |
---|
568 | | - mutex_lock(&sr_mutex); |
---|
| 576 | + mutex_lock(&cd->lock); |
---|
569 | 577 | |
---|
570 | 578 | ret = scsi_ioctl_block_when_processing_errors(sdev, cmd, |
---|
571 | 579 | (mode & FMODE_NDELAY) != 0); |
---|
.. | .. |
---|
595 | 603 | scsi_autopm_put_device(sdev); |
---|
596 | 604 | |
---|
597 | 605 | out: |
---|
598 | | - mutex_unlock(&sr_mutex); |
---|
| 606 | + mutex_unlock(&cd->lock); |
---|
599 | 607 | return ret; |
---|
600 | 608 | } |
---|
| 609 | + |
---|
| 610 | +#ifdef CONFIG_COMPAT |
---|
| 611 | +static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, |
---|
| 612 | + unsigned long arg) |
---|
| 613 | +{ |
---|
| 614 | + struct scsi_cd *cd = scsi_cd(bdev->bd_disk); |
---|
| 615 | + struct scsi_device *sdev = cd->device; |
---|
| 616 | + void __user *argp = compat_ptr(arg); |
---|
| 617 | + int ret; |
---|
| 618 | + |
---|
| 619 | + mutex_lock(&cd->lock); |
---|
| 620 | + |
---|
| 621 | + ret = scsi_ioctl_block_when_processing_errors(sdev, cmd, |
---|
| 622 | + (mode & FMODE_NDELAY) != 0); |
---|
| 623 | + if (ret) |
---|
| 624 | + goto out; |
---|
| 625 | + |
---|
| 626 | + scsi_autopm_get_device(sdev); |
---|
| 627 | + |
---|
| 628 | + /* |
---|
| 629 | + * Send SCSI addressing ioctls directly to mid level, send other |
---|
| 630 | + * ioctls to cdrom/block level. |
---|
| 631 | + */ |
---|
| 632 | + switch (cmd) { |
---|
| 633 | + case SCSI_IOCTL_GET_IDLUN: |
---|
| 634 | + case SCSI_IOCTL_GET_BUS_NUMBER: |
---|
| 635 | + ret = scsi_compat_ioctl(sdev, cmd, argp); |
---|
| 636 | + goto put; |
---|
| 637 | + } |
---|
| 638 | + |
---|
| 639 | + ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, (unsigned long)argp); |
---|
| 640 | + if (ret != -ENOSYS) |
---|
| 641 | + goto put; |
---|
| 642 | + |
---|
| 643 | + ret = scsi_compat_ioctl(sdev, cmd, argp); |
---|
| 644 | + |
---|
| 645 | +put: |
---|
| 646 | + scsi_autopm_put_device(sdev); |
---|
| 647 | + |
---|
| 648 | +out: |
---|
| 649 | + mutex_unlock(&cd->lock); |
---|
| 650 | + return ret; |
---|
| 651 | + |
---|
| 652 | +} |
---|
| 653 | +#endif |
---|
601 | 654 | |
---|
602 | 655 | static unsigned int sr_block_check_events(struct gendisk *disk, |
---|
603 | 656 | unsigned int clearing) |
---|
.. | .. |
---|
616 | 669 | return ret; |
---|
617 | 670 | } |
---|
618 | 671 | |
---|
619 | | -static int sr_block_revalidate_disk(struct gendisk *disk) |
---|
620 | | -{ |
---|
621 | | - struct scsi_sense_hdr sshdr; |
---|
622 | | - struct scsi_cd *cd; |
---|
623 | | - |
---|
624 | | - cd = scsi_cd_get(disk); |
---|
625 | | - if (!cd) |
---|
626 | | - return -ENXIO; |
---|
627 | | - |
---|
628 | | - /* if the unit is not ready, nothing more to do */ |
---|
629 | | - if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) |
---|
630 | | - goto out; |
---|
631 | | - |
---|
632 | | - sr_cd_check(&cd->cdi); |
---|
633 | | - get_sectorsize(cd); |
---|
634 | | -out: |
---|
635 | | - scsi_cd_put(cd); |
---|
636 | | - return 0; |
---|
637 | | -} |
---|
638 | | - |
---|
639 | 672 | static const struct block_device_operations sr_bdops = |
---|
640 | 673 | { |
---|
641 | 674 | .owner = THIS_MODULE, |
---|
642 | 675 | .open = sr_block_open, |
---|
643 | 676 | .release = sr_block_release, |
---|
644 | 677 | .ioctl = sr_block_ioctl, |
---|
| 678 | +#ifdef CONFIG_COMPAT |
---|
| 679 | + .compat_ioctl = sr_block_compat_ioctl, |
---|
| 680 | +#endif |
---|
645 | 681 | .check_events = sr_block_check_events, |
---|
646 | | - .revalidate_disk = sr_block_revalidate_disk, |
---|
647 | | - /* |
---|
648 | | - * No compat_ioctl for now because sr_block_ioctl never |
---|
649 | | - * seems to pass arbitrary ioctls down to host drivers. |
---|
650 | | - */ |
---|
651 | 682 | }; |
---|
652 | 683 | |
---|
653 | 684 | static int sr_open(struct cdrom_device_info *cdi, int purpose) |
---|
.. | .. |
---|
701 | 732 | disk = alloc_disk(1); |
---|
702 | 733 | if (!disk) |
---|
703 | 734 | goto fail_free; |
---|
| 735 | + mutex_init(&cd->lock); |
---|
704 | 736 | |
---|
705 | 737 | spin_lock(&sr_index_lock); |
---|
706 | 738 | minor = find_first_zero_bit(sr_index_bits, SR_DISKS); |
---|
.. | .. |
---|
718 | 750 | disk->fops = &sr_bdops; |
---|
719 | 751 | disk->flags = GENHD_FL_CD | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
---|
720 | 752 | disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; |
---|
| 753 | + disk->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT; |
---|
721 | 754 | |
---|
722 | 755 | blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); |
---|
723 | 756 | |
---|
.. | .. |
---|
747 | 780 | set_capacity(disk, cd->capacity); |
---|
748 | 781 | disk->private_data = &cd->driver; |
---|
749 | 782 | disk->queue = sdev->request_queue; |
---|
750 | | - cd->cdi.disk = disk; |
---|
751 | 783 | |
---|
752 | | - if (register_cdrom(&cd->cdi)) |
---|
| 784 | + if (register_cdrom(disk, &cd->cdi)) |
---|
753 | 785 | goto fail_minor; |
---|
754 | 786 | |
---|
755 | 787 | /* |
---|
.. | .. |
---|
760 | 792 | |
---|
761 | 793 | dev_set_drvdata(dev, cd); |
---|
762 | 794 | disk->flags |= GENHD_FL_REMOVABLE; |
---|
763 | | - device_add_disk(&sdev->sdev_gendev, disk); |
---|
| 795 | + sr_revalidate_disk(cd); |
---|
| 796 | + device_add_disk(&sdev->sdev_gendev, disk, NULL); |
---|
764 | 797 | |
---|
765 | 798 | sdev_printk(KERN_DEBUG, sdev, |
---|
766 | 799 | "Attached scsi CD-ROM %s\n", cd->cdi.name); |
---|
.. | .. |
---|
774 | 807 | spin_unlock(&sr_index_lock); |
---|
775 | 808 | fail_put: |
---|
776 | 809 | put_disk(disk); |
---|
| 810 | + mutex_destroy(&cd->lock); |
---|
777 | 811 | fail_free: |
---|
778 | 812 | kfree(cd); |
---|
779 | 813 | fail: |
---|
.. | .. |
---|
811 | 845 | } else { |
---|
812 | 846 | long last_written; |
---|
813 | 847 | |
---|
814 | | - cd->capacity = 1 + ((buffer[0] << 24) | (buffer[1] << 16) | |
---|
815 | | - (buffer[2] << 8) | buffer[3]); |
---|
| 848 | + cd->capacity = 1 + get_unaligned_be32(&buffer[0]); |
---|
816 | 849 | /* |
---|
817 | 850 | * READ_CAPACITY doesn't return the correct size on |
---|
818 | 851 | * certain UDF media. If last_written is larger, use |
---|
.. | .. |
---|
823 | 856 | if (!cdrom_get_last_written(&cd->cdi, &last_written)) |
---|
824 | 857 | cd->capacity = max_t(long, cd->capacity, last_written); |
---|
825 | 858 | |
---|
826 | | - sector_size = (buffer[4] << 24) | |
---|
827 | | - (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; |
---|
| 859 | + sector_size = get_unaligned_be32(&buffer[4]); |
---|
828 | 860 | switch (sector_size) { |
---|
829 | 861 | /* |
---|
830 | 862 | * HP 4020i CD-Recorder reports 2340 byte sectors |
---|
.. | .. |
---|
836 | 868 | case 2340: |
---|
837 | 869 | case 2352: |
---|
838 | 870 | sector_size = 2048; |
---|
839 | | - /* fall through */ |
---|
| 871 | + fallthrough; |
---|
840 | 872 | case 2048: |
---|
841 | 873 | cd->capacity *= 4; |
---|
842 | | - /* fall through */ |
---|
| 874 | + fallthrough; |
---|
843 | 875 | case 512: |
---|
844 | 876 | break; |
---|
845 | 877 | default: |
---|
.. | .. |
---|
898 | 930 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len, |
---|
899 | 931 | SR_TIMEOUT, 3, &data, NULL); |
---|
900 | 932 | |
---|
901 | | - if (!scsi_status_is_good(rc) || data.length > ms_len || |
---|
| 933 | + if (rc < 0 || data.length > ms_len || |
---|
902 | 934 | data.header_length + data.block_descriptor_length > data.length) { |
---|
903 | 935 | /* failed, drive doesn't have capabilities mode page */ |
---|
904 | 936 | cd->cdi.speed = 1; |
---|
.. | .. |
---|
912 | 944 | } |
---|
913 | 945 | |
---|
914 | 946 | n = data.header_length + data.block_descriptor_length; |
---|
915 | | - cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176; |
---|
| 947 | + cd->cdi.speed = get_unaligned_be16(&buffer[n + 8]) / 176; |
---|
916 | 948 | cd->readcd_known = 1; |
---|
917 | 949 | cd->readcd_cdda = buffer[n + 5] & 0x01; |
---|
918 | 950 | /* print some capability bits */ |
---|
919 | 951 | sr_printk(KERN_INFO, cd, |
---|
920 | 952 | "scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", |
---|
921 | | - ((buffer[n + 14] << 8) + buffer[n + 15]) / 176, |
---|
| 953 | + get_unaligned_be16(&buffer[n + 14]) / 176, |
---|
922 | 954 | cd->cdi.speed, |
---|
923 | 955 | buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */ |
---|
924 | 956 | buffer[n + 3] & 0x20 ? "dvd-ram " : "", |
---|
.. | .. |
---|
1014 | 1046 | |
---|
1015 | 1047 | put_disk(disk); |
---|
1016 | 1048 | |
---|
| 1049 | + mutex_destroy(&cd->lock); |
---|
| 1050 | + |
---|
1017 | 1051 | kfree(cd); |
---|
1018 | 1052 | } |
---|
1019 | 1053 | |
---|