diff options
author | Seokmann Ju <seokmann.ju@qlogic.com> | 2007-07-05 16:16:51 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-07-14 20:08:05 -0400 |
commit | 2c3dfe3f6ad8daff5acdb01713e4f2b116e78136 (patch) | |
tree | 8d95e2356c0f5121ceab48ab564d2796b6530d29 /drivers/scsi/qla2xxx/qla_attr.c | |
parent | 968a5763fb7247feb0e69573a2975a7a0c094267 (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.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 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 | ||
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 |
@@ -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 | ||
965 | static int | ||
966 | qla24xx_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; | ||
1026 | vport_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 | |||
1035 | int | ||
1036 | qla24xx_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 | |||
1068 | int | ||
1069 | qla24xx_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 | |||
962 | struct fc_function_template qla2xxx_transport_functions = { | 1081 | struct 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 | |||
1124 | struct 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 | ||
1001 | void | 1163 | void |
@@ -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 | } |