aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 942db9de785e..3eb2208675ae 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -6,8 +6,11 @@
6 */ 6 */
7#include "qla_def.h" 7#include "qla_def.h"
8 8
9#include <linux/kthread.h>
9#include <linux/vmalloc.h> 10#include <linux/vmalloc.h>
10 11
12int qla24xx_vport_disable(struct fc_vport *, bool);
13
11/* SYSFS attributes --------------------------------------------------------- */ 14/* SYSFS attributes --------------------------------------------------------- */
12 15
13static ssize_t 16static ssize_t
@@ -963,6 +966,122 @@ qla2x00_get_host_port_state(struct Scsi_Host *shost)
963 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 966 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
964} 967}
965 968
969static int
970qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
971{
972 int ret = 0;
973 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata;
974 scsi_qla_host_t *vha;
975
976 ret = qla24xx_vport_create_req_sanity_check(fc_vport);
977 if (ret) {
978 DEBUG15(printk("qla24xx_vport_create_req_sanity_check failed, "
979 "status %x\n", ret));
980 return (ret);
981 }
982
983 vha = qla24xx_create_vhost(fc_vport);
984 if (vha == NULL) {
985 DEBUG15(printk ("qla24xx_create_vhost failed, vha = %p\n",
986 vha));
987 return FC_VPORT_FAILED;
988 }
989 if (disable) {
990 atomic_set(&vha->vp_state, VP_OFFLINE);
991 fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
992 } else
993 atomic_set(&vha->vp_state, VP_FAILED);
994
995 /* ready to create vport */
996 qla_printk(KERN_INFO, vha, "VP entry id %d assigned.\n", vha->vp_idx);
997
998 /* initialized vport states */
999 atomic_set(&vha->loop_state, LOOP_DOWN);
1000 vha->vp_err_state= VP_ERR_PORTDWN;
1001 vha->vp_prev_err_state= VP_ERR_UNKWN;
1002 /* Check if physical ha port is Up */
1003 if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
1004 atomic_read(&ha->loop_state) == LOOP_DEAD) {
1005 /* Don't retry or attempt login of this virtual port */
1006 DEBUG15(printk ("scsi(%ld): pport loop_state is not UP.\n",
1007 vha->host_no));
1008 atomic_set(&vha->loop_state, LOOP_DEAD);
1009 if (!disable)
1010 fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
1011 }
1012
1013 if (scsi_add_host(vha->host, &fc_vport->dev)) {
1014 DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n",
1015 vha->host_no, vha->vp_idx));
1016 goto vport_create_failed_2;
1017 }
1018
1019 /* initialize attributes */
1020 fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
1021 fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name);
1022 fc_host_supported_classes(vha->host) =
1023 fc_host_supported_classes(ha->host);
1024 fc_host_supported_speeds(vha->host) =
1025 fc_host_supported_speeds(ha->host);
1026
1027 qla24xx_vport_disable(fc_vport, disable);
1028
1029 return 0;
1030vport_create_failed_2:
1031 qla24xx_disable_vp(vha);
1032 qla24xx_deallocate_vp_id(vha);
1033 kfree(vha->port_name);
1034 kfree(vha->node_name);
1035 scsi_host_put(vha->host);
1036 return FC_VPORT_FAILED;
1037}
1038
1039int
1040qla24xx_vport_delete(struct fc_vport *fc_vport)
1041{
1042 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata;
1043 scsi_qla_host_t *vha = fc_vport->dd_data;
1044
1045 qla24xx_disable_vp(vha);
1046 qla24xx_deallocate_vp_id(vha);
1047
1048 down(&ha->vport_sem);
1049 ha->cur_vport_count--;
1050 clear_bit(vha->vp_idx, (unsigned long *)ha->vp_idx_map);
1051 up(&ha->vport_sem);
1052
1053 kfree(vha->node_name);
1054 kfree(vha->port_name);
1055
1056 if (vha->timer_active) {
1057 qla2x00_vp_stop_timer(vha);
1058 DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p "
1059 "has stopped\n",
1060 vha->host_no, vha->vp_idx, vha));
1061 }
1062
1063 fc_remove_host(vha->host);
1064
1065 scsi_remove_host(vha->host);
1066
1067 scsi_host_put(vha->host);
1068
1069 return 0;
1070}
1071
1072int
1073qla24xx_vport_disable(struct fc_vport *fc_vport, bool disable)
1074{
1075 scsi_qla_host_t *vha = fc_vport->dd_data;
1076
1077 if (disable)
1078 qla24xx_disable_vp(vha);
1079 else
1080 qla24xx_enable_vp(vha);
1081
1082 return 0;
1083}
1084
966struct fc_function_template qla2xxx_transport_functions = { 1085struct fc_function_template qla2xxx_transport_functions = {
967 1086
968 .show_host_node_name = 1, 1087 .show_host_node_name = 1,
@@ -1000,6 +1119,49 @@ struct fc_function_template qla2xxx_transport_functions = {
1000 1119
1001 .issue_fc_host_lip = qla2x00_issue_lip, 1120 .issue_fc_host_lip = qla2x00_issue_lip,
1002 .get_fc_host_stats = qla2x00_get_fc_host_stats, 1121 .get_fc_host_stats = qla2x00_get_fc_host_stats,
1122
1123 .vport_create = qla24xx_vport_create,
1124 .vport_disable = qla24xx_vport_disable,
1125 .vport_delete = qla24xx_vport_delete,
1126};
1127
1128struct fc_function_template qla2xxx_transport_vport_functions = {
1129
1130 .show_host_node_name = 1,
1131 .show_host_port_name = 1,
1132 .show_host_supported_classes = 1,
1133
1134 .get_host_port_id = qla2x00_get_host_port_id,
1135 .show_host_port_id = 1,
1136 .get_host_speed = qla2x00_get_host_speed,
1137 .show_host_speed = 1,
1138 .get_host_port_type = qla2x00_get_host_port_type,
1139 .show_host_port_type = 1,
1140 .get_host_symbolic_name = qla2x00_get_host_symbolic_name,
1141 .show_host_symbolic_name = 1,
1142 .set_host_system_hostname = qla2x00_set_host_system_hostname,
1143 .show_host_system_hostname = 1,
1144 .get_host_fabric_name = qla2x00_get_host_fabric_name,
1145 .show_host_fabric_name = 1,
1146 .get_host_port_state = qla2x00_get_host_port_state,
1147 .show_host_port_state = 1,
1148
1149 .dd_fcrport_size = sizeof(struct fc_port *),
1150 .show_rport_supported_classes = 1,
1151
1152 .get_starget_node_name = qla2x00_get_starget_node_name,
1153 .show_starget_node_name = 1,
1154 .get_starget_port_name = qla2x00_get_starget_port_name,
1155 .show_starget_port_name = 1,
1156 .get_starget_port_id = qla2x00_get_starget_port_id,
1157 .show_starget_port_id = 1,
1158
1159 .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
1160 .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
1161 .show_rport_dev_loss_tmo = 1,
1162
1163 .issue_fc_host_lip = qla2x00_issue_lip,
1164 .get_fc_host_stats = qla2x00_get_fc_host_stats,
1003}; 1165};
1004 1166
1005void 1167void
@@ -1008,4 +1170,6 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha)
1008 fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); 1170 fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
1009 fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); 1171 fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
1010 fc_host_supported_classes(ha->host) = FC_COS_CLASS3; 1172 fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
1173 fc_host_max_npiv_vports(ha->host) = MAX_NUM_VPORT_FABRIC;
1174 fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count;
1011} 1175}