diff options
author | Eddie Wai <eddie.wai@broadcom.com> | 2011-02-16 16:04:30 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-02-24 12:40:05 -0500 |
commit | 09813ba5bc1a09e39402d66c1671715af0124942 (patch) | |
tree | d57091b31e25a77ce9a038e0a05a9b40d628ac8f /drivers/scsi/bnx2i | |
parent | 45188354ebd15be7fb15d2b144a1a0ecd2e797a9 (diff) |
[SCSI] bnx2i: Added iSCSI text pdu support for iSCSI offload
This is part of an effort to support send target discovery via
the iSCSI offload path.
Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bnx2i')
-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 | |