aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 352bc77b7c88..7992635d405f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -105,7 +105,7 @@ static void sd_unlock_native_capacity(struct gendisk *disk);
105static int sd_probe(struct device *); 105static int sd_probe(struct device *);
106static int sd_remove(struct device *); 106static int sd_remove(struct device *);
107static void sd_shutdown(struct device *); 107static void sd_shutdown(struct device *);
108static int sd_suspend(struct device *, pm_message_t state); 108static int sd_suspend(struct device *);
109static int sd_resume(struct device *); 109static int sd_resume(struct device *);
110static void sd_rescan(struct device *); 110static void sd_rescan(struct device *);
111static int sd_done(struct scsi_cmnd *); 111static int sd_done(struct scsi_cmnd *);
@@ -465,15 +465,23 @@ static struct class sd_disk_class = {
465 .dev_attrs = sd_disk_attrs, 465 .dev_attrs = sd_disk_attrs,
466}; 466};
467 467
468static const struct dev_pm_ops sd_pm_ops = {
469 .suspend = sd_suspend,
470 .resume = sd_resume,
471 .poweroff = sd_suspend,
472 .restore = sd_resume,
473 .runtime_suspend = sd_suspend,
474 .runtime_resume = sd_resume,
475};
476
468static struct scsi_driver sd_template = { 477static struct scsi_driver sd_template = {
469 .owner = THIS_MODULE, 478 .owner = THIS_MODULE,
470 .gendrv = { 479 .gendrv = {
471 .name = "sd", 480 .name = "sd",
472 .probe = sd_probe, 481 .probe = sd_probe,
473 .remove = sd_remove, 482 .remove = sd_remove,
474 .suspend = sd_suspend,
475 .resume = sd_resume,
476 .shutdown = sd_shutdown, 483 .shutdown = sd_shutdown,
484 .pm = &sd_pm_ops,
477 }, 485 },
478 .rescan = sd_rescan, 486 .rescan = sd_rescan,
479 .done = sd_done, 487 .done = sd_done,
@@ -1011,7 +1019,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
1011 SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff; 1019 SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff;
1012 SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff; 1020 SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff;
1013 SCpnt->cmnd[31] = (unsigned char) this_count & 0xff; 1021 SCpnt->cmnd[31] = (unsigned char) this_count & 0xff;
1014 } else if (block > 0xffffffff) { 1022 } else if (sdp->use_16_for_rw) {
1015 SCpnt->cmnd[0] += READ_16 - READ_6; 1023 SCpnt->cmnd[0] += READ_16 - READ_6;
1016 SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); 1024 SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0);
1017 SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; 1025 SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0;
@@ -2203,6 +2211,8 @@ got_data:
2203 } 2211 }
2204 } 2212 }
2205 2213
2214 sdp->use_16_for_rw = (sdkp->capacity > 0xffffffff);
2215
2206 /* Rescale capacity to 512-byte units */ 2216 /* Rescale capacity to 512-byte units */
2207 if (sector_size == 4096) 2217 if (sector_size == 4096)
2208 sdkp->capacity <<= 3; 2218 sdkp->capacity <<= 3;
@@ -3052,7 +3062,7 @@ exit:
3052 scsi_disk_put(sdkp); 3062 scsi_disk_put(sdkp);
3053} 3063}
3054 3064
3055static int sd_suspend(struct device *dev, pm_message_t mesg) 3065static int sd_suspend(struct device *dev)
3056{ 3066{
3057 struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 3067 struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
3058 int ret = 0; 3068 int ret = 0;
@@ -3067,7 +3077,7 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
3067 goto done; 3077 goto done;
3068 } 3078 }
3069 3079
3070 if ((mesg.event & PM_EVENT_SLEEP) && sdkp->device->manage_start_stop) { 3080 if (sdkp->device->manage_start_stop) {
3071 sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); 3081 sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
3072 ret = sd_start_stop_device(sdkp, 0); 3082 ret = sd_start_stop_device(sdkp, 0);
3073 } 3083 }
@@ -3116,10 +3126,6 @@ static int __init init_sd(void)
3116 if (err) 3126 if (err)
3117 goto err_out; 3127 goto err_out;
3118 3128
3119 err = scsi_register_driver(&sd_template.gendrv);
3120 if (err)
3121 goto err_out_class;
3122
3123 sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE, 3129 sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE,
3124 0, 0, NULL); 3130 0, 0, NULL);
3125 if (!sd_cdb_cache) { 3131 if (!sd_cdb_cache) {
@@ -3133,8 +3139,15 @@ static int __init init_sd(void)
3133 goto err_out_cache; 3139 goto err_out_cache;
3134 } 3140 }
3135 3141
3142 err = scsi_register_driver(&sd_template.gendrv);
3143 if (err)
3144 goto err_out_driver;
3145
3136 return 0; 3146 return 0;
3137 3147
3148err_out_driver:
3149 mempool_destroy(sd_cdb_pool);
3150
3138err_out_cache: 3151err_out_cache:
3139 kmem_cache_destroy(sd_cdb_cache); 3152 kmem_cache_destroy(sd_cdb_cache);
3140 3153
@@ -3157,10 +3170,10 @@ static void __exit exit_sd(void)
3157 3170
3158 SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); 3171 SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
3159 3172
3173 scsi_unregister_driver(&sd_template.gendrv);
3160 mempool_destroy(sd_cdb_pool); 3174 mempool_destroy(sd_cdb_pool);
3161 kmem_cache_destroy(sd_cdb_cache); 3175 kmem_cache_destroy(sd_cdb_cache);
3162 3176
3163 scsi_unregister_driver(&sd_template.gendrv);
3164 class_unregister(&sd_disk_class); 3177 class_unregister(&sd_disk_class);
3165 3178
3166 for (i = 0; i < SD_MAJORS; i++) 3179 for (i = 0; i < SD_MAJORS; i++)