uint8_t load_flag;
#define FC_LOADING 0x1 /* HBA in process of loading drvr */
#define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */
- char *vname; /* Application assigned name */
-
/* Vport Config Parameters */
uint32_t cfg_scan_down;
uint32_t cfg_lun_queue_depth;
int error;
error = sysfs_create_bin_file(&shost->shost_dev.kobj,
- &sysfs_ctlreg_attr);
- if (error)
+ &sysfs_drvr_stat_data_attr);
+
+ /* Virtual ports do not need ctrl_reg and mbox */
+ if (error || vport->port_type == LPFC_NPIV_PORT)
goto out;
error = sysfs_create_bin_file(&shost->shost_dev.kobj,
- &sysfs_mbox_attr);
+ &sysfs_ctlreg_attr);
if (error)
- goto out_remove_ctlreg_attr;
+ goto out_remove_stat_attr;
error = sysfs_create_bin_file(&shost->shost_dev.kobj,
- &sysfs_drvr_stat_data_attr);
+ &sysfs_mbox_attr);
if (error)
- goto out_remove_mbox_attr;
+ goto out_remove_ctlreg_attr;
return 0;
-out_remove_mbox_attr:
- sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
out_remove_ctlreg_attr:
sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
+out_remove_stat_attr:
+ sysfs_remove_bin_file(&shost->shost_dev.kobj,
+ &sysfs_drvr_stat_data_attr);
out:
return error;
}
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
sysfs_remove_bin_file(&shost->shost_dev.kobj,
&sysfs_drvr_stat_data_attr);
+ /* Virtual ports do not need ctrl_reg and mbox */
+ if (vport->port_type == LPFC_NPIV_PORT)
+ return;
sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
}
lpfc_rport_show_function(field, format_string, sz, ) \
static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
+/**
+ * lpfc_set_vport_symbolic_name: Set the vport's symbolic name.
+ * @fc_vport: The fc_vport who's symbolic name has been changed.
+ *
+ * Description:
+ * This function is called by the transport after the @fc_vport's symbolic name
+ * has been changed. This function re-registers the symbolic name with the
+ * switch to propogate the change into the fabric if the vport is active.
+ **/
+static void
+lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
+{
+ struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
+
+ if (vport->port_state == LPFC_VPORT_READY)
+ lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
+}
struct fc_function_template lpfc_transport_functions = {
/* fixed attributes the driver supports */
.show_host_supported_fc4s = 1,
.show_host_supported_speeds = 1,
.show_host_maxframe_size = 1,
+ .show_host_symbolic_name = 1,
/* dynamic attributes the driver supports */
.get_host_port_id = lpfc_get_host_port_id,
.terminate_rport_io = lpfc_terminate_rport_io,
.dd_fcvport_size = sizeof(struct lpfc_vport *),
+
+ .vport_disable = lpfc_vport_disable,
+
+ .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
};
struct fc_function_template lpfc_vport_transport_functions = {
.show_host_supported_fc4s = 1,
.show_host_supported_speeds = 1,
.show_host_maxframe_size = 1,
+ .show_host_symbolic_name = 1,
/* dynamic attributes the driver supports */
.get_host_port_id = lpfc_get_host_port_id,
.terminate_rport_io = lpfc_terminate_rport_io,
.vport_disable = lpfc_vport_disable,
+
+ .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
};
/**
irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
/* Don't bother processing response if vport is being torn down. */
- if (vport->load_flag & FC_UNLOADING)
+ if (vport->load_flag & FC_UNLOADING) {
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
goto out;
+ }
if (lpfc_els_chk_latt(vport)) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0216 Link event during NS query\n");
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
goto out;
}
if (lpfc_error_lost_link(irsp)) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0226 NS query failed due to link event\n");
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
goto out;
}
if (irsp->ulpStatus) {
if (rc == 0)
goto out;
}
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"0257 GID_FT Query error: 0x%x 0x%x\n",
if (n < size)
n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi);
- if (n < size && vport->vname)
- n += snprintf(symbol + n, size - n, " VName-%s", vport->vname);
+ if (n < size &&
+ strlen(vport->fc_vport->symbolic_name))
+ n += snprintf(symbol + n, size - n, " VName-%s",
+ vport->fc_vport->symbolic_name);
return n;
}
/* For ELS_REQUEST64_CR, use the VPI by default */
icmd->ulpContext = vport->vpi;
icmd->ulpCt_h = 0;
- icmd->ulpCt_l = 1;
+ /* The CT field must be 0=INVALID_RPI for the ECHO cmd */
+ if (elscmd == ELS_CMD_ECHO)
+ icmd->ulpCt_l = 0; /* context = invalid RPI */
+ else
+ icmd->ulpCt_l = 1; /* context = VPI */
}
bpl = (struct ulp_bde64 *) pbuflist->virt;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba;
- kfree(vport->vname);
-
lpfc_debugfs_terminate(vport);
fc_remove_host(shost);
scsi_remove_host(shost);
{
struct Scsi_Host *shost = pci_get_drvdata(pdev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+ struct lpfc_vport **vports;
struct lpfc_hba *phba = vport->phba;
+ int i;
int bars = pci_select_bars(pdev, IORESOURCE_MEM);
spin_lock_irq(&phba->hbalock);
vport->load_flag |= FC_UNLOADING;
spin_unlock_irq(&phba->hbalock);
- kfree(vport->vname);
lpfc_free_sysfs_attr(vport);
kthread_stop(phba->worker_thread);
+ /* Release all the vports against this physical port */
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for (i = 1; i <= phba->max_vpi && vports[i] != NULL; i++)
+ fc_vport_terminate(vports[i]->fc_vport);
+ lpfc_destroy_vport_work_array(phba, vports);
+
+ /* Remove FC host and then SCSI host with the physical port */
fc_remove_host(shost);
scsi_remove_host(shost);
lpfc_cleanup(vport);
int vpi;
int rc = VPORT_ERROR;
int status;
- int size;
- if ((phba->sli_rev < 3) ||
- !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
+ if ((phba->sli_rev < 3) || !(phba->cfg_enable_npiv)) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
"1808 Create VPORT failed: "
"NPIV is not enabled: SLImode:%d\n",
memcpy(vport->fc_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8);
memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.u.wwn, 8);
- size = strnlen(fc_vport->symbolic_name, LPFC_VNAME_LEN);
- if (size) {
- vport->vname = kzalloc(size+1, GFP_KERNEL);
- if (!vport->vname) {
- lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
- "1814 Create VPORT failed. "
- "vname allocation failed.\n");
- rc = VPORT_ERROR;
- lpfc_free_vpi(phba, vpi);
- destroy_port(vport);
- goto error_out;
- }
- memcpy(vport->vname, fc_vport->symbolic_name, size+1);
- }
if (fc_vport->node_name != 0)
u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn);
if (fc_vport->port_name != 0)
goto error_out;
}
+ /* Create binary sysfs attribute for vport */
+ lpfc_alloc_sysfs_attr(vport);
+
*(struct lpfc_vport **)fc_vport->dd_data = vport;
vport->fc_vport = fc_vport;
}
if (disable) {
+ lpfc_vport_set_state(vport, FC_VPORT_DISABLED);
rc = VPORT_OK;
goto out;
}
spin_lock_irq(&phba->hbalock);
vport->load_flag |= FC_UNLOADING;
spin_unlock_irq(&phba->hbalock);
- kfree(vport->vname);
+
+ lpfc_free_sysfs_attr(vport);
+
lpfc_debugfs_terminate(vport);
+
+ /* Remove FC host and then SCSI host with the vport */
fc_remove_host(lpfc_shost_from_vport(vport));
scsi_remove_host(lpfc_shost_from_vport(vport));