aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-10-27 13:37:17 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:31 -0500
commit7ee5d43e2ea25336a7638715420c75583bd2ed69 (patch)
tree2687f4508fa05465b231a61e606b1063c944d107
parent57127f157298ea2dacbbc878a3c5d2a5daca772c (diff)
[SCSI] lpfc 8.2.3 : NPIV bug fixes
NPIV bug fixes: - Remove vport params on physical hba when npiv is disabled - Implement new DA_ID CT command to remove vport information from the switch after delete. Some switches didn't clean this up unless the physical link dropped. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/lpfc/lpfc.h9
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c81
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c76
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h5
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c14
7 files changed, 127 insertions, 81 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index c1343fb2fcf4..ff6b7d33ccab 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -272,10 +272,16 @@ struct lpfc_vport {
272#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ 272#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
273#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ 273#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
274#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ 274#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */
275#define FC_RFF_NOT_SUPPORTED 0x40000 /* RFF_ID was rejected by switch */
276#define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */ 275#define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */
277#define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */ 276#define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */
278 277
278 uint32_t ct_flags;
279#define FC_CT_RFF_ID 0x1 /* RFF_ID accepted by switch */
280#define FC_CT_RNN_ID 0x2 /* RNN_ID accepted by switch */
281#define FC_CT_RSNN_NN 0x4 /* RSNN_NN accepted by switch */
282#define FC_CT_RSPN_ID 0x8 /* RSPN_ID accepted by switch */
283#define FC_CT_RFT_ID 0x10 /* RFT_ID accepted by switch */
284
279 struct list_head fc_nodes; 285 struct list_head fc_nodes;
280 286
281 /* Keep counters for the number of entries in each list. */ 287 /* Keep counters for the number of entries in each list. */
@@ -344,6 +350,7 @@ struct lpfc_vport {
344 uint32_t cfg_discovery_threads; 350 uint32_t cfg_discovery_threads;
345 uint32_t cfg_log_verbose; 351 uint32_t cfg_log_verbose;
346 uint32_t cfg_max_luns; 352 uint32_t cfg_max_luns;
353 uint32_t cfg_enable_da_id;
347 354
348 uint32_t dev_loss_tmo_changed; 355 uint32_t dev_loss_tmo_changed;
349 356
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index bd35e9c7b995..356dede9cd65 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1113,7 +1113,13 @@ MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:"
1113 " 2 - select SLI-2 even on SLI-3 capable HBAs," 1113 " 2 - select SLI-2 even on SLI-3 capable HBAs,"
1114 " 3 - select SLI-3"); 1114 " 3 - select SLI-3");
1115 1115
1116LPFC_ATTR_R(enable_npiv, 0, 0, 1, "Enable NPIV functionality"); 1116int lpfc_enable_npiv = 0;
1117module_param(lpfc_enable_npiv, int, 0);
1118MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality");
1119lpfc_param_show(enable_npiv);
1120lpfc_param_init(enable_npiv, 0, 0, 1);
1121static CLASS_DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO,
1122 lpfc_enable_npiv_show, NULL);
1117 1123
1118/* 1124/*
1119# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear 1125# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
@@ -1259,6 +1265,13 @@ LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff,
1259 "Verbose logging bit-mask"); 1265 "Verbose logging bit-mask");
1260 1266
1261/* 1267/*
1268# lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters
1269# objects that have been registered with the nameserver after login.
1270*/
1271LPFC_VPORT_ATTR_R(enable_da_id, 0, 0, 1,
1272 "Deregister nameserver objects before LOGO");
1273
1274/*
1262# lun_queue_depth: This parameter is used to limit the number of outstanding 1275# lun_queue_depth: This parameter is used to limit the number of outstanding
1263# commands per FCP LUN. Value range is [1,128]. Default value is 30. 1276# commands per FCP LUN. Value range is [1,128]. Default value is 30.
1264*/ 1277*/
@@ -1564,6 +1577,7 @@ struct class_device_attribute *lpfc_vport_attrs[] = {
1564 &class_device_attr_lpfc_max_luns, 1577 &class_device_attr_lpfc_max_luns,
1565 &class_device_attr_nport_evt_cnt, 1578 &class_device_attr_nport_evt_cnt,
1566 &class_device_attr_npiv_info, 1579 &class_device_attr_npiv_info,
1580 &class_device_attr_lpfc_enable_da_id,
1567 NULL, 1581 NULL,
1568}; 1582};
1569 1583
@@ -2349,69 +2363,13 @@ struct fc_function_template lpfc_transport_functions = {
2349 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk, 2363 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
2350 .terminate_rport_io = lpfc_terminate_rport_io, 2364 .terminate_rport_io = lpfc_terminate_rport_io,
2351 2365
2352 .vport_create = lpfc_vport_create, 2366 /* Vport fields are filled in at runtime based on enable_npiv */
2353 .vport_delete = lpfc_vport_delete, 2367 .vport_create = NULL,
2368 .vport_delete = NULL,
2369 .vport_disable = NULL,
2354 .dd_fcvport_size = sizeof(struct lpfc_vport *), 2370 .dd_fcvport_size = sizeof(struct lpfc_vport *),
2355}; 2371};
2356 2372
2357struct fc_function_template lpfc_vport_transport_functions = {
2358 /* fixed attributes the driver supports */
2359 .show_host_node_name = 1,
2360 .show_host_port_name = 1,
2361 .show_host_supported_classes = 1,
2362 .show_host_supported_fc4s = 1,
2363 .show_host_supported_speeds = 1,
2364 .show_host_maxframe_size = 1,
2365
2366 /* dynamic attributes the driver supports */
2367 .get_host_port_id = lpfc_get_host_port_id,
2368 .show_host_port_id = 1,
2369
2370 .get_host_port_type = lpfc_get_host_port_type,
2371 .show_host_port_type = 1,
2372
2373 .get_host_port_state = lpfc_get_host_port_state,
2374 .show_host_port_state = 1,
2375
2376 /* active_fc4s is shown but doesn't change (thus no get function) */
2377 .show_host_active_fc4s = 1,
2378
2379 .get_host_speed = lpfc_get_host_speed,
2380 .show_host_speed = 1,
2381
2382 .get_host_fabric_name = lpfc_get_host_fabric_name,
2383 .show_host_fabric_name = 1,
2384
2385 /*
2386 * The LPFC driver treats linkdown handling as target loss events
2387 * so there are no sysfs handlers for link_down_tmo.
2388 */
2389
2390 .get_fc_host_stats = lpfc_get_stats,
2391 .reset_fc_host_stats = lpfc_reset_stats,
2392
2393 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
2394 .show_rport_maxframe_size = 1,
2395 .show_rport_supported_classes = 1,
2396
2397 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
2398 .show_rport_dev_loss_tmo = 1,
2399
2400 .get_starget_port_id = lpfc_get_starget_port_id,
2401 .show_starget_port_id = 1,
2402
2403 .get_starget_node_name = lpfc_get_starget_node_name,
2404 .show_starget_node_name = 1,
2405
2406 .get_starget_port_name = lpfc_get_starget_port_name,
2407 .show_starget_port_name = 1,
2408
2409 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
2410 .terminate_rport_io = lpfc_terminate_rport_io,
2411
2412 .vport_disable = lpfc_vport_disable,
2413};
2414
2415void 2373void
2416lpfc_get_cfgparam(struct lpfc_hba *phba) 2374lpfc_get_cfgparam(struct lpfc_hba *phba)
2417{ 2375{
@@ -2460,5 +2418,6 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
2460 lpfc_discovery_threads_init(vport, lpfc_discovery_threads); 2418 lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
2461 lpfc_max_luns_init(vport, lpfc_max_luns); 2419 lpfc_max_luns_init(vport, lpfc_max_luns);
2462 lpfc_scan_down_init(vport, lpfc_scan_down); 2420 lpfc_scan_down_init(vport, lpfc_scan_down);
2421 lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
2463 return; 2422 return;
2464} 2423}
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index f3916645e817..be4b6584167a 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -260,8 +260,8 @@ extern struct class_device_attribute *lpfc_vport_attrs[];
260extern struct scsi_host_template lpfc_template; 260extern struct scsi_host_template lpfc_template;
261extern struct scsi_host_template lpfc_vport_template; 261extern struct scsi_host_template lpfc_vport_template;
262extern struct fc_function_template lpfc_transport_functions; 262extern struct fc_function_template lpfc_transport_functions;
263extern struct fc_function_template lpfc_vport_transport_functions;
264extern int lpfc_sli_mode; 263extern int lpfc_sli_mode;
264extern int lpfc_enable_npiv;
265 265
266int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); 266int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t);
267void lpfc_terminate_rport_io(struct fc_rport *); 267void lpfc_terminate_rport_io(struct fc_rport *);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index c701e4d611a9..dbe020e66b09 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -458,7 +458,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
458 ((lpfc_find_vport_by_did(phba, Did) == NULL) || 458 ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
459 vport->cfg_peer_port_login)) { 459 vport->cfg_peer_port_login)) {
460 if ((vport->port_type != LPFC_NPIV_PORT) || 460 if ((vport->port_type != LPFC_NPIV_PORT) ||
461 (vport->fc_flag & FC_RFF_NOT_SUPPORTED) || 461 (!vport->ct_flags & FC_CT_RFF_ID) ||
462 (!vport->cfg_restrict_login)) { 462 (!vport->cfg_restrict_login)) {
463 ndlp = lpfc_setup_disc_node(vport, Did); 463 ndlp = lpfc_setup_disc_node(vport, Did);
464 if (ndlp) { 464 if (ndlp) {
@@ -778,8 +778,8 @@ out:
778 778
779 779
780static void 780static void
781lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 781lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
782 struct lpfc_iocbq *rspiocb) 782 struct lpfc_iocbq *rspiocb)
783{ 783{
784 struct lpfc_vport *vport = cmdiocb->vport; 784 struct lpfc_vport *vport = cmdiocb->vport;
785 struct lpfc_dmabuf *inp; 785 struct lpfc_dmabuf *inp;
@@ -809,7 +809,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
809 809
810 /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ 810 /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
811 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 811 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
812 "0209 RFT request completes, latt %d, " 812 "0209 CT Request completes, latt %d, "
813 "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", 813 "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
814 latt, irsp->ulpStatus, 814 latt, irsp->ulpStatus,
815 CTrsp->CommandResponse.bits.CmdRsp, 815 CTrsp->CommandResponse.bits.CmdRsp,
@@ -848,10 +848,28 @@ out:
848} 848}
849 849
850static void 850static void
851lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
852 struct lpfc_iocbq *rspiocb)
853{
854 IOCB_t *irsp = &rspiocb->iocb;
855 struct lpfc_vport *vport = cmdiocb->vport;
856
857 if (irsp->ulpStatus == IOSTAT_SUCCESS)
858 vport->ct_flags |= FC_CT_RFT_ID;
859 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
860 return;
861}
862
863static void
851lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 864lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
852 struct lpfc_iocbq *rspiocb) 865 struct lpfc_iocbq *rspiocb)
853{ 866{
854 lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); 867 IOCB_t *irsp = &rspiocb->iocb;
868 struct lpfc_vport *vport = cmdiocb->vport;
869
870 if (irsp->ulpStatus == IOSTAT_SUCCESS)
871 vport->ct_flags |= FC_CT_RNN_ID;
872 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
855 return; 873 return;
856} 874}
857 875
@@ -859,7 +877,12 @@ static void
859lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 877lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
860 struct lpfc_iocbq *rspiocb) 878 struct lpfc_iocbq *rspiocb)
861{ 879{
862 lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); 880 IOCB_t *irsp = &rspiocb->iocb;
881 struct lpfc_vport *vport = cmdiocb->vport;
882
883 if (irsp->ulpStatus == IOSTAT_SUCCESS)
884 vport->ct_flags |= FC_CT_RSPN_ID;
885 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
863 return; 886 return;
864} 887}
865 888
@@ -867,7 +890,24 @@ static void
867lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 890lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
868 struct lpfc_iocbq *rspiocb) 891 struct lpfc_iocbq *rspiocb)
869{ 892{
870 lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); 893 IOCB_t *irsp = &rspiocb->iocb;
894 struct lpfc_vport *vport = cmdiocb->vport;
895
896 if (irsp->ulpStatus == IOSTAT_SUCCESS)
897 vport->ct_flags |= FC_CT_RSNN_NN;
898 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
899 return;
900}
901
902static void
903lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
904 struct lpfc_iocbq *rspiocb)
905{
906 struct lpfc_vport *vport = cmdiocb->vport;
907
908 /* even if it fails we will act as though it succeeded. */
909 vport->ct_flags = 0;
910 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
871 return; 911 return;
872} 912}
873 913
@@ -878,10 +918,9 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
878 IOCB_t *irsp = &rspiocb->iocb; 918 IOCB_t *irsp = &rspiocb->iocb;
879 struct lpfc_vport *vport = cmdiocb->vport; 919 struct lpfc_vport *vport = cmdiocb->vport;
880 920
881 if (irsp->ulpStatus != IOSTAT_SUCCESS) 921 if (irsp->ulpStatus == IOSTAT_SUCCESS)
882 vport->fc_flag |= FC_RFF_NOT_SUPPORTED; 922 vport->ct_flags |= FC_CT_RFF_ID;
883 923 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
884 lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
885 return; 924 return;
886} 925}
887 926
@@ -1001,6 +1040,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1001 bpl->tus.f.bdeSize = RSPN_REQUEST_SZ; 1040 bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
1002 else if (cmdcode == SLI_CTNS_RSNN_NN) 1041 else if (cmdcode == SLI_CTNS_RSNN_NN)
1003 bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; 1042 bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
1043 else if (cmdcode == SLI_CTNS_DA_ID)
1044 bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
1004 else if (cmdcode == SLI_CTNS_RFF_ID) 1045 else if (cmdcode == SLI_CTNS_RFF_ID)
1005 bpl->tus.f.bdeSize = RFF_REQUEST_SZ; 1046 bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
1006 else 1047 else
@@ -1034,6 +1075,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1034 break; 1075 break;
1035 1076
1036 case SLI_CTNS_RFT_ID: 1077 case SLI_CTNS_RFT_ID:
1078 vport->ct_flags &= ~FC_CT_RFT_ID;
1037 CtReq->CommandResponse.bits.CmdRsp = 1079 CtReq->CommandResponse.bits.CmdRsp =
1038 be16_to_cpu(SLI_CTNS_RFT_ID); 1080 be16_to_cpu(SLI_CTNS_RFT_ID);
1039 CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID); 1081 CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID);
@@ -1042,6 +1084,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1042 break; 1084 break;
1043 1085
1044 case SLI_CTNS_RNN_ID: 1086 case SLI_CTNS_RNN_ID:
1087 vport->ct_flags &= ~FC_CT_RNN_ID;
1045 CtReq->CommandResponse.bits.CmdRsp = 1088 CtReq->CommandResponse.bits.CmdRsp =
1046 be16_to_cpu(SLI_CTNS_RNN_ID); 1089 be16_to_cpu(SLI_CTNS_RNN_ID);
1047 CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID); 1090 CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID);
@@ -1051,6 +1094,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1051 break; 1094 break;
1052 1095
1053 case SLI_CTNS_RSPN_ID: 1096 case SLI_CTNS_RSPN_ID:
1097 vport->ct_flags &= ~FC_CT_RSPN_ID;
1054 CtReq->CommandResponse.bits.CmdRsp = 1098 CtReq->CommandResponse.bits.CmdRsp =
1055 be16_to_cpu(SLI_CTNS_RSPN_ID); 1099 be16_to_cpu(SLI_CTNS_RSPN_ID);
1056 CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID); 1100 CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID);
@@ -1061,6 +1105,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1061 cmpl = lpfc_cmpl_ct_cmd_rspn_id; 1105 cmpl = lpfc_cmpl_ct_cmd_rspn_id;
1062 break; 1106 break;
1063 case SLI_CTNS_RSNN_NN: 1107 case SLI_CTNS_RSNN_NN:
1108 vport->ct_flags &= ~FC_CT_RSNN_NN;
1064 CtReq->CommandResponse.bits.CmdRsp = 1109 CtReq->CommandResponse.bits.CmdRsp =
1065 be16_to_cpu(SLI_CTNS_RSNN_NN); 1110 be16_to_cpu(SLI_CTNS_RSNN_NN);
1066 memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, 1111 memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
@@ -1071,8 +1116,15 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1071 CtReq->un.rsnn.symbname, size); 1116 CtReq->un.rsnn.symbname, size);
1072 cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; 1117 cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
1073 break; 1118 break;
1119 case SLI_CTNS_DA_ID:
1120 /* Implement DA_ID Nameserver request */
1121 CtReq->CommandResponse.bits.CmdRsp =
1122 be16_to_cpu(SLI_CTNS_DA_ID);
1123 CtReq->un.da_id.port_id = be32_to_cpu(vport->fc_myDID);
1124 cmpl = lpfc_cmpl_ct_cmd_da_id;
1125 break;
1074 case SLI_CTNS_RFF_ID: 1126 case SLI_CTNS_RFF_ID:
1075 vport->fc_flag &= ~FC_RFF_NOT_SUPPORTED; 1127 vport->ct_flags &= ~FC_CT_RFF_ID;
1076 CtReq->CommandResponse.bits.CmdRsp = 1128 CtReq->CommandResponse.bits.CmdRsp =
1077 be16_to_cpu(SLI_CTNS_RFF_ID); 1129 be16_to_cpu(SLI_CTNS_RFF_ID);
1078 CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);; 1130 CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);;
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 098dd022a7eb..b075d5956488 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -139,6 +139,9 @@ struct lpfc_sli_ct_request {
139 uint8_t len; 139 uint8_t len;
140 uint8_t symbname[255]; 140 uint8_t symbname[255];
141 } rsnn; 141 } rsnn;
142 struct da_id { /* For DA_ID requests */
143 uint32_t port_id;
144 } da_id;
142 struct rspn { /* For RSPN_ID requests */ 145 struct rspn { /* For RSPN_ID requests */
143 uint32_t PortId; 146 uint32_t PortId;
144 uint8_t len; 147 uint8_t len;
@@ -177,6 +180,8 @@ struct lpfc_sli_ct_request {
177 sizeof(struct rnn)) 180 sizeof(struct rnn))
178#define RSNN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \ 181#define RSNN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
179 sizeof(struct rsnn)) 182 sizeof(struct rsnn))
183#define DA_ID_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
184 sizeof(struct da_id))
180#define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \ 185#define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
181 sizeof(struct rspn)) 186 sizeof(struct rspn))
182 187
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 17f445478beb..86c2f2b15b68 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2294,12 +2294,24 @@ lpfc_init(void)
2294 printk(LPFC_MODULE_DESC "\n"); 2294 printk(LPFC_MODULE_DESC "\n");
2295 printk(LPFC_COPYRIGHT "\n"); 2295 printk(LPFC_COPYRIGHT "\n");
2296 2296
2297 if (lpfc_enable_npiv) {
2298 lpfc_transport_functions.vport_create = lpfc_vport_create;
2299 lpfc_transport_functions.vport_delete = lpfc_vport_delete;
2300 }
2297 lpfc_transport_template = 2301 lpfc_transport_template =
2298 fc_attach_transport(&lpfc_transport_functions); 2302 fc_attach_transport(&lpfc_transport_functions);
2299 lpfc_vport_transport_template = 2303 if (lpfc_transport_template == NULL)
2300 fc_attach_transport(&lpfc_vport_transport_functions);
2301 if (!lpfc_transport_template || !lpfc_vport_transport_template)
2302 return -ENOMEM; 2304 return -ENOMEM;
2305 if (lpfc_enable_npiv) {
2306 lpfc_transport_functions.vport_create = NULL;
2307 lpfc_transport_functions.vport_delete = NULL;
2308 lpfc_transport_functions.issue_fc_host_lip = NULL;
2309 lpfc_transport_functions.vport_disable = lpfc_vport_disable;
2310 lpfc_vport_transport_template =
2311 fc_attach_transport(&lpfc_transport_functions);
2312 if (lpfc_vport_transport_template == NULL)
2313 return -ENOMEM;
2314 }
2303 error = pci_register_driver(&lpfc_driver); 2315 error = pci_register_driver(&lpfc_driver);
2304 if (error) { 2316 if (error) {
2305 fc_release_transport(lpfc_transport_template); 2317 fc_release_transport(lpfc_transport_template);
@@ -2314,7 +2326,8 @@ lpfc_exit(void)
2314{ 2326{
2315 pci_unregister_driver(&lpfc_driver); 2327 pci_unregister_driver(&lpfc_driver);
2316 fc_release_transport(lpfc_transport_template); 2328 fc_release_transport(lpfc_transport_template);
2317 fc_release_transport(lpfc_vport_transport_template); 2329 if (lpfc_enable_npiv)
2330 fc_release_transport(lpfc_vport_transport_template);
2318} 2331}
2319 2332
2320module_init(lpfc_init); 2333module_init(lpfc_init);
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index dcb415e717c3..3b705ccc771a 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -482,8 +482,18 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
482 482
483 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); 483 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
484 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && 484 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
485 phba->link_state >= LPFC_LINK_UP) { 485 phba->link_state >= LPFC_LINK_UP) {
486 486 if (vport->cfg_enable_da_id) {
487 timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
488 if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))
489 while (vport->ct_flags && timeout)
490 timeout = schedule_timeout(timeout);
491 else
492 lpfc_printf_log(vport->phba, KERN_WARNING,
493 LOG_VPORT,
494 "1829 CT command failed to "
495 "delete objects on fabric. \n");
496 }
487 /* First look for the Fabric ndlp */ 497 /* First look for the Fabric ndlp */
488 ndlp = lpfc_findnode_did(vport, Fabric_DID); 498 ndlp = lpfc_findnode_did(vport, Fabric_DID);
489 if (!ndlp) { 499 if (!ndlp) {