Lines Matching +full:add +full:- +full:disk

1 // SPDX-License-Identifier: GPL-2.0-only
8 * Linux scsi disk driver by
12 * add scatter-gather, multiple outstanding request, and other
16 * low-level scsi drivers.
19 * provide auto-eject.
21 * Modified by Gerd Knorr <kraxel@cs.tu-berlin.de> to support the
24 * Modified by Jens Axboe <axboe@suse.de> - Uniform sr_packet()
29 * Modified by Jens Axboe <axboe@suse.de> - support DVD-RAM
49 #include <linux/blk-pm.h>
140 static inline struct scsi_cd *scsi_cd(struct gendisk *disk) in scsi_cd() argument
142 return disk->private_data; in scsi_cd()
152 if (cd->media_present) in sr_runtime_suspend()
153 return -EBUSY; in sr_runtime_suspend()
183 if (result || be16_to_cpu(eh->data_len) < sizeof(*med)) in sr_get_events()
186 if (eh->nea || eh->notification_class != 0x4) in sr_get_events()
189 if (med->media_event_code == 1) in sr_get_events()
191 else if (med->media_event_code == 2) in sr_get_events()
193 else if (med->media_event_code == 3) in sr_get_events()
202 * reported it. The past events are accumulated in sdev->changed and
208 struct scsi_cd *cd = cdi->handle; in sr_check_events()
218 events = sr_get_events(cd->device); in sr_check_events()
219 cd->get_event_changed |= events & DISK_EVENT_MEDIA_CHANGE; in sr_check_events()
227 if (cd->ignore_get_event) { in sr_check_events()
237 if (cd->device->changed) { in sr_check_events()
239 cd->device->changed = 0; in sr_check_events()
240 cd->tur_changed = true; in sr_check_events()
247 last_present = cd->media_present; in sr_check_events()
248 ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); in sr_check_events()
252 * sense data indicating something other than media-not-present in sr_check_events()
255 cd->media_present = scsi_status_is_good(ret) || in sr_check_events()
258 if (last_present != cd->media_present) in sr_check_events()
259 cd->device->changed = 1; in sr_check_events()
261 if (cd->device->changed) { in sr_check_events()
263 cd->device->changed = 0; in sr_check_events()
264 cd->tur_changed = true; in sr_check_events()
267 if (cd->ignore_get_event) in sr_check_events()
271 if (!cd->tur_changed) { in sr_check_events()
272 if (cd->get_event_changed) { in sr_check_events()
273 if (cd->tur_mismatch++ > 8) { in sr_check_events()
276 cd->ignore_get_event = true; in sr_check_events()
279 cd->tur_mismatch = 0; in sr_check_events()
282 cd->tur_changed = false; in sr_check_events()
283 cd->get_event_changed = false; in sr_check_events()
296 int result = SCpnt->result; in sr_done()
302 struct scsi_cd *cd = scsi_cd(rq->q->disk); in sr_done()
315 (SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */ in sr_done()
316 switch (SCpnt->sense_buffer[2]) { in sr_done()
320 if (!(SCpnt->sense_buffer[0] & 0x90)) in sr_done()
323 get_unaligned_be32(&SCpnt->sense_buffer[3]); in sr_done()
324 if (rq->bio != NULL) in sr_done()
325 block_sectors = bio_sectors(rq->bio); in sr_done()
328 if (cd->device->sector_size == 2048) in sr_done()
330 error_sector &= ~(block_sectors - 1); in sr_done()
331 good_bytes = (error_sector - blk_rq_pos(rq)) << 9; in sr_done()
342 if (error_sector < get_capacity(cd->disk) && in sr_done()
343 cd->capacity - error_sector < 4 * 75) in sr_done()
344 set_capacity(cd->disk, error_sector); in sr_done()
369 cd = scsi_cd(rq->q->disk); in sr_init_command()
374 if (!cd->device || !scsi_device_online(cd->device)) { in sr_init_command()
382 if (cd->device->changed) { in sr_init_command()
390 s_size = cd->device->sector_size; in sr_init_command()
398 if (!cd->writeable) in sr_init_command()
400 SCpnt->cmnd[0] = WRITE_10; in sr_init_command()
401 cd->cdi.media_written = 1; in sr_init_command()
404 SCpnt->cmnd[0] = READ_10; in sr_init_command()
416 size += sg->length; in sr_init_command()
423 SCpnt->sdb.length = size; in sr_init_command()
428 * request doesn't start on hw block boundary, add scatter pads in sr_init_command()
445 SCpnt->cmnd[1] = 0; in sr_init_command()
450 SCpnt->sdb.length = this_count * s_size; in sr_init_command()
453 put_unaligned_be32(block, &SCpnt->cmnd[2]); in sr_init_command()
454 SCpnt->cmnd[6] = SCpnt->cmnd[9] = 0; in sr_init_command()
455 put_unaligned_be16(this_count, &SCpnt->cmnd[7]); in sr_init_command()
462 SCpnt->transfersize = cd->device->sector_size; in sr_init_command()
463 SCpnt->underflow = this_count << 9; in sr_init_command()
464 SCpnt->allowed = MAX_RETRIES; in sr_init_command()
465 SCpnt->cmd_len = 10; in sr_init_command()
481 if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) in sr_revalidate_disk()
483 sr_cd_check(&cd->cdi); in sr_revalidate_disk()
487 static int sr_block_open(struct gendisk *disk, blk_mode_t mode) in sr_block_open() argument
489 struct scsi_cd *cd = scsi_cd(disk); in sr_block_open()
490 struct scsi_device *sdev = cd->device; in sr_block_open()
493 if (scsi_device_get(cd->device)) in sr_block_open()
494 return -ENXIO; in sr_block_open()
497 if (disk_check_media_change(disk)) { in sr_block_open()
503 mutex_lock(&cd->lock); in sr_block_open()
504 ret = cdrom_open(&cd->cdi, mode); in sr_block_open()
505 mutex_unlock(&cd->lock); in sr_block_open()
509 scsi_device_put(cd->device); in sr_block_open()
513 static void sr_block_release(struct gendisk *disk) in sr_block_release() argument
515 struct scsi_cd *cd = scsi_cd(disk); in sr_block_release()
517 mutex_lock(&cd->lock); in sr_block_release()
518 cdrom_release(&cd->cdi); in sr_block_release()
519 mutex_unlock(&cd->lock); in sr_block_release()
521 scsi_device_put(cd->device); in sr_block_release()
527 struct scsi_cd *cd = scsi_cd(bdev->bd_disk); in sr_block_ioctl()
528 struct scsi_device *sdev = cd->device; in sr_block_ioctl()
533 return -ENOIOCTLCMD; in sr_block_ioctl()
535 mutex_lock(&cd->lock); in sr_block_ioctl()
545 ret = cdrom_ioctl(&cd->cdi, bdev, cmd, arg); in sr_block_ioctl()
546 if (ret != -ENOSYS) in sr_block_ioctl()
554 mutex_unlock(&cd->lock); in sr_block_ioctl()
558 static unsigned int sr_block_check_events(struct gendisk *disk, in sr_block_check_events() argument
561 struct scsi_cd *cd = disk->private_data; in sr_block_check_events()
563 if (atomic_read(&cd->device->disk_events_disable_depth)) in sr_block_check_events()
565 return cdrom_check_events(&cd->cdi, clearing); in sr_block_check_events()
568 static void sr_free_disk(struct gendisk *disk) in sr_free_disk() argument
570 struct scsi_cd *cd = disk->private_data; in sr_free_disk()
573 clear_bit(MINOR(disk_devt(disk)), sr_index_bits); in sr_free_disk()
576 unregister_cdrom(&cd->cdi); in sr_free_disk()
577 mutex_destroy(&cd->lock); in sr_free_disk()
594 struct scsi_cd *cd = cdi->handle; in sr_open()
595 struct scsi_device *sdev = cd->device; in sr_open()
602 return -ENXIO; in sr_open()
614 struct gendisk *disk; in sr_probe() local
619 error = -ENODEV; in sr_probe()
620 if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM) in sr_probe()
623 error = -ENOMEM; in sr_probe()
628 disk = blk_mq_alloc_disk_for_queue(sdev->request_queue, in sr_probe()
630 if (!disk) in sr_probe()
632 mutex_init(&cd->lock); in sr_probe()
638 error = -EBUSY; in sr_probe()
644 disk->major = SCSI_CDROM_MAJOR; in sr_probe()
645 disk->first_minor = minor; in sr_probe()
646 disk->minors = 1; in sr_probe()
647 sprintf(disk->disk_name, "sr%d", minor); in sr_probe()
648 disk->fops = &sr_bdops; in sr_probe()
649 disk->flags |= GENHD_FL_REMOVABLE | GENHD_FL_NO_PART; in sr_probe()
650 disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; in sr_probe()
651 disk->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT | in sr_probe()
654 blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); in sr_probe()
656 cd->device = sdev; in sr_probe()
657 cd->disk = disk; in sr_probe()
658 cd->capacity = 0x1fffff; in sr_probe()
659 cd->device->changed = 1; /* force recheck CD type */ in sr_probe()
660 cd->media_present = 1; in sr_probe()
661 cd->use = 1; in sr_probe()
662 cd->readcd_known = 0; in sr_probe()
663 cd->readcd_cdda = 0; in sr_probe()
665 cd->cdi.ops = &sr_dops; in sr_probe()
666 cd->cdi.handle = cd; in sr_probe()
667 cd->cdi.mask = 0; in sr_probe()
668 cd->cdi.capacity = 1; in sr_probe()
669 sprintf(cd->cdi.name, "sr%d", minor); in sr_probe()
671 sdev->sector_size = 2048; /* A guess, just in case */ in sr_probe()
673 error = -ENOMEM; in sr_probe()
678 set_capacity(disk, cd->capacity); in sr_probe()
679 disk->private_data = cd; in sr_probe()
681 if (register_cdrom(disk, &cd->cdi)) in sr_probe()
688 blk_pm_runtime_init(sdev->request_queue, dev); in sr_probe()
695 error = device_add_disk(&sdev->sdev_gendev, disk, NULL); in sr_probe()
700 "Attached scsi CD-ROM %s\n", cd->cdi.name); in sr_probe()
701 scsi_autopm_put_device(cd->device); in sr_probe()
706 unregister_cdrom(&cd->cdi); in sr_probe()
712 put_disk(disk); in sr_probe()
713 mutex_destroy(&cd->lock); in sr_probe()
724 struct request_queue *q = cd->device->request_queue; in get_sectorsize()
745 err = scsi_execute_cmd(cd->device, cmd, REQ_OP_DRV_IN, buffer, in get_sectorsize()
749 cd->capacity = 0x1fffff; in get_sectorsize()
754 cd->capacity = 1 + get_unaligned_be32(&buffer[0]); in get_sectorsize()
762 if (!cdrom_get_last_written(&cd->cdi, &last_written)) in get_sectorsize()
763 cd->capacity = max_t(long, cd->capacity, last_written); in get_sectorsize()
768 * HP 4020i CD-Recorder reports 2340 byte sectors in get_sectorsize()
769 * Philips CD-Writers report 2352 byte sectors in get_sectorsize()
779 cd->capacity *= 4; in get_sectorsize()
786 cd->capacity = 0; in get_sectorsize()
789 cd->device->sector_size = sector_size; in get_sectorsize()
792 * Add this so that we have the ability to correctly gauge in get_sectorsize()
795 set_capacity(cd->disk, cd->capacity); in get_sectorsize()
815 "pop-up", in get_capabilities()
828 return -ENOMEM; in get_capabilities()
832 scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); in get_capabilities()
835 rc = scsi_mode_sense(cd->device, 0, 0x2a, 0, buffer, ms_len, in get_capabilities()
841 cd->cdi.speed = 1; in get_capabilities()
842 cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | in get_capabilities()
847 sr_printk(KERN_INFO, cd, "scsi-1 drive"); in get_capabilities()
852 cd->cdi.speed = get_unaligned_be16(&buffer[n + 8]) / 176; in get_capabilities()
853 cd->readcd_known = 1; in get_capabilities()
854 cd->readcd_cdda = buffer[n + 5] & 0x01; in get_capabilities()
857 "scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", in get_capabilities()
859 cd->cdi.speed, in get_capabilities()
861 buffer[n + 3] & 0x20 ? "dvd-ram " : "", in get_capabilities()
868 cd->cdi.mask |= CDC_CLOSE_TRAY; in get_capabilities()
871 cd->cdi.mask |= CDC_DVD; in get_capabilities()
873 /* can't write DVD-RAM media */ in get_capabilities()
874 cd->cdi.mask |= CDC_DVD_RAM; in get_capabilities()
876 /* can't write DVD-R media */ in get_capabilities()
877 cd->cdi.mask |= CDC_DVD_R; in get_capabilities()
879 /* can't write CD-RW media */ in get_capabilities()
880 cd->cdi.mask |= CDC_CD_RW; in get_capabilities()
882 /* can't write CD-R media */ in get_capabilities()
883 cd->cdi.mask |= CDC_CD_R; in get_capabilities()
886 cd->cdi.mask |= CDC_OPEN_TRAY; in get_capabilities()
890 cd->cdi.capacity = in get_capabilities()
891 cdrom_number_of_slots(&cd->cdi); in get_capabilities()
892 if (cd->cdi.capacity <= 1) in get_capabilities()
894 cd->cdi.mask |= CDC_SELECT_DISC; in get_capabilities()
896 cd->cdi.mask |= CDC_CLOSE_TRAY; */ in get_capabilities()
899 * if DVD-RAM, MRW-W or CD-RW, we are randomly writable in get_capabilities()
901 if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) != in get_capabilities()
903 cd->writeable = 1; in get_capabilities()
912 * by the Uniform CD-ROM layer.
917 struct scsi_cd *cd = cdi->handle; in sr_packet()
918 struct scsi_device *sdev = cd->device; in sr_packet()
920 if (cgc->cmd[0] == GPCMD_READ_DISC_INFO && sdev->no_read_disc_info) in sr_packet()
921 return -EDRIVE_CANT_DO_THIS; in sr_packet()
923 if (cgc->timeout <= 0) in sr_packet()
924 cgc->timeout = IOCTL_TIMEOUT; in sr_packet()
928 return cgc->stat; in sr_packet()
934 struct gendisk *disk = cdi->disk; in sr_read_cdda_bpc() local
941 rq = scsi_alloc_request(disk->queue, REQ_OP_DRV_IN, 0); in sr_read_cdda_bpc()
946 ret = blk_rq_map_user(disk->queue, rq, NULL, ubuf, len, GFP_KERNEL); in sr_read_cdda_bpc()
950 scmd->cmnd[0] = GPCMD_READ_CD; in sr_read_cdda_bpc()
951 scmd->cmnd[1] = 1 << 2; in sr_read_cdda_bpc()
952 scmd->cmnd[2] = (lba >> 24) & 0xff; in sr_read_cdda_bpc()
953 scmd->cmnd[3] = (lba >> 16) & 0xff; in sr_read_cdda_bpc()
954 scmd->cmnd[4] = (lba >> 8) & 0xff; in sr_read_cdda_bpc()
955 scmd->cmnd[5] = lba & 0xff; in sr_read_cdda_bpc()
956 scmd->cmnd[6] = (nr >> 16) & 0xff; in sr_read_cdda_bpc()
957 scmd->cmnd[7] = (nr >> 8) & 0xff; in sr_read_cdda_bpc()
958 scmd->cmnd[8] = nr & 0xff; in sr_read_cdda_bpc()
959 scmd->cmnd[9] = 0xf8; in sr_read_cdda_bpc()
960 scmd->cmd_len = 12; in sr_read_cdda_bpc()
961 rq->timeout = 60 * HZ; in sr_read_cdda_bpc()
962 bio = rq->bio; in sr_read_cdda_bpc()
965 if (scmd->result) { in sr_read_cdda_bpc()
968 scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len, in sr_read_cdda_bpc()
971 ret = -EIO; in sr_read_cdda_bpc()
975 ret = -EFAULT; in sr_read_cdda_bpc()
985 scsi_autopm_get_device(cd->device); in sr_remove()
987 del_gendisk(cd->disk); in sr_remove()
988 put_disk(cd->disk); in sr_remove()