diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 35 |
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); | |||
105 | static int sd_probe(struct device *); | 105 | static int sd_probe(struct device *); |
106 | static int sd_remove(struct device *); | 106 | static int sd_remove(struct device *); |
107 | static void sd_shutdown(struct device *); | 107 | static void sd_shutdown(struct device *); |
108 | static int sd_suspend(struct device *, pm_message_t state); | 108 | static int sd_suspend(struct device *); |
109 | static int sd_resume(struct device *); | 109 | static int sd_resume(struct device *); |
110 | static void sd_rescan(struct device *); | 110 | static void sd_rescan(struct device *); |
111 | static int sd_done(struct scsi_cmnd *); | 111 | static 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 | ||
468 | static 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 | |||
468 | static struct scsi_driver sd_template = { | 477 | static 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 | ||
3055 | static int sd_suspend(struct device *dev, pm_message_t mesg) | 3065 | static 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 | ||
3148 | err_out_driver: | ||
3149 | mempool_destroy(sd_cdb_pool); | ||
3150 | |||
3138 | err_out_cache: | 3151 | err_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++) |