diff options
| -rw-r--r-- | drivers/scsi/bnx2i/bnx2i.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/bnx2i/bnx2i_hwi.c | 116 | ||||
| -rw-r--r-- | drivers/scsi/bnx2i/bnx2i_iscsi.c | 6 |
3 files changed, 123 insertions, 1 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 275685392e01..cfd59023227b 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h | |||
| @@ -751,6 +751,8 @@ extern int bnx2i_send_iscsi_login(struct bnx2i_conn *conn, | |||
| 751 | struct iscsi_task *mtask); | 751 | struct iscsi_task *mtask); |
| 752 | extern int bnx2i_send_iscsi_tmf(struct bnx2i_conn *conn, | 752 | extern int bnx2i_send_iscsi_tmf(struct bnx2i_conn *conn, |
| 753 | struct iscsi_task *mtask); | 753 | struct iscsi_task *mtask); |
| 754 | extern int bnx2i_send_iscsi_text(struct bnx2i_conn *conn, | ||
| 755 | struct iscsi_task *mtask); | ||
| 754 | extern int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *conn, | 756 | extern int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *conn, |
| 755 | struct bnx2i_cmd *cmnd); | 757 | struct bnx2i_cmd *cmnd); |
| 756 | extern int bnx2i_send_iscsi_nopout(struct bnx2i_conn *conn, | 758 | extern int bnx2i_send_iscsi_nopout(struct bnx2i_conn *conn, |
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index c8eff57d3c00..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 |
| @@ -1428,6 +1478,68 @@ done: | |||
| 1428 | return 0; | 1478 | return 0; |
| 1429 | } | 1479 | } |
| 1430 | 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 | |||
| 1431 | /** | 1543 | /** |
| 1432 | * bnx2i_process_tmf_resp - this function handles iscsi TMF response | 1544 | * bnx2i_process_tmf_resp - this function handles iscsi TMF response |
| 1433 | * @session: iscsi session pointer | 1545 | * @session: iscsi session pointer |
| @@ -1769,6 +1881,10 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn) | |||
| 1769 | bnx2i_process_tmf_resp(session, bnx2i_conn, | 1881 | bnx2i_process_tmf_resp(session, bnx2i_conn, |
| 1770 | qp->cq_cons_qe); | 1882 | qp->cq_cons_qe); |
| 1771 | break; | 1883 | break; |
| 1884 | case ISCSI_OP_TEXT_RSP: | ||
| 1885 | bnx2i_process_text_resp(session, bnx2i_conn, | ||
| 1886 | qp->cq_cons_qe); | ||
| 1887 | break; | ||
| 1772 | case ISCSI_OP_LOGOUT_RSP: | 1888 | case ISCSI_OP_LOGOUT_RSP: |
| 1773 | bnx2i_process_logout_resp(session, bnx2i_conn, | 1889 | bnx2i_process_logout_resp(session, bnx2i_conn, |
| 1774 | qp->cq_cons_qe); | 1890 | qp->cq_cons_qe); |
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index f9415aa35300..05bb8086069a 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c | |||
| @@ -1092,6 +1092,9 @@ static int bnx2i_iscsi_send_generic_request(struct iscsi_task *task) | |||
| 1092 | case ISCSI_OP_SCSI_TMFUNC: | 1092 | case ISCSI_OP_SCSI_TMFUNC: |
| 1093 | rc = bnx2i_send_iscsi_tmf(bnx2i_conn, task); | 1093 | rc = bnx2i_send_iscsi_tmf(bnx2i_conn, task); |
| 1094 | break; | 1094 | break; |
| 1095 | case ISCSI_OP_TEXT: | ||
| 1096 | rc = bnx2i_send_iscsi_text(bnx2i_conn, task); | ||
| 1097 | break; | ||
| 1095 | default: | 1098 | default: |
| 1096 | iscsi_conn_printk(KERN_ALERT, bnx2i_conn->cls_conn->dd_data, | 1099 | iscsi_conn_printk(KERN_ALERT, bnx2i_conn->cls_conn->dd_data, |
| 1097 | "send_gen: unsupported op 0x%x\n", | 1100 | "send_gen: unsupported op 0x%x\n", |
| @@ -2167,7 +2170,8 @@ struct iscsi_transport bnx2i_iscsi_transport = { | |||
| 2167 | .name = "bnx2i", | 2170 | .name = "bnx2i", |
| 2168 | .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | | 2171 | .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | |
| 2169 | CAP_MULTI_R2T | CAP_DATADGST | | 2172 | CAP_MULTI_R2T | CAP_DATADGST | |
| 2170 | CAP_DATA_PATH_OFFLOAD, | 2173 | CAP_DATA_PATH_OFFLOAD | |
| 2174 | CAP_TEXT_NEGO, | ||
| 2171 | .param_mask = ISCSI_MAX_RECV_DLENGTH | | 2175 | .param_mask = ISCSI_MAX_RECV_DLENGTH | |
| 2172 | ISCSI_MAX_XMIT_DLENGTH | | 2176 | ISCSI_MAX_XMIT_DLENGTH | |
| 2173 | ISCSI_HDRDGST_EN | | 2177 | ISCSI_HDRDGST_EN | |
