}
#endif
-static struct block_device_operations sd_fops = {
+static const struct block_device_operations sd_fops = {
.owner = THIS_MODULE,
.open = sd_open,
.release = sd_release,
kfree(buffer);
}
+static int sd_try_extended_inquiry(struct scsi_device *sdp)
+{
+ /*
+ * Although VPD inquiries can go to SCSI-2 type devices,
+ * some USB ones crash on receiving them, and the pages
+ * we currently ask for are for SPC-3 and beyond
+ */
+ if (sdp->scsi_level > SCSI_SPC_2)
+ return 1;
+ return 0;
+}
+
/**
* sd_revalidate_disk - called the first time a new disk is seen,
* performs disk spin up, read_capacity, etc.
*/
if (sdkp->media_present) {
sd_read_capacity(sdkp, buffer);
- sd_read_block_limits(sdkp);
- sd_read_block_characteristics(sdkp);
+
+ if (sd_try_extended_inquiry(sdp)) {
+ sd_read_block_limits(sdkp);
+ sd_read_block_characteristics(sdkp);
+ }
+
sd_read_write_protect_flag(sdkp, buffer);
sd_read_cache_type(sdkp, buffer);
sd_read_app_tag_own(sdkp, buffer);
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
+ put_device(&sdkp->dev);
}
/**
get_device(&sdp->sdev_gendev);
+ get_device(&sdkp->dev); /* prevent release before async_schedule */
async_schedule(sd_probe_async, sdkp);
return 0;
async_synchronize_full();
sdkp = dev_get_drvdata(dev);
+ blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn);
device_del(&sdkp->dev);
del_gendisk(sdkp->disk);
sd_shutdown(dev);