diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 176 |
1 files changed, 109 insertions, 67 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 47daebfa7e59..722f22de8753 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -25,14 +25,6 @@ static u32 rscn_range_mask[] = { | |||
25 | [RSCN_FABRIC_ADDRESS] = 0x000000, | 25 | [RSCN_FABRIC_ADDRESS] = 0x000000, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | struct ct_iu_gpn_ft_req { | ||
29 | struct ct_hdr header; | ||
30 | u8 flags; | ||
31 | u8 domain_id_scope; | ||
32 | u8 area_id_scope; | ||
33 | u8 fc4_type; | ||
34 | } __attribute__ ((packed)); | ||
35 | |||
36 | struct gpn_ft_resp_acc { | 28 | struct gpn_ft_resp_acc { |
37 | u8 control; | 29 | u8 control; |
38 | u8 port_id[3]; | 30 | u8 port_id[3]; |
@@ -65,7 +57,7 @@ struct zfcp_fc_ns_handler_data { | |||
65 | unsigned long handler_data; | 57 | unsigned long handler_data; |
66 | }; | 58 | }; |
67 | 59 | ||
68 | static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port) | 60 | static int zfcp_fc_wka_port_get(struct zfcp_wka_port *wka_port) |
69 | { | 61 | { |
70 | if (mutex_lock_interruptible(&wka_port->mutex)) | 62 | if (mutex_lock_interruptible(&wka_port->mutex)) |
71 | return -ERESTARTSYS; | 63 | return -ERESTARTSYS; |
@@ -90,7 +82,7 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port) | |||
90 | return -EIO; | 82 | return -EIO; |
91 | } | 83 | } |
92 | 84 | ||
93 | static void zfcp_wka_port_offline(struct work_struct *work) | 85 | static void zfcp_fc_wka_port_offline(struct work_struct *work) |
94 | { | 86 | { |
95 | struct delayed_work *dw = to_delayed_work(work); | 87 | struct delayed_work *dw = to_delayed_work(work); |
96 | struct zfcp_wka_port *wka_port = | 88 | struct zfcp_wka_port *wka_port = |
@@ -110,7 +102,7 @@ out: | |||
110 | mutex_unlock(&wka_port->mutex); | 102 | mutex_unlock(&wka_port->mutex); |
111 | } | 103 | } |
112 | 104 | ||
113 | static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port) | 105 | static void zfcp_fc_wka_port_put(struct zfcp_wka_port *wka_port) |
114 | { | 106 | { |
115 | if (atomic_dec_return(&wka_port->refcount) != 0) | 107 | if (atomic_dec_return(&wka_port->refcount) != 0) |
116 | return; | 108 | return; |
@@ -129,10 +121,10 @@ static void zfcp_fc_wka_port_init(struct zfcp_wka_port *wka_port, u32 d_id, | |||
129 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | 121 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; |
130 | atomic_set(&wka_port->refcount, 0); | 122 | atomic_set(&wka_port->refcount, 0); |
131 | mutex_init(&wka_port->mutex); | 123 | mutex_init(&wka_port->mutex); |
132 | INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline); | 124 | INIT_DELAYED_WORK(&wka_port->work, zfcp_fc_wka_port_offline); |
133 | } | 125 | } |
134 | 126 | ||
135 | void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka) | 127 | static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka) |
136 | { | 128 | { |
137 | cancel_delayed_work_sync(&wka->work); | 129 | cancel_delayed_work_sync(&wka->work); |
138 | mutex_lock(&wka->mutex); | 130 | mutex_lock(&wka->mutex); |
@@ -140,15 +132,13 @@ void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka) | |||
140 | mutex_unlock(&wka->mutex); | 132 | mutex_unlock(&wka->mutex); |
141 | } | 133 | } |
142 | 134 | ||
143 | void zfcp_fc_wka_ports_init(struct zfcp_adapter *adapter) | 135 | void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs) |
144 | { | 136 | { |
145 | struct zfcp_wka_ports *gs = adapter->gs; | 137 | zfcp_fc_wka_port_force_offline(&gs->ms); |
146 | 138 | zfcp_fc_wka_port_force_offline(&gs->ts); | |
147 | zfcp_fc_wka_port_init(&gs->ms, FC_FID_MGMT_SERV, adapter); | 139 | zfcp_fc_wka_port_force_offline(&gs->ds); |
148 | zfcp_fc_wka_port_init(&gs->ts, FC_FID_TIME_SERV, adapter); | 140 | zfcp_fc_wka_port_force_offline(&gs->as); |
149 | zfcp_fc_wka_port_init(&gs->ds, FC_FID_DIR_SERV, adapter); | 141 | zfcp_fc_wka_port_force_offline(&gs->ks); |
150 | zfcp_fc_wka_port_init(&gs->as, FC_FID_ALIASES, adapter); | ||
151 | zfcp_fc_wka_port_init(&gs->ks, FC_FID_SEC_KEY, adapter); | ||
152 | } | 142 | } |
153 | 143 | ||
154 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | 144 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, |
@@ -160,7 +150,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |||
160 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 150 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
161 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { | 151 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { |
162 | if ((port->d_id & range) == (elem->nport_did & range)) | 152 | if ((port->d_id & range) == (elem->nport_did & range)) |
163 | zfcp_test_link(port); | 153 | zfcp_fc_test_link(port); |
164 | if (!port->d_id) | 154 | if (!port->d_id) |
165 | zfcp_erp_port_reopen(port, | 155 | zfcp_erp_port_reopen(port, |
166 | ZFCP_STATUS_COMMON_ERP_FAILED, | 156 | ZFCP_STATUS_COMMON_ERP_FAILED, |
@@ -241,7 +231,7 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) | |||
241 | (struct fsf_status_read_buffer *) fsf_req->data; | 231 | (struct fsf_status_read_buffer *) fsf_req->data; |
242 | unsigned int els_type = status_buffer->payload.data[0]; | 232 | unsigned int els_type = status_buffer->payload.data[0]; |
243 | 233 | ||
244 | zfcp_san_dbf_event_incoming_els(fsf_req); | 234 | zfcp_dbf_san_incoming_els(fsf_req); |
245 | if (els_type == LS_PLOGI) | 235 | if (els_type == LS_PLOGI) |
246 | zfcp_fc_incoming_plogi(fsf_req); | 236 | zfcp_fc_incoming_plogi(fsf_req); |
247 | else if (els_type == LS_LOGO) | 237 | else if (els_type == LS_LOGO) |
@@ -281,19 +271,18 @@ static void zfcp_fc_ns_gid_pn_eval(unsigned long data) | |||
281 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; | 271 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; |
282 | } | 272 | } |
283 | 273 | ||
284 | int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, | 274 | static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, |
285 | struct zfcp_gid_pn_data *gid_pn) | 275 | struct zfcp_gid_pn_data *gid_pn) |
286 | { | 276 | { |
287 | struct zfcp_adapter *adapter = erp_action->adapter; | 277 | struct zfcp_adapter *adapter = port->adapter; |
288 | struct zfcp_fc_ns_handler_data compl_rec; | 278 | struct zfcp_fc_ns_handler_data compl_rec; |
289 | int ret; | 279 | int ret; |
290 | 280 | ||
291 | /* setup parameters for send generic command */ | 281 | /* setup parameters for send generic command */ |
292 | gid_pn->port = erp_action->port; | 282 | gid_pn->port = port; |
293 | gid_pn->ct.wka_port = &adapter->gs->ds; | 283 | gid_pn->ct.wka_port = &adapter->gs->ds; |
294 | gid_pn->ct.handler = zfcp_fc_ns_handler; | 284 | gid_pn->ct.handler = zfcp_fc_ns_handler; |
295 | gid_pn->ct.handler_data = (unsigned long) &compl_rec; | 285 | gid_pn->ct.handler_data = (unsigned long) &compl_rec; |
296 | gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; | ||
297 | gid_pn->ct.req = &gid_pn->req; | 286 | gid_pn->ct.req = &gid_pn->req; |
298 | gid_pn->ct.resp = &gid_pn->resp; | 287 | gid_pn->ct.resp = &gid_pn->resp; |
299 | sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req, | 288 | sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req, |
@@ -308,13 +297,12 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, | |||
308 | gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS; | 297 | gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS; |
309 | gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN; | 298 | gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN; |
310 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4; | 299 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4; |
311 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; | 300 | gid_pn->ct_iu_req.wwpn = port->wwpn; |
312 | 301 | ||
313 | init_completion(&compl_rec.done); | 302 | init_completion(&compl_rec.done); |
314 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; | 303 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; |
315 | compl_rec.handler_data = (unsigned long) gid_pn; | 304 | compl_rec.handler_data = (unsigned long) gid_pn; |
316 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, | 305 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.gid_pn_req); |
317 | erp_action); | ||
318 | if (!ret) | 306 | if (!ret) |
319 | wait_for_completion(&compl_rec.done); | 307 | wait_for_completion(&compl_rec.done); |
320 | return ret; | 308 | return ret; |
@@ -322,33 +310,56 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, | |||
322 | 310 | ||
323 | /** | 311 | /** |
324 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | 312 | * 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 | 313 | * @port: port where GID_PN request is needed |
326 | * return: -ENOMEM on error, 0 otherwise | 314 | * return: -ENOMEM on error, 0 otherwise |
327 | */ | 315 | */ |
328 | int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | 316 | static int zfcp_fc_ns_gid_pn(struct zfcp_port *port) |
329 | { | 317 | { |
330 | int ret; | 318 | int ret; |
331 | struct zfcp_gid_pn_data *gid_pn; | 319 | struct zfcp_gid_pn_data *gid_pn; |
332 | struct zfcp_adapter *adapter = erp_action->adapter; | 320 | struct zfcp_adapter *adapter = port->adapter; |
333 | 321 | ||
334 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | 322 | gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC); |
335 | if (!gid_pn) | 323 | if (!gid_pn) |
336 | return -ENOMEM; | 324 | return -ENOMEM; |
337 | 325 | ||
338 | memset(gid_pn, 0, sizeof(*gid_pn)); | 326 | memset(gid_pn, 0, sizeof(*gid_pn)); |
339 | 327 | ||
340 | ret = zfcp_wka_port_get(&adapter->gs->ds); | 328 | ret = zfcp_fc_wka_port_get(&adapter->gs->ds); |
341 | if (ret) | 329 | if (ret) |
342 | goto out; | 330 | goto out; |
343 | 331 | ||
344 | ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn); | 332 | ret = zfcp_fc_ns_gid_pn_request(port, gid_pn); |
345 | 333 | ||
346 | zfcp_wka_port_put(&adapter->gs->ds); | 334 | zfcp_fc_wka_port_put(&adapter->gs->ds); |
347 | out: | 335 | out: |
348 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | 336 | mempool_free(gid_pn, adapter->pool.gid_pn_data); |
349 | return ret; | 337 | return ret; |
350 | } | 338 | } |
351 | 339 | ||
340 | void zfcp_fc_port_did_lookup(struct work_struct *work) | ||
341 | { | ||
342 | int ret; | ||
343 | struct zfcp_port *port = container_of(work, struct zfcp_port, | ||
344 | gid_pn_work); | ||
345 | |||
346 | ret = zfcp_fc_ns_gid_pn(port); | ||
347 | if (ret) { | ||
348 | /* could not issue gid_pn for some reason */ | ||
349 | zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1", NULL); | ||
350 | goto out; | ||
351 | } | ||
352 | |||
353 | if (!port->d_id) { | ||
354 | zfcp_erp_port_failed(port, "fcgpn_2", NULL); | ||
355 | goto out; | ||
356 | } | ||
357 | |||
358 | zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL); | ||
359 | out: | ||
360 | zfcp_port_put(port); | ||
361 | } | ||
362 | |||
352 | /** | 363 | /** |
353 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload | 364 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload |
354 | * @port: zfcp_port structure | 365 | * @port: zfcp_port structure |
@@ -404,6 +415,7 @@ static void zfcp_fc_adisc_handler(unsigned long data) | |||
404 | /* port is good, unblock rport without going through erp */ | 415 | /* port is good, unblock rport without going through erp */ |
405 | zfcp_scsi_schedule_rport_register(port); | 416 | zfcp_scsi_schedule_rport_register(port); |
406 | out: | 417 | out: |
418 | atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); | ||
407 | zfcp_port_put(port); | 419 | zfcp_port_put(port); |
408 | kfree(adisc); | 420 | kfree(adisc); |
409 | } | 421 | } |
@@ -450,28 +462,36 @@ void zfcp_fc_link_test_work(struct work_struct *work) | |||
450 | port->rport_task = RPORT_DEL; | 462 | port->rport_task = RPORT_DEL; |
451 | zfcp_scsi_rport_work(&port->rport_work); | 463 | zfcp_scsi_rport_work(&port->rport_work); |
452 | 464 | ||
465 | /* only issue one test command at one time per port */ | ||
466 | if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) | ||
467 | goto out; | ||
468 | |||
469 | atomic_set_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); | ||
470 | |||
453 | retval = zfcp_fc_adisc(port); | 471 | retval = zfcp_fc_adisc(port); |
454 | if (retval == 0) | 472 | if (retval == 0) |
455 | return; | 473 | return; |
456 | 474 | ||
457 | /* send of ADISC was not possible */ | 475 | /* send of ADISC was not possible */ |
476 | atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); | ||
458 | zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL); | 477 | zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL); |
459 | 478 | ||
479 | out: | ||
460 | zfcp_port_put(port); | 480 | zfcp_port_put(port); |
461 | } | 481 | } |
462 | 482 | ||
463 | /** | 483 | /** |
464 | * zfcp_test_link - lightweight link test procedure | 484 | * zfcp_fc_test_link - lightweight link test procedure |
465 | * @port: port to be tested | 485 | * @port: port to be tested |
466 | * | 486 | * |
467 | * Test status of a link to a remote port using the ELS command ADISC. | 487 | * Test status of a link to a remote port using the ELS command ADISC. |
468 | * If there is a problem with the remote port, error recovery steps | 488 | * If there is a problem with the remote port, error recovery steps |
469 | * will be triggered. | 489 | * will be triggered. |
470 | */ | 490 | */ |
471 | void zfcp_test_link(struct zfcp_port *port) | 491 | void zfcp_fc_test_link(struct zfcp_port *port) |
472 | { | 492 | { |
473 | zfcp_port_get(port); | 493 | zfcp_port_get(port); |
474 | if (!queue_work(zfcp_data.work_queue, &port->test_link_work)) | 494 | if (!queue_work(port->adapter->work_queue, &port->test_link_work)) |
475 | zfcp_port_put(port); | 495 | zfcp_port_put(port); |
476 | } | 496 | } |
477 | 497 | ||
@@ -479,7 +499,7 @@ static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num) | |||
479 | { | 499 | { |
480 | struct scatterlist *sg = &gpn_ft->sg_req; | 500 | struct scatterlist *sg = &gpn_ft->sg_req; |
481 | 501 | ||
482 | kfree(sg_virt(sg)); /* free request buffer */ | 502 | kmem_cache_free(zfcp_data.gpn_ft_cache, sg_virt(sg)); |
483 | zfcp_sg_free_table(gpn_ft->sg_resp, buf_num); | 503 | zfcp_sg_free_table(gpn_ft->sg_resp, buf_num); |
484 | 504 | ||
485 | kfree(gpn_ft); | 505 | kfree(gpn_ft); |
@@ -494,7 +514,7 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num) | |||
494 | if (!gpn_ft) | 514 | if (!gpn_ft) |
495 | return NULL; | 515 | return NULL; |
496 | 516 | ||
497 | req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL); | 517 | req = kmem_cache_alloc(zfcp_data.gpn_ft_cache, GFP_KERNEL); |
498 | if (!req) { | 518 | if (!req) { |
499 | kfree(gpn_ft); | 519 | kfree(gpn_ft); |
500 | gpn_ft = NULL; | 520 | gpn_ft = NULL; |
@@ -511,9 +531,8 @@ out: | |||
511 | } | 531 | } |
512 | 532 | ||
513 | 533 | ||
514 | static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | 534 | static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft, |
515 | struct zfcp_adapter *adapter, | 535 | struct zfcp_adapter *adapter, int max_bytes) |
516 | int max_bytes) | ||
517 | { | 536 | { |
518 | struct zfcp_send_ct *ct = &gpn_ft->ct; | 537 | struct zfcp_send_ct *ct = &gpn_ft->ct; |
519 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); | 538 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); |
@@ -536,19 +555,18 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
536 | ct->wka_port = &adapter->gs->ds; | 555 | ct->wka_port = &adapter->gs->ds; |
537 | ct->handler = zfcp_fc_ns_handler; | 556 | ct->handler = zfcp_fc_ns_handler; |
538 | ct->handler_data = (unsigned long)&compl_rec; | 557 | ct->handler_data = (unsigned long)&compl_rec; |
539 | ct->timeout = 10; | ||
540 | ct->req = &gpn_ft->sg_req; | 558 | ct->req = &gpn_ft->sg_req; |
541 | ct->resp = gpn_ft->sg_resp; | 559 | ct->resp = gpn_ft->sg_resp; |
542 | 560 | ||
543 | init_completion(&compl_rec.done); | 561 | init_completion(&compl_rec.done); |
544 | compl_rec.handler = NULL; | 562 | compl_rec.handler = NULL; |
545 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); | 563 | ret = zfcp_fsf_send_ct(ct, NULL); |
546 | if (!ret) | 564 | if (!ret) |
547 | wait_for_completion(&compl_rec.done); | 565 | wait_for_completion(&compl_rec.done); |
548 | return ret; | 566 | return ret; |
549 | } | 567 | } |
550 | 568 | ||
551 | static void zfcp_validate_port(struct zfcp_port *port) | 569 | static void zfcp_fc_validate_port(struct zfcp_port *port) |
552 | { | 570 | { |
553 | struct zfcp_adapter *adapter = port->adapter; | 571 | struct zfcp_adapter *adapter = port->adapter; |
554 | 572 | ||
@@ -568,7 +586,7 @@ static void zfcp_validate_port(struct zfcp_port *port) | |||
568 | zfcp_port_dequeue(port); | 586 | zfcp_port_dequeue(port); |
569 | } | 587 | } |
570 | 588 | ||
571 | static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries) | 589 | static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries) |
572 | { | 590 | { |
573 | struct zfcp_send_ct *ct = &gpn_ft->ct; | 591 | struct zfcp_send_ct *ct = &gpn_ft->ct; |
574 | struct scatterlist *sg = gpn_ft->sg_resp; | 592 | struct scatterlist *sg = gpn_ft->sg_resp; |
@@ -595,7 +613,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries) | |||
595 | return -E2BIG; | 613 | return -E2BIG; |
596 | } | 614 | } |
597 | 615 | ||
598 | down(&zfcp_data.config_sema); | 616 | mutex_lock(&zfcp_data.config_mutex); |
599 | 617 | ||
600 | /* first entry is the header */ | 618 | /* first entry is the header */ |
601 | for (x = 1; x < max_entries && !last; x++) { | 619 | for (x = 1; x < max_entries && !last; x++) { |
@@ -628,16 +646,16 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries) | |||
628 | 646 | ||
629 | zfcp_erp_wait(adapter); | 647 | zfcp_erp_wait(adapter); |
630 | list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list) | 648 | list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list) |
631 | zfcp_validate_port(port); | 649 | zfcp_fc_validate_port(port); |
632 | up(&zfcp_data.config_sema); | 650 | mutex_unlock(&zfcp_data.config_mutex); |
633 | return ret; | 651 | return ret; |
634 | } | 652 | } |
635 | 653 | ||
636 | /** | 654 | /** |
637 | * zfcp_scan_ports - scan remote ports and attach new ports | 655 | * zfcp_fc_scan_ports - scan remote ports and attach new ports |
638 | * @adapter: pointer to struct zfcp_adapter | 656 | * @adapter: pointer to struct zfcp_adapter |
639 | */ | 657 | */ |
640 | int zfcp_scan_ports(struct zfcp_adapter *adapter) | 658 | int zfcp_fc_scan_ports(struct zfcp_adapter *adapter) |
641 | { | 659 | { |
642 | int ret, i; | 660 | int ret, i; |
643 | struct zfcp_gpn_ft *gpn_ft; | 661 | struct zfcp_gpn_ft *gpn_ft; |
@@ -652,7 +670,7 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
652 | fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV) | 670 | fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV) |
653 | return 0; | 671 | return 0; |
654 | 672 | ||
655 | ret = zfcp_wka_port_get(&adapter->gs->ds); | 673 | ret = zfcp_fc_wka_port_get(&adapter->gs->ds); |
656 | if (ret) | 674 | if (ret) |
657 | return ret; | 675 | return ret; |
658 | 676 | ||
@@ -663,9 +681,9 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
663 | } | 681 | } |
664 | 682 | ||
665 | for (i = 0; i < 3; i++) { | 683 | for (i = 0; i < 3; i++) { |
666 | ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter, max_bytes); | 684 | ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes); |
667 | if (!ret) { | 685 | if (!ret) { |
668 | ret = zfcp_scan_eval_gpn_ft(gpn_ft, max_entries); | 686 | ret = zfcp_fc_eval_gpn_ft(gpn_ft, max_entries); |
669 | if (ret == -EAGAIN) | 687 | if (ret == -EAGAIN) |
670 | ssleep(1); | 688 | ssleep(1); |
671 | else | 689 | else |
@@ -674,14 +692,14 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
674 | } | 692 | } |
675 | zfcp_free_sg_env(gpn_ft, buf_num); | 693 | zfcp_free_sg_env(gpn_ft, buf_num); |
676 | out: | 694 | out: |
677 | zfcp_wka_port_put(&adapter->gs->ds); | 695 | zfcp_fc_wka_port_put(&adapter->gs->ds); |
678 | return ret; | 696 | return ret; |
679 | } | 697 | } |
680 | 698 | ||
681 | 699 | ||
682 | void _zfcp_scan_ports_later(struct work_struct *work) | 700 | void _zfcp_fc_scan_ports_later(struct work_struct *work) |
683 | { | 701 | { |
684 | zfcp_scan_ports(container_of(work, struct zfcp_adapter, scan_work)); | 702 | zfcp_fc_scan_ports(container_of(work, struct zfcp_adapter, scan_work)); |
685 | } | 703 | } |
686 | 704 | ||
687 | struct zfcp_els_fc_job { | 705 | struct zfcp_els_fc_job { |
@@ -732,7 +750,7 @@ int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job) | |||
732 | els_fc_job->els.adapter = adapter; | 750 | els_fc_job->els.adapter = adapter; |
733 | if (rport) { | 751 | if (rport) { |
734 | read_lock_irq(&zfcp_data.config_lock); | 752 | read_lock_irq(&zfcp_data.config_lock); |
735 | port = rport->dd_data; | 753 | port = zfcp_get_port_by_wwpn(adapter, rport->port_name); |
736 | if (port) | 754 | if (port) |
737 | els_fc_job->els.d_id = port->d_id; | 755 | els_fc_job->els.d_id = port->d_id; |
738 | read_unlock_irq(&zfcp_data.config_lock); | 756 | read_unlock_irq(&zfcp_data.config_lock); |
@@ -771,7 +789,7 @@ static void zfcp_fc_generic_ct_handler(unsigned long data) | |||
771 | job->state_flags = FC_RQST_STATE_DONE; | 789 | job->state_flags = FC_RQST_STATE_DONE; |
772 | job->job_done(job); | 790 | job->job_done(job); |
773 | 791 | ||
774 | zfcp_wka_port_put(ct_fc_job->ct.wka_port); | 792 | zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port); |
775 | 793 | ||
776 | kfree(ct_fc_job); | 794 | kfree(ct_fc_job); |
777 | } | 795 | } |
@@ -817,7 +835,7 @@ int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job) | |||
817 | return -EINVAL; /* no such service */ | 835 | return -EINVAL; /* no such service */ |
818 | } | 836 | } |
819 | 837 | ||
820 | ret = zfcp_wka_port_get(ct_fc_job->ct.wka_port); | 838 | ret = zfcp_fc_wka_port_get(ct_fc_job->ct.wka_port); |
821 | if (ret) { | 839 | if (ret) { |
822 | kfree(ct_fc_job); | 840 | kfree(ct_fc_job); |
823 | return ret; | 841 | return ret; |
@@ -825,16 +843,40 @@ int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job) | |||
825 | 843 | ||
826 | ct_fc_job->ct.req = job->request_payload.sg_list; | 844 | ct_fc_job->ct.req = job->request_payload.sg_list; |
827 | ct_fc_job->ct.resp = job->reply_payload.sg_list; | 845 | ct_fc_job->ct.resp = job->reply_payload.sg_list; |
828 | ct_fc_job->ct.timeout = ZFCP_FSF_REQUEST_TIMEOUT; | ||
829 | ct_fc_job->ct.handler = zfcp_fc_generic_ct_handler; | 846 | ct_fc_job->ct.handler = zfcp_fc_generic_ct_handler; |
830 | ct_fc_job->ct.handler_data = (unsigned long) ct_fc_job; | 847 | ct_fc_job->ct.handler_data = (unsigned long) ct_fc_job; |
831 | ct_fc_job->ct.completion = NULL; | 848 | ct_fc_job->ct.completion = NULL; |
832 | ct_fc_job->job = job; | 849 | ct_fc_job->job = job; |
833 | 850 | ||
834 | ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL, NULL); | 851 | ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL); |
835 | if (ret) { | 852 | if (ret) { |
836 | kfree(ct_fc_job); | 853 | kfree(ct_fc_job); |
837 | zfcp_wka_port_put(ct_fc_job->ct.wka_port); | 854 | zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port); |
838 | } | 855 | } |
839 | return ret; | 856 | return ret; |
840 | } | 857 | } |
858 | |||
859 | int zfcp_fc_gs_setup(struct zfcp_adapter *adapter) | ||
860 | { | ||
861 | struct zfcp_wka_ports *wka_ports; | ||
862 | |||
863 | wka_ports = kzalloc(sizeof(struct zfcp_wka_ports), GFP_KERNEL); | ||
864 | if (!wka_ports) | ||
865 | return -ENOMEM; | ||
866 | |||
867 | adapter->gs = wka_ports; | ||
868 | zfcp_fc_wka_port_init(&wka_ports->ms, FC_FID_MGMT_SERV, adapter); | ||
869 | zfcp_fc_wka_port_init(&wka_ports->ts, FC_FID_TIME_SERV, adapter); | ||
870 | zfcp_fc_wka_port_init(&wka_ports->ds, FC_FID_DIR_SERV, adapter); | ||
871 | zfcp_fc_wka_port_init(&wka_ports->as, FC_FID_ALIASES, adapter); | ||
872 | zfcp_fc_wka_port_init(&wka_ports->ks, FC_FID_SEC_KEY, adapter); | ||
873 | |||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | void zfcp_fc_gs_destroy(struct zfcp_adapter *adapter) | ||
878 | { | ||
879 | kfree(adapter->gs); | ||
880 | adapter->gs = NULL; | ||
881 | } | ||
882 | |||