diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 227 |
1 files changed, 158 insertions, 69 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 56196c98c07b..1a7c80a77ff5 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -39,6 +39,84 @@ struct zfcp_gpn_ft { | |||
39 | struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; | 39 | struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct zfcp_fc_ns_handler_data { | ||
43 | struct completion done; | ||
44 | void (*handler)(unsigned long); | ||
45 | unsigned long handler_data; | ||
46 | }; | ||
47 | |||
48 | static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port) | ||
49 | { | ||
50 | if (mutex_lock_interruptible(&wka_port->mutex)) | ||
51 | return -ERESTARTSYS; | ||
52 | |||
53 | if (wka_port->status != ZFCP_WKA_PORT_ONLINE) { | ||
54 | wka_port->status = ZFCP_WKA_PORT_OPENING; | ||
55 | if (zfcp_fsf_open_wka_port(wka_port)) | ||
56 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
57 | } | ||
58 | |||
59 | mutex_unlock(&wka_port->mutex); | ||
60 | |||
61 | wait_event_timeout( | ||
62 | wka_port->completion_wq, | ||
63 | wka_port->status == ZFCP_WKA_PORT_ONLINE || | ||
64 | wka_port->status == ZFCP_WKA_PORT_OFFLINE, | ||
65 | HZ >> 1); | ||
66 | |||
67 | if (wka_port->status == ZFCP_WKA_PORT_ONLINE) { | ||
68 | atomic_inc(&wka_port->refcount); | ||
69 | return 0; | ||
70 | } | ||
71 | return -EIO; | ||
72 | } | ||
73 | |||
74 | static void zfcp_wka_port_offline(struct work_struct *work) | ||
75 | { | ||
76 | struct delayed_work *dw = container_of(work, struct delayed_work, work); | ||
77 | struct zfcp_wka_port *wka_port = | ||
78 | container_of(dw, struct zfcp_wka_port, work); | ||
79 | |||
80 | wait_event(wka_port->completion_wq, | ||
81 | atomic_read(&wka_port->refcount) == 0); | ||
82 | |||
83 | mutex_lock(&wka_port->mutex); | ||
84 | if ((atomic_read(&wka_port->refcount) != 0) || | ||
85 | (wka_port->status != ZFCP_WKA_PORT_ONLINE)) | ||
86 | goto out; | ||
87 | |||
88 | wka_port->status = ZFCP_WKA_PORT_CLOSING; | ||
89 | if (zfcp_fsf_close_wka_port(wka_port)) { | ||
90 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
91 | wake_up(&wka_port->completion_wq); | ||
92 | } | ||
93 | out: | ||
94 | mutex_unlock(&wka_port->mutex); | ||
95 | } | ||
96 | |||
97 | static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port) | ||
98 | { | ||
99 | if (atomic_dec_return(&wka_port->refcount) != 0) | ||
100 | return; | ||
101 | /* wait 10 miliseconds, other reqs might pop in */ | ||
102 | schedule_delayed_work(&wka_port->work, HZ / 100); | ||
103 | } | ||
104 | |||
105 | void zfcp_fc_nameserver_init(struct zfcp_adapter *adapter) | ||
106 | { | ||
107 | struct zfcp_wka_port *wka_port = &adapter->nsp; | ||
108 | |||
109 | init_waitqueue_head(&wka_port->completion_wq); | ||
110 | |||
111 | wka_port->adapter = adapter; | ||
112 | wka_port->d_id = ZFCP_DID_DIRECTORY_SERVICE; | ||
113 | |||
114 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
115 | atomic_set(&wka_port->refcount, 0); | ||
116 | mutex_init(&wka_port->mutex); | ||
117 | INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline); | ||
118 | } | ||
119 | |||
42 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | 120 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, |
43 | struct fcp_rscn_element *elem) | 121 | struct fcp_rscn_element *elem) |
44 | { | 122 | { |
@@ -47,10 +125,8 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |||
47 | 125 | ||
48 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 126 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
49 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { | 127 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { |
50 | if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) | ||
51 | continue; | ||
52 | /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ | 128 | /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ |
53 | if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) | 129 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID)) |
54 | /* Try to connect to unused ports anyway. */ | 130 | /* Try to connect to unused ports anyway. */ |
55 | zfcp_erp_port_reopen(port, | 131 | zfcp_erp_port_reopen(port, |
56 | ZFCP_STATUS_COMMON_ERP_FAILED, | 132 | ZFCP_STATUS_COMMON_ERP_FAILED, |
@@ -102,7 +178,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) | |||
102 | schedule_work(&fsf_req->adapter->scan_work); | 178 | schedule_work(&fsf_req->adapter->scan_work); |
103 | } | 179 | } |
104 | 180 | ||
105 | static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn) | 181 | static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn) |
106 | { | 182 | { |
107 | struct zfcp_adapter *adapter = req->adapter; | 183 | struct zfcp_adapter *adapter = req->adapter; |
108 | struct zfcp_port *port; | 184 | struct zfcp_port *port; |
@@ -157,7 +233,18 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) | |||
157 | zfcp_fc_incoming_rscn(fsf_req); | 233 | zfcp_fc_incoming_rscn(fsf_req); |
158 | } | 234 | } |
159 | 235 | ||
160 | static void zfcp_ns_gid_pn_handler(unsigned long data) | 236 | static void zfcp_fc_ns_handler(unsigned long data) |
237 | { | ||
238 | struct zfcp_fc_ns_handler_data *compl_rec = | ||
239 | (struct zfcp_fc_ns_handler_data *) data; | ||
240 | |||
241 | if (compl_rec->handler) | ||
242 | compl_rec->handler(compl_rec->handler_data); | ||
243 | |||
244 | complete(&compl_rec->done); | ||
245 | } | ||
246 | |||
247 | static void zfcp_fc_ns_gid_pn_eval(unsigned long data) | ||
161 | { | 248 | { |
162 | struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data; | 249 | struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data; |
163 | struct zfcp_send_ct *ct = &gid_pn->ct; | 250 | struct zfcp_send_ct *ct = &gid_pn->ct; |
@@ -166,43 +253,31 @@ static void zfcp_ns_gid_pn_handler(unsigned long data) | |||
166 | struct zfcp_port *port = gid_pn->port; | 253 | struct zfcp_port *port = gid_pn->port; |
167 | 254 | ||
168 | if (ct->status) | 255 | if (ct->status) |
169 | goto out; | 256 | return; |
170 | if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) { | 257 | if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) { |
171 | atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); | 258 | atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); |
172 | goto out; | 259 | return; |
173 | } | 260 | } |
174 | /* paranoia */ | 261 | /* paranoia */ |
175 | if (ct_iu_req->wwpn != port->wwpn) | 262 | if (ct_iu_req->wwpn != port->wwpn) |
176 | goto out; | 263 | return; |
177 | /* looks like a valid d_id */ | 264 | /* looks like a valid d_id */ |
178 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; | 265 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; |
179 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); | 266 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); |
180 | out: | ||
181 | mempool_free(gid_pn, port->adapter->pool.data_gid_pn); | ||
182 | } | 267 | } |
183 | 268 | ||
184 | /** | 269 | int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, |
185 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | 270 | struct zfcp_gid_pn_data *gid_pn) |
186 | * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed | ||
187 | * return: -ENOMEM on error, 0 otherwise | ||
188 | */ | ||
189 | int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action) | ||
190 | { | 271 | { |
191 | int ret; | ||
192 | struct zfcp_gid_pn_data *gid_pn; | ||
193 | struct zfcp_adapter *adapter = erp_action->adapter; | 272 | struct zfcp_adapter *adapter = erp_action->adapter; |
194 | 273 | struct zfcp_fc_ns_handler_data compl_rec; | |
195 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | 274 | int ret; |
196 | if (!gid_pn) | ||
197 | return -ENOMEM; | ||
198 | |||
199 | memset(gid_pn, 0, sizeof(*gid_pn)); | ||
200 | 275 | ||
201 | /* setup parameters for send generic command */ | 276 | /* setup parameters for send generic command */ |
202 | gid_pn->port = erp_action->port; | 277 | gid_pn->port = erp_action->port; |
203 | gid_pn->ct.port = adapter->nameserver_port; | 278 | gid_pn->ct.wka_port = &adapter->nsp; |
204 | gid_pn->ct.handler = zfcp_ns_gid_pn_handler; | 279 | gid_pn->ct.handler = zfcp_fc_ns_handler; |
205 | gid_pn->ct.handler_data = (unsigned long) gid_pn; | 280 | gid_pn->ct.handler_data = (unsigned long) &compl_rec; |
206 | gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; | 281 | gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; |
207 | gid_pn->ct.req = &gid_pn->req; | 282 | gid_pn->ct.req = &gid_pn->req; |
208 | gid_pn->ct.resp = &gid_pn->resp; | 283 | gid_pn->ct.resp = &gid_pn->resp; |
@@ -222,10 +297,42 @@ int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action) | |||
222 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; | 297 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; |
223 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; | 298 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; |
224 | 299 | ||
300 | init_completion(&compl_rec.done); | ||
301 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; | ||
302 | compl_rec.handler_data = (unsigned long) gid_pn; | ||
225 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, | 303 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, |
226 | erp_action); | 304 | erp_action); |
305 | if (!ret) | ||
306 | wait_for_completion(&compl_rec.done); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | ||
312 | * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed | ||
313 | * return: -ENOMEM on error, 0 otherwise | ||
314 | */ | ||
315 | int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | ||
316 | { | ||
317 | int ret; | ||
318 | struct zfcp_gid_pn_data *gid_pn; | ||
319 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
320 | |||
321 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | ||
322 | if (!gid_pn) | ||
323 | return -ENOMEM; | ||
324 | |||
325 | memset(gid_pn, 0, sizeof(*gid_pn)); | ||
326 | |||
327 | ret = zfcp_wka_port_get(&adapter->nsp); | ||
227 | if (ret) | 328 | if (ret) |
228 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | 329 | goto out; |
330 | |||
331 | ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn); | ||
332 | |||
333 | zfcp_wka_port_put(&adapter->nsp); | ||
334 | out: | ||
335 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | ||
229 | return ret; | 336 | return ret; |
230 | } | 337 | } |
231 | 338 | ||
@@ -255,14 +362,14 @@ struct zfcp_els_adisc { | |||
255 | struct scatterlist req; | 362 | struct scatterlist req; |
256 | struct scatterlist resp; | 363 | struct scatterlist resp; |
257 | struct zfcp_ls_adisc ls_adisc; | 364 | struct zfcp_ls_adisc ls_adisc; |
258 | struct zfcp_ls_adisc_acc ls_adisc_acc; | 365 | struct zfcp_ls_adisc ls_adisc_acc; |
259 | }; | 366 | }; |
260 | 367 | ||
261 | static void zfcp_fc_adisc_handler(unsigned long data) | 368 | static void zfcp_fc_adisc_handler(unsigned long data) |
262 | { | 369 | { |
263 | struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data; | 370 | struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data; |
264 | struct zfcp_port *port = adisc->els.port; | 371 | struct zfcp_port *port = adisc->els.port; |
265 | struct zfcp_ls_adisc_acc *ls_adisc = &adisc->ls_adisc_acc; | 372 | struct zfcp_ls_adisc *ls_adisc = &adisc->ls_adisc_acc; |
266 | 373 | ||
267 | if (adisc->els.status) { | 374 | if (adisc->els.status) { |
268 | /* request rejected or timed out */ | 375 | /* request rejected or timed out */ |
@@ -295,7 +402,7 @@ static int zfcp_fc_adisc(struct zfcp_port *port) | |||
295 | sg_init_one(adisc->els.req, &adisc->ls_adisc, | 402 | sg_init_one(adisc->els.req, &adisc->ls_adisc, |
296 | sizeof(struct zfcp_ls_adisc)); | 403 | sizeof(struct zfcp_ls_adisc)); |
297 | sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc, | 404 | sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc, |
298 | sizeof(struct zfcp_ls_adisc_acc)); | 405 | sizeof(struct zfcp_ls_adisc)); |
299 | 406 | ||
300 | adisc->els.req_count = 1; | 407 | adisc->els.req_count = 1; |
301 | adisc->els.resp_count = 1; | 408 | adisc->els.resp_count = 1; |
@@ -338,30 +445,6 @@ void zfcp_test_link(struct zfcp_port *port) | |||
338 | zfcp_erp_port_forced_reopen(port, 0, 65, NULL); | 445 | zfcp_erp_port_forced_reopen(port, 0, 65, NULL); |
339 | } | 446 | } |
340 | 447 | ||
341 | static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) | ||
342 | { | ||
343 | int ret; | ||
344 | |||
345 | if (!adapter->nameserver_port) | ||
346 | return -EINTR; | ||
347 | |||
348 | if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, | ||
349 | &adapter->nameserver_port->status)) { | ||
350 | ret = zfcp_erp_port_reopen(adapter->nameserver_port, 0, 148, | ||
351 | NULL); | ||
352 | if (ret) | ||
353 | return ret; | ||
354 | zfcp_erp_wait(adapter); | ||
355 | } | ||
356 | return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, | ||
357 | &adapter->nameserver_port->status); | ||
358 | } | ||
359 | |||
360 | static void zfcp_gpn_ft_handler(unsigned long _done) | ||
361 | { | ||
362 | complete((struct completion *)_done); | ||
363 | } | ||
364 | |||
365 | static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) | 448 | static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) |
366 | { | 449 | { |
367 | struct scatterlist *sg = &gpn_ft->sg_req; | 450 | struct scatterlist *sg = &gpn_ft->sg_req; |
@@ -403,7 +486,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
403 | { | 486 | { |
404 | struct zfcp_send_ct *ct = &gpn_ft->ct; | 487 | struct zfcp_send_ct *ct = &gpn_ft->ct; |
405 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); | 488 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); |
406 | struct completion done; | 489 | struct zfcp_fc_ns_handler_data compl_rec; |
407 | int ret; | 490 | int ret; |
408 | 491 | ||
409 | /* prepare CT IU for GPN_FT */ | 492 | /* prepare CT IU for GPN_FT */ |
@@ -420,19 +503,20 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
420 | req->fc4_type = ZFCP_CT_SCSI_FCP; | 503 | req->fc4_type = ZFCP_CT_SCSI_FCP; |
421 | 504 | ||
422 | /* prepare zfcp_send_ct */ | 505 | /* prepare zfcp_send_ct */ |
423 | ct->port = adapter->nameserver_port; | 506 | ct->wka_port = &adapter->nsp; |
424 | ct->handler = zfcp_gpn_ft_handler; | 507 | ct->handler = zfcp_fc_ns_handler; |
425 | ct->handler_data = (unsigned long)&done; | 508 | ct->handler_data = (unsigned long)&compl_rec; |
426 | ct->timeout = 10; | 509 | ct->timeout = 10; |
427 | ct->req = &gpn_ft->sg_req; | 510 | ct->req = &gpn_ft->sg_req; |
428 | ct->resp = gpn_ft->sg_resp; | 511 | ct->resp = gpn_ft->sg_resp; |
429 | ct->req_count = 1; | 512 | ct->req_count = 1; |
430 | ct->resp_count = ZFCP_GPN_FT_BUFFERS; | 513 | ct->resp_count = ZFCP_GPN_FT_BUFFERS; |
431 | 514 | ||
432 | init_completion(&done); | 515 | init_completion(&compl_rec.done); |
516 | compl_rec.handler = NULL; | ||
433 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); | 517 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); |
434 | if (!ret) | 518 | if (!ret) |
435 | wait_for_completion(&done); | 519 | wait_for_completion(&compl_rec.done); |
436 | return ret; | 520 | return ret; |
437 | } | 521 | } |
438 | 522 | ||
@@ -442,9 +526,8 @@ static void zfcp_validate_port(struct zfcp_port *port) | |||
442 | 526 | ||
443 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); | 527 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); |
444 | 528 | ||
445 | if (port == adapter->nameserver_port) | 529 | if ((port->supported_classes != 0) || |
446 | return; | 530 | !list_empty(&port->unit_list_head)) { |
447 | if ((port->supported_classes != 0) || (port->units != 0)) { | ||
448 | zfcp_port_put(port); | 531 | zfcp_port_put(port); |
449 | return; | 532 | return; |
450 | } | 533 | } |
@@ -460,7 +543,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) | |||
460 | struct scatterlist *sg = gpn_ft->sg_resp; | 543 | struct scatterlist *sg = gpn_ft->sg_resp; |
461 | struct ct_hdr *hdr = sg_virt(sg); | 544 | struct ct_hdr *hdr = sg_virt(sg); |
462 | struct gpn_ft_resp_acc *acc = sg_virt(sg); | 545 | struct gpn_ft_resp_acc *acc = sg_virt(sg); |
463 | struct zfcp_adapter *adapter = ct->port->adapter; | 546 | struct zfcp_adapter *adapter = ct->wka_port->adapter; |
464 | struct zfcp_port *port, *tmp; | 547 | struct zfcp_port *port, *tmp; |
465 | u32 d_id; | 548 | u32 d_id; |
466 | int ret = 0, x, last = 0; | 549 | int ret = 0, x, last = 0; |
@@ -490,6 +573,9 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) | |||
490 | d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | | 573 | d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | |
491 | acc->port_id[2]; | 574 | acc->port_id[2]; |
492 | 575 | ||
576 | /* don't attach ports with a well known address */ | ||
577 | if ((d_id & ZFCP_DID_WKA) == ZFCP_DID_WKA) | ||
578 | continue; | ||
493 | /* skip the adapter's port and known remote ports */ | 579 | /* skip the adapter's port and known remote ports */ |
494 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) | 580 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) |
495 | continue; | 581 | continue; |
@@ -528,13 +614,15 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
528 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) | 614 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) |
529 | return 0; | 615 | return 0; |
530 | 616 | ||
531 | ret = zfcp_scan_get_nameserver(adapter); | 617 | ret = zfcp_wka_port_get(&adapter->nsp); |
532 | if (ret) | 618 | if (ret) |
533 | return ret; | 619 | return ret; |
534 | 620 | ||
535 | gpn_ft = zfcp_alloc_sg_env(); | 621 | gpn_ft = zfcp_alloc_sg_env(); |
536 | if (!gpn_ft) | 622 | if (!gpn_ft) { |
537 | return -ENOMEM; | 623 | ret = -ENOMEM; |
624 | goto out; | ||
625 | } | ||
538 | 626 | ||
539 | for (i = 0; i < 3; i++) { | 627 | for (i = 0; i < 3; i++) { |
540 | ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); | 628 | ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); |
@@ -547,7 +635,8 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
547 | } | 635 | } |
548 | } | 636 | } |
549 | zfcp_free_sg_env(gpn_ft); | 637 | zfcp_free_sg_env(gpn_ft); |
550 | 638 | out: | |
639 | zfcp_wka_port_put(&adapter->nsp); | ||
551 | return ret; | 640 | return ret; |
552 | } | 641 | } |
553 | 642 | ||