diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 111 |
1 files changed, 45 insertions, 66 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a3406bd62391..149d406aacc9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -568,6 +568,7 @@ static struct scsi_driver sd_template = { | |||
568 | .name = "sd", | 568 | .name = "sd", |
569 | .owner = THIS_MODULE, | 569 | .owner = THIS_MODULE, |
570 | .probe = sd_probe, | 570 | .probe = sd_probe, |
571 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, | ||
571 | .remove = sd_remove, | 572 | .remove = sd_remove, |
572 | .shutdown = sd_shutdown, | 573 | .shutdown = sd_shutdown, |
573 | .pm = &sd_pm_ops, | 574 | .pm = &sd_pm_ops, |
@@ -3252,69 +3253,6 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen) | |||
3252 | return 0; | 3253 | return 0; |
3253 | } | 3254 | } |
3254 | 3255 | ||
3255 | /* | ||
3256 | * The asynchronous part of sd_probe | ||
3257 | */ | ||
3258 | static void sd_probe_async(void *data, async_cookie_t cookie) | ||
3259 | { | ||
3260 | struct scsi_disk *sdkp = data; | ||
3261 | struct scsi_device *sdp; | ||
3262 | struct gendisk *gd; | ||
3263 | u32 index; | ||
3264 | struct device *dev; | ||
3265 | |||
3266 | sdp = sdkp->device; | ||
3267 | gd = sdkp->disk; | ||
3268 | index = sdkp->index; | ||
3269 | dev = &sdp->sdev_gendev; | ||
3270 | |||
3271 | gd->major = sd_major((index & 0xf0) >> 4); | ||
3272 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); | ||
3273 | |||
3274 | gd->fops = &sd_fops; | ||
3275 | gd->private_data = &sdkp->driver; | ||
3276 | gd->queue = sdkp->device->request_queue; | ||
3277 | |||
3278 | /* defaults, until the device tells us otherwise */ | ||
3279 | sdp->sector_size = 512; | ||
3280 | sdkp->capacity = 0; | ||
3281 | sdkp->media_present = 1; | ||
3282 | sdkp->write_prot = 0; | ||
3283 | sdkp->cache_override = 0; | ||
3284 | sdkp->WCE = 0; | ||
3285 | sdkp->RCD = 0; | ||
3286 | sdkp->ATO = 0; | ||
3287 | sdkp->first_scan = 1; | ||
3288 | sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; | ||
3289 | |||
3290 | sd_revalidate_disk(gd); | ||
3291 | |||
3292 | gd->flags = GENHD_FL_EXT_DEVT; | ||
3293 | if (sdp->removable) { | ||
3294 | gd->flags |= GENHD_FL_REMOVABLE; | ||
3295 | gd->events |= DISK_EVENT_MEDIA_CHANGE; | ||
3296 | gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT; | ||
3297 | } | ||
3298 | |||
3299 | blk_pm_runtime_init(sdp->request_queue, dev); | ||
3300 | device_add_disk(dev, gd, NULL); | ||
3301 | if (sdkp->capacity) | ||
3302 | sd_dif_config_host(sdkp); | ||
3303 | |||
3304 | sd_revalidate_disk(gd); | ||
3305 | |||
3306 | if (sdkp->security) { | ||
3307 | sdkp->opal_dev = init_opal_dev(sdp, &sd_sec_submit); | ||
3308 | if (sdkp->opal_dev) | ||
3309 | sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n"); | ||
3310 | } | ||
3311 | |||
3312 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", | ||
3313 | sdp->removable ? "removable " : ""); | ||
3314 | scsi_autopm_put_device(sdp); | ||
3315 | put_device(&sdkp->dev); | ||
3316 | } | ||
3317 | |||
3318 | /** | 3256 | /** |
3319 | * sd_probe - called during driver initialization and whenever a | 3257 | * sd_probe - called during driver initialization and whenever a |
3320 | * new scsi device is attached to the system. It is called once | 3258 | * new scsi device is attached to the system. It is called once |
@@ -3404,8 +3342,50 @@ static int sd_probe(struct device *dev) | |||
3404 | get_device(dev); | 3342 | get_device(dev); |
3405 | dev_set_drvdata(dev, sdkp); | 3343 | dev_set_drvdata(dev, sdkp); |
3406 | 3344 | ||
3407 | get_device(&sdkp->dev); /* prevent release before async_schedule */ | 3345 | gd->major = sd_major((index & 0xf0) >> 4); |
3408 | async_schedule_domain(sd_probe_async, sdkp, &scsi_sd_probe_domain); | 3346 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); |
3347 | |||
3348 | gd->fops = &sd_fops; | ||
3349 | gd->private_data = &sdkp->driver; | ||
3350 | gd->queue = sdkp->device->request_queue; | ||
3351 | |||
3352 | /* defaults, until the device tells us otherwise */ | ||
3353 | sdp->sector_size = 512; | ||
3354 | sdkp->capacity = 0; | ||
3355 | sdkp->media_present = 1; | ||
3356 | sdkp->write_prot = 0; | ||
3357 | sdkp->cache_override = 0; | ||
3358 | sdkp->WCE = 0; | ||
3359 | sdkp->RCD = 0; | ||
3360 | sdkp->ATO = 0; | ||
3361 | sdkp->first_scan = 1; | ||
3362 | sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; | ||
3363 | |||
3364 | sd_revalidate_disk(gd); | ||
3365 | |||
3366 | gd->flags = GENHD_FL_EXT_DEVT; | ||
3367 | if (sdp->removable) { | ||
3368 | gd->flags |= GENHD_FL_REMOVABLE; | ||
3369 | gd->events |= DISK_EVENT_MEDIA_CHANGE; | ||
3370 | gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT; | ||
3371 | } | ||
3372 | |||
3373 | blk_pm_runtime_init(sdp->request_queue, dev); | ||
3374 | device_add_disk(dev, gd, NULL); | ||
3375 | if (sdkp->capacity) | ||
3376 | sd_dif_config_host(sdkp); | ||
3377 | |||
3378 | sd_revalidate_disk(gd); | ||
3379 | |||
3380 | if (sdkp->security) { | ||
3381 | sdkp->opal_dev = init_opal_dev(sdp, &sd_sec_submit); | ||
3382 | if (sdkp->opal_dev) | ||
3383 | sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n"); | ||
3384 | } | ||
3385 | |||
3386 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", | ||
3387 | sdp->removable ? "removable " : ""); | ||
3388 | scsi_autopm_put_device(sdp); | ||
3409 | 3389 | ||
3410 | return 0; | 3390 | return 0; |
3411 | 3391 | ||
@@ -3441,7 +3421,6 @@ static int sd_remove(struct device *dev) | |||
3441 | scsi_autopm_get_device(sdkp->device); | 3421 | scsi_autopm_get_device(sdkp->device); |
3442 | 3422 | ||
3443 | async_synchronize_full_domain(&scsi_sd_pm_domain); | 3423 | async_synchronize_full_domain(&scsi_sd_pm_domain); |
3444 | async_synchronize_full_domain(&scsi_sd_probe_domain); | ||
3445 | device_del(&sdkp->dev); | 3424 | device_del(&sdkp->dev); |
3446 | del_gendisk(sdkp->disk); | 3425 | del_gendisk(sdkp->disk); |
3447 | sd_shutdown(dev); | 3426 | sd_shutdown(dev); |