aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
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
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')
-rw-r--r--drivers/scsi/qla2xxx/Makefile2
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c164
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h83
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h91
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h39
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c166
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c28
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c39
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c396
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c497
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c229
13 files changed, 1593 insertions, 154 deletions
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index 411663af7bb7..71ddb5db4944 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -1,4 +1,4 @@
1qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ 1qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
2 qla_dbg.o qla_sup.o qla_attr.o 2 qla_dbg.o qla_sup.o qla_attr.o qla_mid.o
3 3
4obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o 4obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
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}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index 5b12278968e0..49dffeb78512 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -21,6 +21,7 @@
21/* #define QL_DEBUG_LEVEL_12 */ /* Output IP trace msgs */ 21/* #define QL_DEBUG_LEVEL_12 */ /* Output IP trace msgs */
22/* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ 22/* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */
23/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ 23/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
24/* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
24/* 25/*
25 * Local Macro Definitions. 26 * Local Macro Definitions.
26 */ 27 */
@@ -30,7 +31,8 @@
30 defined(QL_DEBUG_LEVEL_7) || defined(QL_DEBUG_LEVEL_8) || \ 31 defined(QL_DEBUG_LEVEL_7) || defined(QL_DEBUG_LEVEL_8) || \
31 defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_10) || \ 32 defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_10) || \
32 defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \ 33 defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \
33 defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) 34 defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) || \
35 defined(QL_DEBUG_LEVEL_15)
34 #define QL_DEBUG_ROUTINES 36 #define QL_DEBUG_ROUTINES
35#endif 37#endif
36 38
@@ -125,6 +127,12 @@
125#define DEBUG14(x) do {} while (0) 127#define DEBUG14(x) do {} while (0)
126#endif 128#endif
127 129
130#if defined(QL_DEBUG_LEVEL_15)
131#define DEBUG15(x) do {x;} while (0)
132#else
133#define DEBUG15(x) do {} while (0)
134#endif
135
128/* 136/*
129 * Firmware Dump structure definition 137 * Firmware Dump structure definition
130 */ 138 */
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index e8948b679f5b..a1ca590ba447 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1551,6 +1551,9 @@ typedef struct fc_port {
1551 1551
1552 unsigned long last_queue_full; 1552 unsigned long last_queue_full;
1553 unsigned long last_ramp_up; 1553 unsigned long last_ramp_up;
1554
1555 struct list_head vp_fcport;
1556 uint16_t vp_idx;
1554} fc_port_t; 1557} fc_port_t;
1555 1558
1556/* 1559/*
@@ -1999,6 +2002,36 @@ struct gid_list_info {
1999}; 2002};
2000#define GID_LIST_SIZE (sizeof(struct gid_list_info) * MAX_FIBRE_DEVICES) 2003#define GID_LIST_SIZE (sizeof(struct gid_list_info) * MAX_FIBRE_DEVICES)
2001 2004
2005/* NPIV */
2006typedef struct vport_info {
2007 uint8_t port_name[WWN_SIZE];
2008 uint8_t node_name[WWN_SIZE];
2009 int vp_id;
2010 uint16_t loop_id;
2011 unsigned long host_no;
2012 uint8_t port_id[3];
2013 int loop_state;
2014} vport_info_t;
2015
2016typedef struct vport_params {
2017 uint8_t port_name[WWN_SIZE];
2018 uint8_t node_name[WWN_SIZE];
2019 uint32_t options;
2020#define VP_OPTS_RETRY_ENABLE BIT_0
2021#define VP_OPTS_VP_DISABLE BIT_1
2022} vport_params_t;
2023
2024/* NPIV - return codes of VP create and modify */
2025#define VP_RET_CODE_OK 0
2026#define VP_RET_CODE_FATAL 1
2027#define VP_RET_CODE_WRONG_ID 2
2028#define VP_RET_CODE_WWPN 3
2029#define VP_RET_CODE_RESOURCES 4
2030#define VP_RET_CODE_NO_MEM 5
2031#define VP_RET_CODE_NOT_FOUND 6
2032
2033#define to_qla_parent(x) (((x)->parent) ? (x)->parent : (x))
2034
2002/* 2035/*
2003 * ISP operations 2036 * ISP operations
2004 */ 2037 */
@@ -2073,6 +2106,16 @@ struct qla_msix_entry {
2073 uint16_t msix_entry; 2106 uint16_t msix_entry;
2074}; 2107};
2075 2108
2109#define WATCH_INTERVAL 1 /* number of seconds */
2110
2111/* NPIV */
2112#define MAX_MULTI_ID_LOOP 126
2113#define MAX_MULTI_ID_FABRIC 64
2114#define MAX_NUM_VPORT_LOOP (MAX_MULTI_ID_LOOP - 1)
2115#define MAX_NUM_VPORT_FABRIC (MAX_MULTI_ID_FABRIC - 1)
2116#define MAX_NUM_VHBA_LOOP (MAX_MULTI_ID_LOOP - 1)
2117#define MAX_NUM_VHBA_FABRIC (MAX_MULTI_ID_FABRIC - 1)
2118
2076/* 2119/*
2077 * Linux Host Adapter structure 2120 * Linux Host Adapter structure
2078 */ 2121 */
@@ -2108,6 +2151,8 @@ typedef struct scsi_qla_host {
2108 uint32_t msix_enabled :1; 2151 uint32_t msix_enabled :1;
2109 uint32_t disable_serdes :1; 2152 uint32_t disable_serdes :1;
2110 uint32_t gpsc_supported :1; 2153 uint32_t gpsc_supported :1;
2154 uint32_t vsan_enabled :1;
2155 uint32_t npiv_supported :1;
2111 } flags; 2156 } flags;
2112 2157
2113 atomic_t loop_state; 2158 atomic_t loop_state;
@@ -2147,6 +2192,7 @@ typedef struct scsi_qla_host {
2147#define BEACON_BLINK_NEEDED 25 2192#define BEACON_BLINK_NEEDED 25
2148#define REGISTER_FDMI_NEEDED 26 2193#define REGISTER_FDMI_NEEDED 26
2149#define FCPORT_UPDATE_NEEDED 27 2194#define FCPORT_UPDATE_NEEDED 27
2195#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
2150 2196
2151 uint32_t device_flags; 2197 uint32_t device_flags;
2152#define DFLG_LOCAL_DEVICES BIT_0 2198#define DFLG_LOCAL_DEVICES BIT_0
@@ -2237,6 +2283,11 @@ typedef struct scsi_qla_host {
2237 2283
2238 /* ISP configuration data. */ 2284 /* ISP configuration data. */
2239 uint16_t loop_id; /* Host adapter loop id */ 2285 uint16_t loop_id; /* Host adapter loop id */
2286 uint16_t switch_cap;
2287#define FLOGI_SEQ_DEL BIT_8
2288#define FLOGI_MID_SUPPORT BIT_10
2289#define FLOGI_VSAN_SUPPORT BIT_12
2290#define FLOGI_SP_SUPPORT BIT_13
2240 uint16_t fb_rev; 2291 uint16_t fb_rev;
2241 2292
2242 port_id_t d_id; /* Host adapter port id */ 2293 port_id_t d_id; /* Host adapter port id */
@@ -2344,6 +2395,7 @@ typedef struct scsi_qla_host {
2344#define MBX_UPDATE_FLASH_ACTIVE 3 2395#define MBX_UPDATE_FLASH_ACTIVE 3
2345 2396
2346 struct semaphore mbx_cmd_sem; /* Serialialize mbx access */ 2397 struct semaphore mbx_cmd_sem; /* Serialialize mbx access */
2398 struct semaphore vport_sem; /* Virtual port synchronization */
2347 struct semaphore mbx_intr_sem; /* Used for completion notification */ 2399 struct semaphore mbx_intr_sem; /* Used for completion notification */
2348 2400
2349 uint32_t mbx_flags; 2401 uint32_t mbx_flags;
@@ -2428,6 +2480,37 @@ typedef struct scsi_qla_host {
2428 struct fc_host_statistics fc_host_stat; 2480 struct fc_host_statistics fc_host_stat;
2429 2481
2430 struct qla_msix_entry msix_entries[QLA_MSIX_ENTRIES]; 2482 struct qla_msix_entry msix_entries[QLA_MSIX_ENTRIES];
2483
2484 struct list_head vp_list; /* list of VP */
2485 struct fc_vport *fc_vport; /* holds fc_vport * for each vport */
2486 uint8_t vp_idx_map[16];
2487 uint16_t num_vhosts; /* number of vports created */
2488 uint16_t num_vsans; /* number of vsan created */
2489 uint16_t vp_idx; /* vport ID */
2490
2491 struct scsi_qla_host *parent; /* holds pport */
2492 unsigned long vp_flags;
2493 struct list_head vp_fcports; /* list of fcports */
2494#define VP_IDX_ACQUIRED 0 /* bit no 0 */
2495#define VP_CREATE_NEEDED 1
2496#define VP_BIND_NEEDED 2
2497#define VP_DELETE_NEEDED 3
2498#define VP_SCR_NEEDED 4 /* State Change Request registration */
2499 atomic_t vp_state;
2500#define VP_OFFLINE 0
2501#define VP_ACTIVE 1
2502#define VP_FAILED 2
2503// #define VP_DISABLE 3
2504 uint16_t vp_err_state;
2505 uint16_t vp_prev_err_state;
2506#define VP_ERR_UNKWN 0
2507#define VP_ERR_PORTDWN 1
2508#define VP_ERR_FAB_UNSUPPORTED 2
2509#define VP_ERR_FAB_NORESOURCES 3
2510#define VP_ERR_FAB_LOGOUT 4
2511#define VP_ERR_ADAP_NORESOURCES 5
2512 int max_npiv_vports; /* 63 or 125 per topoloty */
2513 int cur_vport_count;
2431} scsi_qla_host_t; 2514} scsi_qla_host_t;
2432 2515
2433 2516
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index a0a722cf4237..63a11fef5d1b 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -69,6 +69,16 @@ struct port_database_24xx {
69 uint8_t reserved_3[24]; 69 uint8_t reserved_3[24];
70}; 70};
71 71
72struct vp_database_24xx {
73 uint16_t vp_status;
74 uint8_t options;
75 uint8_t id;
76 uint8_t port_name[WWN_SIZE];
77 uint8_t node_name[WWN_SIZE];
78 uint16_t port_id_low;
79 uint16_t port_id_high;
80};
81
72struct nvram_24xx { 82struct nvram_24xx {
73 /* NVRAM header. */ 83 /* NVRAM header. */
74 uint8_t id[4]; 84 uint8_t id[4];
@@ -962,6 +972,25 @@ struct mid_db_24xx {
962 struct mid_db_entry_24xx entries[MAX_MID_VPS]; 972 struct mid_db_entry_24xx entries[MAX_MID_VPS];
963}; 973};
964 974
975 /*
976 * Virtual Fabric ID type definition.
977 */
978typedef struct vf_id {
979 uint16_t id : 12;
980 uint16_t priority : 4;
981} vf_id_t;
982
983/*
984 * Virtual Fabric HopCt type definition.
985 */
986typedef struct vf_hopct {
987 uint16_t reserved : 8;
988 uint16_t hopct : 8;
989} vf_hopct_t;
990
991/*
992 * Virtual Port Control IOCB
993 */
965#define VP_CTRL_IOCB_TYPE 0x30 /* Vitual Port Control entry. */ 994#define VP_CTRL_IOCB_TYPE 0x30 /* Vitual Port Control entry. */
966struct vp_ctrl_entry_24xx { 995struct vp_ctrl_entry_24xx {
967 uint8_t entry_type; /* Entry type. */ 996 uint8_t entry_type; /* Entry type. */
@@ -974,6 +1003,7 @@ struct vp_ctrl_entry_24xx {
974 uint16_t vp_idx_failed; 1003 uint16_t vp_idx_failed;
975 1004
976 uint16_t comp_status; /* Completion status. */ 1005 uint16_t comp_status; /* Completion status. */
1006#define CS_VCE_IOCB_ERROR 0x01 /* Error processing IOCB */
977#define CS_VCE_ACQ_ID_ERROR 0x02 /* Error while acquireing ID. */ 1007#define CS_VCE_ACQ_ID_ERROR 0x02 /* Error while acquireing ID. */
978#define CS_VCE_BUSY 0x05 /* Firmware not ready to accept cmd. */ 1008#define CS_VCE_BUSY 0x05 /* Firmware not ready to accept cmd. */
979 1009
@@ -982,24 +1012,34 @@ struct vp_ctrl_entry_24xx {
982#define VCE_COMMAND_DISABLE_VPS 0x08 /* Disable VPs. */ 1012#define VCE_COMMAND_DISABLE_VPS 0x08 /* Disable VPs. */
983#define VCE_COMMAND_DISABLE_VPS_REINIT 0x09 /* Disable VPs and reinit link. */ 1013#define VCE_COMMAND_DISABLE_VPS_REINIT 0x09 /* Disable VPs and reinit link. */
984#define VCE_COMMAND_DISABLE_VPS_LOGO 0x0a /* Disable VPs and LOGO ports. */ 1014#define VCE_COMMAND_DISABLE_VPS_LOGO 0x0a /* Disable VPs and LOGO ports. */
1015#define VCE_COMMAND_DISABLE_VPS_LOGO_ALL 0x0b /* Disable VPs and LOGO ports. */
985 1016
986 uint16_t vp_count; 1017 uint16_t vp_count;
987 1018
988 uint8_t vp_idx_map[16]; 1019 uint8_t vp_idx_map[16];
989 1020 uint16_t flags;
990 uint8_t reserved_4[32]; 1021 struct vf_id id;
1022 uint16_t reserved_4;
1023 struct vf_hopct hopct;
1024 uint8_t reserved_5[8];
991}; 1025};
992 1026
1027/*
1028 * Modify Virtual Port Configuration IOCB
1029 */
993#define VP_CONFIG_IOCB_TYPE 0x31 /* Vitual Port Config entry. */ 1030#define VP_CONFIG_IOCB_TYPE 0x31 /* Vitual Port Config entry. */
994struct vp_config_entry_24xx { 1031struct vp_config_entry_24xx {
995 uint8_t entry_type; /* Entry type. */ 1032 uint8_t entry_type; /* Entry type. */
996 uint8_t entry_count; /* Entry count. */ 1033 uint8_t entry_count; /* Entry count. */
997 uint8_t sys_define; /* System defined. */ 1034 uint8_t handle_count;
998 uint8_t entry_status; /* Entry Status. */ 1035 uint8_t entry_status; /* Entry Status. */
999 1036
1000 uint32_t handle; /* System handle. */ 1037 uint32_t handle; /* System handle. */
1001 1038
1002 uint16_t reserved_1; 1039 uint16_t flags;
1040#define CS_VF_BIND_VPORTS_TO_VF BIT_0
1041#define CS_VF_SET_QOS_OF_VPORTS BIT_1
1042#define CS_VF_SET_HOPS_OF_VPORTS BIT_2
1003 1043
1004 uint16_t comp_status; /* Completion status. */ 1044 uint16_t comp_status; /* Completion status. */
1005#define CS_VCT_STS_ERROR 0x01 /* Specified VPs were not disabled. */ 1045#define CS_VCT_STS_ERROR 0x01 /* Specified VPs were not disabled. */
@@ -1009,27 +1049,29 @@ struct vp_config_entry_24xx {
1009#define CS_VCT_BUSY 0x05 /* Firmware not ready to accept cmd. */ 1049#define CS_VCT_BUSY 0x05 /* Firmware not ready to accept cmd. */
1010 1050
1011 uint8_t command; 1051 uint8_t command;
1012#define VCT_COMMAND_MOD_VPS 0x00 /* Enable VPs. */ 1052#define VCT_COMMAND_MOD_VPS 0x00 /* Modify VP configurations. */
1013#define VCT_COMMAND_MOD_ENABLE_VPS 0x08 /* Disable VPs. */ 1053#define VCT_COMMAND_MOD_ENABLE_VPS 0x01 /* Modify configuration & enable VPs. */
1014 1054
1015 uint8_t vp_count; 1055 uint8_t vp_count;
1016 1056
1017 uint8_t vp_idx1; 1057 uint8_t vp_index1;
1018 uint8_t vp_idx2; 1058 uint8_t vp_index2;
1019 1059
1020 uint8_t options_idx1; 1060 uint8_t options_idx1;
1021 uint8_t hard_address_idx1; 1061 uint8_t hard_address_idx1;
1022 uint16_t reserved_2; 1062 uint16_t reserved_vp1;
1023 uint8_t port_name_idx1[WWN_SIZE]; 1063 uint8_t port_name_idx1[WWN_SIZE];
1024 uint8_t node_name_idx1[WWN_SIZE]; 1064 uint8_t node_name_idx1[WWN_SIZE];
1025 1065
1026 uint8_t options_idx2; 1066 uint8_t options_idx2;
1027 uint8_t hard_address_idx2; 1067 uint8_t hard_address_idx2;
1028 uint16_t reserved_3; 1068 uint16_t reserved_vp2;
1029 uint8_t port_name_idx2[WWN_SIZE]; 1069 uint8_t port_name_idx2[WWN_SIZE];
1030 uint8_t node_name_idx2[WWN_SIZE]; 1070 uint8_t node_name_idx2[WWN_SIZE];
1031 1071 struct vf_id id;
1032 uint8_t reserved_4[8]; 1072 uint16_t reserved_4;
1073 struct vf_hopct hopct;
1074 uint8_t reserved_5;
1033}; 1075};
1034 1076
1035#define VP_RPT_ID_IOCB_TYPE 0x32 /* Report ID Acquisition entry. */ 1077#define VP_RPT_ID_IOCB_TYPE 0x32 /* Report ID Acquisition entry. */
@@ -1054,5 +1096,30 @@ struct vp_rpt_id_entry_24xx {
1054 uint8_t reserved_4[32]; 1096 uint8_t reserved_4[32];
1055}; 1097};
1056 1098
1099#define VF_EVFP_IOCB_TYPE 0x26 /* Exchange Virtual Fabric Parameters entry. */
1100struct vf_evfp_entry_24xx {
1101 uint8_t entry_type; /* Entry type. */
1102 uint8_t entry_count; /* Entry count. */
1103 uint8_t sys_define; /* System defined. */
1104 uint8_t entry_status; /* Entry Status. */
1105
1106 uint32_t handle; /* System handle. */
1107 uint16_t comp_status; /* Completion status. */
1108 uint16_t timeout; /* timeout */
1109 uint16_t adim_tagging_mode;
1110
1111 uint16_t vfport_id;
1112 uint32_t exch_addr;
1113
1114 uint16_t nport_handle; /* N_PORT handle. */
1115 uint16_t control_flags;
1116 uint32_t io_parameter_0;
1117 uint32_t io_parameter_1;
1118 uint32_t tx_address[2]; /* Data segment 0 address. */
1119 uint32_t tx_len; /* Data segment 0 length. */
1120 uint32_t rx_address[2]; /* Data segment 1 address. */
1121 uint32_t rx_len; /* Data segment 1 length. */
1122};
1123
1057/* END MID Support ***********************************************************/ 1124/* END MID Support ***********************************************************/
1058#endif 1125#endif
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 74544ae4b0e2..b44eff2803ce 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -62,6 +62,38 @@ extern int ql2xfdmienable;
62extern int ql2xallocfwdump; 62extern int ql2xallocfwdump;
63extern int ql2xextended_error_logging; 63extern int ql2xextended_error_logging;
64extern int ql2xqfullrampup; 64extern int ql2xqfullrampup;
65extern int num_hosts;
66
67/*
68 * Global Functions in qla_mid.c source file.
69 */
70extern struct scsi_host_template qla2x00_driver_template;
71extern struct scsi_host_template qla24xx_driver_template;
72extern struct scsi_transport_template *qla2xxx_transport_vport_template;
73extern uint8_t qla2x00_mem_alloc(scsi_qla_host_t *);
74extern void qla2x00_timer(scsi_qla_host_t *);
75extern void qla2x00_start_timer(scsi_qla_host_t *, void *, unsigned long);
76extern void qla2x00_stop_timer(scsi_qla_host_t *);
77extern uint32_t qla24xx_allocate_vp_id(scsi_qla_host_t *);
78extern void qla24xx_deallocate_vp_id(scsi_qla_host_t *);
79extern int qla24xx_disable_vp (scsi_qla_host_t *);
80extern int qla24xx_enable_vp (scsi_qla_host_t *);
81extern void qla2x00_mem_free(scsi_qla_host_t *);
82extern int qla24xx_control_vp(scsi_qla_host_t *, int );
83extern int qla24xx_modify_vp_config(scsi_qla_host_t *);
84extern int qla2x00_send_change_request(scsi_qla_host_t *, uint16_t, uint16_t);
85extern void qla2x00_vp_stop_timer(scsi_qla_host_t *);
86extern int qla24xx_configure_vhba (scsi_qla_host_t *);
87extern int qla24xx_get_vp_entry(scsi_qla_host_t *, uint16_t, int);
88extern int qla24xx_get_vp_database(scsi_qla_host_t *, uint16_t);
89extern int qla2x00_do_dpc_vp(scsi_qla_host_t *);
90extern void qla24xx_report_id_acquisition(scsi_qla_host_t *,
91 struct vp_rpt_id_entry_24xx *);
92extern scsi_qla_host_t * qla24xx_find_vhost_by_name(scsi_qla_host_t *,
93 uint8_t *);
94extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *);
95extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *);
96extern scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *);
65 97
66extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); 98extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
67 99
@@ -77,6 +109,10 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
77extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *); 109extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
78 110
79extern void qla2xxx_wake_dpc(scsi_qla_host_t *); 111extern void qla2xxx_wake_dpc(scsi_qla_host_t *);
112extern void qla2x00_alert_all_vps(scsi_qla_host_t *, uint16_t *);
113extern void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
114extern void qla2x00_vp_abort_isp(scsi_qla_host_t *);
115extern int qla24xx_vport_delete(struct fc_vport *);
80 116
81/* 117/*
82 * Global Function Prototypes in qla_iocb.c source file. 118 * Global Function Prototypes in qla_iocb.c source file.
@@ -128,7 +164,7 @@ qla2x00_abort_target(fc_port_t *);
128 164
129extern int 165extern int
130qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, 166qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
131 uint8_t *, uint16_t *); 167 uint8_t *, uint16_t *, uint16_t *);
132 168
133extern int 169extern int
134qla2x00_get_retry_cnt(scsi_qla_host_t *, uint8_t *, uint8_t *, uint16_t *); 170qla2x00_get_retry_cnt(scsi_qla_host_t *, uint8_t *, uint8_t *, uint16_t *);
@@ -303,6 +339,7 @@ struct class_device_attribute;
303extern struct class_device_attribute *qla2x00_host_attrs[]; 339extern struct class_device_attribute *qla2x00_host_attrs[];
304struct fc_function_template; 340struct fc_function_template;
305extern struct fc_function_template qla2xxx_transport_functions; 341extern struct fc_function_template qla2xxx_transport_functions;
342extern struct fc_function_template qla2xxx_transport_vport_functions;
306extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); 343extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
307extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); 344extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
308extern void qla2x00_init_host_attr(scsi_qla_host_t *); 345extern void qla2x00_init_host_attr(scsi_qla_host_t *);
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index ec5b2dd90d6a..a086b3f0df65 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -88,6 +88,7 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
88 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 88 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
89 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 89 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
90 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 90 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
91 ct_pkt->vp_index = ha->vp_idx;
91 92
92 return (ct_pkt); 93 return (ct_pkt);
93} 94}
@@ -1186,6 +1187,7 @@ qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
1186 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1187 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1187 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1188 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1188 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 1189 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1190 ct_pkt->vp_index = ha->vp_idx;
1189 1191
1190 return ct_pkt; 1192 return ct_pkt;
1191} 1193}
@@ -1746,6 +1748,7 @@ qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size,
1746 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1748 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1747 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1749 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1748 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 1750 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1751 ct_pkt->vp_index = ha->vp_idx;
1749 1752
1750 return ct_pkt; 1753 return ct_pkt;
1751} 1754}
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 2a45aec4ff29..bd95f7dc5cfc 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -899,6 +899,10 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
899 &ha->fw_subminor_version, 899 &ha->fw_subminor_version,
900 &ha->fw_attributes, &ha->fw_memory_size); 900 &ha->fw_attributes, &ha->fw_memory_size);
901 qla2x00_resize_request_q(ha); 901 qla2x00_resize_request_q(ha);
902 ha->flags.npiv_supported = 0;
903 if (IS_QLA24XX(ha) &&
904 (ha->fw_attributes & BIT_2))
905 ha->flags.npiv_supported = 1;
902 906
903 if (ql2xallocfwdump) 907 if (ql2xallocfwdump)
904 qla2x00_alloc_fw_dump(ha); 908 qla2x00_alloc_fw_dump(ha);
@@ -1101,6 +1105,8 @@ qla2x00_init_rings(scsi_qla_host_t *ha)
1101 int rval; 1105 int rval;
1102 unsigned long flags = 0; 1106 unsigned long flags = 0;
1103 int cnt; 1107 int cnt;
1108 struct mid_init_cb_24xx *mid_init_cb =
1109 (struct mid_init_cb_24xx *) ha->init_cb;
1104 1110
1105 spin_lock_irqsave(&ha->hardware_lock, flags); 1111 spin_lock_irqsave(&ha->hardware_lock, flags);
1106 1112
@@ -1132,6 +1138,10 @@ qla2x00_init_rings(scsi_qla_host_t *ha)
1132 ha->isp_ops.update_fw_options(ha); 1138 ha->isp_ops.update_fw_options(ha);
1133 1139
1134 DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); 1140 DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no));
1141
1142 mid_init_cb->count = MAX_NUM_VPORT_FABRIC;
1143 ha->max_npiv_vports = MAX_NUM_VPORT_FABRIC;
1144
1135 rval = qla2x00_init_firmware(ha, ha->init_cb_size); 1145 rval = qla2x00_init_firmware(ha, ha->init_cb_size);
1136 if (rval) { 1146 if (rval) {
1137 DEBUG2_3(printk("scsi(%ld): Init firmware **** FAILED ****.\n", 1147 DEBUG2_3(printk("scsi(%ld): Init firmware **** FAILED ****.\n",
@@ -1263,6 +1273,7 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
1263 int rval; 1273 int rval;
1264 uint16_t loop_id; 1274 uint16_t loop_id;
1265 uint16_t topo; 1275 uint16_t topo;
1276 uint16_t sw_cap;
1266 uint8_t al_pa; 1277 uint8_t al_pa;
1267 uint8_t area; 1278 uint8_t area;
1268 uint8_t domain; 1279 uint8_t domain;
@@ -1270,7 +1281,7 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
1270 1281
1271 /* Get host addresses. */ 1282 /* Get host addresses. */
1272 rval = qla2x00_get_adapter_id(ha, 1283 rval = qla2x00_get_adapter_id(ha,
1273 &loop_id, &al_pa, &area, &domain, &topo); 1284 &loop_id, &al_pa, &area, &domain, &topo, &sw_cap);
1274 if (rval != QLA_SUCCESS) { 1285 if (rval != QLA_SUCCESS) {
1275 if (LOOP_TRANSITION(ha) || atomic_read(&ha->loop_down_timer) || 1286 if (LOOP_TRANSITION(ha) || atomic_read(&ha->loop_down_timer) ||
1276 (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) { 1287 (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) {
@@ -1295,6 +1306,7 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
1295 /* initialize */ 1306 /* initialize */
1296 ha->min_external_loopid = SNS_FIRST_LOOP_ID; 1307 ha->min_external_loopid = SNS_FIRST_LOOP_ID;
1297 ha->operating_mode = LOOP; 1308 ha->operating_mode = LOOP;
1309 ha->switch_cap = 0;
1298 1310
1299 switch (topo) { 1311 switch (topo) {
1300 case 0: 1312 case 0:
@@ -1307,6 +1319,7 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
1307 case 1: 1319 case 1:
1308 DEBUG3(printk("scsi(%ld): HBA in FL topology.\n", 1320 DEBUG3(printk("scsi(%ld): HBA in FL topology.\n",
1309 ha->host_no)); 1321 ha->host_no));
1322 ha->switch_cap = sw_cap;
1310 ha->current_topology = ISP_CFG_FL; 1323 ha->current_topology = ISP_CFG_FL;
1311 strcpy(connect_type, "(FL_Port)"); 1324 strcpy(connect_type, "(FL_Port)");
1312 break; 1325 break;
@@ -1322,6 +1335,7 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
1322 case 3: 1335 case 3:
1323 DEBUG3(printk("scsi(%ld): HBA in F P2P topology.\n", 1336 DEBUG3(printk("scsi(%ld): HBA in F P2P topology.\n",
1324 ha->host_no)); 1337 ha->host_no));
1338 ha->switch_cap = sw_cap;
1325 ha->operating_mode = P2P; 1339 ha->operating_mode = P2P;
1326 ha->current_topology = ISP_CFG_F; 1340 ha->current_topology = ISP_CFG_F;
1327 strcpy(connect_type, "(F_Port)"); 1341 strcpy(connect_type, "(F_Port)");
@@ -1743,7 +1757,6 @@ qla2x00_rport_del(void *data)
1743 spin_unlock_irqrestore(&fcport->rport_lock, flags); 1757 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1744 if (rport) 1758 if (rport)
1745 fc_remote_port_delete(rport); 1759 fc_remote_port_delete(rport);
1746
1747} 1760}
1748 1761
1749/** 1762/**
@@ -1765,6 +1778,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
1765 /* Setup fcport template structure. */ 1778 /* Setup fcport template structure. */
1766 memset(fcport, 0, sizeof (fc_port_t)); 1779 memset(fcport, 0, sizeof (fc_port_t));
1767 fcport->ha = ha; 1780 fcport->ha = ha;
1781 fcport->vp_idx = ha->vp_idx;
1768 fcport->port_type = FCT_UNKNOWN; 1782 fcport->port_type = FCT_UNKNOWN;
1769 fcport->loop_id = FC_NO_LOOP_ID; 1783 fcport->loop_id = FC_NO_LOOP_ID;
1770 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1784 atomic_set(&fcport->state, FCS_UNCONFIGURED);
@@ -1911,6 +1925,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
1911 char *id_iter; 1925 char *id_iter;
1912 uint16_t loop_id; 1926 uint16_t loop_id;
1913 uint8_t domain, area, al_pa; 1927 uint8_t domain, area, al_pa;
1928 scsi_qla_host_t *pha = to_qla_parent(ha);
1914 1929
1915 found_devs = 0; 1930 found_devs = 0;
1916 new_fcport = NULL; 1931 new_fcport = NULL;
@@ -1942,7 +1957,10 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
1942 /* 1957 /*
1943 * Mark local devices that were present with FCF_DEVICE_LOST for now. 1958 * Mark local devices that were present with FCF_DEVICE_LOST for now.
1944 */ 1959 */
1945 list_for_each_entry(fcport, &ha->fcports, list) { 1960 list_for_each_entry(fcport, &pha->fcports, list) {
1961 if (fcport->vp_idx != ha->vp_idx)
1962 continue;
1963
1946 if (atomic_read(&fcport->state) == FCS_ONLINE && 1964 if (atomic_read(&fcport->state) == FCS_ONLINE &&
1947 fcport->port_type != FCT_BROADCAST && 1965 fcport->port_type != FCT_BROADCAST &&
1948 (fcport->flags & FCF_FABRIC_DEVICE) == 0) { 1966 (fcport->flags & FCF_FABRIC_DEVICE) == 0) {
@@ -1988,6 +2006,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
1988 new_fcport->d_id.b.area = area; 2006 new_fcport->d_id.b.area = area;
1989 new_fcport->d_id.b.al_pa = al_pa; 2007 new_fcport->d_id.b.al_pa = al_pa;
1990 new_fcport->loop_id = loop_id; 2008 new_fcport->loop_id = loop_id;
2009 new_fcport->vp_idx = ha->vp_idx;
1991 rval2 = qla2x00_get_port_database(ha, new_fcport, 0); 2010 rval2 = qla2x00_get_port_database(ha, new_fcport, 0);
1992 if (rval2 != QLA_SUCCESS) { 2011 if (rval2 != QLA_SUCCESS) {
1993 DEBUG2(printk("scsi(%ld): Failed to retrieve fcport " 2012 DEBUG2(printk("scsi(%ld): Failed to retrieve fcport "
@@ -2003,7 +2022,10 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
2003 /* Check for matching device in port list. */ 2022 /* Check for matching device in port list. */
2004 found = 0; 2023 found = 0;
2005 fcport = NULL; 2024 fcport = NULL;
2006 list_for_each_entry(fcport, &ha->fcports, list) { 2025 list_for_each_entry(fcport, &pha->fcports, list) {
2026 if (fcport->vp_idx != ha->vp_idx)
2027 continue;
2028
2007 if (memcmp(new_fcport->port_name, fcport->port_name, 2029 if (memcmp(new_fcport->port_name, fcport->port_name,
2008 WWN_SIZE)) 2030 WWN_SIZE))
2009 continue; 2031 continue;
@@ -2023,7 +2045,13 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
2023 if (!found) { 2045 if (!found) {
2024 /* New device, add to fcports list. */ 2046 /* New device, add to fcports list. */
2025 new_fcport->flags &= ~FCF_PERSISTENT_BOUND; 2047 new_fcport->flags &= ~FCF_PERSISTENT_BOUND;
2026 list_add_tail(&new_fcport->list, &ha->fcports); 2048 if (ha->parent) {
2049 new_fcport->ha = ha;
2050 new_fcport->vp_idx = ha->vp_idx;
2051 list_add_tail(&new_fcport->vp_fcport,
2052 &ha->vp_fcports);
2053 }
2054 list_add_tail(&new_fcport->list, &pha->fcports);
2027 2055
2028 /* Allocate a new replacement fcport. */ 2056 /* Allocate a new replacement fcport. */
2029 fcport = new_fcport; 2057 fcport = new_fcport;
@@ -2199,11 +2227,13 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2199void 2227void
2200qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) 2228qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
2201{ 2229{
2230 scsi_qla_host_t *pha = to_qla_parent(ha);
2231
2202 fcport->ha = ha; 2232 fcport->ha = ha;
2203 fcport->login_retry = 0; 2233 fcport->login_retry = 0;
2204 fcport->port_login_retry_count = ha->port_down_retry_count * 2234 fcport->port_login_retry_count = pha->port_down_retry_count *
2205 PORT_RETRY_TIME; 2235 PORT_RETRY_TIME;
2206 atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * 2236 atomic_set(&fcport->port_down_timer, pha->port_down_retry_count *
2207 PORT_RETRY_TIME); 2237 PORT_RETRY_TIME);
2208 fcport->flags &= ~FCF_LOGIN_NEEDED; 2238 fcport->flags &= ~FCF_LOGIN_NEEDED;
2209 2239
@@ -2234,6 +2264,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
2234 uint16_t mb[MAILBOX_REGISTER_COUNT]; 2264 uint16_t mb[MAILBOX_REGISTER_COUNT];
2235 uint16_t loop_id; 2265 uint16_t loop_id;
2236 LIST_HEAD(new_fcports); 2266 LIST_HEAD(new_fcports);
2267 scsi_qla_host_t *pha = to_qla_parent(ha);
2237 2268
2238 /* If FL port exists, then SNS is present */ 2269 /* If FL port exists, then SNS is present */
2239 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) 2270 if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
@@ -2307,7 +2338,10 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
2307 * Logout all previous fabric devices marked lost, except 2338 * Logout all previous fabric devices marked lost, except
2308 * tape devices. 2339 * tape devices.
2309 */ 2340 */
2310 list_for_each_entry(fcport, &ha->fcports, list) { 2341 list_for_each_entry(fcport, &pha->fcports, list) {
2342 if (fcport->vp_idx !=ha->vp_idx)
2343 continue;
2344
2311 if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) 2345 if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
2312 break; 2346 break;
2313 2347
@@ -2332,13 +2366,16 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
2332 } 2366 }
2333 2367
2334 /* Starting free loop ID. */ 2368 /* Starting free loop ID. */
2335 next_loopid = ha->min_external_loopid; 2369 next_loopid = pha->min_external_loopid;
2336 2370
2337 /* 2371 /*
2338 * Scan through our port list and login entries that need to be 2372 * Scan through our port list and login entries that need to be
2339 * logged in. 2373 * logged in.
2340 */ 2374 */
2341 list_for_each_entry(fcport, &ha->fcports, list) { 2375 list_for_each_entry(fcport, &pha->fcports, list) {
2376 if (fcport->vp_idx != ha->vp_idx)
2377 continue;
2378
2342 if (atomic_read(&ha->loop_down_timer) || 2379 if (atomic_read(&ha->loop_down_timer) ||
2343 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) 2380 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
2344 break; 2381 break;
@@ -2380,11 +2417,18 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
2380 break; 2417 break;
2381 } 2418 }
2382 2419
2383 /* Remove device from the new list and add it to DB */
2384 list_move_tail(&fcport->list, &ha->fcports);
2385
2386 /* Login and update database */ 2420 /* Login and update database */
2387 qla2x00_fabric_dev_login(ha, fcport, &next_loopid); 2421 qla2x00_fabric_dev_login(ha, fcport, &next_loopid);
2422
2423 if (ha->parent) {
2424 fcport->ha = ha;
2425 fcport->vp_idx = ha->vp_idx;
2426 list_add_tail(&fcport->vp_fcport,
2427 &ha->vp_fcports);
2428 list_move_tail(&fcport->list,
2429 &ha->parent->fcports);
2430 } else
2431 list_move_tail(&fcport->list, &ha->fcports);
2388 } 2432 }
2389 } while (0); 2433 } while (0);
2390 2434
@@ -2428,6 +2472,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2428 int swl_idx; 2472 int swl_idx;
2429 int first_dev, last_dev; 2473 int first_dev, last_dev;
2430 port_id_t wrap, nxt_d_id; 2474 port_id_t wrap, nxt_d_id;
2475 int vp_index;
2476 int empty_vp_index;
2477 int found_vp;
2478 scsi_qla_host_t *vha;
2479 scsi_qla_host_t *pha = to_qla_parent(ha);
2431 2480
2432 rval = QLA_SUCCESS; 2481 rval = QLA_SUCCESS;
2433 2482
@@ -2461,13 +2510,13 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2461 return (QLA_MEMORY_ALLOC_FAILED); 2510 return (QLA_MEMORY_ALLOC_FAILED);
2462 } 2511 }
2463 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED); 2512 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
2464 2513 new_fcport->vp_idx = ha->vp_idx;
2465 /* Set start port ID scan at adapter ID. */ 2514 /* Set start port ID scan at adapter ID. */
2466 first_dev = 1; 2515 first_dev = 1;
2467 last_dev = 0; 2516 last_dev = 0;
2468 2517
2469 /* Starting free loop ID. */ 2518 /* Starting free loop ID. */
2470 loop_id = ha->min_external_loopid; 2519 loop_id = pha->min_external_loopid;
2471 for (; loop_id <= ha->last_loop_id; loop_id++) { 2520 for (; loop_id <= ha->last_loop_id; loop_id++) {
2472 if (qla2x00_is_reserved_id(ha, loop_id)) 2521 if (qla2x00_is_reserved_id(ha, loop_id))
2473 continue; 2522 continue;
@@ -2521,10 +2570,42 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2521 break; 2570 break;
2522 } 2571 }
2523 2572
2524 /* Bypass if host adapter. */ 2573 /* Bypass if same physical adapter. */
2525 if (new_fcport->d_id.b24 == ha->d_id.b24) 2574 if (new_fcport->d_id.b24 == pha->d_id.b24)
2526 continue; 2575 continue;
2527 2576
2577 /* Bypass virtual ports of the same host. */
2578 if (pha->num_vhosts) {
2579 vp_index = find_next_bit(
2580 (unsigned long *)pha->vp_idx_map,
2581 MAX_MULTI_ID_FABRIC + 1, 1);
2582
2583 for (;vp_index <= MAX_MULTI_ID_FABRIC;
2584 vp_index = find_next_bit(
2585 (unsigned long *)pha->vp_idx_map,
2586 MAX_MULTI_ID_FABRIC + 1, vp_index + 1)) {
2587 empty_vp_index = 1;
2588 found_vp = 0;
2589 list_for_each_entry(vha, &pha->vp_list,
2590 vp_list) {
2591 if (vp_index == vha->vp_idx) {
2592 empty_vp_index = 0;
2593 found_vp = 1;
2594 break;
2595 }
2596 }
2597
2598 if (empty_vp_index)
2599 continue;
2600
2601 if (found_vp &&
2602 new_fcport->d_id.b24 == vha->d_id.b24)
2603 break;
2604 }
2605 if (vp_index <= MAX_MULTI_ID_FABRIC)
2606 continue;
2607 }
2608
2528 /* Bypass if same domain and area of adapter. */ 2609 /* Bypass if same domain and area of adapter. */
2529 if (((new_fcport->d_id.b24 & 0xffff00) == 2610 if (((new_fcport->d_id.b24 & 0xffff00) ==
2530 (ha->d_id.b24 & 0xffff00)) && ha->current_topology == 2611 (ha->d_id.b24 & 0xffff00)) && ha->current_topology ==
@@ -2537,7 +2618,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2537 2618
2538 /* Locate matching device in database. */ 2619 /* Locate matching device in database. */
2539 found = 0; 2620 found = 0;
2540 list_for_each_entry(fcport, &ha->fcports, list) { 2621 list_for_each_entry(fcport, &pha->fcports, list) {
2622 if (new_fcport->vp_idx != fcport->vp_idx)
2623 continue;
2541 if (memcmp(new_fcport->port_name, fcport->port_name, 2624 if (memcmp(new_fcport->port_name, fcport->port_name,
2542 WWN_SIZE)) 2625 WWN_SIZE))
2543 continue; 2626 continue;
@@ -2605,6 +2688,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2605 } 2688 }
2606 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED); 2689 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
2607 new_fcport->d_id.b24 = nxt_d_id.b24; 2690 new_fcport->d_id.b24 = nxt_d_id.b24;
2691 new_fcport->vp_idx = ha->vp_idx;
2608 } 2692 }
2609 2693
2610 kfree(swl); 2694 kfree(swl);
@@ -2637,6 +2721,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev)
2637 int found; 2721 int found;
2638 fc_port_t *fcport; 2722 fc_port_t *fcport;
2639 uint16_t first_loop_id; 2723 uint16_t first_loop_id;
2724 scsi_qla_host_t *pha = to_qla_parent(ha);
2640 2725
2641 rval = QLA_SUCCESS; 2726 rval = QLA_SUCCESS;
2642 2727
@@ -2663,7 +2748,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev)
2663 /* Check for loop ID being already in use. */ 2748 /* Check for loop ID being already in use. */
2664 found = 0; 2749 found = 0;
2665 fcport = NULL; 2750 fcport = NULL;
2666 list_for_each_entry(fcport, &ha->fcports, list) { 2751 list_for_each_entry(fcport, &pha->fcports, list) {
2667 if (fcport->loop_id == dev->loop_id && fcport != dev) { 2752 if (fcport->loop_id == dev->loop_id && fcport != dev) {
2668 /* ID possibly in use */ 2753 /* ID possibly in use */
2669 found++; 2754 found++;
@@ -2710,6 +2795,7 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
2710 uint8_t rscn_out_iter; 2795 uint8_t rscn_out_iter;
2711 uint8_t format; 2796 uint8_t format;
2712 port_id_t d_id; 2797 port_id_t d_id;
2798 scsi_qla_host_t *pha = to_qla_parent(ha);
2713 2799
2714 rval = QLA_RSCNS_HANDLED; 2800 rval = QLA_RSCNS_HANDLED;
2715 2801
@@ -2776,7 +2862,10 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
2776 2862
2777 rval = QLA_SUCCESS; 2863 rval = QLA_SUCCESS;
2778 2864
2779 list_for_each_entry(fcport, &ha->fcports, list) { 2865 list_for_each_entry(fcport, &pha->fcports, list) {
2866 if (fcport->vp_idx != ha->vp_idx)
2867 continue;
2868
2780 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || 2869 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 ||
2781 (fcport->d_id.b24 & mask) != d_id.b24 || 2870 (fcport->d_id.b24 & mask) != d_id.b24 ||
2782 fcport->port_type == FCT_BROADCAST) 2871 fcport->port_type == FCT_BROADCAST)
@@ -3940,3 +4029,40 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha)
3940 ret = qla2x00_stop_firmware(ha); 4029 ret = qla2x00_stop_firmware(ha);
3941 } 4030 }
3942} 4031}
4032
4033int
4034qla24xx_configure_vhba(scsi_qla_host_t *ha)
4035{
4036 int rval = QLA_SUCCESS;
4037 uint16_t mb[MAILBOX_REGISTER_COUNT];
4038
4039 if (!ha->parent)
4040 return -EINVAL;
4041
4042 rval = qla2x00_fw_ready(ha);
4043 if (rval == QLA_SUCCESS) {
4044 clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
4045 qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
4046 }
4047
4048 ha->flags.management_server_logged_in = 0;
4049
4050 /* Login to SNS first */
4051 qla24xx_login_fabric(ha, NPH_SNS, 0xff, 0xff, 0xfc,
4052 mb, BIT_1);
4053 if (mb[0] != MBS_COMMAND_COMPLETE) {
4054 DEBUG15(qla_printk(KERN_INFO, ha,
4055 "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x "
4056 "mb[2]=%x mb[6]=%x mb[7]=%x\n", NPH_SNS,
4057 mb[0], mb[1], mb[2], mb[6], mb[7]));
4058 return (QLA_FUNCTION_FAILED);
4059 }
4060
4061 atomic_set(&ha->loop_down_timer, 0);
4062 atomic_set(&ha->loop_state, LOOP_UP);
4063 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
4064 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
4065 rval = qla2x00_loop_resync(ha);
4066
4067 return rval;
4068}
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index c517a1478e44..c71863ff5489 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -179,7 +179,6 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
179 cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address; 179 cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;
180 180
181 /* Load data segments */ 181 /* Load data segments */
182
183 scsi_for_each_sg(cmd, sg, tot_dsds, i) { 182 scsi_for_each_sg(cmd, sg, tot_dsds, i) {
184 cont_entry_t *cont_pkt; 183 cont_entry_t *cont_pkt;
185 184
@@ -316,9 +315,14 @@ qla2x00_start_scsi(srb_t *sp)
316 goto queuing_error; 315 goto queuing_error;
317 316
318 /* Map the sg table so we have an accurate count of sg entries needed */ 317 /* Map the sg table so we have an accurate count of sg entries needed */
319 nseg = scsi_dma_map(cmd); 318 if (scsi_sg_count(cmd)) {
320 if (nseg < 0) 319 nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
321 goto queuing_error; 320 scsi_sg_count(cmd), cmd->sc_data_direction);
321 if (unlikely(!nseg))
322 goto queuing_error;
323 } else
324 nseg = 0;
325
322 tot_dsds = nseg; 326 tot_dsds = nseg;
323 327
324 /* Calculate the number of request entries needed. */ 328 /* Calculate the number of request entries needed. */
@@ -414,9 +418,10 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
414{ 418{
415 mrk_entry_t *mrk; 419 mrk_entry_t *mrk;
416 struct mrk_entry_24xx *mrk24; 420 struct mrk_entry_24xx *mrk24;
421 scsi_qla_host_t *pha = to_qla_parent(ha);
417 422
418 mrk24 = NULL; 423 mrk24 = NULL;
419 mrk = (mrk_entry_t *)qla2x00_req_pkt(ha); 424 mrk = (mrk_entry_t *)qla2x00_req_pkt(pha);
420 if (mrk == NULL) { 425 if (mrk == NULL) {
421 DEBUG2_3(printk("%s(%ld): failed to allocate Marker IOCB.\n", 426 DEBUG2_3(printk("%s(%ld): failed to allocate Marker IOCB.\n",
422 __func__, ha->host_no)); 427 __func__, ha->host_no));
@@ -433,6 +438,7 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
433 mrk24->lun[1] = LSB(lun); 438 mrk24->lun[1] = LSB(lun);
434 mrk24->lun[2] = MSB(lun); 439 mrk24->lun[2] = MSB(lun);
435 host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun)); 440 host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
441 mrk24->vp_index = ha->vp_idx;
436 } else { 442 } else {
437 SET_TARGET_ID(ha, mrk->target, loop_id); 443 SET_TARGET_ID(ha, mrk->target, loop_id);
438 mrk->lun = cpu_to_le16(lun); 444 mrk->lun = cpu_to_le16(lun);
@@ -440,7 +446,7 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
440 } 446 }
441 wmb(); 447 wmb();
442 448
443 qla2x00_isp_cmd(ha); 449 qla2x00_isp_cmd(pha);
444 450
445 return (QLA_SUCCESS); 451 return (QLA_SUCCESS);
446} 452}
@@ -712,9 +718,14 @@ qla24xx_start_scsi(srb_t *sp)
712 goto queuing_error; 718 goto queuing_error;
713 719
714 /* Map the sg table so we have an accurate count of sg entries needed */ 720 /* Map the sg table so we have an accurate count of sg entries needed */
715 nseg = scsi_dma_map(cmd); 721 if (scsi_sg_count(cmd)) {
716 if (nseg < 0) 722 nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
723 scsi_sg_count(cmd), cmd->sc_data_direction);
724 if (unlikely(!nseg))
717 goto queuing_error; 725 goto queuing_error;
726 } else
727 nseg = 0;
728
718 tot_dsds = nseg; 729 tot_dsds = nseg;
719 730
720 req_cnt = qla24xx_calc_iocbs(tot_dsds); 731 req_cnt = qla24xx_calc_iocbs(tot_dsds);
@@ -750,6 +761,7 @@ qla24xx_start_scsi(srb_t *sp)
750 cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; 761 cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
751 cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; 762 cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
752 cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; 763 cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
764 cmd_pkt->vp_index = sp->fcport->vp_idx;
753 765
754 int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); 766 int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
755 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); 767 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 6ce532cdc4c1..0ba4c8d37879 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -9,7 +9,6 @@
9#include <scsi/scsi_tcq.h> 9#include <scsi/scsi_tcq.h>
10 10
11static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); 11static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
12static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
13static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); 12static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
14static void qla2x00_status_entry(scsi_qla_host_t *, void *); 13static void qla2x00_status_entry(scsi_qla_host_t *, void *);
15static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); 14static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
@@ -244,7 +243,7 @@ qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
244 * @ha: SCSI driver HA context 243 * @ha: SCSI driver HA context
245 * @mb: Mailbox registers (0 - 3) 244 * @mb: Mailbox registers (0 - 3)
246 */ 245 */
247static void 246void
248qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) 247qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
249{ 248{
250#define LS_UNKNOWN 2 249#define LS_UNKNOWN 2
@@ -386,6 +385,11 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
386 qla2x00_mark_all_devices_lost(ha, 1); 385 qla2x00_mark_all_devices_lost(ha, 1);
387 } 386 }
388 387
388 if (ha->parent) {
389 atomic_set(&ha->vp_state, VP_FAILED);
390 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
391 }
392
389 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); 393 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
390 394
391 ha->flags.management_server_logged_in = 0; 395 ha->flags.management_server_logged_in = 0;
@@ -422,6 +426,11 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
422 qla2x00_mark_all_devices_lost(ha, 1); 426 qla2x00_mark_all_devices_lost(ha, 1);
423 } 427 }
424 428
429 if (ha->parent) {
430 atomic_set(&ha->vp_state, VP_FAILED);
431 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
432 }
433
425 ha->flags.management_server_logged_in = 0; 434 ha->flags.management_server_logged_in = 0;
426 ha->link_data_rate = PORT_SPEED_UNKNOWN; 435 ha->link_data_rate = PORT_SPEED_UNKNOWN;
427 if (ql2xfdmienable) 436 if (ql2xfdmienable)
@@ -440,6 +449,11 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
440 qla2x00_mark_all_devices_lost(ha, 1); 449 qla2x00_mark_all_devices_lost(ha, 1);
441 } 450 }
442 451
452 if (ha->parent) {
453 atomic_set(&ha->vp_state, VP_FAILED);
454 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
455 }
456
443 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); 457 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
444 458
445 ha->operating_mode = LOOP; 459 ha->operating_mode = LOOP;
@@ -465,6 +479,11 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
465 qla2x00_mark_all_devices_lost(ha, 1); 479 qla2x00_mark_all_devices_lost(ha, 1);
466 } 480 }
467 481
482 if (ha->parent) {
483 atomic_set(&ha->vp_state, VP_FAILED);
484 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
485 }
486
468 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) { 487 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
469 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); 488 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
470 } 489 }
@@ -491,6 +510,11 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
491 qla2x00_mark_all_devices_lost(ha, 1); 510 qla2x00_mark_all_devices_lost(ha, 1);
492 } 511 }
493 512
513 if (ha->parent) {
514 atomic_set(&ha->vp_state, VP_FAILED);
515 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
516 }
517
494 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); 518 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
495 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); 519 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
496 break; 520 break;
@@ -530,6 +554,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
530 break; 554 break;
531 555
532 case MBA_RSCN_UPDATE: /* State Change Registration */ 556 case MBA_RSCN_UPDATE: /* State Change Registration */
557 /* Check if the Vport has issued a SCR */
558 if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags))
559 break;
560
533 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", 561 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
534 ha->host_no)); 562 ha->host_no));
535 DEBUG(printk(KERN_INFO 563 DEBUG(printk(KERN_INFO
@@ -589,6 +617,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
589 ha->host_no, mb[1], mb[2])); 617 ha->host_no, mb[1], mb[2]));
590 break; 618 break;
591 } 619 }
620
621 if (!ha->parent && ha->num_vhosts)
622 qla2x00_alert_all_vps(ha, mb);
592} 623}
593 624
594static void 625static void
@@ -1393,6 +1424,10 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
1393 case MS_IOCB_TYPE: 1424 case MS_IOCB_TYPE:
1394 qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt); 1425 qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
1395 break; 1426 break;
1427 case VP_RPT_ID_IOCB_TYPE:
1428 qla24xx_report_id_acquisition(ha,
1429 (struct vp_rpt_id_entry_24xx *)pkt);
1430 break;
1396 default: 1431 default:
1397 /* Type Not Supported. */ 1432 /* Type Not Supported. */
1398 DEBUG4(printk(KERN_WARNING 1433 DEBUG4(printk(KERN_WARNING
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 71e32a248528..2cd0cff25928 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -42,25 +42,29 @@ qla2x00_mbx_sem_timeout(unsigned long data)
42 * Kernel context. 42 * Kernel context.
43 */ 43 */
44static int 44static int
45qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) 45qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
46{ 46{
47 int rval; 47 int rval;
48 unsigned long flags = 0; 48 unsigned long flags = 0;
49 device_reg_t __iomem *reg = ha->iobase; 49 device_reg_t __iomem *reg;
50 struct timer_list tmp_intr_timer; 50 struct timer_list tmp_intr_timer;
51 uint8_t abort_active; 51 uint8_t abort_active;
52 uint8_t io_lock_on = ha->flags.init_done; 52 uint8_t io_lock_on;
53 uint16_t command; 53 uint16_t command;
54 uint16_t *iptr; 54 uint16_t *iptr;
55 uint16_t __iomem *optr; 55 uint16_t __iomem *optr;
56 uint32_t cnt; 56 uint32_t cnt;
57 uint32_t mboxes; 57 uint32_t mboxes;
58 unsigned long wait_time; 58 unsigned long wait_time;
59 scsi_qla_host_t *ha = to_qla_parent(pvha);
60
61 reg = ha->iobase;
62 io_lock_on = ha->flags.init_done;
59 63
60 rval = QLA_SUCCESS; 64 rval = QLA_SUCCESS;
61 abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); 65 abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
62 66
63 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 67 DEBUG11(printk("%s(%ld): entered.\n", __func__, pvha->host_no));
64 68
65 /* 69 /*
66 * Wait for active mailbox commands to finish by waiting at most tov 70 * Wait for active mailbox commands to finish by waiting at most tov
@@ -889,7 +893,7 @@ qla2x00_abort_target(fc_port_t *fcport)
889 */ 893 */
890int 894int
891qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, 895qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
892 uint8_t *area, uint8_t *domain, uint16_t *top) 896 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
893{ 897{
894 int rval; 898 int rval;
895 mbx_cmd_t mc; 899 mbx_cmd_t mc;
@@ -899,8 +903,9 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
899 ha->host_no)); 903 ha->host_no));
900 904
901 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; 905 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
906 mcp->mb[9] = ha->vp_idx;
902 mcp->out_mb = MBX_0; 907 mcp->out_mb = MBX_0;
903 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 908 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
904 mcp->tov = 30; 909 mcp->tov = 30;
905 mcp->flags = 0; 910 mcp->flags = 0;
906 rval = qla2x00_mailbox_command(ha, mcp); 911 rval = qla2x00_mailbox_command(ha, mcp);
@@ -913,6 +918,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
913 *area = MSB(mcp->mb[2]); 918 *area = MSB(mcp->mb[2]);
914 *domain = LSB(mcp->mb[3]); 919 *domain = LSB(mcp->mb[3]);
915 *top = mcp->mb[6]; 920 *top = mcp->mb[6];
921 *sw_cap = mcp->mb[7];
916 922
917 if (rval != QLA_SUCCESS) { 923 if (rval != QLA_SUCCESS) {
918 /*EMPTY*/ 924 /*EMPTY*/
@@ -1009,7 +1015,11 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
1009 DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", 1015 DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
1010 ha->host_no)); 1016 ha->host_no));
1011 1017
1012 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; 1018 if (ha->flags.npiv_supported)
1019 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1020 else
1021 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1022
1013 mcp->mb[2] = MSW(ha->init_cb_dma); 1023 mcp->mb[2] = MSW(ha->init_cb_dma);
1014 mcp->mb[3] = LSW(ha->init_cb_dma); 1024 mcp->mb[3] = LSW(ha->init_cb_dma);
1015 mcp->mb[4] = 0; 1025 mcp->mb[4] = 0;
@@ -1081,7 +1091,8 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
1081 mcp->mb[3] = LSW(pd_dma); 1091 mcp->mb[3] = LSW(pd_dma);
1082 mcp->mb[6] = MSW(MSD(pd_dma)); 1092 mcp->mb[6] = MSW(MSD(pd_dma));
1083 mcp->mb[7] = LSW(MSD(pd_dma)); 1093 mcp->mb[7] = LSW(MSD(pd_dma));
1084 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1094 mcp->mb[9] = ha->vp_idx;
1095 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1085 mcp->in_mb = MBX_0; 1096 mcp->in_mb = MBX_0;
1086 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 1097 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
1087 mcp->mb[1] = fcport->loop_id; 1098 mcp->mb[1] = fcport->loop_id;
@@ -1259,7 +1270,8 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
1259 ha->host_no)); 1270 ha->host_no));
1260 1271
1261 mcp->mb[0] = MBC_GET_PORT_NAME; 1272 mcp->mb[0] = MBC_GET_PORT_NAME;
1262 mcp->out_mb = MBX_1|MBX_0; 1273 mcp->mb[9] = ha->vp_idx;
1274 mcp->out_mb = MBX_9|MBX_1|MBX_0;
1263 if (HAS_EXTENDED_IDS(ha)) { 1275 if (HAS_EXTENDED_IDS(ha)) {
1264 mcp->mb[1] = loop_id; 1276 mcp->mb[1] = loop_id;
1265 mcp->mb[10] = opt; 1277 mcp->mb[10] = opt;
@@ -1447,6 +1459,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
1447 lg->port_id[0] = al_pa; 1459 lg->port_id[0] = al_pa;
1448 lg->port_id[1] = area; 1460 lg->port_id[1] = area;
1449 lg->port_id[2] = domain; 1461 lg->port_id[2] = domain;
1462 lg->vp_index = cpu_to_le16(ha->vp_idx);
1450 rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); 1463 rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0);
1451 if (rval != QLA_SUCCESS) { 1464 if (rval != QLA_SUCCESS) {
1452 DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " 1465 DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB "
@@ -1701,6 +1714,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
1701 lg->port_id[0] = al_pa; 1714 lg->port_id[0] = al_pa;
1702 lg->port_id[1] = area; 1715 lg->port_id[1] = area;
1703 lg->port_id[2] = domain; 1716 lg->port_id[2] = domain;
1717 lg->vp_index = cpu_to_le16(ha->vp_idx);
1704 rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); 1718 rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0);
1705 if (rval != QLA_SUCCESS) { 1719 if (rval != QLA_SUCCESS) {
1706 DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " 1720 DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB "
@@ -1863,7 +1877,8 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
1863 mcp->mb[6] = MSW(MSD(id_list_dma)); 1877 mcp->mb[6] = MSW(MSD(id_list_dma));
1864 mcp->mb[7] = LSW(MSD(id_list_dma)); 1878 mcp->mb[7] = LSW(MSD(id_list_dma));
1865 mcp->mb[8] = 0; 1879 mcp->mb[8] = 0;
1866 mcp->out_mb |= MBX_8|MBX_7|MBX_6|MBX_3|MBX_2; 1880 mcp->mb[9] = ha->vp_idx;
1881 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
1867 } else { 1882 } else {
1868 mcp->mb[1] = MSW(id_list_dma); 1883 mcp->mb[1] = MSW(id_list_dma);
1869 mcp->mb[2] = LSW(id_list_dma); 1884 mcp->mb[2] = LSW(id_list_dma);
@@ -2212,6 +2227,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
2212 abt->port_id[0] = fcport->d_id.b.al_pa; 2227 abt->port_id[0] = fcport->d_id.b.al_pa;
2213 abt->port_id[1] = fcport->d_id.b.area; 2228 abt->port_id[1] = fcport->d_id.b.area;
2214 abt->port_id[2] = fcport->d_id.b.domain; 2229 abt->port_id[2] = fcport->d_id.b.domain;
2230 abt->vp_index = fcport->vp_idx;
2215 rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); 2231 rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0);
2216 if (rval != QLA_SUCCESS) { 2232 if (rval != QLA_SUCCESS) {
2217 DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", 2233 DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n",
@@ -2249,7 +2265,7 @@ qla24xx_abort_target(fc_port_t *fcport)
2249 int rval; 2265 int rval;
2250 struct tsk_mgmt_cmd *tsk; 2266 struct tsk_mgmt_cmd *tsk;
2251 dma_addr_t tsk_dma; 2267 dma_addr_t tsk_dma;
2252 scsi_qla_host_t *ha; 2268 scsi_qla_host_t *ha, *pha;
2253 2269
2254 if (fcport == NULL) 2270 if (fcport == NULL)
2255 return 0; 2271 return 0;
@@ -2257,7 +2273,8 @@ qla24xx_abort_target(fc_port_t *fcport)
2257 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); 2273 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
2258 2274
2259 ha = fcport->ha; 2275 ha = fcport->ha;
2260 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); 2276 pha = to_qla_parent(ha);
2277 tsk = dma_pool_alloc(pha->s_dma_pool, GFP_KERNEL, &tsk_dma);
2261 if (tsk == NULL) { 2278 if (tsk == NULL) {
2262 DEBUG2_3(printk("%s(%ld): failed to allocate Task Management " 2279 DEBUG2_3(printk("%s(%ld): failed to allocate Task Management "
2263 "IOCB.\n", __func__, ha->host_no)); 2280 "IOCB.\n", __func__, ha->host_no));
@@ -2273,6 +2290,8 @@ qla24xx_abort_target(fc_port_t *fcport)
2273 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; 2290 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2274 tsk->p.tsk.port_id[1] = fcport->d_id.b.area; 2291 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2275 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; 2292 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
2293 tsk->p.tsk.vp_index = fcport->vp_idx;
2294
2276 rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); 2295 rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0);
2277 if (rval != QLA_SUCCESS) { 2296 if (rval != QLA_SUCCESS) {
2278 DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " 2297 DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB "
@@ -2303,7 +2322,7 @@ qla24xx_abort_target(fc_port_t *fcport)
2303 } 2322 }
2304 2323
2305atarget_done: 2324atarget_done:
2306 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma); 2325 dma_pool_free(pha->s_dma_pool, tsk, tsk_dma);
2307 2326
2308 return rval; 2327 return rval;
2309} 2328}
@@ -2610,3 +2629,354 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
2610 2629
2611 return rval; 2630 return rval;
2612} 2631}
2632
2633/*
2634 * qla24xx_get_vp_database
2635 * Get the VP's database for all configured ports.
2636 *
2637 * Input:
2638 * ha = adapter block pointer.
2639 * size = size of initialization control block.
2640 *
2641 * Returns:
2642 * qla2x00 local function return status code.
2643 *
2644 * Context:
2645 * Kernel context.
2646 */
2647int
2648qla24xx_get_vp_database(scsi_qla_host_t *ha, uint16_t size)
2649{
2650 int rval;
2651 mbx_cmd_t mc;
2652 mbx_cmd_t *mcp = &mc;
2653
2654 DEBUG11(printk("scsi(%ld):%s - entered.\n",
2655 ha->host_no, __func__));
2656
2657 mcp->mb[0] = MBC_MID_GET_VP_DATABASE;
2658 mcp->mb[2] = MSW(ha->init_cb_dma);
2659 mcp->mb[3] = LSW(ha->init_cb_dma);
2660 mcp->mb[4] = 0;
2661 mcp->mb[5] = 0;
2662 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
2663 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
2664 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2665 mcp->in_mb = MBX_1|MBX_0;
2666 mcp->buf_size = size;
2667 mcp->flags = MBX_DMA_OUT;
2668 mcp->tov = MBX_TOV_SECONDS;
2669 rval = qla2x00_mailbox_command(ha, mcp);
2670
2671 if (rval != QLA_SUCCESS) {
2672 /*EMPTY*/
2673 DEBUG2_3_11(printk("%s(%ld): failed=%x "
2674 "mb0=%x.\n",
2675 __func__, ha->host_no, rval, mcp->mb[0]));
2676 } else {
2677 /*EMPTY*/
2678 DEBUG11(printk("%s(%ld): done.\n",
2679 __func__, ha->host_no));
2680 }
2681
2682 return rval;
2683}
2684
2685int
2686qla24xx_get_vp_entry(scsi_qla_host_t *ha, uint16_t size, int vp_id)
2687{
2688 int rval;
2689 mbx_cmd_t mc;
2690 mbx_cmd_t *mcp = &mc;
2691
2692 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
2693
2694 mcp->mb[0] = MBC_MID_GET_VP_ENTRY;
2695 mcp->mb[2] = MSW(ha->init_cb_dma);
2696 mcp->mb[3] = LSW(ha->init_cb_dma);
2697 mcp->mb[4] = 0;
2698 mcp->mb[5] = 0;
2699 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
2700 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
2701 mcp->mb[9] = vp_id;
2702 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2703 mcp->in_mb = MBX_0;
2704 mcp->buf_size = size;
2705 mcp->flags = MBX_DMA_OUT;
2706 mcp->tov = 30;
2707 rval = qla2x00_mailbox_command(ha, mcp);
2708
2709 if (rval != QLA_SUCCESS) {
2710 /*EMPTY*/
2711 DEBUG2_3_11(printk("qla24xx_get_vp_entry(%ld): failed=%x "
2712 "mb0=%x.\n",
2713 ha->host_no, rval, mcp->mb[0]));
2714 } else {
2715 /*EMPTY*/
2716 DEBUG11(printk("qla24xx_get_vp_entry(%ld): done.\n",
2717 ha->host_no));
2718 }
2719
2720 return rval;
2721}
2722
2723void
2724qla24xx_report_id_acquisition(scsi_qla_host_t *ha,
2725 struct vp_rpt_id_entry_24xx *rptid_entry)
2726{
2727 uint8_t vp_idx;
2728 scsi_qla_host_t *vha;
2729
2730 if (rptid_entry->entry_status != 0)
2731 return;
2732 if (rptid_entry->entry_status != __constant_cpu_to_le16(CS_COMPLETE))
2733 return;
2734
2735 if (rptid_entry->format == 0) {
2736 DEBUG15(printk("%s:format 0 : scsi(%ld) number of VPs setup %d,"
2737 " number of VPs acquired %d\n", __func__, ha->host_no,
2738 MSB(rptid_entry->vp_count), LSB(rptid_entry->vp_count)));
2739 DEBUG15(printk("%s primary port id %02x%02x%02x\n", __func__,
2740 rptid_entry->port_id[2], rptid_entry->port_id[1],
2741 rptid_entry->port_id[0]));
2742 } else if (rptid_entry->format == 1) {
2743 vp_idx = LSB(rptid_entry->vp_idx);
2744 DEBUG15(printk("%s:format 1: scsi(%ld): VP[%d] enabled "
2745 "- status %d - "
2746 "with port id %02x%02x%02x\n",__func__,ha->host_no,
2747 vp_idx, MSB(rptid_entry->vp_idx),
2748 rptid_entry->port_id[2], rptid_entry->port_id[1],
2749 rptid_entry->port_id[0]));
2750 if (vp_idx == 0)
2751 return;
2752
2753 if (MSB(rptid_entry->vp_idx) == 1)
2754 return;
2755
2756 list_for_each_entry(vha, &ha->vp_list, vp_list)
2757 if (vp_idx == vha->vp_idx)
2758 break;
2759
2760 if (!vha)
2761 return;
2762
2763 vha->d_id.b.domain = rptid_entry->port_id[2];
2764 vha->d_id.b.area = rptid_entry->port_id[1];
2765 vha->d_id.b.al_pa = rptid_entry->port_id[0];
2766
2767 /*
2768 * Cannot configure here as we are still sitting on the
2769 * response queue. Handle it in dpc context.
2770 */
2771 set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
2772 set_bit(VP_DPC_NEEDED, &ha->dpc_flags);
2773
2774 wake_up_process(ha->dpc_thread);
2775 }
2776}
2777
2778/*
2779 * qla24xx_modify_vp_config
2780 * Change VP configuration for vha
2781 *
2782 * Input:
2783 * vha = adapter block pointer.
2784 *
2785 * Returns:
2786 * qla2xxx local function return status code.
2787 *
2788 * Context:
2789 * Kernel context.
2790 */
2791int
2792qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2793{
2794 int rval;
2795 struct vp_config_entry_24xx *vpmod;
2796 dma_addr_t vpmod_dma;
2797 scsi_qla_host_t *pha;
2798
2799 /* This can be called by the parent */
2800 pha = to_qla_parent(vha);
2801
2802 vpmod = dma_pool_alloc(pha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
2803 if (!vpmod) {
2804 DEBUG2_3(printk("%s(%ld): failed to allocate Modify VP "
2805 "IOCB.\n", __func__, pha->host_no));
2806 return QLA_MEMORY_ALLOC_FAILED;
2807 }
2808
2809 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2810 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2811 vpmod->entry_count = 1;
2812 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2813 vpmod->vp_count = 1;
2814 vpmod->vp_index1 = vha->vp_idx;
2815 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2816 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2817 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2818 vpmod->entry_count = 1;
2819
2820 rval = qla2x00_issue_iocb(pha, vpmod, vpmod_dma, 0);
2821 if (rval != QLA_SUCCESS) {
2822 DEBUG2_3_11(printk("%s(%ld): failed to issue VP config IOCB"
2823 "(%x).\n", __func__, pha->host_no, rval));
2824 } else if (vpmod->comp_status != 0) {
2825 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
2826 "-- error status (%x).\n", __func__, pha->host_no,
2827 vpmod->comp_status));
2828 rval = QLA_FUNCTION_FAILED;
2829 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
2830 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
2831 "-- completion status (%x).\n", __func__, pha->host_no,
2832 le16_to_cpu(vpmod->comp_status)));
2833 rval = QLA_FUNCTION_FAILED;
2834 } else {
2835 /* EMPTY */
2836 DEBUG11(printk("%s(%ld): done.\n", __func__, pha->host_no));
2837 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
2838 }
2839 dma_pool_free(pha->s_dma_pool, vpmod, vpmod_dma);
2840
2841 return rval;
2842}
2843
2844/*
2845 * qla24xx_control_vp
2846 * Enable a virtual port for given host
2847 *
2848 * Input:
2849 * ha = adapter block pointer.
2850 * vhba = virtual adapter (unused)
2851 * index = index number for enabled VP
2852 *
2853 * Returns:
2854 * qla2xxx local function return status code.
2855 *
2856 * Context:
2857 * Kernel context.
2858 */
2859int
2860qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
2861{
2862 int rval;
2863 int map, pos;
2864 struct vp_ctrl_entry_24xx *vce;
2865 dma_addr_t vce_dma;
2866 scsi_qla_host_t *ha = vha->parent;
2867 int vp_index = vha->vp_idx;
2868
2869 DEBUG11(printk("%s(%ld): entered. Enabling index %d\n", __func__,
2870 ha->host_no, vp_index));
2871
2872 if (vp_index == 0 || vp_index >= MAX_MULTI_ID_LOOP)
2873 return QLA_PARAMETER_ERROR;
2874
2875 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
2876 if (!vce) {
2877 DEBUG2_3(printk("%s(%ld): "
2878 "failed to allocate VP Control IOCB.\n", __func__,
2879 ha->host_no));
2880 return QLA_MEMORY_ALLOC_FAILED;
2881 }
2882 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
2883
2884 vce->entry_type = VP_CTRL_IOCB_TYPE;
2885 vce->entry_count = 1;
2886 vce->command = cpu_to_le16(cmd);
2887 vce->vp_count = __constant_cpu_to_le16(1);
2888
2889 /* index map in firmware starts with 1; decrement index
2890 * this is ok as we never use index 0
2891 */
2892 map = (vp_index - 1) / 8;
2893 pos = (vp_index - 1) & 7;
2894 down(&ha->vport_sem);
2895 vce->vp_idx_map[map] |= 1 << pos;
2896 up(&ha->vport_sem);
2897
2898 rval = qla2x00_issue_iocb(ha, vce, vce_dma, 0);
2899 if (rval != QLA_SUCCESS) {
2900 DEBUG2_3_11(printk("%s(%ld): failed to issue VP control IOCB"
2901 "(%x).\n", __func__, ha->host_no, rval));
2902 printk("%s(%ld): failed to issue VP control IOCB"
2903 "(%x).\n", __func__, ha->host_no, rval);
2904 } else if (vce->entry_status != 0) {
2905 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
2906 "-- error status (%x).\n", __func__, ha->host_no,
2907 vce->entry_status));
2908 printk("%s(%ld): failed to complete IOCB "
2909 "-- error status (%x).\n", __func__, ha->host_no,
2910 vce->entry_status);
2911 rval = QLA_FUNCTION_FAILED;
2912 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
2913 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
2914 "-- completion status (%x).\n", __func__, ha->host_no,
2915 le16_to_cpu(vce->comp_status)));
2916 printk("%s(%ld): failed to complete IOCB "
2917 "-- completion status (%x).\n", __func__, ha->host_no,
2918 le16_to_cpu(vce->comp_status));
2919 rval = QLA_FUNCTION_FAILED;
2920 } else {
2921 DEBUG2(printk("%s(%ld): done.\n", __func__, ha->host_no));
2922 }
2923
2924 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
2925
2926 return rval;
2927}
2928
2929/*
2930 * qla2x00_send_change_request
2931 * Receive or disable RSCN request from fabric controller
2932 *
2933 * Input:
2934 * ha = adapter block pointer
2935 * format = registration format:
2936 * 0 - Reserved
2937 * 1 - Fabric detected registration
2938 * 2 - N_port detected registration
2939 * 3 - Full registration
2940 * FF - clear registration
2941 * vp_idx = Virtual port index
2942 *
2943 * Returns:
2944 * qla2x00 local function return status code.
2945 *
2946 * Context:
2947 * Kernel Context
2948 */
2949
2950int
2951qla2x00_send_change_request(scsi_qla_host_t *ha, uint16_t format,
2952 uint16_t vp_idx)
2953{
2954 int rval;
2955 mbx_cmd_t mc;
2956 mbx_cmd_t *mcp = &mc;
2957
2958 /*
2959 * This command is implicitly executed by firmware during login for the
2960 * physical hosts
2961 */
2962 if (vp_idx == 0)
2963 return QLA_FUNCTION_FAILED;
2964
2965 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
2966 mcp->mb[1] = format;
2967 mcp->mb[9] = vp_idx;
2968 mcp->out_mb = MBX_9|MBX_1|MBX_0;
2969 mcp->in_mb = MBX_0|MBX_1;
2970 mcp->tov = MBX_TOV_SECONDS;
2971 mcp->flags = 0;
2972 rval = qla2x00_mailbox_command(ha, mcp);
2973
2974 if (rval == QLA_SUCCESS) {
2975 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2976 rval = BIT_1;
2977 }
2978 } else
2979 rval = BIT_1;
2980
2981 return rval;
2982}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
new file mode 100644
index 000000000000..54dc415d8b53
--- /dev/null
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -0,0 +1,497 @@
1/*
2 * QLOGIC LINUX SOFTWARE
3 *
4 * QLogic ISP2x00 device driver for Linux 2.6.x
5 * Copyright (C) 2003-2005 QLogic Corporation
6 * (www.qlogic.com)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 */
19#include "qla_def.h"
20
21#include <linux/version.h>
22#include <linux/moduleparam.h>
23#include <linux/vmalloc.h>
24#include <linux/smp_lock.h>
25#include <linux/list.h>
26
27#include <scsi/scsi_tcq.h>
28#include <scsi/scsicam.h>
29#include <linux/delay.h>
30
31void qla2x00_vp_stop_timer(scsi_qla_host_t *);
32
33void
34qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
35{
36 if (vha->parent && vha->timer_active) {
37 del_timer_sync(&vha->timer);
38 vha->timer_active = 0;
39 }
40}
41
42uint32_t
43qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
44{
45 uint32_t vp_id;
46 scsi_qla_host_t *ha = vha->parent;
47
48 /* Find an empty slot and assign an vp_id */
49 down(&ha->vport_sem);
50 vp_id = find_first_zero_bit((unsigned long *)ha->vp_idx_map,
51 MAX_MULTI_ID_FABRIC);
52 if (vp_id > MAX_MULTI_ID_FABRIC) {
53 DEBUG15(printk ("vp_id %d is bigger than MAX_MULTI_ID_FABRID\n",
54 vp_id));
55 up(&ha->vport_sem);
56 return vp_id;
57 }
58
59 set_bit(vp_id, (unsigned long *)ha->vp_idx_map);
60 ha->num_vhosts++;
61 vha->vp_idx = vp_id;
62 list_add_tail(&vha->vp_list, &ha->vp_list);
63 up(&ha->vport_sem);
64 return vp_id;
65}
66
67void
68qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
69{
70 uint16_t vp_id;
71 scsi_qla_host_t *ha = vha->parent;
72
73 down(&ha->vport_sem);
74 vp_id = vha->vp_idx;
75 ha->num_vhosts--;
76 clear_bit(vp_id, (unsigned long *)ha->vp_idx_map);
77 list_del(&vha->vp_list);
78 up(&ha->vport_sem);
79}
80
81scsi_qla_host_t *
82qla24xx_find_vhost_by_name(scsi_qla_host_t *ha, uint8_t *port_name)
83{
84 scsi_qla_host_t *vha;
85
86 /* Locate matching device in database. */
87 list_for_each_entry(vha, &ha->vp_list, vp_list) {
88 if (!memcmp(port_name, vha->port_name, WWN_SIZE))
89 return vha;
90 }
91 return NULL;
92}
93
94/*
95 * qla2x00_mark_vp_devices_dead
96 * Updates fcport state when device goes offline.
97 *
98 * Input:
99 * ha = adapter block pointer.
100 * fcport = port structure pointer.
101 *
102 * Return:
103 * None.
104 *
105 * Context:
106 */
107void
108qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
109{
110 fc_port_t *fcport;
111 scsi_qla_host_t *pha = to_qla_parent(vha);
112
113 list_for_each_entry(fcport, &pha->fcports, list) {
114 if (fcport->vp_idx != vha->vp_idx)
115 continue;
116
117 DEBUG15(printk("scsi(%ld): Marking port dead, "
118 "loop_id=0x%04x :%x\n",
119 vha->host_no, fcport->loop_id, fcport->vp_idx));
120
121 atomic_set(&fcport->state, FCS_DEVICE_DEAD);
122 qla2x00_mark_device_lost(vha, fcport, 0, 0);
123 }
124}
125
126int
127qla24xx_disable_vp(scsi_qla_host_t *vha)
128{
129 int ret;
130
131 ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
132 atomic_set(&vha->loop_state, LOOP_DOWN);
133 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
134
135 /* Delete all vp's fcports from parent's list */
136 qla2x00_mark_vp_devices_dead(vha);
137 atomic_set(&vha->vp_state, VP_FAILED);
138 vha->flags.management_server_logged_in = 0;
139 if (ret == QLA_SUCCESS) {
140 fc_vport_set_state(vha->fc_vport, FC_VPORT_DISABLED);
141 } else {
142 fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
143 return -1;
144 }
145 return 0;
146}
147
148int
149qla24xx_enable_vp(scsi_qla_host_t *vha)
150{
151 int ret;
152 scsi_qla_host_t *ha = vha->parent;
153
154 /* Check if physical ha port is Up */
155 if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
156 atomic_read(&ha->loop_state) == LOOP_DEAD ) {
157 vha->vp_err_state = VP_ERR_PORTDWN;
158 fc_vport_set_state(vha->fc_vport, FC_VPORT_LINKDOWN);
159 goto enable_failed;
160 }
161
162 /* Initialize the new vport unless it is a persistent port */
163 down(&ha->vport_sem);
164 ret = qla24xx_modify_vp_config(vha);
165 up(&ha->vport_sem);
166
167 if (ret != QLA_SUCCESS) {
168 fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
169 goto enable_failed;
170 }
171
172 DEBUG15(qla_printk(KERN_INFO, ha,
173 "Virtual port with id: %d - Enabled\n", vha->vp_idx));
174 return 0;
175
176enable_failed:
177 DEBUG15(qla_printk(KERN_INFO, ha,
178 "Virtual port with id: %d - Disabled\n", vha->vp_idx));
179 return 1;
180}
181
182/**
183 * qla24xx_modify_vport() - Modifies the virtual fabric port's configuration
184 * @ha: HA context
185 * @vp: pointer to buffer of virtual port parameters.
186 * @ret_code: return error code:
187 *
188 * Returns the virtual port id, or MAX_VSAN_ID, if couldn't create.
189 */
190uint32_t
191qla24xx_modify_vhba(scsi_qla_host_t *ha, vport_params_t *vp, uint32_t *vp_id)
192{
193 scsi_qla_host_t *vha;
194
195 vha = qla24xx_find_vhost_by_name(ha, vp->port_name);
196 if (!vha) {
197 *vp_id = MAX_NUM_VPORT_LOOP;
198 return VP_RET_CODE_WWPN;
199 }
200
201 if (qla24xx_enable_vp(vha)) {
202 scsi_host_put(vha->host);
203 qla2x00_mem_free(vha);
204 *vp_id = MAX_NUM_VPORT_LOOP;
205 return VP_RET_CODE_RESOURCES;
206 }
207
208 *vp_id = vha->vp_idx;
209 return VP_RET_CODE_OK;
210}
211
212void
213qla24xx_configure_vp(scsi_qla_host_t *vha)
214{
215 struct fc_vport *fc_vport;
216 int ret;
217
218 fc_vport = vha->fc_vport;
219
220 DEBUG15(printk("scsi(%ld): %s: change request #3 for this host.\n",
221 vha->host_no, __func__));
222 ret = qla2x00_send_change_request(vha, 0x3, vha->vp_idx);
223 if (ret != QLA_SUCCESS) {
224 DEBUG15(qla_printk(KERN_ERR, vha, "Failed to enable receiving"
225 " of RSCN requests: 0x%x\n", ret));
226 return;
227 } else {
228 /* Corresponds to SCR enabled */
229 clear_bit(VP_SCR_NEEDED, &vha->vp_flags);
230 }
231
232 vha->flags.online = 1;
233 if (qla24xx_configure_vhba(vha))
234 return;
235
236 atomic_set(&vha->vp_state, VP_ACTIVE);
237 fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
238}
239
240void
241qla2x00_alert_all_vps(scsi_qla_host_t *ha, uint16_t *mb)
242{
243 int i, vp_idx_matched;
244 scsi_qla_host_t *vha;
245
246 if (ha->parent)
247 return;
248
249 i = find_next_bit((unsigned long *)ha->vp_idx_map,
250 MAX_MULTI_ID_FABRIC + 1, 1);
251 for (;i <= MAX_MULTI_ID_FABRIC;
252 i = find_next_bit((unsigned long *)ha->vp_idx_map,
253 MAX_MULTI_ID_FABRIC + 1, i + 1)) {
254 vp_idx_matched = 0;
255
256 list_for_each_entry(vha, &ha->vp_list, vp_list) {
257 if (i == vha->vp_idx) {
258 vp_idx_matched = 1;
259 break;
260 }
261 }
262
263 if (vp_idx_matched) {
264 switch (mb[0]) {
265 case MBA_LIP_OCCURRED:
266 case MBA_LOOP_UP:
267 case MBA_LOOP_DOWN:
268 case MBA_LIP_RESET:
269 case MBA_POINT_TO_POINT:
270 case MBA_CHG_IN_CONNECTION:
271 case MBA_PORT_UPDATE:
272 case MBA_RSCN_UPDATE:
273 DEBUG15(printk("scsi(%ld)%s: Async_event for"
274 " VP[%d], mb = 0x%x, vha=%p\n",
275 vha->host_no, __func__,i, *mb, vha));
276 qla2x00_async_event(vha, mb);
277 break;
278 }
279 }
280 }
281}
282
283void
284qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
285{
286 /*
287 * Physical port will do most of the abort and recovery work. We can
288 * just treat it as a loop down
289 */
290 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
291 atomic_set(&vha->loop_state, LOOP_DOWN);
292 qla2x00_mark_all_devices_lost(vha, 0);
293 } else {
294 if (!atomic_read(&vha->loop_down_timer))
295 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
296 }
297
298 DEBUG15(printk("scsi(%ld): Scheduling enable of Vport %d...\n",
299 vha->host_no, vha->vp_idx));
300 qla24xx_enable_vp(vha);
301}
302
303int
304qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
305{
306 if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
307 /* VP acquired. complete port configuration */
308 qla24xx_configure_vp(vha);
309 return 0;
310 }
311
312 if (test_and_clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
313 qla2x00_vp_abort_isp(vha);
314
315 if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) &&
316 (!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) {
317 clear_bit(RESET_ACTIVE, &vha->dpc_flags);
318 }
319
320 if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
321 if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) {
322 qla2x00_loop_resync(vha);
323 clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags);
324 }
325 }
326
327 return 0;
328}
329
330void
331qla2x00_do_dpc_all_vps(scsi_qla_host_t *ha)
332{
333 int ret;
334 int i, vp_idx_matched;
335 scsi_qla_host_t *vha;
336
337 if (ha->parent)
338 return;
339 if (list_empty(&ha->vp_list))
340 return;
341
342 clear_bit(VP_DPC_NEEDED, &ha->dpc_flags);
343
344 i = find_next_bit((unsigned long *)ha->vp_idx_map,
345 MAX_MULTI_ID_FABRIC + 1, 1);
346 for (;i <= MAX_MULTI_ID_FABRIC;
347 i = find_next_bit((unsigned long *)ha->vp_idx_map,
348 MAX_MULTI_ID_FABRIC + 1, i + 1)) {
349 vp_idx_matched = 0;
350
351 list_for_each_entry(vha, &ha->vp_list, vp_list) {
352 if (i == vha->vp_idx) {
353 vp_idx_matched = 1;
354 break;
355 }
356 }
357
358 if (vp_idx_matched)
359 ret = qla2x00_do_dpc_vp(vha);
360 }
361}
362
363int
364qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
365{
366 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata;
367 scsi_qla_host_t *vha;
368 uint8_t port_name[WWN_SIZE];
369
370 if (fc_vport->roles != FC_PORT_ROLE_FCP_INITIATOR)
371 return VPCERR_UNSUPPORTED;
372
373 /* Check up the F/W and H/W support NPIV */
374 if (!ha->flags.npiv_supported)
375 return VPCERR_UNSUPPORTED;
376
377 /* Check up whether npiv supported switch presented */
378 if (!(ha->switch_cap & FLOGI_MID_SUPPORT))
379 return VPCERR_NO_FABRIC_SUPP;
380
381 /* Check up unique WWPN */
382 u64_to_wwn(fc_vport->port_name, port_name);
383 vha = qla24xx_find_vhost_by_name(ha, port_name);
384 if (vha)
385 return VPCERR_BAD_WWN;
386
387 /* Check up max-npiv-supports */
388 if (ha->num_vhosts > ha->max_npiv_vports) {
389 DEBUG15(printk("scsi(%ld): num_vhosts %d is bigger than "
390 "max_npv_vports %d.\n", ha->host_no,
391 (uint16_t) ha->num_vhosts, (int) ha->max_npiv_vports));
392 return VPCERR_UNSUPPORTED;
393 }
394 return 0;
395}
396
397scsi_qla_host_t *
398qla24xx_create_vhost(struct fc_vport *fc_vport)
399{
400 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata;
401 scsi_qla_host_t *vha;
402 struct Scsi_Host *host;
403
404 host = scsi_host_alloc(&qla24xx_driver_template,
405 sizeof(scsi_qla_host_t));
406 if (!host) {
407 printk(KERN_WARNING
408 "qla2xxx: scsi_host_alloc() failed for vport\n");
409 return(NULL);
410 }
411
412 vha = (scsi_qla_host_t *)host->hostdata;
413
414 /* clone the parent hba */
415 memcpy(vha, ha, sizeof (scsi_qla_host_t));
416
417 fc_vport->dd_data = vha;
418
419 vha->node_name = kmalloc(WWN_SIZE * sizeof(char), GFP_KERNEL);
420 if (!vha->node_name)
421 goto create_vhost_failed_1;
422
423 vha->port_name = kmalloc(WWN_SIZE * sizeof(char), GFP_KERNEL);
424 if (!vha->port_name)
425 goto create_vhost_failed_2;
426
427 /* New host info */
428 u64_to_wwn(fc_vport->node_name, vha->node_name);
429 u64_to_wwn(fc_vport->port_name, vha->port_name);
430
431 vha->host = host;
432 vha->host_no = host->host_no;
433 vha->parent = ha;
434 vha->fc_vport = fc_vport;
435 vha->device_flags = 0;
436 vha->instance = num_hosts;
437 vha->vp_idx = qla24xx_allocate_vp_id(vha);
438 if (vha->vp_idx > ha->max_npiv_vports) {
439 DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n",
440 vha->host_no));
441 goto create_vhost_failed_3;
442 }
443 vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
444
445 init_MUTEX(&vha->mbx_cmd_sem);
446 init_MUTEX_LOCKED(&vha->mbx_intr_sem);
447
448 INIT_LIST_HEAD(&vha->list);
449 INIT_LIST_HEAD(&vha->fcports);
450 INIT_LIST_HEAD(&vha->vp_fcports);
451
452 vha->dpc_flags = 0L;
453 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
454 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
455
456 /*
457 * To fix the issue of processing a parent's RSCN for the vport before
458 * its SCR is complete.
459 */
460 set_bit(VP_SCR_NEEDED, &vha->vp_flags);
461 atomic_set(&vha->loop_state, LOOP_DOWN);
462 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
463
464 qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL);
465
466 host->can_queue = vha->request_q_length + 128;
467 host->this_id = 255;
468 host->cmd_per_lun = 3;
469 host->max_cmd_len = MAX_CMDSZ;
470 host->max_channel = MAX_BUSES - 1;
471 host->max_lun = MAX_LUNS;
472 host->unique_id = vha->instance;
473 host->max_id = MAX_TARGETS_2200;
474 host->transportt = qla2xxx_transport_vport_template;
475
476 DEBUG15(printk("DEBUG: detect vport hba %ld at address = %p\n",
477 vha->host_no, vha));
478
479 vha->flags.init_done = 1;
480 num_hosts++;
481
482 down(&ha->vport_sem);
483 set_bit(vha->vp_idx, (unsigned long *)ha->vp_idx_map);
484 ha->cur_vport_count++;
485 up(&ha->vport_sem);
486
487 return vha;
488
489create_vhost_failed_3:
490 kfree(vha->port_name);
491
492create_vhost_failed_2:
493 kfree(vha->node_name);
494
495create_vhost_failed_1:
496 return NULL;
497}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 18baa5bf69c4..a8658b1d284f 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -29,8 +29,7 @@ static struct kmem_cache *srb_cachep;
29/* 29/*
30 * Ioctl related information. 30 * Ioctl related information.
31 */ 31 */
32static int num_hosts; 32int num_hosts;
33
34int ql2xlogintimeout = 20; 33int ql2xlogintimeout = 20;
35module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); 34module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
36MODULE_PARM_DESC(ql2xlogintimeout, 35MODULE_PARM_DESC(ql2xlogintimeout,
@@ -112,7 +111,7 @@ static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *);
112static int qla2x00_change_queue_depth(struct scsi_device *, int); 111static int qla2x00_change_queue_depth(struct scsi_device *, int);
113static int qla2x00_change_queue_type(struct scsi_device *, int); 112static int qla2x00_change_queue_type(struct scsi_device *, int);
114 113
115static struct scsi_host_template qla2x00_driver_template = { 114struct scsi_host_template qla2x00_driver_template = {
116 .module = THIS_MODULE, 115 .module = THIS_MODULE,
117 .name = QLA2XXX_DRIVER_NAME, 116 .name = QLA2XXX_DRIVER_NAME,
118 .queuecommand = qla2x00_queuecommand, 117 .queuecommand = qla2x00_queuecommand,
@@ -143,7 +142,7 @@ static struct scsi_host_template qla2x00_driver_template = {
143 .shost_attrs = qla2x00_host_attrs, 142 .shost_attrs = qla2x00_host_attrs,
144}; 143};
145 144
146static struct scsi_host_template qla24xx_driver_template = { 145struct scsi_host_template qla24xx_driver_template = {
147 .module = THIS_MODULE, 146 .module = THIS_MODULE,
148 .name = QLA2XXX_DRIVER_NAME, 147 .name = QLA2XXX_DRIVER_NAME,
149 .queuecommand = qla24xx_queuecommand, 148 .queuecommand = qla24xx_queuecommand,
@@ -171,21 +170,21 @@ static struct scsi_host_template qla24xx_driver_template = {
171}; 170};
172 171
173static struct scsi_transport_template *qla2xxx_transport_template = NULL; 172static struct scsi_transport_template *qla2xxx_transport_template = NULL;
173struct scsi_transport_template *qla2xxx_transport_vport_template = NULL;
174 174
175/* TODO Convert to inlines 175/* TODO Convert to inlines
176 * 176 *
177 * Timer routines 177 * Timer routines
178 */ 178 */
179#define WATCH_INTERVAL 1 /* number of seconds */
180 179
181static void qla2x00_timer(scsi_qla_host_t *); 180void qla2x00_timer(scsi_qla_host_t *);
182 181
183static __inline__ void qla2x00_start_timer(scsi_qla_host_t *, 182__inline__ void qla2x00_start_timer(scsi_qla_host_t *,
184 void *, unsigned long); 183 void *, unsigned long);
185static __inline__ void qla2x00_restart_timer(scsi_qla_host_t *, unsigned long); 184static __inline__ void qla2x00_restart_timer(scsi_qla_host_t *, unsigned long);
186static __inline__ void qla2x00_stop_timer(scsi_qla_host_t *); 185__inline__ void qla2x00_stop_timer(scsi_qla_host_t *);
187 186
188static inline void 187__inline__ void
189qla2x00_start_timer(scsi_qla_host_t *ha, void *func, unsigned long interval) 188qla2x00_start_timer(scsi_qla_host_t *ha, void *func, unsigned long interval)
190{ 189{
191 init_timer(&ha->timer); 190 init_timer(&ha->timer);
@@ -202,7 +201,7 @@ qla2x00_restart_timer(scsi_qla_host_t *ha, unsigned long interval)
202 mod_timer(&ha->timer, jiffies + interval * HZ); 201 mod_timer(&ha->timer, jiffies + interval * HZ);
203} 202}
204 203
205static __inline__ void 204__inline__ void
206qla2x00_stop_timer(scsi_qla_host_t *ha) 205qla2x00_stop_timer(scsi_qla_host_t *ha)
207{ 206{
208 del_timer_sync(&ha->timer); 207 del_timer_sync(&ha->timer);
@@ -213,8 +212,8 @@ static int qla2x00_do_dpc(void *data);
213 212
214static void qla2x00_rst_aen(scsi_qla_host_t *); 213static void qla2x00_rst_aen(scsi_qla_host_t *);
215 214
216static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *); 215uint8_t qla2x00_mem_alloc(scsi_qla_host_t *);
217static void qla2x00_mem_free(scsi_qla_host_t *ha); 216void qla2x00_mem_free(scsi_qla_host_t *ha);
218static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha); 217static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha);
219static void qla2x00_free_sp_pool(scsi_qla_host_t *ha); 218static void qla2x00_free_sp_pool(scsi_qla_host_t *ha);
220static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *); 219static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *);
@@ -438,6 +437,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
438 struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); 437 struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
439 srb_t *sp; 438 srb_t *sp;
440 int rval; 439 int rval;
440 scsi_qla_host_t *pha = to_qla_parent(ha);
441 441
442 rval = fc_remote_port_chkready(rport); 442 rval = fc_remote_port_chkready(rport);
443 if (rval) { 443 if (rval) {
@@ -453,7 +453,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
453 453
454 if (atomic_read(&fcport->state) != FCS_ONLINE) { 454 if (atomic_read(&fcport->state) != FCS_ONLINE) {
455 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || 455 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
456 atomic_read(&ha->loop_state) == LOOP_DEAD) { 456 atomic_read(&pha->loop_state) == LOOP_DEAD) {
457 cmd->result = DID_NO_CONNECT << 16; 457 cmd->result = DID_NO_CONNECT << 16;
458 goto qc24_fail_command; 458 goto qc24_fail_command;
459 } 459 }
@@ -462,7 +462,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
462 462
463 spin_unlock_irq(ha->host->host_lock); 463 spin_unlock_irq(ha->host->host_lock);
464 464
465 sp = qla2x00_get_new_sp(ha, fcport, cmd, done); 465 sp = qla2x00_get_new_sp(pha, fcport, cmd, done);
466 if (!sp) 466 if (!sp)
467 goto qc24_host_busy_lock; 467 goto qc24_host_busy_lock;
468 468
@@ -475,8 +475,8 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
475 return 0; 475 return 0;
476 476
477qc24_host_busy_free_sp: 477qc24_host_busy_free_sp:
478 qla2x00_sp_free_dma(ha, sp); 478 qla2x00_sp_free_dma(pha, sp);
479 mempool_free(sp, ha->srb_mempool); 479 mempool_free(sp, pha->srb_mempool);
480 480
481qc24_host_busy_lock: 481qc24_host_busy_lock:
482 spin_lock_irq(ha->host->host_lock); 482 spin_lock_irq(ha->host->host_lock);
@@ -548,16 +548,17 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
548{ 548{
549 int return_status; 549 int return_status;
550 unsigned long wait_online; 550 unsigned long wait_online;
551 scsi_qla_host_t *pha = to_qla_parent(ha);
551 552
552 wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ); 553 wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
553 while (((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) || 554 while (((test_bit(ISP_ABORT_NEEDED, &pha->dpc_flags)) ||
554 test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || 555 test_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags) ||
555 test_bit(ISP_ABORT_RETRY, &ha->dpc_flags) || 556 test_bit(ISP_ABORT_RETRY, &pha->dpc_flags) ||
556 ha->dpc_active) && time_before(jiffies, wait_online)) { 557 pha->dpc_active) && time_before(jiffies, wait_online)) {
557 558
558 msleep(1000); 559 msleep(1000);
559 } 560 }
560 if (ha->flags.online) 561 if (pha->flags.online)
561 return_status = QLA_SUCCESS; 562 return_status = QLA_SUCCESS;
562 else 563 else
563 return_status = QLA_FUNCTION_FAILED; 564 return_status = QLA_FUNCTION_FAILED;
@@ -588,14 +589,15 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
588{ 589{
589 int return_status = QLA_SUCCESS; 590 int return_status = QLA_SUCCESS;
590 unsigned long loop_timeout ; 591 unsigned long loop_timeout ;
592 scsi_qla_host_t *pha = to_qla_parent(ha);
591 593
592 /* wait for 5 min at the max for loop to be ready */ 594 /* wait for 5 min at the max for loop to be ready */
593 loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ); 595 loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ);
594 596
595 while ((!atomic_read(&ha->loop_down_timer) && 597 while ((!atomic_read(&pha->loop_down_timer) &&
596 atomic_read(&ha->loop_state) == LOOP_DOWN) || 598 atomic_read(&pha->loop_state) == LOOP_DOWN) ||
597 atomic_read(&ha->loop_state) != LOOP_READY) { 599 atomic_read(&pha->loop_state) != LOOP_READY) {
598 if (atomic_read(&ha->loop_state) == LOOP_DEAD) { 600 if (atomic_read(&pha->loop_state) == LOOP_DEAD) {
599 return_status = QLA_FUNCTION_FAILED; 601 return_status = QLA_FUNCTION_FAILED;
600 break; 602 break;
601 } 603 }
@@ -650,6 +652,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
650 unsigned long serial; 652 unsigned long serial;
651 unsigned long flags; 653 unsigned long flags;
652 int wait = 0; 654 int wait = 0;
655 scsi_qla_host_t *pha = to_qla_parent(ha);
653 656
654 qla2x00_block_error_handler(cmd); 657 qla2x00_block_error_handler(cmd);
655 658
@@ -663,9 +666,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
663 serial = cmd->serial_number; 666 serial = cmd->serial_number;
664 667
665 /* Check active list for command command. */ 668 /* Check active list for command command. */
666 spin_lock_irqsave(&ha->hardware_lock, flags); 669 spin_lock_irqsave(&pha->hardware_lock, flags);
667 for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { 670 for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
668 sp = ha->outstanding_cmds[i]; 671 sp = pha->outstanding_cmds[i];
669 672
670 if (sp == NULL) 673 if (sp == NULL)
671 continue; 674 continue;
@@ -677,7 +680,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
677 __func__, ha->host_no, sp, serial)); 680 __func__, ha->host_no, sp, serial));
678 DEBUG3(qla2x00_print_scsi_cmd(cmd)); 681 DEBUG3(qla2x00_print_scsi_cmd(cmd));
679 682
680 spin_unlock_irqrestore(&ha->hardware_lock, flags); 683 spin_unlock_irqrestore(&pha->hardware_lock, flags);
681 if (ha->isp_ops.abort_command(ha, sp)) { 684 if (ha->isp_ops.abort_command(ha, sp)) {
682 DEBUG2(printk("%s(%ld): abort_command " 685 DEBUG2(printk("%s(%ld): abort_command "
683 "mbx failed.\n", __func__, ha->host_no)); 686 "mbx failed.\n", __func__, ha->host_no));
@@ -686,11 +689,11 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
686 "mbx success.\n", __func__, ha->host_no)); 689 "mbx success.\n", __func__, ha->host_no));
687 wait = 1; 690 wait = 1;
688 } 691 }
689 spin_lock_irqsave(&ha->hardware_lock, flags); 692 spin_lock_irqsave(&pha->hardware_lock, flags);
690 693
691 break; 694 break;
692 } 695 }
693 spin_unlock_irqrestore(&ha->hardware_lock, flags); 696 spin_unlock_irqrestore(&pha->hardware_lock, flags);
694 697
695 /* Wait for the command to be returned. */ 698 /* Wait for the command to be returned. */
696 if (wait) { 699 if (wait) {
@@ -731,6 +734,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
731 srb_t *sp; 734 srb_t *sp;
732 struct scsi_cmnd *cmd; 735 struct scsi_cmnd *cmd;
733 unsigned long flags; 736 unsigned long flags;
737 scsi_qla_host_t *pha = to_qla_parent(ha);
734 738
735 status = 0; 739 status = 0;
736 740
@@ -739,19 +743,20 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
739 * array 743 * array
740 */ 744 */
741 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { 745 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
742 spin_lock_irqsave(&ha->hardware_lock, flags); 746 spin_lock_irqsave(&pha->hardware_lock, flags);
743 sp = ha->outstanding_cmds[cnt]; 747 sp = pha->outstanding_cmds[cnt];
744 if (sp) { 748 if (sp) {
745 cmd = sp->cmd; 749 cmd = sp->cmd;
746 spin_unlock_irqrestore(&ha->hardware_lock, flags); 750 spin_unlock_irqrestore(&pha->hardware_lock, flags);
747 if (cmd->device->id == t) { 751 if (cmd->device->id == t &&
752 ha->vp_idx == sp->ha->vp_idx) {
748 if (!qla2x00_eh_wait_on_command(ha, cmd)) { 753 if (!qla2x00_eh_wait_on_command(ha, cmd)) {
749 status = 1; 754 status = 1;
750 break; 755 break;
751 } 756 }
752 } 757 }
753 } else { 758 } else {
754 spin_unlock_irqrestore(&ha->hardware_lock, flags); 759 spin_unlock_irqrestore(&pha->hardware_lock, flags);
755 } 760 }
756 } 761 }
757 return (status); 762 return (status);
@@ -782,14 +787,12 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
782{ 787{
783 scsi_qla_host_t *ha = to_qla_host(cmd->device->host); 788 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
784 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 789 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
785 int ret; 790 int ret = FAILED;
786 unsigned int id, lun; 791 unsigned int id, lun;
787 unsigned long serial; 792 unsigned long serial;
788 793
789 qla2x00_block_error_handler(cmd); 794 qla2x00_block_error_handler(cmd);
790 795
791 ret = FAILED;
792
793 id = cmd->device->id; 796 id = cmd->device->id;
794 lun = cmd->device->lun; 797 lun = cmd->device->lun;
795 serial = cmd->serial_number; 798 serial = cmd->serial_number;
@@ -912,15 +915,14 @@ static int
912qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) 915qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
913{ 916{
914 scsi_qla_host_t *ha = to_qla_host(cmd->device->host); 917 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
918 scsi_qla_host_t *pha = to_qla_parent(ha);
915 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 919 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
916 int ret; 920 int ret = FAILED;
917 unsigned int id, lun; 921 unsigned int id, lun;
918 unsigned long serial; 922 unsigned long serial;
919 923
920 qla2x00_block_error_handler(cmd); 924 qla2x00_block_error_handler(cmd);
921 925
922 ret = FAILED;
923
924 id = cmd->device->id; 926 id = cmd->device->id;
925 lun = cmd->device->lun; 927 lun = cmd->device->lun;
926 serial = cmd->serial_number; 928 serial = cmd->serial_number;
@@ -944,7 +946,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
944 goto eh_bus_reset_done; 946 goto eh_bus_reset_done;
945 947
946 /* Flush outstanding commands. */ 948 /* Flush outstanding commands. */
947 if (!qla2x00_eh_wait_for_pending_commands(ha)) 949 if (!qla2x00_eh_wait_for_pending_commands(pha))
948 ret = FAILED; 950 ret = FAILED;
949 951
950eh_bus_reset_done: 952eh_bus_reset_done:
@@ -974,14 +976,13 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
974{ 976{
975 scsi_qla_host_t *ha = to_qla_host(cmd->device->host); 977 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
976 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 978 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
977 int ret; 979 int ret = FAILED;
978 unsigned int id, lun; 980 unsigned int id, lun;
979 unsigned long serial; 981 unsigned long serial;
982 scsi_qla_host_t *pha = to_qla_parent(ha);
980 983
981 qla2x00_block_error_handler(cmd); 984 qla2x00_block_error_handler(cmd);
982 985
983 ret = FAILED;
984
985 id = cmd->device->id; 986 id = cmd->device->id;
986 lun = cmd->device->lun; 987 lun = cmd->device->lun;
987 serial = cmd->serial_number; 988 serial = cmd->serial_number;
@@ -1004,21 +1005,24 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
1004 * while dpc is stuck for the mailbox to complete. 1005 * while dpc is stuck for the mailbox to complete.
1005 */ 1006 */
1006 qla2x00_wait_for_loop_ready(ha); 1007 qla2x00_wait_for_loop_ready(ha);
1007 set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); 1008 set_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags);
1008 if (qla2x00_abort_isp(ha)) { 1009 if (qla2x00_abort_isp(pha)) {
1009 clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); 1010 clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags);
1010 /* failed. schedule dpc to try */ 1011 /* failed. schedule dpc to try */
1011 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 1012 set_bit(ISP_ABORT_NEEDED, &pha->dpc_flags);
1012 1013
1013 if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) 1014 if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
1014 goto eh_host_reset_lock; 1015 goto eh_host_reset_lock;
1015 } 1016 }
1016 clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); 1017 clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags);
1017 1018
1018 /* Waiting for our command in done_queue to be returned to OS.*/ 1019 /* Waiting for our command in done_queue to be returned to OS.*/
1019 if (qla2x00_eh_wait_for_pending_commands(ha)) 1020 if (qla2x00_eh_wait_for_pending_commands(pha))
1020 ret = SUCCESS; 1021 ret = SUCCESS;
1021 1022
1023 if (ha->parent)
1024 qla2x00_vp_abort_isp(ha);
1025
1022eh_host_reset_lock: 1026eh_host_reset_lock:
1023 qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, 1027 qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
1024 (ret == FAILED) ? "failed" : "succeded"); 1028 (ret == FAILED) ? "failed" : "succeded");
@@ -1435,6 +1439,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1435 ha->host = host; 1439 ha->host = host;
1436 ha->host_no = host->host_no; 1440 ha->host_no = host->host_no;
1437 sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); 1441 sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no);
1442 ha->parent = NULL;
1438 1443
1439 /* Set ISP-type information. */ 1444 /* Set ISP-type information. */
1440 qla2x00_set_isp_flags(ha); 1445 qla2x00_set_isp_flags(ha);
@@ -1452,7 +1457,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1452 1457
1453 ha->prev_topology = 0; 1458 ha->prev_topology = 0;
1454 ha->init_cb_size = sizeof(init_cb_t); 1459 ha->init_cb_size = sizeof(init_cb_t);
1455 ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; 1460 ha->mgmt_svr_loop_id = MANAGEMENT_SERVER + ha->vp_idx;
1456 ha->link_data_rate = PORT_SPEED_UNKNOWN; 1461 ha->link_data_rate = PORT_SPEED_UNKNOWN;
1457 ha->optrom_size = OPTROM_SIZE_2300; 1462 ha->optrom_size = OPTROM_SIZE_2300;
1458 1463
@@ -1524,8 +1529,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1524 ha->request_q_length = REQUEST_ENTRY_CNT_24XX; 1529 ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
1525 ha->response_q_length = RESPONSE_ENTRY_CNT_2300; 1530 ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
1526 ha->last_loop_id = SNS_LAST_LOOP_ID_2300; 1531 ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
1527 ha->init_cb_size = sizeof(struct init_cb_24xx); 1532 ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
1528 ha->mgmt_svr_loop_id = 10; 1533 ha->mgmt_svr_loop_id = 10 + ha->vp_idx;
1529 ha->isp_ops.pci_config = qla24xx_pci_config; 1534 ha->isp_ops.pci_config = qla24xx_pci_config;
1530 ha->isp_ops.reset_chip = qla24xx_reset_chip; 1535 ha->isp_ops.reset_chip = qla24xx_reset_chip;
1531 ha->isp_ops.chip_diag = qla24xx_chip_diag; 1536 ha->isp_ops.chip_diag = qla24xx_chip_diag;
@@ -1563,10 +1568,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1563 ha->instance = num_hosts; 1568 ha->instance = num_hosts;
1564 1569
1565 init_MUTEX(&ha->mbx_cmd_sem); 1570 init_MUTEX(&ha->mbx_cmd_sem);
1571 init_MUTEX(&ha->vport_sem);
1566 init_MUTEX_LOCKED(&ha->mbx_intr_sem); 1572 init_MUTEX_LOCKED(&ha->mbx_intr_sem);
1567 1573
1568 INIT_LIST_HEAD(&ha->list); 1574 INIT_LIST_HEAD(&ha->list);
1569 INIT_LIST_HEAD(&ha->fcports); 1575 INIT_LIST_HEAD(&ha->fcports);
1576 INIT_LIST_HEAD(&ha->vp_list);
1577
1578 set_bit(0, (unsigned long *) ha->vp_idx_map);
1570 1579
1571 qla2x00_config_dma_addressing(ha); 1580 qla2x00_config_dma_addressing(ha);
1572 if (qla2x00_mem_alloc(ha)) { 1581 if (qla2x00_mem_alloc(ha)) {
@@ -1789,7 +1798,8 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
1789void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, 1798void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
1790 int do_login, int defer) 1799 int do_login, int defer)
1791{ 1800{
1792 if (atomic_read(&fcport->state) == FCS_ONLINE) 1801 if (atomic_read(&fcport->state) == FCS_ONLINE &&
1802 ha->vp_idx == fcport->vp_idx)
1793 qla2x00_schedule_rport_del(ha, fcport, defer); 1803 qla2x00_schedule_rport_del(ha, fcport, defer);
1794 1804
1795 /* 1805 /*
@@ -1840,19 +1850,23 @@ void
1840qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) 1850qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
1841{ 1851{
1842 fc_port_t *fcport; 1852 fc_port_t *fcport;
1853 scsi_qla_host_t *pha = to_qla_parent(ha);
1843 1854
1844 list_for_each_entry(fcport, &ha->fcports, list) { 1855 list_for_each_entry(fcport, &pha->fcports, list) {
1845 if (fcport->port_type != FCT_TARGET) 1856 if (ha->vp_idx != 0 && ha->vp_idx != fcport->vp_idx)
1846 continue; 1857 continue;
1847
1848 /* 1858 /*
1849 * No point in marking the device as lost, if the device is 1859 * No point in marking the device as lost, if the device is
1850 * already DEAD. 1860 * already DEAD.
1851 */ 1861 */
1852 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 1862 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
1853 continue; 1863 continue;
1854 if (atomic_read(&fcport->state) == FCS_ONLINE) 1864 if (atomic_read(&fcport->state) == FCS_ONLINE) {
1855 qla2x00_schedule_rport_del(ha, fcport, defer); 1865 if (defer)
1866 qla2x00_schedule_rport_del(ha, fcport, defer);
1867 else if (ha->vp_idx == fcport->vp_idx)
1868 qla2x00_schedule_rport_del(ha, fcport, defer);
1869 }
1856 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1870 atomic_set(&fcport->state, FCS_DEVICE_LOST);
1857 } 1871 }
1858 1872
@@ -1868,7 +1882,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
1868* 0 = success. 1882* 0 = success.
1869* 1 = failure. 1883* 1 = failure.
1870*/ 1884*/
1871static uint8_t 1885uint8_t
1872qla2x00_mem_alloc(scsi_qla_host_t *ha) 1886qla2x00_mem_alloc(scsi_qla_host_t *ha)
1873{ 1887{
1874 char name[16]; 1888 char name[16];
@@ -1920,33 +1934,33 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
1920 continue; 1934 continue;
1921 } 1935 }
1922 1936
1923 snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME, 1937 /* get consistent memory allocated for init control block */
1924 ha->host_no); 1938 ha->init_cb = dma_alloc_coherent(&ha->pdev->dev,
1925 ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev, 1939 ha->init_cb_size, &ha->init_cb_dma, GFP_KERNEL);
1926 DMA_POOL_SIZE, 8, 0); 1940 if (ha->init_cb == NULL) {
1927 if (ha->s_dma_pool == NULL) {
1928 qla_printk(KERN_WARNING, ha, 1941 qla_printk(KERN_WARNING, ha,
1929 "Memory Allocation failed - s_dma_pool\n"); 1942 "Memory Allocation failed - init_cb\n");
1930 1943
1931 qla2x00_mem_free(ha); 1944 qla2x00_mem_free(ha);
1932 msleep(100); 1945 msleep(100);
1933 1946
1934 continue; 1947 continue;
1935 } 1948 }
1949 memset(ha->init_cb, 0, ha->init_cb_size);
1936 1950
1937 /* get consistent memory allocated for init control block */ 1951 snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME,
1938 ha->init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, 1952 ha->host_no);
1939 &ha->init_cb_dma); 1953 ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
1940 if (ha->init_cb == NULL) { 1954 DMA_POOL_SIZE, 8, 0);
1955 if (ha->s_dma_pool == NULL) {
1941 qla_printk(KERN_WARNING, ha, 1956 qla_printk(KERN_WARNING, ha,
1942 "Memory Allocation failed - init_cb\n"); 1957 "Memory Allocation failed - s_dma_pool\n");
1943 1958
1944 qla2x00_mem_free(ha); 1959 qla2x00_mem_free(ha);
1945 msleep(100); 1960 msleep(100);
1946 1961
1947 continue; 1962 continue;
1948 } 1963 }
1949 memset(ha->init_cb, 0, ha->init_cb_size);
1950 1964
1951 if (qla2x00_allocate_sp_pool(ha)) { 1965 if (qla2x00_allocate_sp_pool(ha)) {
1952 qla_printk(KERN_WARNING, ha, 1966 qla_printk(KERN_WARNING, ha,
@@ -2052,7 +2066,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
2052* Input: 2066* Input:
2053* ha = adapter block pointer. 2067* ha = adapter block pointer.
2054*/ 2068*/
2055static void 2069void
2056qla2x00_mem_free(scsi_qla_host_t *ha) 2070qla2x00_mem_free(scsi_qla_host_t *ha)
2057{ 2071{
2058 struct list_head *fcpl, *fcptemp; 2072 struct list_head *fcpl, *fcptemp;
@@ -2088,12 +2102,13 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2088 if (ha->ms_iocb) 2102 if (ha->ms_iocb)
2089 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); 2103 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
2090 2104
2091 if (ha->init_cb)
2092 dma_pool_free(ha->s_dma_pool, ha->init_cb, ha->init_cb_dma);
2093
2094 if (ha->s_dma_pool) 2105 if (ha->s_dma_pool)
2095 dma_pool_destroy(ha->s_dma_pool); 2106 dma_pool_destroy(ha->s_dma_pool);
2096 2107
2108 if (ha->init_cb)
2109 dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
2110 ha->init_cb, ha->init_cb_dma);
2111
2097 if (ha->gid_list) 2112 if (ha->gid_list)
2098 dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, 2113 dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
2099 ha->gid_list_dma); 2114 ha->gid_list_dma);
@@ -2199,6 +2214,7 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha)
2199static int 2214static int
2200qla2x00_do_dpc(void *data) 2215qla2x00_do_dpc(void *data)
2201{ 2216{
2217 int rval;
2202 scsi_qla_host_t *ha; 2218 scsi_qla_host_t *ha;
2203 fc_port_t *fcport; 2219 fc_port_t *fcport;
2204 uint8_t status; 2220 uint8_t status;
@@ -2347,7 +2363,7 @@ qla2x00_do_dpc(void *data)
2347 if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, 2363 if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE,
2348 &ha->dpc_flags))) { 2364 &ha->dpc_flags))) {
2349 2365
2350 qla2x00_loop_resync(ha); 2366 rval = qla2x00_loop_resync(ha);
2351 2367
2352 clear_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags); 2368 clear_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags);
2353 } 2369 }
@@ -2374,6 +2390,8 @@ qla2x00_do_dpc(void *data)
2374 if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags)) 2390 if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags))
2375 ha->isp_ops.beacon_blink(ha); 2391 ha->isp_ops.beacon_blink(ha);
2376 2392
2393 qla2x00_do_dpc_all_vps(ha);
2394
2377 ha->dpc_active = 0; 2395 ha->dpc_active = 0;
2378 } /* End of while(1) */ 2396 } /* End of while(1) */
2379 2397
@@ -2452,7 +2470,7 @@ qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *sp)
2452* 2470*
2453* Context: Interrupt 2471* Context: Interrupt
2454***************************************************************************/ 2472***************************************************************************/
2455static void 2473void
2456qla2x00_timer(scsi_qla_host_t *ha) 2474qla2x00_timer(scsi_qla_host_t *ha)
2457{ 2475{
2458 unsigned long cpu_flags = 0; 2476 unsigned long cpu_flags = 0;
@@ -2461,6 +2479,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
2461 int index; 2479 int index;
2462 srb_t *sp; 2480 srb_t *sp;
2463 int t; 2481 int t;
2482 scsi_qla_host_t *pha = to_qla_parent(ha);
2464 2483
2465 /* 2484 /*
2466 * Ports - Port down timer. 2485 * Ports - Port down timer.
@@ -2506,23 +2525,29 @@ qla2x00_timer(scsi_qla_host_t *ha)
2506 atomic_set(&ha->loop_state, LOOP_DEAD); 2525 atomic_set(&ha->loop_state, LOOP_DEAD);
2507 2526
2508 /* Schedule an ISP abort to return any tape commands. */ 2527 /* Schedule an ISP abort to return any tape commands. */
2509 spin_lock_irqsave(&ha->hardware_lock, cpu_flags); 2528 /* NPIV - scan physical port only */
2510 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; 2529 if (!ha->parent) {
2511 index++) { 2530 spin_lock_irqsave(&ha->hardware_lock,
2512 fc_port_t *sfcp; 2531 cpu_flags);
2532 for (index = 1;
2533 index < MAX_OUTSTANDING_COMMANDS;
2534 index++) {
2535 fc_port_t *sfcp;
2536
2537 sp = ha->outstanding_cmds[index];
2538 if (!sp)
2539 continue;
2540 sfcp = sp->fcport;
2541 if (!(sfcp->flags & FCF_TAPE_PRESENT))
2542 continue;
2513 2543
2514 sp = ha->outstanding_cmds[index]; 2544 set_bit(ISP_ABORT_NEEDED,
2515 if (!sp) 2545 &ha->dpc_flags);
2516 continue; 2546 break;
2517 sfcp = sp->fcport; 2547 }
2518 if (!(sfcp->flags & FCF_TAPE_PRESENT)) 2548 spin_unlock_irqrestore(&ha->hardware_lock,
2519 continue; 2549 cpu_flags);
2520
2521 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
2522 break;
2523 } 2550 }
2524 spin_unlock_irqrestore(&ha->hardware_lock, cpu_flags);
2525
2526 set_bit(ABORT_QUEUES_NEEDED, &ha->dpc_flags); 2551 set_bit(ABORT_QUEUES_NEEDED, &ha->dpc_flags);
2527 start_dpc++; 2552 start_dpc++;
2528 } 2553 }
@@ -2566,8 +2591,9 @@ qla2x00_timer(scsi_qla_host_t *ha)
2566 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || 2591 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
2567 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || 2592 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
2568 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || 2593 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
2594 test_bit(VP_DPC_NEEDED, &ha->dpc_flags) ||
2569 test_bit(RELOGIN_NEEDED, &ha->dpc_flags))) 2595 test_bit(RELOGIN_NEEDED, &ha->dpc_flags)))
2570 qla2xxx_wake_dpc(ha); 2596 qla2xxx_wake_dpc(pha);
2571 2597
2572 qla2x00_restart_timer(ha, WATCH_INTERVAL); 2598 qla2x00_restart_timer(ha, WATCH_INTERVAL);
2573} 2599}
@@ -2711,14 +2737,24 @@ qla2x00_module_init(void)
2711 2737
2712 qla2xxx_transport_template = 2738 qla2xxx_transport_template =
2713 fc_attach_transport(&qla2xxx_transport_functions); 2739 fc_attach_transport(&qla2xxx_transport_functions);
2714 if (!qla2xxx_transport_template) 2740 if (!qla2xxx_transport_template) {
2741 kmem_cache_destroy(srb_cachep);
2742 return -ENODEV;
2743 }
2744 qla2xxx_transport_vport_template =
2745 fc_attach_transport(&qla2xxx_transport_vport_functions);
2746 if (!qla2xxx_transport_vport_template) {
2747 kmem_cache_destroy(srb_cachep);
2748 fc_release_transport(qla2xxx_transport_template);
2715 return -ENODEV; 2749 return -ENODEV;
2750 }
2716 2751
2717 printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); 2752 printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
2718 ret = pci_register_driver(&qla2xxx_pci_driver); 2753 ret = pci_register_driver(&qla2xxx_pci_driver);
2719 if (ret) { 2754 if (ret) {
2720 kmem_cache_destroy(srb_cachep); 2755 kmem_cache_destroy(srb_cachep);
2721 fc_release_transport(qla2xxx_transport_template); 2756 fc_release_transport(qla2xxx_transport_template);
2757 fc_release_transport(qla2xxx_transport_vport_template);
2722 } 2758 }
2723 return ret; 2759 return ret;
2724} 2760}
@@ -2733,6 +2769,7 @@ qla2x00_module_exit(void)
2733 qla2x00_release_firmware(); 2769 qla2x00_release_firmware();
2734 kmem_cache_destroy(srb_cachep); 2770 kmem_cache_destroy(srb_cachep);
2735 fc_release_transport(qla2xxx_transport_template); 2771 fc_release_transport(qla2xxx_transport_template);
2772 fc_release_transport(qla2xxx_transport_vport_template);
2736} 2773}
2737 2774
2738module_init(qla2x00_module_init); 2775module_init(qla2x00_module_init);