diff options
author | Chandra Seetharaman <sekharan@us.ibm.com> | 2009-10-21 12:22:46 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:00:46 -0500 |
commit | 3ae31f6a7b6e442fc6a92f29330fbad230dc3992 (patch) | |
tree | 9ca152ac3412de2917c0486b64898e6a75f853d9 | |
parent | 42e62a74377bcbb526565a31aa18da8f712b93ee (diff) |
[SCSI] scsi_dh: Change the scsidh_activate interface to be asynchronous
Make scsi_dh_activate() function asynchronous, by taking in two additional
parameters, one is the callback function and the other is the data to call
the callback function with.
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r-- | drivers/md/dm-mpath.c | 8 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh.c | 17 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_alua.c | 7 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_emc.c | 7 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_hp_sw.c | 7 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_rdac.c | 7 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 3 | ||||
-rw-r--r-- | include/scsi/scsi_dh.h | 6 |
8 files changed, 42 insertions, 20 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 32d0b878eccc..dce971dbdfa3 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1116,8 +1116,9 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath) | |||
1116 | return limit_reached; | 1116 | return limit_reached; |
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | static void pg_init_done(struct dm_path *path, int errors) | 1119 | static void pg_init_done(void *data, int errors) |
1120 | { | 1120 | { |
1121 | struct dm_path *path = data; | ||
1121 | struct pgpath *pgpath = path_to_pgpath(path); | 1122 | struct pgpath *pgpath = path_to_pgpath(path); |
1122 | struct priority_group *pg = pgpath->pg; | 1123 | struct priority_group *pg = pgpath->pg; |
1123 | struct multipath *m = pg->m; | 1124 | struct multipath *m = pg->m; |
@@ -1183,12 +1184,11 @@ static void pg_init_done(struct dm_path *path, int errors) | |||
1183 | 1184 | ||
1184 | static void activate_path(struct work_struct *work) | 1185 | static void activate_path(struct work_struct *work) |
1185 | { | 1186 | { |
1186 | int ret; | ||
1187 | struct pgpath *pgpath = | 1187 | struct pgpath *pgpath = |
1188 | container_of(work, struct pgpath, activate_path); | 1188 | container_of(work, struct pgpath, activate_path); |
1189 | 1189 | ||
1190 | ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev)); | 1190 | scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev), |
1191 | pg_init_done(&pgpath->path, ret); | 1191 | pg_init_done, &pgpath->path); |
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | /* | 1194 | /* |
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index 3ee1cbc89479..6f7f798910e8 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c | |||
@@ -226,7 +226,7 @@ store_dh_state(struct device *dev, struct device_attribute *attr, | |||
226 | * Activate a device handler | 226 | * Activate a device handler |
227 | */ | 227 | */ |
228 | if (scsi_dh->activate) | 228 | if (scsi_dh->activate) |
229 | err = scsi_dh->activate(sdev); | 229 | err = scsi_dh->activate(sdev, NULL, NULL); |
230 | else | 230 | else |
231 | err = 0; | 231 | err = 0; |
232 | } | 232 | } |
@@ -423,10 +423,17 @@ EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); | |||
423 | /* | 423 | /* |
424 | * scsi_dh_activate - activate the path associated with the scsi_device | 424 | * scsi_dh_activate - activate the path associated with the scsi_device |
425 | * corresponding to the given request queue. | 425 | * corresponding to the given request queue. |
426 | * @q - Request queue that is associated with the scsi_device to be | 426 | * Returns immediately without waiting for activation to be completed. |
427 | * activated. | 427 | * @q - Request queue that is associated with the scsi_device to be |
428 | * activated. | ||
429 | * @fn - Function to be called upon completion of the activation. | ||
430 | * Function fn is called with data (below) and the error code. | ||
431 | * Function fn may be called from the same calling context. So, | ||
432 | * do not hold the lock in the caller which may be needed in fn. | ||
433 | * @data - data passed to the function fn upon completion. | ||
434 | * | ||
428 | */ | 435 | */ |
429 | int scsi_dh_activate(struct request_queue *q) | 436 | int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) |
430 | { | 437 | { |
431 | int err = 0; | 438 | int err = 0; |
432 | unsigned long flags; | 439 | unsigned long flags; |
@@ -445,7 +452,7 @@ int scsi_dh_activate(struct request_queue *q) | |||
445 | return err; | 452 | return err; |
446 | 453 | ||
447 | if (scsi_dh->activate) | 454 | if (scsi_dh->activate) |
448 | err = scsi_dh->activate(sdev); | 455 | err = scsi_dh->activate(sdev, fn, data); |
449 | put_device(&sdev->sdev_gendev); | 456 | put_device(&sdev->sdev_gendev); |
450 | return err; | 457 | return err; |
451 | } | 458 | } |
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index b5cdefaf2608..e8a8928e58bc 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -652,7 +652,8 @@ out: | |||
652 | * based on a certain policy. But until we actually encounter them it | 652 | * based on a certain policy. But until we actually encounter them it |
653 | * should be okay. | 653 | * should be okay. |
654 | */ | 654 | */ |
655 | static int alua_activate(struct scsi_device *sdev) | 655 | static int alua_activate(struct scsi_device *sdev, |
656 | activate_complete fn, void *data) | ||
656 | { | 657 | { |
657 | struct alua_dh_data *h = get_alua_data(sdev); | 658 | struct alua_dh_data *h = get_alua_data(sdev); |
658 | int err = SCSI_DH_OK; | 659 | int err = SCSI_DH_OK; |
@@ -667,7 +668,9 @@ static int alua_activate(struct scsi_device *sdev) | |||
667 | err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h); | 668 | err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h); |
668 | 669 | ||
669 | out: | 670 | out: |
670 | return err; | 671 | if (fn) |
672 | fn(data, err); | ||
673 | return 0; | ||
671 | } | 674 | } |
672 | 675 | ||
673 | /* | 676 | /* |
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 0cffe84976fe..61966750bd60 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -528,7 +528,8 @@ retry: | |||
528 | return err; | 528 | return err; |
529 | } | 529 | } |
530 | 530 | ||
531 | static int clariion_activate(struct scsi_device *sdev) | 531 | static int clariion_activate(struct scsi_device *sdev, |
532 | activate_complete fn, void *data) | ||
532 | { | 533 | { |
533 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | 534 | struct clariion_dh_data *csdev = get_clariion_data(sdev); |
534 | int result; | 535 | int result; |
@@ -559,7 +560,9 @@ done: | |||
559 | csdev->port, lun_state[csdev->lun_state], | 560 | csdev->port, lun_state[csdev->lun_state], |
560 | csdev->default_sp + 'A'); | 561 | csdev->default_sp + 'A'); |
561 | 562 | ||
562 | return result; | 563 | if (fn) |
564 | fn(data, result); | ||
565 | return 0; | ||
563 | } | 566 | } |
564 | /* | 567 | /* |
565 | * params - parameters in the following format | 568 | * params - parameters in the following format |
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index f7da7530875e..0aacafc96f21 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c | |||
@@ -268,7 +268,8 @@ static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req) | |||
268 | * activate the passive path (and deactivate the | 268 | * activate the passive path (and deactivate the |
269 | * previously active one). | 269 | * previously active one). |
270 | */ | 270 | */ |
271 | static int hp_sw_activate(struct scsi_device *sdev) | 271 | static int hp_sw_activate(struct scsi_device *sdev, |
272 | activate_complete fn, void *data) | ||
272 | { | 273 | { |
273 | int ret = SCSI_DH_OK; | 274 | int ret = SCSI_DH_OK; |
274 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | 275 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); |
@@ -283,7 +284,9 @@ static int hp_sw_activate(struct scsi_device *sdev) | |||
283 | HP_SW_NAME); | 284 | HP_SW_NAME); |
284 | } | 285 | } |
285 | 286 | ||
286 | return ret; | 287 | if (fn) |
288 | fn(data, ret); | ||
289 | return 0; | ||
287 | } | 290 | } |
288 | 291 | ||
289 | static const struct scsi_dh_devlist hp_sw_dh_data_list[] = { | 292 | static const struct scsi_dh_devlist hp_sw_dh_data_list[] = { |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 268189d31d9c..be362adbd8e7 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
@@ -568,7 +568,8 @@ done: | |||
568 | return err; | 568 | return err; |
569 | } | 569 | } |
570 | 570 | ||
571 | static int rdac_activate(struct scsi_device *sdev) | 571 | static int rdac_activate(struct scsi_device *sdev, |
572 | activate_complete fn, void *data) | ||
572 | { | 573 | { |
573 | struct rdac_dh_data *h = get_rdac_data(sdev); | 574 | struct rdac_dh_data *h = get_rdac_data(sdev); |
574 | int err = SCSI_DH_OK; | 575 | int err = SCSI_DH_OK; |
@@ -580,7 +581,9 @@ static int rdac_activate(struct scsi_device *sdev) | |||
580 | if (h->lun_state == RDAC_LUN_UNOWNED) | 581 | if (h->lun_state == RDAC_LUN_UNOWNED) |
581 | err = send_mode_select(sdev, h); | 582 | err = send_mode_select(sdev, h); |
582 | done: | 583 | done: |
583 | return err; | 584 | if (fn) |
585 | fn(data, err); | ||
586 | return 0; | ||
584 | } | 587 | } |
585 | 588 | ||
586 | static int rdac_prep_fn(struct scsi_device *sdev, struct request *req) | 589 | static int rdac_prep_fn(struct scsi_device *sdev, struct request *req) |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 92c4c3bd916d..68d185c79bae 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -177,6 +177,7 @@ struct scsi_dh_devlist { | |||
177 | char *model; | 177 | char *model; |
178 | }; | 178 | }; |
179 | 179 | ||
180 | typedef void (*activate_complete)(void *, int); | ||
180 | struct scsi_device_handler { | 181 | struct scsi_device_handler { |
181 | /* Used by the infrastructure */ | 182 | /* Used by the infrastructure */ |
182 | struct list_head list; /* list of scsi_device_handlers */ | 183 | struct list_head list; /* list of scsi_device_handlers */ |
@@ -188,7 +189,7 @@ struct scsi_device_handler { | |||
188 | int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); | 189 | int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); |
189 | int (*attach)(struct scsi_device *); | 190 | int (*attach)(struct scsi_device *); |
190 | void (*detach)(struct scsi_device *); | 191 | void (*detach)(struct scsi_device *); |
191 | int (*activate)(struct scsi_device *); | 192 | int (*activate)(struct scsi_device *, activate_complete, void *); |
192 | int (*prep_fn)(struct scsi_device *, struct request *); | 193 | int (*prep_fn)(struct scsi_device *, struct request *); |
193 | int (*set_params)(struct scsi_device *, const char *); | 194 | int (*set_params)(struct scsi_device *, const char *); |
194 | }; | 195 | }; |
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h index ff2407405b42..e3f2db212ddc 100644 --- a/include/scsi/scsi_dh.h +++ b/include/scsi/scsi_dh.h | |||
@@ -56,14 +56,16 @@ enum { | |||
56 | SCSI_DH_DRIVER_MAX, | 56 | SCSI_DH_DRIVER_MAX, |
57 | }; | 57 | }; |
58 | #if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) | 58 | #if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) |
59 | extern int scsi_dh_activate(struct request_queue *); | 59 | extern int scsi_dh_activate(struct request_queue *, activate_complete, void *); |
60 | extern int scsi_dh_handler_exist(const char *); | 60 | extern int scsi_dh_handler_exist(const char *); |
61 | extern int scsi_dh_attach(struct request_queue *, const char *); | 61 | extern int scsi_dh_attach(struct request_queue *, const char *); |
62 | extern void scsi_dh_detach(struct request_queue *); | 62 | extern void scsi_dh_detach(struct request_queue *); |
63 | extern int scsi_dh_set_params(struct request_queue *, const char *); | 63 | extern int scsi_dh_set_params(struct request_queue *, const char *); |
64 | #else | 64 | #else |
65 | static inline int scsi_dh_activate(struct request_queue *req) | 65 | static inline int scsi_dh_activate(struct request_queue *req, |
66 | activate_complete fn, void *data) | ||
66 | { | 67 | { |
68 | fn(data, 0); | ||
67 | return 0; | 69 | return 0; |
68 | } | 70 | } |
69 | static inline int scsi_dh_handler_exist(const char *name) | 71 | static inline int scsi_dh_handler_exist(const char *name) |