aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_attr.c
diff options
context:
space:
mode:
authorSeokmann Ju <seokmann.ju@qlogic.com>2007-07-05 16:16:51 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-07-14 20:08:05 -0400
commit2c3dfe3f6ad8daff5acdb01713e4f2b116e78136 (patch)
tree8d95e2356c0f5121ceab48ab564d2796b6530d29 /drivers/scsi/qla2xxx/qla_attr.c
parent968a5763fb7247feb0e69573a2975a7a0c094267 (diff)
[SCSI] qla2xxx: add support for NPIV
Following patch adds support for NPIV (N-Port ID Virtualization) to the qla2xxx. - supported within switched-fabric topologies only. - supports up to 63 virtual ports on each physical port. Signed-off-by: Seokmann Ju <seokmann.ju@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
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 8081b637d97e..b79c4dfc2a9c 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
@@ -959,6 +962,122 @@ qla2x00_get_host_port_state(struct Scsi_Host *shost)
959 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 962 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
960} 963}
961 964
965static int
966qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
967{
968 int ret = 0;
969 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata;
970 scsi_qla_host_t *vha;
971
972 ret = qla24xx_vport_create_req_sanity_check(fc_vport);
973 if (ret) {
974 DEBUG15(printk("qla24xx_vport_create_req_sanity_check failed, "
975 "status %x\n", ret));
976 return (ret);
977 }
978
979 vha = qla24xx_create_vhost(fc_vport);
980 if (vha == NULL) {
981 DEBUG15(printk ("qla24xx_create_vhost failed, vha = %p\n",
982 vha));
983 return FC_VPORT_FAILED;
984 }
985 if (disable) {
986 atomic_set(&vha->vp_state, VP_OFFLINE);
987 fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
988 } else
989 atomic_set(&vha->vp_state, VP_FAILED);
990
991 /* ready to create vport */
992 qla_printk(KERN_INFO, vha, "VP entry id %d assigned.\n", vha->vp_idx);
993
994 /* initialized vport states */
995 atomic_set(&vha->loop_state, LOOP_DOWN);
996 vha->vp_err_state= VP_ERR_PORTDWN;
997 vha->vp_prev_err_state= VP_ERR_UNKWN;
998 /* Check if physical ha port is Up */
999 if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
1000 atomic_read(&ha->loop_state) == LOOP_DEAD) {
1001 /* Don't retry or attempt login of this virtual port */
1002 DEBUG15(printk ("scsi(%ld): pport loop_state is not UP.\n",
1003 vha->host_no));
1004 atomic_set(&vha->loop_state, LOOP_DEAD);
1005 if (!disable)
1006 fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
1007 }
1008
1009 if (scsi_add_host(vha->host, &fc_vport->dev)) {
1010 DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n",
1011 vha->host_no, vha->vp_idx));
1012 goto vport_create_failed_2;
1013 }
1014
1015 /* initialize attributes */
1016 fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
1017 fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name);
1018 fc_host_supported_classes(vha->host) =
1019 fc_host_supported_classes(ha->host);
1020 fc_host_supported_speeds(vha->host) =
1021 fc_host_supported_speeds(ha->host);
1022
1023 qla24xx_vport_disable(fc_vport, disable);
1024
1025 return 0;
1026vport_create_failed_2:
1027 qla24xx_disable_vp(vha);
1028 qla24xx_deallocate_vp_id(vha);
1029 kfree(vha->port_name);
1030 kfree(vha->node_name);
1031 scsi_host_put(vha->host);
1032 return FC_VPORT_FAILED;
1033}
1034
1035int
1036qla24xx_vport_delete(struct fc_vport *fc_vport)
1037{
1038 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata;
1039 scsi_qla_host_t *vha = fc_vport->dd_data;
1040
1041 qla24xx_disable_vp(vha);
1042 qla24xx_deallocate_vp_id(vha);
1043
1044 down(&ha->vport_sem);
1045 ha->cur_vport_count--;
1046 clear_bit(vha->vp_idx, (unsigned long *)ha->vp_idx_map);
1047 up(&ha->vport_sem);
1048
1049 kfree(vha->node_name);
1050 kfree(vha->port_name);
1051
1052 if (vha->timer_active) {
1053 qla2x00_vp_stop_timer(vha);
1054 DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p "
1055 "has stopped\n",
1056 vha->host_no, vha->vp_idx, vha));
1057 }
1058
1059 fc_remove_host(vha->host);
1060
1061 scsi_remove_host(vha->host);
1062
1063 scsi_host_put(vha->host);
1064
1065 return 0;
1066}
1067
1068int
1069qla24xx_vport_disable(struct fc_vport *fc_vport, bool disable)
1070{
1071 scsi_qla_host_t *vha = fc_vport->dd_data;
1072
1073 if (disable)
1074 qla24xx_disable_vp(vha);
1075 else
1076 qla24xx_enable_vp(vha);
1077
1078 return 0;
1079}
1080
962struct fc_function_template qla2xxx_transport_functions = { 1081struct fc_function_template qla2xxx_transport_functions = {
963 1082
964 .show_host_node_name = 1, 1083 .show_host_node_name = 1,
@@ -996,6 +1115,49 @@ struct fc_function_template qla2xxx_transport_functions = {
996 1115
997 .issue_fc_host_lip = qla2x00_issue_lip, 1116 .issue_fc_host_lip = qla2x00_issue_lip,
998 .get_fc_host_stats = qla2x00_get_fc_host_stats, 1117 .get_fc_host_stats = qla2x00_get_fc_host_stats,
1118
1119 .vport_create = qla24xx_vport_create,
1120 .vport_disable = qla24xx_vport_disable,
1121 .vport_delete = qla24xx_vport_delete,
1122};
1123
1124struct fc_function_template qla2xxx_transport_vport_functions = {
1125
1126 .show_host_node_name = 1,
1127 .show_host_port_name = 1,
1128 .show_host_supported_classes = 1,
1129
1130 .get_host_port_id = qla2x00_get_host_port_id,
1131 .show_host_port_id = 1,
1132 .get_host_speed = qla2x00_get_host_speed,
1133 .show_host_speed = 1,
1134 .get_host_port_type = qla2x00_get_host_port_type,
1135 .show_host_port_type = 1,
1136 .get_host_symbolic_name = qla2x00_get_host_symbolic_name,
1137 .show_host_symbolic_name = 1,
1138 .set_host_system_hostname = qla2x00_set_host_system_hostname,
1139 .show_host_system_hostname = 1,
1140 .get_host_fabric_name = qla2x00_get_host_fabric_name,
1141 .show_host_fabric_name = 1,
1142 .get_host_port_state = qla2x00_get_host_port_state,
1143 .show_host_port_state = 1,
1144
1145 .dd_fcrport_size = sizeof(struct fc_port *),
1146 .show_rport_supported_classes = 1,
1147
1148 .get_starget_node_name = qla2x00_get_starget_node_name,
1149 .show_starget_node_name = 1,
1150 .get_starget_port_name = qla2x00_get_starget_port_name,
1151 .show_starget_port_name = 1,
1152 .get_starget_port_id = qla2x00_get_starget_port_id,
1153 .show_starget_port_id = 1,
1154
1155 .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
1156 .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
1157 .show_rport_dev_loss_tmo = 1,
1158
1159 .issue_fc_host_lip = qla2x00_issue_lip,
1160 .get_fc_host_stats = qla2x00_get_fc_host_stats,
999}; 1161};
1000 1162
1001void 1163void
@@ -1004,4 +1166,6 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha)
1004 fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); 1166 fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
1005 fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); 1167 fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
1006 fc_host_supported_classes(ha->host) = FC_COS_CLASS3; 1168 fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
1169 fc_host_max_npiv_vports(ha->host) = MAX_NUM_VPORT_FABRIC;
1170 fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count;
1007} 1171}