diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 143 |
1 files changed, 35 insertions, 108 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0d7c6e86f149..5d81bcc1dc75 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -593,6 +593,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp) mutex_unlock(&sd_ref_mutex); } +struct gendisk *scsi_gendisk_get_from_dev(struct device *dev) +{ + struct scsi_disk *sdkp; + + mutex_lock(&sd_ref_mutex); + sdkp = dev_get_drvdata(dev); + if (sdkp) + sdkp = scsi_disk_get(sdkp->disk); + mutex_unlock(&sd_ref_mutex); + return !sdkp ? NULL : sdkp->disk; +} +EXPORT_SYMBOL(scsi_gendisk_get_from_dev); + +void scsi_gendisk_put(struct device *dev) +{ + struct scsi_disk *sdkp = dev_get_drvdata(dev); + struct scsi_device *sdev = sdkp->device; + + mutex_lock(&sd_ref_mutex); + put_device(&sdkp->dev); + scsi_device_put(sdev); + mutex_unlock(&sd_ref_mutex); +} +EXPORT_SYMBOL(scsi_gendisk_put); + static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, unsigned int dix, unsigned int dif) { @@ -1387,81 +1412,6 @@ static int media_not_present(struct scsi_disk *sdkp, return 0; } -/** - * sd_check_events - check media events - * @disk: kernel device descriptor - * @clearing: disk events currently being cleared - * - * Returns mask of DISK_EVENT_*. - * - * Note: this function is invoked from the block subsystem. - **/ -static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) -{ - struct scsi_disk *sdkp = scsi_disk(disk); - struct scsi_device *sdp = sdkp->device; - struct scsi_sense_hdr *sshdr = NULL; - int retval; - - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); - - /* - * If the device is offline, don't send any commands - just pretend as - * if the command failed. If the device ever comes back online, we - * can deal with it then. It is only because of unrecoverable errors - * that we would ever take a device offline in the first place. - */ - if (!scsi_device_online(sdp)) { - set_media_not_present(sdkp); - goto out; - } - - /* - * Using TEST_UNIT_READY enables differentiation between drive with - * no cartridge loaded - NOT READY, drive with changed cartridge - - * UNIT ATTENTION, or with same cartridge - GOOD STATUS. - * - * Drives that auto spin down. eg iomega jaz 1G, will be started - * by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever - * sd_revalidate() is called. - */ - retval = -ENODEV; - - if (scsi_block_when_processing_errors(sdp)) { - sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); - retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES, - sshdr); - } - - /* failed to execute TUR, assume media not present */ - if (host_byte(retval)) { - set_media_not_present(sdkp); - goto out; - } - - if (media_not_present(sdkp, sshdr)) - goto out; - - /* - * For removable scsi disk we have to recognise the presence - * of a disk in the drive. - */ - if (!sdkp->media_present) - sdp->changed = 1; - sdkp->media_present = 1; -out: - /* - * sdp->changed is set under the following conditions: - * - * Medium present state has changed in either direction. - * Device has indicated UNIT_ATTENTION. - */ - kfree(sshdr); - retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; - sdp->changed = 0; - return retval; -} - static int sd_sync_cache(struct scsi_disk *sdkp) { int retries, res; @@ -1654,7 +1604,6 @@ static const struct block_device_operations sd_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl, #endif - .check_events = sd_check_events, .revalidate_disk = sd_revalidate_disk, .unlock_native_capacity = sd_unlock_native_capacity, .pr_ops = &sd_pr_ops, @@ -2323,11 +2272,6 @@ got_data: sizeof(cap_str_10)); if (sdkp->first_scan || old_capacity != sdkp->capacity) { - sd_printk(KERN_NOTICE, sdkp, - "%llu %d-byte logical blocks: (%s/%s)\n", - (unsigned long long)sdkp->capacity, - sector_size, cap_str_10, cap_str_2); - if (sdkp->physical_block_size != sector_size) sd_printk(KERN_NOTICE, sdkp, "%u-byte physical blocks\n", @@ -2364,7 +2308,6 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) int res; struct scsi_device *sdp = sdkp->device; struct scsi_mode_data data; - int old_wp = sdkp->write_prot; set_disk_ro(sdkp->disk, 0); if (sdp->skip_ms_page_3f) { @@ -2405,13 +2348,6 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) } else { sdkp->write_prot = ((data.device_specific & 0x80) != 0); set_disk_ro(sdkp->disk, sdkp->write_prot); - if (sdkp->first_scan || old_wp != sdkp->write_prot) { - sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", - sdkp->write_prot ? "on" : "off"); - sd_printk(KERN_DEBUG, sdkp, - "Mode Sense: %02x %02x %02x %02x\n", - buffer[0], buffer[1], buffer[2], buffer[3]); - } } } @@ -2424,16 +2360,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) { int len = 0, res; struct scsi_device *sdp = sdkp->device; + struct Scsi_Host *host = sdp->host; int dbd; int modepage; int first_len; struct scsi_mode_data data; struct scsi_sense_hdr sshdr; - int old_wce = sdkp->WCE; - int old_rcd = sdkp->RCD; - int old_dpofua = sdkp->DPOFUA; - if (sdkp->cache_override) return; @@ -2455,7 +2388,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) dbd = 8; } else { modepage = 8; - dbd = 0; + if (host->set_dbd_for_caching) + dbd = 8; + else + dbd = 0; } /* cautiously ask */ @@ -2555,15 +2491,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) if (sdkp->WCE && sdkp->write_prot) sdkp->WCE = 0; - if (sdkp->first_scan || old_wce != sdkp->WCE || - old_rcd != sdkp->RCD || old_dpofua != sdkp->DPOFUA) - sd_printk(KERN_NOTICE, sdkp, - "Write cache: %s, read cache: %s, %s\n", - sdkp->WCE ? "enabled" : "disabled", - sdkp->RCD ? "disabled" : "enabled", - sdkp->DPOFUA ? "supports DPO and FUA" - : "doesn't support DPO or FUA"); - return; } @@ -3008,14 +2935,15 @@ static void sd_probe_async(void *data, async_cookie_t cookie) } blk_pm_runtime_init(sdp->request_queue, dev); + if (sdp->autosuspend_delay >= 0) + pm_runtime_set_autosuspend_delay(dev, sdp->autosuspend_delay); + add_disk(gd); if (sdkp->capacity) sd_dif_config_host(sdkp); sd_revalidate_disk(gd); - sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", - sdp->removable ? "removable " : ""); scsi_autopm_put_device(sdp); put_device(&sdkp->dev); } @@ -3260,7 +3188,6 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) return 0; if (sdkp->WCE && sdkp->media_present) { - sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); ret = sd_sync_cache(sdkp); if (ret) { /* ignore OFFLINE device */ @@ -3271,7 +3198,7 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) } if (sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); + sd_printk(KERN_DEBUG, sdkp, "Stopping disk\n"); /* an error is not worth aborting a system sleep */ ret = sd_start_stop_device(sdkp, 0); if (ignore_stop_errors) @@ -3302,7 +3229,7 @@ static int sd_resume(struct device *dev) if (!sdkp->device->manage_start_stop) return 0; - sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); + sd_printk(KERN_DEBUG, sdkp, "Starting disk\n"); return sd_start_stop_device(sdkp, 1); } |