diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2012-08-22 22:50:20 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-09-24 04:10:55 -0400 |
commit | ebfe83921bd860e0b28a1a74e90be57baf2c8255 (patch) | |
tree | 3036edb85d9472a1f1f14032544edbc148f9fa30 /drivers/scsi/bfa | |
parent | c0e4eaae2e0affb498bd04b2a9923904d3868b26 (diff) |
[SCSI] bfa: Support vport symbolic name change from sysfs.
- Implemented the FC function template set_vport_symbolic_name entry
point to modify the vport symbolic name from sysfs.
- Implemented support to send RSPN_ID to switch to register the
modified vport symbolic name.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs.h | 2 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_lport.c | 63 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_attr.c | 32 |
3 files changed, 97 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 51c9e1345719..050a7e900434 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h | |||
@@ -338,6 +338,8 @@ void bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *vport); | |||
338 | void bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *vport); | 338 | void bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *vport); |
339 | void bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *vport); | 339 | void bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *vport); |
340 | void bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port); | 340 | void bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port); |
341 | void bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, | ||
342 | struct bfa_fcxp_s *fcxp_alloced); | ||
341 | void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport); | 343 | void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport); |
342 | void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport); | 344 | void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport); |
343 | void bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *vport); | 345 | void bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *vport); |
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index bcc4966e8ba4..f8e801747ea7 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c | |||
@@ -4355,6 +4355,69 @@ bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port) | |||
4355 | } | 4355 | } |
4356 | } | 4356 | } |
4357 | 4357 | ||
4358 | void | ||
4359 | bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) | ||
4360 | { | ||
4361 | struct bfa_fcs_lport_ns_s *ns = cbarg; | ||
4362 | struct bfa_fcs_lport_s *port = ns->port; | ||
4363 | struct fchs_s fchs; | ||
4364 | struct bfa_fcxp_s *fcxp; | ||
4365 | u8 symbl[256]; | ||
4366 | u8 *psymbl = &symbl[0]; | ||
4367 | int len; | ||
4368 | |||
4369 | if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) | ||
4370 | return; | ||
4371 | |||
4372 | /* Avoid sending RSPN in the following states. */ | ||
4373 | if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) || | ||
4374 | bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) || | ||
4375 | bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) || | ||
4376 | bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) || | ||
4377 | bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry)) | ||
4378 | return; | ||
4379 | |||
4380 | memset(symbl, 0, sizeof(symbl)); | ||
4381 | bfa_trc(port->fcs, port->port_cfg.pwwn); | ||
4382 | |||
4383 | fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); | ||
4384 | if (!fcxp) { | ||
4385 | port->stats.ns_rspnid_alloc_wait++; | ||
4386 | bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, | ||
4387 | bfa_fcs_lport_ns_util_send_rspn_id, ns); | ||
4388 | return; | ||
4389 | } | ||
4390 | |||
4391 | ns->fcxp = fcxp; | ||
4392 | |||
4393 | if (port->vport) { | ||
4394 | /* | ||
4395 | * For Vports, we append the vport's port symbolic name | ||
4396 | * to that of the base port. | ||
4397 | */ | ||
4398 | strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name | ||
4399 | (bfa_fcs_get_base_port(port->fcs))), | ||
4400 | strlen((char *)&bfa_fcs_lport_get_psym_name( | ||
4401 | bfa_fcs_get_base_port(port->fcs)))); | ||
4402 | |||
4403 | /* Ensure we have a null terminating string. */ | ||
4404 | ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name( | ||
4405 | bfa_fcs_get_base_port(port->fcs)))] = 0; | ||
4406 | |||
4407 | strncat((char *)psymbl, | ||
4408 | (char *)&(bfa_fcs_lport_get_psym_name(port)), | ||
4409 | strlen((char *)&bfa_fcs_lport_get_psym_name(port))); | ||
4410 | } | ||
4411 | |||
4412 | len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), | ||
4413 | bfa_fcs_lport_get_fcid(port), 0, psymbl); | ||
4414 | |||
4415 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, | ||
4416 | FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); | ||
4417 | |||
4418 | port->stats.ns_rspnid_sent++; | ||
4419 | } | ||
4420 | |||
4358 | /* | 4421 | /* |
4359 | * FCS SCN | 4422 | * FCS SCN |
4360 | */ | 4423 | */ |
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index b83927440171..1d18a803cff0 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c | |||
@@ -587,6 +587,37 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable) | |||
587 | return 0; | 587 | return 0; |
588 | } | 588 | } |
589 | 589 | ||
590 | void | ||
591 | bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport) | ||
592 | { | ||
593 | struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data; | ||
594 | struct bfad_im_port_s *im_port = | ||
595 | (struct bfad_im_port_s *)vport->drv_port.im_port; | ||
596 | struct bfad_s *bfad = im_port->bfad; | ||
597 | struct Scsi_Host *vshost = vport->drv_port.im_port->shost; | ||
598 | char *sym_name = fc_vport->symbolic_name; | ||
599 | struct bfa_fcs_vport_s *fcs_vport; | ||
600 | wwn_t pwwn; | ||
601 | unsigned long flags; | ||
602 | |||
603 | u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); | ||
604 | |||
605 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
606 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); | ||
607 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
608 | |||
609 | if (fcs_vport == NULL) | ||
610 | return; | ||
611 | |||
612 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
613 | if (strlen(sym_name) > 0) { | ||
614 | strcpy(fcs_vport->lport.port_cfg.sym_name.symname, sym_name); | ||
615 | bfa_fcs_lport_ns_util_send_rspn_id( | ||
616 | BFA_FCS_GET_NS_FROM_PORT((&fcs_vport->lport)), NULL); | ||
617 | } | ||
618 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
619 | } | ||
620 | |||
590 | struct fc_function_template bfad_im_fc_function_template = { | 621 | struct fc_function_template bfad_im_fc_function_template = { |
591 | 622 | ||
592 | /* Target dynamic attributes */ | 623 | /* Target dynamic attributes */ |
@@ -640,6 +671,7 @@ struct fc_function_template bfad_im_fc_function_template = { | |||
640 | .vport_create = bfad_im_vport_create, | 671 | .vport_create = bfad_im_vport_create, |
641 | .vport_delete = bfad_im_vport_delete, | 672 | .vport_delete = bfad_im_vport_delete, |
642 | .vport_disable = bfad_im_vport_disable, | 673 | .vport_disable = bfad_im_vport_disable, |
674 | .set_vport_symbolic_name = bfad_im_vport_set_symbolic_name, | ||
643 | .bsg_request = bfad_im_bsg_request, | 675 | .bsg_request = bfad_im_bsg_request, |
644 | .bsg_timeout = bfad_im_bsg_timeout, | 676 | .bsg_timeout = bfad_im_bsg_timeout, |
645 | }; | 677 | }; |