diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-10-27 13:37:17 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:22:31 -0500 |
commit | 7ee5d43e2ea25336a7638715420c75583bd2ed69 (patch) | |
tree | 2687f4508fa05465b231a61e606b1063c944d107 | |
parent | 57127f157298ea2dacbbc878a3c5d2a5daca772c (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.h | 9 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 81 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 76 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 21 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 14 |
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 | ||
1116 | LPFC_ATTR_R(enable_npiv, 0, 0, 1, "Enable NPIV functionality"); | 1116 | int lpfc_enable_npiv = 0; |
1117 | module_param(lpfc_enable_npiv, int, 0); | ||
1118 | MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality"); | ||
1119 | lpfc_param_show(enable_npiv); | ||
1120 | lpfc_param_init(enable_npiv, 0, 0, 1); | ||
1121 | static 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 | */ | ||
1271 | LPFC_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 | ||
2357 | struct 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 | |||
2415 | void | 2373 | void |
2416 | lpfc_get_cfgparam(struct lpfc_hba *phba) | 2374 | lpfc_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[]; | |||
260 | extern struct scsi_host_template lpfc_template; | 260 | extern struct scsi_host_template lpfc_template; |
261 | extern struct scsi_host_template lpfc_vport_template; | 261 | extern struct scsi_host_template lpfc_vport_template; |
262 | extern struct fc_function_template lpfc_transport_functions; | 262 | extern struct fc_function_template lpfc_transport_functions; |
263 | extern struct fc_function_template lpfc_vport_transport_functions; | ||
264 | extern int lpfc_sli_mode; | 263 | extern int lpfc_sli_mode; |
264 | extern int lpfc_enable_npiv; | ||
265 | 265 | ||
266 | int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); | 266 | int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); |
267 | void lpfc_terminate_rport_io(struct fc_rport *); | 267 | void 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 | ||
780 | static void | 780 | static void |
781 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 781 | lpfc_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 | ||
850 | static void | 850 | static void |
851 | lpfc_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 | |||
863 | static void | ||
851 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 864 | lpfc_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 | |||
859 | lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 877 | lpfc_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 | |||
867 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 890 | lpfc_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 | |||
902 | static void | ||
903 | lpfc_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 | ||
2320 | module_init(lpfc_init); | 2333 | module_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) { |