diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 164 |
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 | ||
12 | int qla24xx_vport_disable(struct fc_vport *, bool); | ||
13 | |||
11 | /* SYSFS attributes --------------------------------------------------------- */ | 14 | /* SYSFS attributes --------------------------------------------------------- */ |
12 | 15 | ||
13 | static ssize_t | 16 | static 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 | ||
969 | static int | ||
970 | qla24xx_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; | ||
1030 | vport_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 | |||
1039 | int | ||
1040 | qla24xx_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 | |||
1072 | int | ||
1073 | qla24xx_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 | |||
966 | struct fc_function_template qla2xxx_transport_functions = { | 1085 | struct 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 | |||
1128 | struct 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 | ||
1005 | void | 1167 | void |
@@ -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 | } |