diff options
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_hwi.c')
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_hwi.c | 125 |
1 files changed, 122 insertions, 3 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 96505e3ab986..1da34c019b8a 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c | |||
@@ -445,6 +445,56 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn, | |||
445 | } | 445 | } |
446 | 446 | ||
447 | /** | 447 | /** |
448 | * bnx2i_send_iscsi_text - post iSCSI text WQE to hardware | ||
449 | * @conn: iscsi connection | ||
450 | * @mtask: driver command structure which is requesting | ||
451 | * a WQE to sent to chip for further processing | ||
452 | * | ||
453 | * prepare and post an iSCSI Text request WQE to CNIC firmware | ||
454 | */ | ||
455 | int bnx2i_send_iscsi_text(struct bnx2i_conn *bnx2i_conn, | ||
456 | struct iscsi_task *mtask) | ||
457 | { | ||
458 | struct bnx2i_cmd *bnx2i_cmd; | ||
459 | struct bnx2i_text_request *text_wqe; | ||
460 | struct iscsi_text *text_hdr; | ||
461 | u32 dword; | ||
462 | |||
463 | bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data; | ||
464 | text_hdr = (struct iscsi_text *)mtask->hdr; | ||
465 | text_wqe = (struct bnx2i_text_request *) bnx2i_conn->ep->qp.sq_prod_qe; | ||
466 | |||
467 | memset(text_wqe, 0, sizeof(struct bnx2i_text_request)); | ||
468 | |||
469 | text_wqe->op_code = text_hdr->opcode; | ||
470 | text_wqe->op_attr = text_hdr->flags; | ||
471 | text_wqe->data_length = ntoh24(text_hdr->dlength); | ||
472 | text_wqe->itt = mtask->itt | | ||
473 | (ISCSI_TASK_TYPE_MPATH << ISCSI_TEXT_REQUEST_TYPE_SHIFT); | ||
474 | text_wqe->ttt = be32_to_cpu(text_hdr->ttt); | ||
475 | |||
476 | text_wqe->cmd_sn = be32_to_cpu(text_hdr->cmdsn); | ||
477 | |||
478 | text_wqe->resp_bd_list_addr_lo = (u32) bnx2i_conn->gen_pdu.resp_bd_dma; | ||
479 | text_wqe->resp_bd_list_addr_hi = | ||
480 | (u32) ((u64) bnx2i_conn->gen_pdu.resp_bd_dma >> 32); | ||
481 | |||
482 | dword = ((1 << ISCSI_TEXT_REQUEST_NUM_RESP_BDS_SHIFT) | | ||
483 | (bnx2i_conn->gen_pdu.resp_buf_size << | ||
484 | ISCSI_TEXT_REQUEST_RESP_BUFFER_LENGTH_SHIFT)); | ||
485 | text_wqe->resp_buffer = dword; | ||
486 | text_wqe->bd_list_addr_lo = (u32) bnx2i_conn->gen_pdu.req_bd_dma; | ||
487 | text_wqe->bd_list_addr_hi = | ||
488 | (u32) ((u64) bnx2i_conn->gen_pdu.req_bd_dma >> 32); | ||
489 | text_wqe->num_bds = 1; | ||
490 | text_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */ | ||
491 | |||
492 | bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1); | ||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | |||
497 | /** | ||
448 | * bnx2i_send_iscsi_scsicmd - post iSCSI scsicmd request WQE to hardware | 498 | * bnx2i_send_iscsi_scsicmd - post iSCSI scsicmd request WQE to hardware |
449 | * @conn: iscsi connection | 499 | * @conn: iscsi connection |
450 | * @cmd: driver command structure which is requesting | 500 | * @cmd: driver command structure which is requesting |
@@ -490,15 +540,18 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn, | |||
490 | bnx2i_cmd = (struct bnx2i_cmd *)task->dd_data; | 540 | bnx2i_cmd = (struct bnx2i_cmd *)task->dd_data; |
491 | nopout_hdr = (struct iscsi_nopout *)task->hdr; | 541 | nopout_hdr = (struct iscsi_nopout *)task->hdr; |
492 | nopout_wqe = (struct bnx2i_nop_out_request *)ep->qp.sq_prod_qe; | 542 | nopout_wqe = (struct bnx2i_nop_out_request *)ep->qp.sq_prod_qe; |
543 | |||
544 | memset(nopout_wqe, 0x00, sizeof(struct bnx2i_nop_out_request)); | ||
545 | |||
493 | nopout_wqe->op_code = nopout_hdr->opcode; | 546 | nopout_wqe->op_code = nopout_hdr->opcode; |
494 | nopout_wqe->op_attr = ISCSI_FLAG_CMD_FINAL; | 547 | nopout_wqe->op_attr = ISCSI_FLAG_CMD_FINAL; |
495 | memcpy(nopout_wqe->lun, nopout_hdr->lun, 8); | 548 | memcpy(nopout_wqe->lun, nopout_hdr->lun, 8); |
496 | 549 | ||
497 | if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) { | 550 | if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) { |
498 | u32 tmp = nopout_hdr->lun[0]; | 551 | u32 tmp = nopout_wqe->lun[0]; |
499 | /* 57710 requires LUN field to be swapped */ | 552 | /* 57710 requires LUN field to be swapped */ |
500 | nopout_hdr->lun[0] = nopout_hdr->lun[1]; | 553 | nopout_wqe->lun[0] = nopout_wqe->lun[1]; |
501 | nopout_hdr->lun[1] = tmp; | 554 | nopout_wqe->lun[1] = tmp; |
502 | } | 555 | } |
503 | 556 | ||
504 | nopout_wqe->itt = ((u16)task->itt | | 557 | nopout_wqe->itt = ((u16)task->itt | |
@@ -1425,6 +1478,68 @@ done: | |||
1425 | return 0; | 1478 | return 0; |
1426 | } | 1479 | } |
1427 | 1480 | ||
1481 | |||
1482 | /** | ||
1483 | * bnx2i_process_text_resp - this function handles iscsi text response | ||
1484 | * @session: iscsi session pointer | ||
1485 | * @bnx2i_conn: iscsi connection pointer | ||
1486 | * @cqe: pointer to newly DMA'ed CQE entry for processing | ||
1487 | * | ||
1488 | * process iSCSI Text Response CQE& complete it to open-iscsi user daemon | ||
1489 | */ | ||
1490 | static int bnx2i_process_text_resp(struct iscsi_session *session, | ||
1491 | struct bnx2i_conn *bnx2i_conn, | ||
1492 | struct cqe *cqe) | ||
1493 | { | ||
1494 | struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data; | ||
1495 | struct iscsi_task *task; | ||
1496 | struct bnx2i_text_response *text; | ||
1497 | struct iscsi_text_rsp *resp_hdr; | ||
1498 | int pld_len; | ||
1499 | int pad_len; | ||
1500 | |||
1501 | text = (struct bnx2i_text_response *) cqe; | ||
1502 | spin_lock(&session->lock); | ||
1503 | task = iscsi_itt_to_task(conn, text->itt & ISCSI_LOGIN_RESPONSE_INDEX); | ||
1504 | if (!task) | ||
1505 | goto done; | ||
1506 | |||
1507 | resp_hdr = (struct iscsi_text_rsp *)&bnx2i_conn->gen_pdu.resp_hdr; | ||
1508 | memset(resp_hdr, 0, sizeof(struct iscsi_hdr)); | ||
1509 | resp_hdr->opcode = text->op_code; | ||
1510 | resp_hdr->flags = text->response_flags; | ||
1511 | resp_hdr->hlength = 0; | ||
1512 | |||
1513 | hton24(resp_hdr->dlength, text->data_length); | ||
1514 | resp_hdr->itt = task->hdr->itt; | ||
1515 | resp_hdr->ttt = cpu_to_be32(text->ttt); | ||
1516 | resp_hdr->statsn = task->hdr->exp_statsn; | ||
1517 | resp_hdr->exp_cmdsn = cpu_to_be32(text->exp_cmd_sn); | ||
1518 | resp_hdr->max_cmdsn = cpu_to_be32(text->max_cmd_sn); | ||
1519 | pld_len = text->data_length; | ||
1520 | bnx2i_conn->gen_pdu.resp_wr_ptr = bnx2i_conn->gen_pdu.resp_buf + | ||
1521 | pld_len; | ||
1522 | pad_len = 0; | ||
1523 | if (pld_len & 0x3) | ||
1524 | pad_len = 4 - (pld_len % 4); | ||
1525 | |||
1526 | if (pad_len) { | ||
1527 | int i = 0; | ||
1528 | for (i = 0; i < pad_len; i++) { | ||
1529 | bnx2i_conn->gen_pdu.resp_wr_ptr[0] = 0; | ||
1530 | bnx2i_conn->gen_pdu.resp_wr_ptr++; | ||
1531 | } | ||
1532 | } | ||
1533 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, | ||
1534 | bnx2i_conn->gen_pdu.resp_buf, | ||
1535 | bnx2i_conn->gen_pdu.resp_wr_ptr - | ||
1536 | bnx2i_conn->gen_pdu.resp_buf); | ||
1537 | done: | ||
1538 | spin_unlock(&session->lock); | ||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1542 | |||
1428 | /** | 1543 | /** |
1429 | * bnx2i_process_tmf_resp - this function handles iscsi TMF response | 1544 | * bnx2i_process_tmf_resp - this function handles iscsi TMF response |
1430 | * @session: iscsi session pointer | 1545 | * @session: iscsi session pointer |
@@ -1766,6 +1881,10 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn) | |||
1766 | bnx2i_process_tmf_resp(session, bnx2i_conn, | 1881 | bnx2i_process_tmf_resp(session, bnx2i_conn, |
1767 | qp->cq_cons_qe); | 1882 | qp->cq_cons_qe); |
1768 | break; | 1883 | break; |
1884 | case ISCSI_OP_TEXT_RSP: | ||
1885 | bnx2i_process_text_resp(session, bnx2i_conn, | ||
1886 | qp->cq_cons_qe); | ||
1887 | break; | ||
1769 | case ISCSI_OP_LOGOUT_RSP: | 1888 | case ISCSI_OP_LOGOUT_RSP: |
1770 | bnx2i_process_logout_resp(session, bnx2i_conn, | 1889 | bnx2i_process_logout_resp(session, bnx2i_conn, |
1771 | qp->cq_cons_qe); | 1890 | qp->cq_cons_qe); |