--- zzzz-none-000/linux-3.10.107/drivers/scsi/sr.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/scsi/sr.c 2021-02-04 17:41:59.000000000 +0000 @@ -79,6 +79,7 @@ static DEFINE_MUTEX(sr_mutex); static int sr_probe(struct device *); static int sr_remove(struct device *); +static int sr_init_command(struct scsi_cmnd *SCpnt); static int sr_done(struct scsi_cmnd *); static int sr_runtime_suspend(struct device *dev); @@ -87,13 +88,14 @@ }; static struct scsi_driver sr_template = { - .owner = THIS_MODULE, .gendrv = { .name = "sr", + .owner = THIS_MODULE, .probe = sr_probe, .remove = sr_remove, .pm = &sr_pm_ops, }, + .init_command = sr_init_command, .done = sr_done, }; @@ -164,14 +166,10 @@ goto out; cd = scsi_cd(disk); kref_get(&cd->kref); - if (scsi_device_get(cd->device)) - goto out_put; - if (!scsi_autopm_get_device(cd->device)) - goto out; - - out_put: - kref_put(&cd->kref, sr_kref_release); - cd = NULL; + if (scsi_device_get(cd->device)) { + kref_put(&cd->kref, sr_kref_release); + cd = NULL; + } out: mutex_unlock(&sr_ref_mutex); return cd; @@ -183,7 +181,6 @@ mutex_lock(&sr_ref_mutex); kref_put(&cd->kref, sr_kref_release); - scsi_autopm_put_device(sdev); scsi_device_put(sdev); mutex_unlock(&sr_ref_mutex); } @@ -298,8 +295,8 @@ if (!cd->tur_changed) { if (cd->get_event_changed) { if (cd->tur_mismatch++ > 8) { - sdev_printk(KERN_WARNING, cd->device, - "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n"); + sr_printk(KERN_WARNING, cd, + "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n"); cd->ignore_get_event = true; } } else { @@ -328,7 +325,7 @@ struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); #ifdef DEBUG - printk("sr.c done: %x\n", result); + scmd_printk(KERN_INFO, SCpnt, "done: %x\n", result); #endif /* @@ -386,22 +383,14 @@ return good_bytes; } -static int sr_prep_fn(struct request_queue *q, struct request *rq) +static int sr_init_command(struct scsi_cmnd *SCpnt) { int block = 0, this_count, s_size; struct scsi_cd *cd; - struct scsi_cmnd *SCpnt; - struct scsi_device *sdp = q->queuedata; + struct request *rq = SCpnt->request; int ret; - if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { - ret = scsi_setup_blk_pc_cmnd(sdp, rq); - goto out; - } else if (rq->cmd_type != REQ_TYPE_FS) { - ret = BLKPREP_KILL; - goto out; - } - ret = scsi_setup_fs_cmnd(sdp, rq); + ret = scsi_init_io(SCpnt); if (ret != BLKPREP_OK) goto out; SCpnt = rq->special; @@ -411,13 +400,14 @@ * is used for a killable error condition */ ret = BLKPREP_KILL; - SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", - cd->disk->disk_name, block)); + SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, + "Doing sr request, block = %d\n", block)); if (!cd->device || !scsi_device_online(cd->device)) { - SCSI_LOG_HLQUEUE(2, printk("Finishing %u sectors\n", - blk_rq_sectors(rq))); - SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); + SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, + "Finishing %u sectors\n", blk_rq_sectors(rq))); + SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, + "Retry with 0x%p\n", SCpnt)); goto out; } @@ -438,7 +428,8 @@ if (!in_interrupt()) sr_set_blocklength(cd, 2048); else - printk("sr: can't switch blocksize: in interrupt\n"); + scmd_printk(KERN_INFO, SCpnt, + "can't switch blocksize: in interrupt\n"); } if (s_size != 512 && s_size != 1024 && s_size != 2048) { @@ -447,14 +438,12 @@ } if (rq_data_dir(rq) == WRITE) { - if (!cd->device->writeable) + if (!cd->writeable) goto out; SCpnt->cmnd[0] = WRITE_10; - SCpnt->sc_data_direction = DMA_TO_DEVICE; - cd->cdi.media_written = 1; + cd->cdi.media_written = 1; } else if (rq_data_dir(rq) == READ) { SCpnt->cmnd[0] = READ_10; - SCpnt->sc_data_direction = DMA_FROM_DEVICE; } else { blk_dump_rq_flags(rq, "Unknown sr command"); goto out; @@ -488,11 +477,11 @@ this_count = (scsi_bufflen(SCpnt) >> 9) / (s_size >> 9); - SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%u 512 byte blocks.\n", - cd->cdi.name, - (rq_data_dir(rq) == WRITE) ? + SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, + "%s %d/%u 512 byte blocks.\n", + (rq_data_dir(rq) == WRITE) ? "writing" : "reading", - this_count, blk_rq_sectors(rq))); + this_count, blk_rq_sectors(rq))); SCpnt->cmnd[1] = 0; block = (unsigned int)blk_rq_pos(rq) / (s_size >> 9); @@ -525,7 +514,7 @@ */ ret = BLKPREP_OK; out: - return scsi_prep_return(q, rq, ret); + return ret; } static int sr_block_open(struct block_device *bdev, fmode_t mode) @@ -561,10 +550,13 @@ void __user *argp = (void __user *)arg; int ret; - scsi_autopm_get_device(cd->device); - mutex_lock(&sr_mutex); + ret = scsi_ioctl_block_when_processing_errors(sdev, cmd, + (mode & FMODE_NDELAY) != 0); + if (ret) + goto out; + /* * Send SCSI addressing ioctls directly to mid level, send other * ioctls to cdrom/block level. @@ -580,21 +572,10 @@ if (ret != -ENOSYS) goto out; - /* - * ENODEV means that we didn't recognise the ioctl, or that we - * cannot execute it in the current device state. In either - * case fall through to scsi_ioctl, which will return ENDOEV again - * if it doesn't recognise the ioctl - */ - ret = scsi_nonblockable_ioctl(sdev, cmd, argp, - (mode & FMODE_NDELAY) != 0); - if (ret != -ENODEV) - goto out; ret = scsi_ioctl(sdev, cmd, argp); out: mutex_unlock(&sr_mutex); - scsi_autopm_put_device(cd->device); return ret; } @@ -602,17 +583,11 @@ unsigned int clearing) { struct scsi_cd *cd = scsi_cd(disk); - unsigned int ret; - if (atomic_read(&cd->device->disk_events_disable_depth) == 0) { - scsi_autopm_get_device(cd->device); - ret = cdrom_check_events(&cd->cdi, clearing); - scsi_autopm_put_device(cd->device); - } else { - ret = 0; - } + if (atomic_read(&cd->device->disk_events_disable_depth)) + return 0; - return ret; + return cdrom_check_events(&cd->cdi, clearing); } static int sr_block_revalidate_disk(struct gendisk *disk) @@ -620,8 +595,6 @@ struct scsi_cd *cd = scsi_cd(disk); struct scsi_sense_hdr sshdr; - scsi_autopm_get_device(cd->device); - /* if the unit is not ready, nothing more to do */ if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) goto out; @@ -629,7 +602,6 @@ sr_cd_check(&cd->cdi); get_sectorsize(cd); out: - scsi_autopm_put_device(cd->device); return 0; } @@ -683,6 +655,7 @@ struct scsi_cd *cd; int minor, error; + scsi_autopm_get_device(sdev); error = -ENODEV; if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM) goto fail; @@ -738,7 +711,6 @@ /* FIXME: need to handle a get_capabilities failure properly ?? */ get_capabilities(cd); - blk_queue_prep_rq(sdev->request_queue, sr_prep_fn); sr_vendor_init(cd); disk->driverfs_dev = &sdev->sdev_gendev; @@ -750,6 +722,12 @@ if (register_cdrom(&cd->cdi)) goto fail_put; + /* + * Initialize block layer runtime PM stuffs before the + * periodic event checking request gets started in add_disk. + */ + blk_pm_runtime_init(sdev->request_queue, dev); + dev_set_drvdata(dev, cd); disk->flags |= GENHD_FL_REMOVABLE; add_disk(disk); @@ -765,6 +743,7 @@ fail_free: kfree(cd); fail: + scsi_autopm_put_device(sdev); return error; } @@ -830,8 +809,8 @@ case 512: break; default: - printk("%s: unsupported sector size %d.\n", - cd->cdi.name, sector_size); + sr_printk(KERN_INFO, cd, + "unsupported sector size %d.", sector_size); cd->capacity = 0; } @@ -855,7 +834,6 @@ unsigned char *buffer; struct scsi_mode_data data; struct scsi_sense_hdr sshdr; - unsigned int ms_len = 128; int rc, n; static const char *loadmech[] = @@ -874,7 +852,7 @@ /* allocate transfer buffer */ buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) { - printk(KERN_ERR "sr: out of memory.\n"); + sr_printk(KERN_ERR, cd, "out of memory.\n"); return; } @@ -882,11 +860,10 @@ scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); /* ask for mode page 0x2a */ - rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len, + rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, SR_TIMEOUT, 3, &data, NULL); - if (!scsi_status_is_good(rc) || data.length > ms_len || - data.header_length + data.block_descriptor_length > data.length) { + if (!scsi_status_is_good(rc)) { /* failed, drive doesn't have capabilities mode page */ cd->cdi.speed = 1; cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | @@ -894,7 +871,7 @@ CDC_SELECT_DISC | CDC_SELECT_SPEED | CDC_MRW | CDC_MRW_W | CDC_RAM); kfree(buffer); - printk("%s: scsi-1 drive\n", cd->cdi.name); + sr_printk(KERN_INFO, cd, "scsi-1 drive"); return; } @@ -903,22 +880,23 @@ cd->readcd_known = 1; cd->readcd_cdda = buffer[n + 5] & 0x01; /* print some capability bits */ - printk("%s: scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", cd->cdi.name, - ((buffer[n + 14] << 8) + buffer[n + 15]) / 176, - cd->cdi.speed, - buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */ - buffer[n + 3] & 0x20 ? "dvd-ram " : "", - buffer[n + 2] & 0x02 ? "cd/rw " : "", /* can read rewriteable */ - buffer[n + 4] & 0x20 ? "xa/form2 " : "", /* can read xa/from2 */ - buffer[n + 5] & 0x01 ? "cdda " : "", /* can read audio data */ - loadmech[buffer[n + 6] >> 5]); + sr_printk(KERN_INFO, cd, + "scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", + ((buffer[n + 14] << 8) + buffer[n + 15]) / 176, + cd->cdi.speed, + buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */ + buffer[n + 3] & 0x20 ? "dvd-ram " : "", + buffer[n + 2] & 0x02 ? "cd/rw " : "", /* can read rewriteable */ + buffer[n + 4] & 0x20 ? "xa/form2 " : "", /* can read xa/from2 */ + buffer[n + 5] & 0x01 ? "cdda " : "", /* can read audio data */ + loadmech[buffer[n + 6] >> 5]); if ((buffer[n + 6] >> 5) == 0) /* caddy drives can't close tray... */ cd->cdi.mask |= CDC_CLOSE_TRAY; if ((buffer[n + 2] & 0x8) == 0) /* not a DVD drive */ cd->cdi.mask |= CDC_DVD; - if ((buffer[n + 3] & 0x20) == 0) + if ((buffer[n + 3] & 0x20) == 0) /* can't write DVD-RAM media */ cd->cdi.mask |= CDC_DVD_RAM; if ((buffer[n + 3] & 0x10) == 0) @@ -949,7 +927,7 @@ */ if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) != (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) { - cd->device->writeable = 1; + cd->writeable = 1; } kfree(buffer); @@ -957,7 +935,7 @@ /* * sr_packet() is the entry point for the generic commands generated - * by the Uniform CD-ROM layer. + * by the Uniform CD-ROM layer. */ static int sr_packet(struct cdrom_device_info *cdi, struct packet_command *cgc) @@ -1009,7 +987,6 @@ scsi_autopm_get_device(cd->device); - blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); del_gendisk(cd->disk); dev_set_drvdata(dev, NULL);