diff options
Diffstat (limited to 'drivers/scsi/bfa/bfad_attr.c')
| -rw-r--r-- | drivers/scsi/bfa/bfad_attr.c | 160 |
1 files changed, 110 insertions, 50 deletions
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 1938fe0473e..40be670a1cb 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -335,23 +335,10 @@ bfad_im_reset_stats(struct Scsi_Host *shost) } /* - * FC transport template entry, get rport loss timeout. - */ -static void -bfad_im_get_rport_loss_tmo(struct fc_rport *rport) -{ - struct bfad_itnim_data_s *itnim_data = rport->dd_data; - struct bfad_itnim_s *itnim = itnim_data->itnim; - struct bfad_s *bfad = itnim->im->bfad; - unsigned long flags; - - spin_lock_irqsave(&bfad->bfad_lock, flags); - rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); -} - -/* * FC transport template entry, set rport loss timeout. + * Update dev_loss_tmo based on the value pushed down by the stack + * In case it is lesser than path_tov of driver, set it to path_tov + 1 + * to ensure that the driver times out before the application */ static void bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) @@ -359,15 +346,11 @@ bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) struct bfad_itnim_data_s *itnim_data = rport->dd_data; struct bfad_itnim_s *itnim = itnim_data->itnim; struct bfad_s *bfad = itnim->im->bfad; - unsigned long flags; - - if (timeout > 0) { - spin_lock_irqsave(&bfad->bfad_lock, flags); - bfa_fcpim_path_tov_set(&bfad->bfa, timeout); - rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); - } + uint16_t path_tov = bfa_fcpim_path_tov_get(&bfad->bfa); + rport->dev_loss_tmo = timeout; + if (timeout < path_tov) + rport->dev_loss_tmo = path_tov + 1; } static int @@ -426,6 +409,23 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) vshost = vport->drv_port.im_port->shost; fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn); fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn); + fc_host_supported_classes(vshost) = FC_COS_CLASS3; + + memset(fc_host_supported_fc4s(vshost), 0, + sizeof(fc_host_supported_fc4s(vshost))); + + /* For FCP type 0x08 */ + if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM) + fc_host_supported_fc4s(vshost)[2] = 1; + + /* For fibre channel services type 0x20 */ + fc_host_supported_fc4s(vshost)[7] = 1; + + fc_host_supported_speeds(vshost) = + bfad_im_supported_speeds(&bfad->bfa); + fc_host_maxframe_size(vshost) = + bfa_fcport_get_maxfrsize(&bfad->bfa); + fc_vport->dd_data = vport; vport->drv_port.im_port->fc_vport = fc_vport; } else if (rc == BFA_STATUS_INVALID_WWN) @@ -442,6 +442,43 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) return status; } +int +bfad_im_issue_fc_host_lip(struct Scsi_Host *shost) +{ + struct bfad_im_port_s *im_port = + (struct bfad_im_port_s *) shost->hostdata[0]; + struct bfad_s *bfad = im_port->bfad; + struct bfad_hal_comp fcomp; + unsigned long flags; + uint32_t status; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + status = bfa_port_disable(&bfad->bfa.modules.port, + bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + if (status != BFA_STATUS_OK) + return -EIO; + + wait_for_completion(&fcomp.comp); + if (fcomp.status != BFA_STATUS_OK) + return -EIO; + + spin_lock_irqsave(&bfad->bfad_lock, flags); + status = bfa_port_enable(&bfad->bfa.modules.port, + bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + if (status != BFA_STATUS_OK) + return -EIO; + + wait_for_completion(&fcomp.comp); + if (fcomp.status != BFA_STATUS_OK) + return -EIO; + + return 0; +} + static int bfad_im_vport_delete(struct fc_vport *fc_vport) { @@ -457,8 +494,12 @@ bfad_im_vport_delete(struct fc_vport *fc_vport) unsigned long flags; struct completion fcomp; - if (im_port->flags & BFAD_PORT_DELETE) - goto free_scsi_host; + if (im_port->flags & BFAD_PORT_DELETE) { + bfad_scsi_host_free(bfad, im_port); + list_del(&vport->list_entry); + kfree(vport); + return 0; + } port = im_port->port; @@ -489,7 +530,6 @@ bfad_im_vport_delete(struct fc_vport *fc_vport) wait_for_completion(vport->comp_del); -free_scsi_host: bfad_scsi_host_free(bfad, im_port); list_del(&vport->list_entry); kfree(vport); @@ -530,6 +570,34 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable) return 0; } +void +bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport) +{ + struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data; + struct bfad_im_port_s *im_port = + (struct bfad_im_port_s *)vport->drv_port.im_port; + struct bfad_s *bfad = im_port->bfad; + struct Scsi_Host *vshost = vport->drv_port.im_port->shost; + char *sym_name = fc_vport->symbolic_name; + struct bfa_fcs_vport_s *fcs_vport; + wwn_t pwwn; + unsigned long flags; + + u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); + + spin_lock_irqsave(&bfad->bfad_lock, flags); + fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + if (fcs_vport == NULL) + return; + + spin_lock_irqsave(&bfad->bfad_lock, flags); + if (strlen(sym_name) > 0) + bfa_fcs_lport_set_symname(&fcs_vport->lport, sym_name); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); +} + struct fc_function_template bfad_im_fc_function_template = { /* Target dynamic attributes */ @@ -577,12 +645,12 @@ struct fc_function_template bfad_im_fc_function_template = { .show_rport_maxframe_size = 1, .show_rport_supported_classes = 1, .show_rport_dev_loss_tmo = 1, - .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, - + .issue_fc_host_lip = bfad_im_issue_fc_host_lip, .vport_create = bfad_im_vport_create, .vport_delete = bfad_im_vport_delete, .vport_disable = bfad_im_vport_disable, + .set_vport_symbolic_name = bfad_im_vport_set_symbolic_name, .bsg_request = bfad_im_bsg_request, .bsg_timeout = bfad_im_bsg_timeout, }; @@ -634,7 +702,6 @@ struct fc_function_template bfad_im_vport_fc_function_template = { .show_rport_maxframe_size = 1, .show_rport_supported_classes = 1, .show_rport_dev_loss_tmo = 1, - .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, }; @@ -719,25 +786,10 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, else if (!strcmp(model, "Brocade-804")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Brocade 8Gbps FC HBA for HP Bladesystem C-class"); - else if (!strcmp(model, "Brocade-902") || - !strcmp(model, "Brocade-1741")) + else if (!strcmp(model, "Brocade-1741")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Brocade 10Gbps CNA for Dell M-Series Blade Servers"); - else if (strstr(model, "Brocade-1560")) { - if (nports == 1) - snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe single port FC HBA"); - else - snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 16Gbps PCIe dual port FC HBA"); - } else if (strstr(model, "Brocade-1710")) { - if (nports == 1) - snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps single port CNA"); - else - snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, - "Brocade 10Gbps dual port CNA"); - } else if (strstr(model, "Brocade-1860")) { + else if (strstr(model, "Brocade-1860")) { if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Brocade 10Gbps single port CNA"); @@ -750,6 +802,13 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Brocade 16Gbps PCIe dual port FC HBA"); + } else if (!strcmp(model, "Brocade-1867")) { + if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) + snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, + "Brocade 16Gbps PCIe single port FC HBA for IBM"); + else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) + snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, + "Brocade 16Gbps PCIe dual port FC HBA for IBM"); } else snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Invalid Model"); @@ -867,15 +926,16 @@ bfad_im_num_of_discovered_ports_show(struct device *dev, struct bfad_port_s *port = im_port->port; struct bfad_s *bfad = im_port->bfad; int nrports = 2048; - wwn_t *rports = NULL; + struct bfa_rport_qualifier_s *rports = NULL; unsigned long flags; - rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); + rports = kzalloc(sizeof(struct bfa_rport_qualifier_s) * nrports, + GFP_ATOMIC); if (rports == NULL) return snprintf(buf, PAGE_SIZE, "Failed\n"); spin_lock_irqsave(&bfad->bfad_lock, flags); - bfa_fcs_lport_get_rports(port->fcs_port, rports, &nrports); + bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports); spin_unlock_irqrestore(&bfad->bfad_lock, flags); kfree(rports); |
