summaryrefslogtreecommitdiff
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c143
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);
}