diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2009-08-18 09:43:20 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 09:49:28 -0400 |
commit | 799b76d09aeee558d18c1f5b93e63f58f1d1fc11 (patch) | |
tree | a1a05faa773b329246a4fa97ba7c0ac5201b5d40 /drivers/s390/scsi/zfcp_fc.c | |
parent | 564e1c86c810f9ccfe4300afa402815e3db4886d (diff) |
[SCSI] zfcp: Decouple gid_pn requests from erp
Don't let the erp wait for gid_pn requests to complete. Instead, queue
the gid_pn work, exit erp and let the finished gid_pn work trigger a
new port reopen.
Reviewed-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 8921e16fdab7..bc0c9f54d0d8 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -282,15 +282,15 @@ static void zfcp_fc_ns_gid_pn_eval(unsigned long data) | |||
282 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; | 282 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; |
283 | } | 283 | } |
284 | 284 | ||
285 | int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, | 285 | static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, |
286 | struct zfcp_gid_pn_data *gid_pn) | 286 | struct zfcp_gid_pn_data *gid_pn) |
287 | { | 287 | { |
288 | struct zfcp_adapter *adapter = erp_action->adapter; | 288 | struct zfcp_adapter *adapter = port->adapter; |
289 | struct zfcp_fc_ns_handler_data compl_rec; | 289 | struct zfcp_fc_ns_handler_data compl_rec; |
290 | int ret; | 290 | int ret; |
291 | 291 | ||
292 | /* setup parameters for send generic command */ | 292 | /* setup parameters for send generic command */ |
293 | gid_pn->port = erp_action->port; | 293 | gid_pn->port = port; |
294 | gid_pn->ct.wka_port = &adapter->gs->ds; | 294 | gid_pn->ct.wka_port = &adapter->gs->ds; |
295 | gid_pn->ct.handler = zfcp_fc_ns_handler; | 295 | gid_pn->ct.handler = zfcp_fc_ns_handler; |
296 | gid_pn->ct.handler_data = (unsigned long) &compl_rec; | 296 | gid_pn->ct.handler_data = (unsigned long) &compl_rec; |
@@ -309,12 +309,12 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, | |||
309 | gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS; | 309 | gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS; |
310 | gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN; | 310 | gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN; |
311 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4; | 311 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4; |
312 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; | 312 | gid_pn->ct_iu_req.wwpn = port->wwpn; |
313 | 313 | ||
314 | init_completion(&compl_rec.done); | 314 | init_completion(&compl_rec.done); |
315 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; | 315 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; |
316 | compl_rec.handler_data = (unsigned long) gid_pn; | 316 | compl_rec.handler_data = (unsigned long) gid_pn; |
317 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.erp_req, erp_action); | 317 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.gid_pn_req); |
318 | if (!ret) | 318 | if (!ret) |
319 | wait_for_completion(&compl_rec.done); | 319 | wait_for_completion(&compl_rec.done); |
320 | return ret; | 320 | return ret; |
@@ -322,14 +322,14 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, | |||
322 | 322 | ||
323 | /** | 323 | /** |
324 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | 324 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request |
325 | * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed | 325 | * @port: port where GID_PN request is needed |
326 | * return: -ENOMEM on error, 0 otherwise | 326 | * return: -ENOMEM on error, 0 otherwise |
327 | */ | 327 | */ |
328 | int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | 328 | static int zfcp_fc_ns_gid_pn(struct zfcp_port *port) |
329 | { | 329 | { |
330 | int ret; | 330 | int ret; |
331 | struct zfcp_gid_pn_data *gid_pn; | 331 | struct zfcp_gid_pn_data *gid_pn; |
332 | struct zfcp_adapter *adapter = erp_action->adapter; | 332 | struct zfcp_adapter *adapter = port->adapter; |
333 | 333 | ||
334 | gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC); | 334 | gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC); |
335 | if (!gid_pn) | 335 | if (!gid_pn) |
@@ -341,7 +341,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | |||
341 | if (ret) | 341 | if (ret) |
342 | goto out; | 342 | goto out; |
343 | 343 | ||
344 | ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn); | 344 | ret = zfcp_fc_ns_gid_pn_request(port, gid_pn); |
345 | 345 | ||
346 | zfcp_wka_port_put(&adapter->gs->ds); | 346 | zfcp_wka_port_put(&adapter->gs->ds); |
347 | out: | 347 | out: |
@@ -349,6 +349,29 @@ out: | |||
349 | return ret; | 349 | return ret; |
350 | } | 350 | } |
351 | 351 | ||
352 | void zfcp_fc_port_did_lookup(struct work_struct *work) | ||
353 | { | ||
354 | int ret; | ||
355 | struct zfcp_port *port = container_of(work, struct zfcp_port, | ||
356 | gid_pn_work); | ||
357 | |||
358 | ret = zfcp_fc_ns_gid_pn(port); | ||
359 | if (ret) { | ||
360 | /* could not issue gid_pn for some reason */ | ||
361 | zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1", NULL); | ||
362 | goto out; | ||
363 | } | ||
364 | |||
365 | if (!port->d_id) { | ||
366 | zfcp_erp_port_failed(port, "fcgpn_2", NULL); | ||
367 | goto out; | ||
368 | } | ||
369 | |||
370 | zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL); | ||
371 | out: | ||
372 | zfcp_port_put(port); | ||
373 | } | ||
374 | |||
352 | /** | 375 | /** |
353 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload | 376 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload |
354 | * @port: zfcp_port structure | 377 | * @port: zfcp_port structure |
@@ -551,7 +574,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
551 | 574 | ||
552 | init_completion(&compl_rec.done); | 575 | init_completion(&compl_rec.done); |
553 | compl_rec.handler = NULL; | 576 | compl_rec.handler = NULL; |
554 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); | 577 | ret = zfcp_fsf_send_ct(ct, NULL); |
555 | if (!ret) | 578 | if (!ret) |
556 | wait_for_completion(&compl_rec.done); | 579 | wait_for_completion(&compl_rec.done); |
557 | return ret; | 580 | return ret; |
@@ -840,7 +863,7 @@ int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job) | |||
840 | ct_fc_job->ct.completion = NULL; | 863 | ct_fc_job->ct.completion = NULL; |
841 | ct_fc_job->job = job; | 864 | ct_fc_job->job = job; |
842 | 865 | ||
843 | ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL, NULL); | 866 | ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL); |
844 | if (ret) { | 867 | if (ret) { |
845 | kfree(ct_fc_job); | 868 | kfree(ct_fc_job); |
846 | zfcp_wka_port_put(ct_fc_job->ct.wka_port); | 869 | zfcp_wka_port_put(ct_fc_job->ct.wka_port); |