aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandra Seetharaman <sekharan@us.ibm.com>2009-10-21 12:22:46 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:00:46 -0500
commit3ae31f6a7b6e442fc6a92f29330fbad230dc3992 (patch)
tree9ca152ac3412de2917c0486b64898e6a75f853d9
parent42e62a74377bcbb526565a31aa18da8f712b93ee (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.c8
-rw-r--r--drivers/scsi/device_handler/scsi_dh.c17
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c7
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c7
-rw-r--r--drivers/scsi/device_handler/scsi_dh_hp_sw.c7
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c7
-rw-r--r--include/scsi/scsi_device.h3
-rw-r--r--include/scsi/scsi_dh.h6
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
1119static void pg_init_done(struct dm_path *path, int errors) 1119static 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
1184static void activate_path(struct work_struct *work) 1185static 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 */
429int scsi_dh_activate(struct request_queue *q) 436int 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 */
655static int alua_activate(struct scsi_device *sdev) 655static 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
669out: 670out:
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
531static int clariion_activate(struct scsi_device *sdev) 531static 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 */
271static int hp_sw_activate(struct scsi_device *sdev) 271static 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
289static const struct scsi_dh_devlist hp_sw_dh_data_list[] = { 292static 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
571static int rdac_activate(struct scsi_device *sdev) 571static 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);
582done: 583done:
583 return err; 584 if (fn)
585 fn(data, err);
586 return 0;
584} 587}
585 588
586static int rdac_prep_fn(struct scsi_device *sdev, struct request *req) 589static 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
180typedef void (*activate_complete)(void *, int);
180struct scsi_device_handler { 181struct 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)
59extern int scsi_dh_activate(struct request_queue *); 59extern int scsi_dh_activate(struct request_queue *, activate_complete, void *);
60extern int scsi_dh_handler_exist(const char *); 60extern int scsi_dh_handler_exist(const char *);
61extern int scsi_dh_attach(struct request_queue *, const char *); 61extern int scsi_dh_attach(struct request_queue *, const char *);
62extern void scsi_dh_detach(struct request_queue *); 62extern void scsi_dh_detach(struct request_queue *);
63extern int scsi_dh_set_params(struct request_queue *, const char *); 63extern int scsi_dh_set_params(struct request_queue *, const char *);
64#else 64#else
65static inline int scsi_dh_activate(struct request_queue *req) 65static 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}
69static inline int scsi_dh_handler_exist(const char *name) 71static inline int scsi_dh_handler_exist(const char *name)