aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2011-02-16 16:04:30 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-24 12:40:05 -0500
commit09813ba5bc1a09e39402d66c1671715af0124942 (patch)
treed57091b31e25a77ce9a038e0a05a9b40d628ac8f /drivers/scsi/bnx2i
parent45188354ebd15be7fb15d2b144a1a0ecd2e797a9 (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.h2
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c116
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c6
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);
752extern int bnx2i_send_iscsi_tmf(struct bnx2i_conn *conn, 752extern int bnx2i_send_iscsi_tmf(struct bnx2i_conn *conn,
753 struct iscsi_task *mtask); 753 struct iscsi_task *mtask);
754extern int bnx2i_send_iscsi_text(struct bnx2i_conn *conn,
755 struct iscsi_task *mtask);
754extern int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *conn, 756extern int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *conn,
755 struct bnx2i_cmd *cmnd); 757 struct bnx2i_cmd *cmnd);
756extern int bnx2i_send_iscsi_nopout(struct bnx2i_conn *conn, 758extern 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 */
455int 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 */
1490static 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);
1537done:
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 |