diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 80 |
1 files changed, 39 insertions, 41 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index e020dec85294..982455603349 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -262,24 +262,18 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) | |||
262 | zfcp_fc_incoming_rscn(fsf_req); | 262 | zfcp_fc_incoming_rscn(fsf_req); |
263 | } | 263 | } |
264 | 264 | ||
265 | static void zfcp_fc_ns_gid_pn_eval(void *data) | 265 | static void zfcp_fc_ns_gid_pn_eval(struct zfcp_fc_req *fc_req) |
266 | { | 266 | { |
267 | struct zfcp_fc_gid_pn *gid_pn = data; | 267 | struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els; |
268 | struct zfcp_fsf_ct_els *ct = &gid_pn->ct; | 268 | struct zfcp_fc_gid_pn_rsp *gid_pn_rsp = &fc_req->u.gid_pn.rsp; |
269 | struct zfcp_fc_gid_pn_req *gid_pn_req = sg_virt(ct->req); | ||
270 | struct zfcp_fc_gid_pn_resp *gid_pn_resp = sg_virt(ct->resp); | ||
271 | struct zfcp_port *port = gid_pn->port; | ||
272 | 269 | ||
273 | if (ct->status) | 270 | if (ct_els->status) |
274 | return; | 271 | return; |
275 | if (gid_pn_resp->ct_hdr.ct_cmd != FC_FS_ACC) | 272 | if (gid_pn_rsp->ct_hdr.ct_cmd != FC_FS_ACC) |
276 | return; | 273 | return; |
277 | 274 | ||
278 | /* paranoia */ | ||
279 | if (gid_pn_req->gid_pn.fn_wwpn != port->wwpn) | ||
280 | return; | ||
281 | /* looks like a valid d_id */ | 275 | /* looks like a valid d_id */ |
282 | port->d_id = ntoh24(gid_pn_resp->gid_pn.fp_fid); | 276 | ct_els->port->d_id = ntoh24(gid_pn_rsp->gid_pn.fp_fid); |
283 | } | 277 | } |
284 | 278 | ||
285 | static void zfcp_fc_complete(void *data) | 279 | static void zfcp_fc_complete(void *data) |
@@ -287,69 +281,73 @@ static void zfcp_fc_complete(void *data) | |||
287 | complete(data); | 281 | complete(data); |
288 | } | 282 | } |
289 | 283 | ||
284 | static void zfcp_fc_ct_ns_init(struct fc_ct_hdr *ct_hdr, u16 cmd, u16 mr_size) | ||
285 | { | ||
286 | ct_hdr->ct_rev = FC_CT_REV; | ||
287 | ct_hdr->ct_fs_type = FC_FST_DIR; | ||
288 | ct_hdr->ct_fs_subtype = FC_NS_SUBTYPE; | ||
289 | ct_hdr->ct_cmd = cmd; | ||
290 | ct_hdr->ct_mr_size = mr_size / 4; | ||
291 | } | ||
292 | |||
290 | static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, | 293 | static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, |
291 | struct zfcp_fc_gid_pn *gid_pn) | 294 | struct zfcp_fc_req *fc_req) |
292 | { | 295 | { |
293 | struct zfcp_adapter *adapter = port->adapter; | 296 | struct zfcp_adapter *adapter = port->adapter; |
294 | DECLARE_COMPLETION_ONSTACK(completion); | 297 | DECLARE_COMPLETION_ONSTACK(completion); |
298 | struct zfcp_fc_gid_pn_req *gid_pn_req = &fc_req->u.gid_pn.req; | ||
299 | struct zfcp_fc_gid_pn_rsp *gid_pn_rsp = &fc_req->u.gid_pn.rsp; | ||
295 | int ret; | 300 | int ret; |
296 | 301 | ||
297 | /* setup parameters for send generic command */ | 302 | /* setup parameters for send generic command */ |
298 | gid_pn->port = port; | 303 | fc_req->ct_els.port = port; |
299 | gid_pn->ct.handler = zfcp_fc_complete; | 304 | fc_req->ct_els.handler = zfcp_fc_complete; |
300 | gid_pn->ct.handler_data = &completion; | 305 | fc_req->ct_els.handler_data = &completion; |
301 | gid_pn->ct.req = &gid_pn->sg_req; | 306 | fc_req->ct_els.req = &fc_req->sg_req; |
302 | gid_pn->ct.resp = &gid_pn->sg_resp; | 307 | fc_req->ct_els.resp = &fc_req->sg_rsp; |
303 | sg_init_one(&gid_pn->sg_req, &gid_pn->gid_pn_req, | 308 | sg_init_one(&fc_req->sg_req, gid_pn_req, sizeof(*gid_pn_req)); |
304 | sizeof(struct zfcp_fc_gid_pn_req)); | 309 | sg_init_one(&fc_req->sg_rsp, gid_pn_rsp, sizeof(*gid_pn_rsp)); |
305 | sg_init_one(&gid_pn->sg_resp, &gid_pn->gid_pn_resp, | 310 | |
306 | sizeof(struct zfcp_fc_gid_pn_resp)); | 311 | zfcp_fc_ct_ns_init(&gid_pn_req->ct_hdr, |
307 | 312 | FC_NS_GID_PN, ZFCP_FC_CT_SIZE_PAGE); | |
308 | /* setup nameserver request */ | 313 | gid_pn_req->gid_pn.fn_wwpn = port->wwpn; |
309 | gid_pn->gid_pn_req.ct_hdr.ct_rev = FC_CT_REV; | 314 | |
310 | gid_pn->gid_pn_req.ct_hdr.ct_fs_type = FC_FST_DIR; | 315 | ret = zfcp_fsf_send_ct(&adapter->gs->ds, &fc_req->ct_els, |
311 | gid_pn->gid_pn_req.ct_hdr.ct_fs_subtype = FC_NS_SUBTYPE; | ||
312 | gid_pn->gid_pn_req.ct_hdr.ct_options = 0; | ||
313 | gid_pn->gid_pn_req.ct_hdr.ct_cmd = FC_NS_GID_PN; | ||
314 | gid_pn->gid_pn_req.ct_hdr.ct_mr_size = ZFCP_FC_CT_SIZE_PAGE / 4; | ||
315 | gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn; | ||
316 | |||
317 | ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct, | ||
318 | adapter->pool.gid_pn_req, | 316 | adapter->pool.gid_pn_req, |
319 | ZFCP_FC_CTELS_TMO); | 317 | ZFCP_FC_CTELS_TMO); |
320 | if (!ret) { | 318 | if (!ret) { |
321 | wait_for_completion(&completion); | 319 | wait_for_completion(&completion); |
322 | zfcp_fc_ns_gid_pn_eval(gid_pn); | 320 | zfcp_fc_ns_gid_pn_eval(fc_req); |
323 | } | 321 | } |
324 | return ret; | 322 | return ret; |
325 | } | 323 | } |
326 | 324 | ||
327 | /** | 325 | /** |
328 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | 326 | * zfcp_fc_ns_gid_pn - initiate GID_PN nameserver request |
329 | * @port: port where GID_PN request is needed | 327 | * @port: port where GID_PN request is needed |
330 | * return: -ENOMEM on error, 0 otherwise | 328 | * return: -ENOMEM on error, 0 otherwise |
331 | */ | 329 | */ |
332 | static int zfcp_fc_ns_gid_pn(struct zfcp_port *port) | 330 | static int zfcp_fc_ns_gid_pn(struct zfcp_port *port) |
333 | { | 331 | { |
334 | int ret; | 332 | int ret; |
335 | struct zfcp_fc_gid_pn *gid_pn; | 333 | struct zfcp_fc_req *fc_req; |
336 | struct zfcp_adapter *adapter = port->adapter; | 334 | struct zfcp_adapter *adapter = port->adapter; |
337 | 335 | ||
338 | gid_pn = mempool_alloc(adapter->pool.gid_pn, GFP_ATOMIC); | 336 | fc_req = mempool_alloc(adapter->pool.gid_pn, GFP_ATOMIC); |
339 | if (!gid_pn) | 337 | if (!fc_req) |
340 | return -ENOMEM; | 338 | return -ENOMEM; |
341 | 339 | ||
342 | memset(gid_pn, 0, sizeof(*gid_pn)); | 340 | memset(fc_req, 0, sizeof(*fc_req)); |
343 | 341 | ||
344 | ret = zfcp_fc_wka_port_get(&adapter->gs->ds); | 342 | ret = zfcp_fc_wka_port_get(&adapter->gs->ds); |
345 | if (ret) | 343 | if (ret) |
346 | goto out; | 344 | goto out; |
347 | 345 | ||
348 | ret = zfcp_fc_ns_gid_pn_request(port, gid_pn); | 346 | ret = zfcp_fc_ns_gid_pn_request(port, fc_req); |
349 | 347 | ||
350 | zfcp_fc_wka_port_put(&adapter->gs->ds); | 348 | zfcp_fc_wka_port_put(&adapter->gs->ds); |
351 | out: | 349 | out: |
352 | mempool_free(gid_pn, adapter->pool.gid_pn); | 350 | mempool_free(fc_req, adapter->pool.gid_pn); |
353 | return ret; | 351 | return ret; |
354 | } | 352 | } |
355 | 353 | ||