diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2010-12-13 19:17:42 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-21 13:37:16 -0500 |
commit | b704495c6707013806d1b66507a967896e2b4a7c (patch) | |
tree | 4ef277e362f33d1803bbacf0e24053e9a6506bb5 /drivers | |
parent | f1d584d70f31f54e0a559049906f42db89e2746d (diff) |
[SCSI] bfa: direct attach mode fix.
- Direct attach is not working due to the check of PID in fcxp_send request.
- Added logic to set the lps->lp_pid with the PID assigned for n2n mode.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_lport.c | 3 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 99 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi_ms.h | 8 |
5 files changed, 111 insertions, 1 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index f0e652b50994..0fd63168573f 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h | |||
@@ -38,6 +38,7 @@ enum bfa_lps_event { | |||
38 | BFA_LPS_SM_DELETE = 5, /* lps delete from user */ | 38 | BFA_LPS_SM_DELETE = 5, /* lps delete from user */ |
39 | BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ | 39 | BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ |
40 | BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */ | 40 | BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */ |
41 | BFA_LPS_SM_SET_N2N_PID = 8, /* Set assigned PID for n2n */ | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | 44 | ||
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index aa4516672eed..4f2e4e095d67 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c | |||
@@ -309,6 +309,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, | |||
309 | return; | 309 | return; |
310 | } | 310 | } |
311 | port->pid = rx_fchs->d_id; | 311 | port->pid = rx_fchs->d_id; |
312 | bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); | ||
312 | } | 313 | } |
313 | 314 | ||
314 | /* | 315 | /* |
@@ -323,6 +324,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, | |||
323 | (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), | 324 | (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), |
324 | (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { | 325 | (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { |
325 | port->pid = rx_fchs->d_id; | 326 | port->pid = rx_fchs->d_id; |
327 | bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); | ||
326 | rport->pid = rx_fchs->s_id; | 328 | rport->pid = rx_fchs->s_id; |
327 | } | 329 | } |
328 | bfa_fcs_rport_plogi(rport, rx_fchs, plogi); | 330 | bfa_fcs_rport_plogi(rport, rx_fchs, plogi); |
@@ -979,6 +981,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port) | |||
979 | ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, | 981 | ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, |
980 | sizeof(wwn_t)) > 0) { | 982 | sizeof(wwn_t)) > 0) { |
981 | port->pid = N2N_LOCAL_PID; | 983 | port->pid = N2N_LOCAL_PID; |
984 | bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID); | ||
982 | /* | 985 | /* |
983 | * First, check if we know the device by pwwn. | 986 | * First, check if we know the device by pwwn. |
984 | */ | 987 | */ |
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 2666472d1429..b7df5534da85 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c | |||
@@ -131,6 +131,7 @@ static void bfa_lps_reqq_resume(void *lps_arg); | |||
131 | static void bfa_lps_free(struct bfa_lps_s *lps); | 131 | static void bfa_lps_free(struct bfa_lps_s *lps); |
132 | static void bfa_lps_send_login(struct bfa_lps_s *lps); | 132 | static void bfa_lps_send_login(struct bfa_lps_s *lps); |
133 | static void bfa_lps_send_logout(struct bfa_lps_s *lps); | 133 | static void bfa_lps_send_logout(struct bfa_lps_s *lps); |
134 | static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps); | ||
134 | static void bfa_lps_login_comp(struct bfa_lps_s *lps); | 135 | static void bfa_lps_login_comp(struct bfa_lps_s *lps); |
135 | static void bfa_lps_logout_comp(struct bfa_lps_s *lps); | 136 | static void bfa_lps_logout_comp(struct bfa_lps_s *lps); |
136 | static void bfa_lps_cvl_event(struct bfa_lps_s *lps); | 137 | static void bfa_lps_cvl_event(struct bfa_lps_s *lps); |
@@ -143,6 +144,8 @@ static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event); | |||
143 | static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event | 144 | static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event |
144 | event); | 145 | event); |
145 | static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event); | 146 | static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event); |
147 | static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, | ||
148 | enum bfa_lps_event event); | ||
146 | static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event); | 149 | static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event); |
147 | static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event | 150 | static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event |
148 | event); | 151 | event); |
@@ -1254,6 +1257,12 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
1254 | else | 1257 | else |
1255 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | 1258 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, |
1256 | BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); | 1259 | BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); |
1260 | /* If N2N, send the assigned PID to FW */ | ||
1261 | bfa_trc(lps->bfa, lps->fport); | ||
1262 | bfa_trc(lps->bfa, lps->lp_pid); | ||
1263 | |||
1264 | if (!lps->fport && lps->lp_pid) | ||
1265 | bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); | ||
1257 | } else { | 1266 | } else { |
1258 | bfa_sm_set_state(lps, bfa_lps_sm_init); | 1267 | bfa_sm_set_state(lps, bfa_lps_sm_init); |
1259 | if (lps->fdisc) | 1268 | if (lps->fdisc) |
@@ -1272,6 +1281,11 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
1272 | bfa_sm_set_state(lps, bfa_lps_sm_init); | 1281 | bfa_sm_set_state(lps, bfa_lps_sm_init); |
1273 | break; | 1282 | break; |
1274 | 1283 | ||
1284 | case BFA_LPS_SM_SET_N2N_PID: | ||
1285 | bfa_trc(lps->bfa, lps->fport); | ||
1286 | bfa_trc(lps->bfa, lps->lp_pid); | ||
1287 | break; | ||
1288 | |||
1275 | default: | 1289 | default: |
1276 | bfa_sm_fault(lps->bfa, event); | 1290 | bfa_sm_fault(lps->bfa, event); |
1277 | } | 1291 | } |
@@ -1340,6 +1354,14 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
1340 | BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); | 1354 | BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); |
1341 | break; | 1355 | break; |
1342 | 1356 | ||
1357 | case BFA_LPS_SM_SET_N2N_PID: | ||
1358 | if (bfa_reqq_full(lps->bfa, lps->reqq)) { | ||
1359 | bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait); | ||
1360 | bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); | ||
1361 | } else | ||
1362 | bfa_lps_send_set_n2n_pid(lps); | ||
1363 | break; | ||
1364 | |||
1343 | case BFA_LPS_SM_OFFLINE: | 1365 | case BFA_LPS_SM_OFFLINE: |
1344 | case BFA_LPS_SM_DELETE: | 1366 | case BFA_LPS_SM_DELETE: |
1345 | bfa_sm_set_state(lps, bfa_lps_sm_init); | 1367 | bfa_sm_set_state(lps, bfa_lps_sm_init); |
@@ -1350,6 +1372,48 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
1350 | } | 1372 | } |
1351 | } | 1373 | } |
1352 | 1374 | ||
1375 | /** | ||
1376 | * login complete | ||
1377 | */ | ||
1378 | static void | ||
1379 | bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event) | ||
1380 | { | ||
1381 | bfa_trc(lps->bfa, lps->lp_tag); | ||
1382 | bfa_trc(lps->bfa, event); | ||
1383 | |||
1384 | switch (event) { | ||
1385 | case BFA_LPS_SM_RESUME: | ||
1386 | bfa_sm_set_state(lps, bfa_lps_sm_online); | ||
1387 | bfa_lps_send_set_n2n_pid(lps); | ||
1388 | break; | ||
1389 | |||
1390 | case BFA_LPS_SM_LOGOUT: | ||
1391 | bfa_sm_set_state(lps, bfa_lps_sm_logowait); | ||
1392 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
1393 | BFA_PL_EID_LOGO, 0, "Logout"); | ||
1394 | break; | ||
1395 | |||
1396 | case BFA_LPS_SM_RX_CVL: | ||
1397 | bfa_sm_set_state(lps, bfa_lps_sm_init); | ||
1398 | bfa_reqq_wcancel(&lps->wqe); | ||
1399 | |||
1400 | /* Let the vport module know about this event */ | ||
1401 | bfa_lps_cvl_event(lps); | ||
1402 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
1403 | BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); | ||
1404 | break; | ||
1405 | |||
1406 | case BFA_LPS_SM_OFFLINE: | ||
1407 | case BFA_LPS_SM_DELETE: | ||
1408 | bfa_sm_set_state(lps, bfa_lps_sm_init); | ||
1409 | bfa_reqq_wcancel(&lps->wqe); | ||
1410 | break; | ||
1411 | |||
1412 | default: | ||
1413 | bfa_sm_fault(lps->bfa, event); | ||
1414 | } | ||
1415 | } | ||
1416 | |||
1353 | /* | 1417 | /* |
1354 | * logout in progress - awaiting firmware response | 1418 | * logout in progress - awaiting firmware response |
1355 | */ | 1419 | */ |
@@ -1498,8 +1562,9 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) | |||
1498 | switch (rsp->status) { | 1562 | switch (rsp->status) { |
1499 | case BFA_STATUS_OK: | 1563 | case BFA_STATUS_OK: |
1500 | lps->fport = rsp->f_port; | 1564 | lps->fport = rsp->f_port; |
1565 | if (lps->fport) | ||
1566 | lps->lp_pid = rsp->lp_pid; | ||
1501 | lps->npiv_en = rsp->npiv_en; | 1567 | lps->npiv_en = rsp->npiv_en; |
1502 | lps->lp_pid = rsp->lp_pid; | ||
1503 | lps->pr_bbcred = be16_to_cpu(rsp->bb_credit); | 1568 | lps->pr_bbcred = be16_to_cpu(rsp->bb_credit); |
1504 | lps->pr_pwwn = rsp->port_name; | 1569 | lps->pr_pwwn = rsp->port_name; |
1505 | lps->pr_nwwn = rsp->node_name; | 1570 | lps->pr_nwwn = rsp->node_name; |
@@ -1626,6 +1691,25 @@ bfa_lps_send_logout(struct bfa_lps_s *lps) | |||
1626 | bfa_reqq_produce(lps->bfa, lps->reqq); | 1691 | bfa_reqq_produce(lps->bfa, lps->reqq); |
1627 | } | 1692 | } |
1628 | 1693 | ||
1694 | /** | ||
1695 | * send n2n pid set request to firmware | ||
1696 | */ | ||
1697 | static void | ||
1698 | bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps) | ||
1699 | { | ||
1700 | struct bfi_lps_n2n_pid_req_s *m; | ||
1701 | |||
1702 | m = bfa_reqq_next(lps->bfa, lps->reqq); | ||
1703 | bfa_assert(m); | ||
1704 | |||
1705 | bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ, | ||
1706 | bfa_lpuid(lps->bfa)); | ||
1707 | |||
1708 | m->lp_tag = lps->lp_tag; | ||
1709 | m->lp_pid = lps->lp_pid; | ||
1710 | bfa_reqq_produce(lps->bfa, lps->reqq); | ||
1711 | } | ||
1712 | |||
1629 | /* | 1713 | /* |
1630 | * Indirect login completion handler for non-fcs | 1714 | * Indirect login completion handler for non-fcs |
1631 | */ | 1715 | */ |
@@ -1846,6 +1930,19 @@ bfa_lps_get_base_pid(struct bfa_s *bfa) | |||
1846 | return BFA_LPS_FROM_TAG(mod, 0)->lp_pid; | 1930 | return BFA_LPS_FROM_TAG(mod, 0)->lp_pid; |
1847 | } | 1931 | } |
1848 | 1932 | ||
1933 | /** | ||
1934 | * Set PID in case of n2n (which is assigned during PLOGI) | ||
1935 | */ | ||
1936 | void | ||
1937 | bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid) | ||
1938 | { | ||
1939 | bfa_trc(lps->bfa, lps->lp_tag); | ||
1940 | bfa_trc(lps->bfa, n2n_pid); | ||
1941 | |||
1942 | lps->lp_pid = n2n_pid; | ||
1943 | bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); | ||
1944 | } | ||
1945 | |||
1849 | /* | 1946 | /* |
1850 | * LPS firmware message class handler. | 1947 | * LPS firmware message class handler. |
1851 | */ | 1948 | */ |
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 36c81c74f04a..331ad992a581 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h | |||
@@ -610,6 +610,7 @@ void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, | |||
610 | void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, | 610 | void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, |
611 | wwn_t pwwn, wwn_t nwwn); | 611 | wwn_t pwwn, wwn_t nwwn); |
612 | void bfa_lps_fdisclogo(struct bfa_lps_s *lps); | 612 | void bfa_lps_fdisclogo(struct bfa_lps_s *lps); |
613 | void bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, u32 n2n_pid); | ||
613 | u32 bfa_lps_get_base_pid(struct bfa_s *bfa); | 614 | u32 bfa_lps_get_base_pid(struct bfa_s *bfa); |
614 | u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid); | 615 | u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid); |
615 | void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); | 616 | void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); |
diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index 8f22ef1a6ed9..19e888a57555 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h | |||
@@ -342,6 +342,7 @@ struct bfi_uf_frm_rcvd_s { | |||
342 | enum bfi_lps_h2i_msgs { | 342 | enum bfi_lps_h2i_msgs { |
343 | BFI_LPS_H2I_LOGIN_REQ = 1, | 343 | BFI_LPS_H2I_LOGIN_REQ = 1, |
344 | BFI_LPS_H2I_LOGOUT_REQ = 2, | 344 | BFI_LPS_H2I_LOGOUT_REQ = 2, |
345 | BFI_LPS_H2I_N2N_PID_REQ = 3, | ||
345 | }; | 346 | }; |
346 | 347 | ||
347 | enum bfi_lps_i2h_msgs { | 348 | enum bfi_lps_i2h_msgs { |
@@ -401,10 +402,17 @@ struct bfi_lps_cvl_event_s { | |||
401 | u8 rsvd[3]; | 402 | u8 rsvd[3]; |
402 | }; | 403 | }; |
403 | 404 | ||
405 | struct bfi_lps_n2n_pid_req_s { | ||
406 | struct bfi_mhdr_s mh; /* common msg header */ | ||
407 | u8 lp_tag; | ||
408 | u32 lp_pid:24; | ||
409 | }; | ||
410 | |||
404 | union bfi_lps_h2i_msg_u { | 411 | union bfi_lps_h2i_msg_u { |
405 | struct bfi_mhdr_s *msg; | 412 | struct bfi_mhdr_s *msg; |
406 | struct bfi_lps_login_req_s *login_req; | 413 | struct bfi_lps_login_req_s *login_req; |
407 | struct bfi_lps_logout_req_s *logout_req; | 414 | struct bfi_lps_logout_req_s *logout_req; |
415 | struct bfi_lps_n2n_pid_req_s *n2n_pid_req; | ||
408 | }; | 416 | }; |
409 | 417 | ||
410 | union bfi_lps_i2h_msg_u { | 418 | union bfi_lps_i2h_msg_u { |