aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r--drivers/s390/scsi/zfcp_fc.c80
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
265static void zfcp_fc_ns_gid_pn_eval(void *data) 265static 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
285static void zfcp_fc_complete(void *data) 279static 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
284static 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
290static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, 293static 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 */
332static int zfcp_fc_ns_gid_pn(struct zfcp_port *port) 330static 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);
351out: 349out:
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