0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <scsi/libfc.h>
0013 #include <linux/export.h>
0014
0015
0016
0017
0018
0019
0020
0021 struct fc_lport *libfc_vport_create(struct fc_vport *vport, int privsize)
0022 {
0023 struct Scsi_Host *shost = vport_to_shost(vport);
0024 struct fc_lport *n_port = shost_priv(shost);
0025 struct fc_lport *vn_port;
0026
0027 vn_port = libfc_host_alloc(shost->hostt, privsize);
0028 if (!vn_port)
0029 return vn_port;
0030
0031 vn_port->vport = vport;
0032 vport->dd_data = vn_port;
0033
0034 mutex_lock(&n_port->lp_mutex);
0035 list_add_tail(&vn_port->list, &n_port->vports);
0036 mutex_unlock(&n_port->lp_mutex);
0037
0038 return vn_port;
0039 }
0040 EXPORT_SYMBOL(libfc_vport_create);
0041
0042
0043
0044
0045
0046
0047
0048
0049 struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id)
0050 {
0051 struct fc_lport *lport = NULL;
0052 struct fc_lport *vn_port;
0053
0054 if (n_port->port_id == port_id)
0055 return n_port;
0056
0057 if (port_id == FC_FID_FLOGI)
0058 return n_port;
0059
0060 mutex_lock(&n_port->lp_mutex);
0061 list_for_each_entry(vn_port, &n_port->vports, list) {
0062 if (vn_port->port_id == port_id) {
0063 lport = vn_port;
0064 break;
0065 }
0066 }
0067 mutex_unlock(&n_port->lp_mutex);
0068
0069 return lport;
0070 }
0071 EXPORT_SYMBOL(fc_vport_id_lookup);
0072
0073
0074
0075
0076
0077
0078
0079 enum libfc_lport_mutex_class {
0080 LPORT_MUTEX_NORMAL = 0,
0081 LPORT_MUTEX_VN_PORT = 1,
0082 };
0083
0084
0085
0086
0087
0088
0089
0090
0091 static void __fc_vport_setlink(struct fc_lport *n_port,
0092 struct fc_lport *vn_port)
0093 {
0094 struct fc_vport *vport = vn_port->vport;
0095
0096 if (vn_port->state == LPORT_ST_DISABLED)
0097 return;
0098
0099 if (n_port->state == LPORT_ST_READY) {
0100 if (n_port->npiv_enabled) {
0101 fc_vport_set_state(vport, FC_VPORT_INITIALIZING);
0102 __fc_linkup(vn_port);
0103 } else {
0104 fc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
0105 __fc_linkdown(vn_port);
0106 }
0107 } else {
0108 fc_vport_set_state(vport, FC_VPORT_LINKDOWN);
0109 __fc_linkdown(vn_port);
0110 }
0111 }
0112
0113
0114
0115
0116
0117 void fc_vport_setlink(struct fc_lport *vn_port)
0118 {
0119 struct fc_vport *vport = vn_port->vport;
0120 struct Scsi_Host *shost = vport_to_shost(vport);
0121 struct fc_lport *n_port = shost_priv(shost);
0122
0123 mutex_lock(&n_port->lp_mutex);
0124 mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
0125 __fc_vport_setlink(n_port, vn_port);
0126 mutex_unlock(&vn_port->lp_mutex);
0127 mutex_unlock(&n_port->lp_mutex);
0128 }
0129 EXPORT_SYMBOL(fc_vport_setlink);
0130
0131
0132
0133
0134
0135
0136
0137 void fc_vports_linkchange(struct fc_lport *n_port)
0138 {
0139 struct fc_lport *vn_port;
0140
0141 list_for_each_entry(vn_port, &n_port->vports, list) {
0142 mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
0143 __fc_vport_setlink(n_port, vn_port);
0144 mutex_unlock(&vn_port->lp_mutex);
0145 }
0146 }
0147