aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi/be_mgmt.c
diff options
context:
space:
mode:
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>2016-08-19 05:50:12 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-08-23 22:42:43 -0400
commit50a4b824be9e4a01f3b87790865e26b1546fcbb8 (patch)
treea677875c94ddad99dd6a1274bbd21a83ffc7c683 /drivers/scsi/be2iscsi/be_mgmt.c
parent9122e991cebb90a7225109ed7627950f485c5f58 (diff)
scsi: be2iscsi: Fix to make boot discovery non-blocking
Boot work involves: 1. Find and fetch configured boot session and its handle. 2. Attempt to open the session if its not. 3. Get the session details for boot kset creation. 4. Logout of that session owned by FW. 5. Create boot kset for session details. All these actions were done in blocking call with retries in global wq. Other works in wq suffered if the IOCTLs stalled or timed out. This change moves all the boot work to make it non-blocking. The work queued in global wq just issues the IOCTL depending on the action to be taken and mcc wq schedules work depending on status of the IOCTL. Initial boot_work is started on link and ASYNC event. The other code changes move all boot related functions in one place and follow naming conventions. Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/be2iscsi/be_mgmt.c')
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c537
1 files changed, 292 insertions, 245 deletions
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 4f2194e324ae..756e7ae33e2c 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -187,120 +187,6 @@ int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
187} 187}
188 188
189/** 189/**
190 * mgmt_reopen_session()- Reopen a session based on reopen_type
191 * @phba: Device priv structure instance
192 * @reopen_type: Type of reopen_session FW should do.
193 * @sess_handle: Session Handle of the session to be re-opened
194 *
195 * return
196 * the TAG used for MBOX Command
197 *
198 **/
199unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
200 unsigned int reopen_type,
201 unsigned int sess_handle)
202{
203 struct be_ctrl_info *ctrl = &phba->ctrl;
204 struct be_mcc_wrb *wrb;
205 struct be_cmd_reopen_session_req *req;
206 unsigned int tag;
207
208 beiscsi_log(phba, KERN_INFO,
209 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
210 "BG_%d : In bescsi_get_boot_target\n");
211
212 mutex_lock(&ctrl->mbox_lock);
213 wrb = alloc_mcc_wrb(phba, &tag);
214 if (!wrb) {
215 mutex_unlock(&ctrl->mbox_lock);
216 return 0;
217 }
218
219 req = embedded_payload(wrb);
220 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
221 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
222 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
223 sizeof(struct be_cmd_reopen_session_resp));
224
225 /* set the reopen_type,sess_handle */
226 req->reopen_type = reopen_type;
227 req->session_handle = sess_handle;
228
229 be_mcc_notify(phba, tag);
230 mutex_unlock(&ctrl->mbox_lock);
231 return tag;
232}
233
234unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
235{
236 struct be_ctrl_info *ctrl = &phba->ctrl;
237 struct be_mcc_wrb *wrb;
238 struct be_cmd_get_boot_target_req *req;
239 unsigned int tag;
240
241 beiscsi_log(phba, KERN_INFO,
242 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
243 "BG_%d : In bescsi_get_boot_target\n");
244
245 mutex_lock(&ctrl->mbox_lock);
246 wrb = alloc_mcc_wrb(phba, &tag);
247 if (!wrb) {
248 mutex_unlock(&ctrl->mbox_lock);
249 return 0;
250 }
251
252 req = embedded_payload(wrb);
253 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
254 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
255 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
256 sizeof(struct be_cmd_get_boot_target_resp));
257
258 be_mcc_notify(phba, tag);
259 mutex_unlock(&ctrl->mbox_lock);
260 return tag;
261}
262
263unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
264 u32 boot_session_handle,
265 struct be_dma_mem *nonemb_cmd)
266{
267 struct be_ctrl_info *ctrl = &phba->ctrl;
268 struct be_mcc_wrb *wrb;
269 unsigned int tag;
270 struct be_cmd_get_session_req *req;
271 struct be_cmd_get_session_resp *resp;
272 struct be_sge *sge;
273
274 beiscsi_log(phba, KERN_INFO,
275 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
276 "BG_%d : In beiscsi_get_session_info\n");
277
278 mutex_lock(&ctrl->mbox_lock);
279 wrb = alloc_mcc_wrb(phba, &tag);
280 if (!wrb) {
281 mutex_unlock(&ctrl->mbox_lock);
282 return 0;
283 }
284
285 nonemb_cmd->size = sizeof(*resp);
286 req = nonemb_cmd->va;
287 memset(req, 0, sizeof(*req));
288 sge = nonembedded_sgl(wrb);
289 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
290 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
291 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
292 sizeof(*resp));
293 req->session_handle = boot_session_handle;
294 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
295 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
296 sge->len = cpu_to_le32(nonemb_cmd->size);
297
298 be_mcc_notify(phba, tag);
299 mutex_unlock(&ctrl->mbox_lock);
300 return tag;
301}
302
303/**
304 * mgmt_get_port_name()- Get port name for the function 190 * mgmt_get_port_name()- Get port name for the function
305 * @ctrl: ptr to Ctrl Info 191 * @ctrl: ptr to Ctrl Info
306 * @phba: ptr to the dev priv structure 192 * @phba: ptr to the dev priv structure
@@ -1419,87 +1305,315 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1419 return tag; 1305 return tag;
1420} 1306}
1421 1307
1308static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
1309 unsigned int tag)
1310{
1311 struct be_cmd_get_boot_target_resp *boot_resp;
1312 struct be_cmd_resp_logout_fw_sess *logo_resp;
1313 struct be_cmd_get_session_resp *sess_resp;
1314 struct be_mcc_wrb *wrb;
1315 struct boot_struct *bs;
1316 int boot_work, status;
1317
1318 if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
1319 __beiscsi_log(phba, KERN_ERR,
1320 "BG_%d : %s no boot work %lx\n",
1321 __func__, phba->state);
1322 return;
1323 }
1324
1325 if (phba->boot_struct.tag != tag) {
1326 __beiscsi_log(phba, KERN_ERR,
1327 "BG_%d : %s tag mismatch %d:%d\n",
1328 __func__, tag, phba->boot_struct.tag);
1329 return;
1330 }
1331 bs = &phba->boot_struct;
1332 boot_work = 1;
1333 status = 0;
1334 switch (bs->action) {
1335 case BEISCSI_BOOT_REOPEN_SESS:
1336 status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
1337 if (!status)
1338 bs->action = BEISCSI_BOOT_GET_SHANDLE;
1339 else
1340 bs->retry--;
1341 break;
1342 case BEISCSI_BOOT_GET_SHANDLE:
1343 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
1344 if (!status) {
1345 boot_resp = embedded_payload(wrb);
1346 bs->s_handle = boot_resp->boot_session_handle;
1347 }
1348 if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
1349 bs->action = BEISCSI_BOOT_REOPEN_SESS;
1350 bs->retry--;
1351 } else {
1352 bs->action = BEISCSI_BOOT_GET_SINFO;
1353 }
1354 break;
1355 case BEISCSI_BOOT_GET_SINFO:
1356 status = __beiscsi_mcc_compl_status(phba, tag, NULL,
1357 &bs->nonemb_cmd);
1358 if (!status) {
1359 sess_resp = bs->nonemb_cmd.va;
1360 memcpy(&bs->boot_sess, &sess_resp->session_info,
1361 sizeof(struct mgmt_session_info));
1362 bs->action = BEISCSI_BOOT_LOGOUT_SESS;
1363 } else {
1364 __beiscsi_log(phba, KERN_ERR,
1365 "BG_%d : get boot session info error : 0x%x\n",
1366 status);
1367 boot_work = 0;
1368 }
1369 pci_free_consistent(phba->ctrl.pdev, bs->nonemb_cmd.size,
1370 bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
1371 bs->nonemb_cmd.va = NULL;
1372 break;
1373 case BEISCSI_BOOT_LOGOUT_SESS:
1374 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
1375 if (!status) {
1376 logo_resp = embedded_payload(wrb);
1377 if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
1378 __beiscsi_log(phba, KERN_ERR,
1379 "BG_%d : FW boot session logout error : 0x%x\n",
1380 logo_resp->session_status);
1381 }
1382 }
1383 /* continue to create boot_kset even if logout failed? */
1384 bs->action = BEISCSI_BOOT_CREATE_KSET;
1385 break;
1386 default:
1387 break;
1388 }
1389
1390 /* clear the tag so no other completion matches this tag */
1391 bs->tag = 0;
1392 if (!bs->retry) {
1393 boot_work = 0;
1394 __beiscsi_log(phba, KERN_ERR,
1395 "BG_%d : failed to setup boot target: status %d action %d\n",
1396 status, bs->action);
1397 }
1398 if (!boot_work) {
1399 /* wait for next event to start boot_work */
1400 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
1401 return;
1402 }
1403 schedule_work(&phba->boot_work);
1404}
1405
1422/** 1406/**
1423 * be_mgmt_get_boot_shandle()- Get the session handle 1407 * beiscsi_boot_logout_sess()- Logout from boot FW session
1424 * @phba: device priv structure instance 1408 * @phba: Device priv structure instance
1425 * @s_handle: session handle returned for boot session. 1409 *
1410 * return
1411 * the TAG used for MBOX Command
1426 * 1412 *
1427 * Get the boot target session handle. In case of 1413 */
1428 * crashdump mode driver has to issue and MBX Cmd 1414unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
1429 * for FW to login to boot target 1415{
1416 struct be_ctrl_info *ctrl = &phba->ctrl;
1417 struct be_mcc_wrb *wrb;
1418 struct be_cmd_req_logout_fw_sess *req;
1419 unsigned int tag;
1420
1421 mutex_lock(&ctrl->mbox_lock);
1422 wrb = alloc_mcc_wrb(phba, &tag);
1423 if (!wrb) {
1424 mutex_unlock(&ctrl->mbox_lock);
1425 return 0;
1426 }
1427
1428 req = embedded_payload(wrb);
1429 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1430 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1431 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1432 sizeof(struct be_cmd_req_logout_fw_sess));
1433 /* Use the session handle copied into boot_sess */
1434 req->session_handle = phba->boot_struct.boot_sess.session_handle;
1435
1436 phba->boot_struct.tag = tag;
1437 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1438 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1439
1440 be_mcc_notify(phba, tag);
1441 mutex_unlock(&ctrl->mbox_lock);
1442
1443 return tag;
1444}
1445/**
1446 * beiscsi_boot_reopen_sess()- Reopen boot session
1447 * @phba: Device priv structure instance
1430 * 1448 *
1431 * return 1449 * return
1432 * Success: 0 1450 * the TAG used for MBOX Command
1433 * Failure: Non-Zero value
1434 * 1451 *
1435 **/ 1452 **/
1436int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba, 1453unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
1437 unsigned int *s_handle)
1438{ 1454{
1439 struct be_cmd_get_boot_target_resp *boot_resp; 1455 struct be_ctrl_info *ctrl = &phba->ctrl;
1440 struct be_mcc_wrb *wrb; 1456 struct be_mcc_wrb *wrb;
1457 struct be_cmd_reopen_session_req *req;
1441 unsigned int tag; 1458 unsigned int tag;
1442 uint8_t boot_retry = 3;
1443 int rc;
1444 1459
1445 do { 1460 mutex_lock(&ctrl->mbox_lock);
1446 /* Get the Boot Target Session Handle and Count*/ 1461 wrb = alloc_mcc_wrb(phba, &tag);
1447 tag = mgmt_get_boot_target(phba); 1462 if (!wrb) {
1448 if (!tag) { 1463 mutex_unlock(&ctrl->mbox_lock);
1449 beiscsi_log(phba, KERN_ERR, 1464 return 0;
1450 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, 1465 }
1451 "BG_%d : Getting Boot Target Info Failed\n");
1452 return -EAGAIN;
1453 }
1454 1466
1455 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL); 1467 req = embedded_payload(wrb);
1456 if (rc) { 1468 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1457 beiscsi_log(phba, KERN_ERR, 1469 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1458 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1470 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
1459 "BG_%d : MBX CMD get_boot_target Failed\n"); 1471 sizeof(struct be_cmd_reopen_session_resp));
1460 return -EBUSY; 1472 req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
1461 } 1473 req->session_handle = BE_BOOT_INVALID_SHANDLE;
1462 1474
1463 boot_resp = embedded_payload(wrb); 1475 phba->boot_struct.tag = tag;
1476 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1477 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1464 1478
1465 /* Check if the there are any Boot targets configured */ 1479 be_mcc_notify(phba, tag);
1466 if (!boot_resp->boot_session_count) { 1480 mutex_unlock(&ctrl->mbox_lock);
1467 beiscsi_log(phba, KERN_INFO, 1481 return tag;
1468 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1482}
1469 "BG_%d ;No boot targets configured\n");
1470 return -ENXIO;
1471 }
1472 1483
1473 /* FW returns the session handle of the boot session */
1474 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1475 *s_handle = boot_resp->boot_session_handle;
1476 return 0;
1477 }
1478 1484
1479 /* Issue MBX Cmd to FW to login to the boot target */ 1485/**
1480 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS, 1486 * beiscsi_boot_get_sinfo()- Get boot session info
1481 INVALID_SESS_HANDLE); 1487 * @phba: device priv structure instance
1482 if (!tag) { 1488 *
1483 beiscsi_log(phba, KERN_ERR, 1489 * Fetches the boot_struct.s_handle info from FW.
1484 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1490 * return
1485 "BG_%d : mgmt_reopen_session Failed\n"); 1491 * the TAG used for MBOX Command
1486 return -EAGAIN; 1492 *
1487 } 1493 **/
1494unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
1495{
1496 struct be_ctrl_info *ctrl = &phba->ctrl;
1497 struct be_cmd_get_session_resp *resp;
1498 struct be_cmd_get_session_req *req;
1499 struct be_dma_mem *nonemb_cmd;
1500 struct be_mcc_wrb *wrb;
1501 struct be_sge *sge;
1502 unsigned int tag;
1488 1503
1489 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL); 1504 mutex_lock(&ctrl->mbox_lock);
1490 if (rc) { 1505 wrb = alloc_mcc_wrb(phba, &tag);
1491 beiscsi_log(phba, KERN_ERR, 1506 if (!wrb) {
1492 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1507 mutex_unlock(&ctrl->mbox_lock);
1493 "BG_%d : mgmt_reopen_session Failed"); 1508 return 0;
1494 return rc; 1509 }
1495 }
1496 } while (--boot_retry);
1497 1510
1498 /* Couldn't log into the boot target */ 1511 nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1499 beiscsi_log(phba, KERN_ERR, 1512 nonemb_cmd->size = sizeof(*resp);
1500 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1513 nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
1501 "BG_%d : Login to Boot Target Failed\n"); 1514 sizeof(nonemb_cmd->size),
1502 return -ENXIO; 1515 &nonemb_cmd->dma);
1516 if (!nonemb_cmd->va)
1517 return 0;
1518
1519 req = nonemb_cmd->va;
1520 memset(req, 0, sizeof(*req));
1521 sge = nonembedded_sgl(wrb);
1522 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1523 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1524 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1525 sizeof(*resp));
1526 req->session_handle = phba->boot_struct.s_handle;
1527 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1528 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1529 sge->len = cpu_to_le32(nonemb_cmd->size);
1530
1531 phba->boot_struct.tag = tag;
1532 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1533 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1534
1535 be_mcc_notify(phba, tag);
1536 mutex_unlock(&ctrl->mbox_lock);
1537 return tag;
1538}
1539
1540unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1541{
1542 struct be_ctrl_info *ctrl = &phba->ctrl;
1543 struct be_mcc_wrb *wrb;
1544 struct be_cmd_get_boot_target_req *req;
1545 unsigned int tag;
1546
1547 mutex_lock(&ctrl->mbox_lock);
1548 wrb = alloc_mcc_wrb(phba, &tag);
1549 if (!wrb) {
1550 mutex_unlock(&ctrl->mbox_lock);
1551 return 0;
1552 }
1553
1554 req = embedded_payload(wrb);
1555 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1556 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1557 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1558 sizeof(struct be_cmd_get_boot_target_resp));
1559
1560 if (async) {
1561 phba->boot_struct.tag = tag;
1562 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1563 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1564 }
1565
1566 be_mcc_notify(phba, tag);
1567 mutex_unlock(&ctrl->mbox_lock);
1568 return tag;
1569}
1570
1571/**
1572 * beiscsi_boot_get_shandle()- Get boot session handle
1573 * @phba: device priv structure instance
1574 * @s_handle: session handle returned for boot session.
1575 *
1576 * return
1577 * Success: 1
1578 * Failure: negative
1579 *
1580 **/
1581int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1582{
1583 struct be_cmd_get_boot_target_resp *boot_resp;
1584 struct be_mcc_wrb *wrb;
1585 unsigned int tag;
1586 int rc;
1587
1588 *s_handle = BE_BOOT_INVALID_SHANDLE;
1589 /* get configured boot session count and handle */
1590 tag = __beiscsi_boot_get_shandle(phba, 0);
1591 if (!tag) {
1592 beiscsi_log(phba, KERN_ERR,
1593 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1594 "BG_%d : Getting Boot Target Info Failed\n");
1595 return -EAGAIN;
1596 }
1597
1598 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1599 if (rc) {
1600 beiscsi_log(phba, KERN_ERR,
1601 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1602 "BG_%d : MBX CMD get_boot_target Failed\n");
1603 return -EBUSY;
1604 }
1605
1606 boot_resp = embedded_payload(wrb);
1607 /* check if there are any boot targets configured */
1608 if (!boot_resp->boot_session_count) {
1609 __beiscsi_log(phba, KERN_INFO,
1610 "BG_%d : No boot targets configured\n");
1611 return -ENXIO;
1612 }
1613
1614 /* only if FW has logged in to the boot target, s_handle is valid */
1615 *s_handle = boot_resp->boot_session_handle;
1616 return 1;
1503} 1617}
1504 1618
1505/** 1619/**
@@ -1809,70 +1923,3 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1809 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1923 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1810 exp_statsn) / 32] + 1)); 1924 exp_statsn) / 32] + 1));
1811} 1925}
1812
1813/**
1814 * beiscsi_logout_fw_sess()- Firmware Session Logout
1815 * @phba: Device priv structure instance
1816 * @fw_sess_handle: FW session handle
1817 *
1818 * Logout from the FW established sessions.
1819 * returns
1820 * Success: 0
1821 * Failure: Non-Zero Value
1822 *
1823 */
1824int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
1825 uint32_t fw_sess_handle)
1826{
1827 struct be_ctrl_info *ctrl = &phba->ctrl;
1828 struct be_mcc_wrb *wrb;
1829 struct be_cmd_req_logout_fw_sess *req;
1830 struct be_cmd_resp_logout_fw_sess *resp;
1831 unsigned int tag;
1832 int rc;
1833
1834 beiscsi_log(phba, KERN_INFO,
1835 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1836 "BG_%d : In bescsi_logout_fwboot_sess\n");
1837
1838 mutex_lock(&ctrl->mbox_lock);
1839 wrb = alloc_mcc_wrb(phba, &tag);
1840 if (!wrb) {
1841 mutex_unlock(&ctrl->mbox_lock);
1842 beiscsi_log(phba, KERN_INFO,
1843 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1844 "BG_%d : MBX Tag Failure\n");
1845 return -EINVAL;
1846 }
1847
1848 req = embedded_payload(wrb);
1849 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1850 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1851 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1852 sizeof(struct be_cmd_req_logout_fw_sess));
1853
1854 /* Set the session handle */
1855 req->session_handle = fw_sess_handle;
1856 be_mcc_notify(phba, tag);
1857 mutex_unlock(&ctrl->mbox_lock);
1858
1859 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1860 if (rc) {
1861 beiscsi_log(phba, KERN_ERR,
1862 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1863 "BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
1864 return -EBUSY;
1865 }
1866
1867 resp = embedded_payload(wrb);
1868 if (resp->session_status !=
1869 BEISCSI_MGMT_SESSION_CLOSE) {
1870 beiscsi_log(phba, KERN_ERR,
1871 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1872 "BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
1873 resp->session_status);
1874 rc = -EINVAL;
1875 }
1876
1877 return rc;
1878}