diff options
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh.c')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index 3ee1cbc89479..6fae3d285ae7 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c | |||
@@ -21,6 +21,7 @@ | |||
21 | * Mike Anderson <andmike@linux.vnet.ibm.com> | 21 | * Mike Anderson <andmike@linux.vnet.ibm.com> |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/slab.h> | ||
24 | #include <scsi/scsi_dh.h> | 25 | #include <scsi/scsi_dh.h> |
25 | #include "../scsi_priv.h" | 26 | #include "../scsi_priv.h" |
26 | 27 | ||
@@ -226,7 +227,7 @@ store_dh_state(struct device *dev, struct device_attribute *attr, | |||
226 | * Activate a device handler | 227 | * Activate a device handler |
227 | */ | 228 | */ |
228 | if (scsi_dh->activate) | 229 | if (scsi_dh->activate) |
229 | err = scsi_dh->activate(sdev); | 230 | err = scsi_dh->activate(sdev, NULL, NULL); |
230 | else | 231 | else |
231 | err = 0; | 232 | err = 0; |
232 | } | 233 | } |
@@ -304,18 +305,15 @@ static int scsi_dh_notifier(struct notifier_block *nb, | |||
304 | sdev = to_scsi_device(dev); | 305 | sdev = to_scsi_device(dev); |
305 | 306 | ||
306 | if (action == BUS_NOTIFY_ADD_DEVICE) { | 307 | if (action == BUS_NOTIFY_ADD_DEVICE) { |
308 | err = device_create_file(dev, &scsi_dh_state_attr); | ||
309 | /* don't care about err */ | ||
307 | devinfo = device_handler_match(NULL, sdev); | 310 | devinfo = device_handler_match(NULL, sdev); |
308 | if (!devinfo) | 311 | if (devinfo) |
309 | goto out; | 312 | err = scsi_dh_handler_attach(sdev, devinfo); |
310 | |||
311 | err = scsi_dh_handler_attach(sdev, devinfo); | ||
312 | if (!err) | ||
313 | err = device_create_file(dev, &scsi_dh_state_attr); | ||
314 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { | 313 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { |
315 | device_remove_file(dev, &scsi_dh_state_attr); | 314 | device_remove_file(dev, &scsi_dh_state_attr); |
316 | scsi_dh_handler_detach(sdev, NULL); | 315 | scsi_dh_handler_detach(sdev, NULL); |
317 | } | 316 | } |
318 | out: | ||
319 | return err; | 317 | return err; |
320 | } | 318 | } |
321 | 319 | ||
@@ -423,10 +421,17 @@ EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); | |||
423 | /* | 421 | /* |
424 | * scsi_dh_activate - activate the path associated with the scsi_device | 422 | * scsi_dh_activate - activate the path associated with the scsi_device |
425 | * corresponding to the given request queue. | 423 | * corresponding to the given request queue. |
426 | * @q - Request queue that is associated with the scsi_device to be | 424 | * Returns immediately without waiting for activation to be completed. |
427 | * activated. | 425 | * @q - Request queue that is associated with the scsi_device to be |
426 | * activated. | ||
427 | * @fn - Function to be called upon completion of the activation. | ||
428 | * Function fn is called with data (below) and the error code. | ||
429 | * Function fn may be called from the same calling context. So, | ||
430 | * do not hold the lock in the caller which may be needed in fn. | ||
431 | * @data - data passed to the function fn upon completion. | ||
432 | * | ||
428 | */ | 433 | */ |
429 | int scsi_dh_activate(struct request_queue *q) | 434 | int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) |
430 | { | 435 | { |
431 | int err = 0; | 436 | int err = 0; |
432 | unsigned long flags; | 437 | unsigned long flags; |
@@ -445,7 +450,7 @@ int scsi_dh_activate(struct request_queue *q) | |||
445 | return err; | 450 | return err; |
446 | 451 | ||
447 | if (scsi_dh->activate) | 452 | if (scsi_dh->activate) |
448 | err = scsi_dh->activate(sdev); | 453 | err = scsi_dh->activate(sdev, fn, data); |
449 | put_device(&sdev->sdev_gendev); | 454 | put_device(&sdev->sdev_gendev); |
450 | return err; | 455 | return err; |
451 | } | 456 | } |