aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2008-05-21 16:54:04 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-12 09:22:18 -0400
commit0af967f5d4f2dd1e00618d34ac988037d37a6c3b (patch)
tree08297980d1b6dab820d22c12c7fe1c54602f2486 /drivers
parentb40977d95fb3a1898ace6a7d97e4ed1a33a440a4 (diff)
[SCSI] libiscsi, iscsi_tcp, iser: add session cmds array accessor
Currently to get a ctask from the session cmd array, you have to know to use the itt modifier. To make this easier on LLDs and so in the future we can easilly kill the session array and use the host shared map instead, this patch adds a nice wrapper to strip the itt into a session->cmds index and return a ctask. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c8
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c23
-rw-r--r--drivers/scsi/iscsi_tcp.c13
-rw-r--r--drivers/scsi/libiscsi.c60
4 files changed, 63 insertions, 41 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 8a1bfb7277c8..7b1468869066 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -98,7 +98,6 @@ iscsi_iser_recv(struct iscsi_conn *conn,
98 struct iscsi_hdr *hdr, char *rx_data, int rx_data_len) 98 struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
99{ 99{
100 int rc = 0; 100 int rc = 0;
101 uint32_t ret_itt;
102 int datalen; 101 int datalen;
103 int ahslen; 102 int ahslen;
104 103
@@ -114,12 +113,7 @@ iscsi_iser_recv(struct iscsi_conn *conn,
114 /* read AHS */ 113 /* read AHS */
115 ahslen = hdr->hlength * 4; 114 ahslen = hdr->hlength * 4;
116 115
117 /* verify itt (itt encoding: age+cid+itt) */ 116 rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
118 rc = iscsi_verify_itt(conn, hdr, &ret_itt);
119
120 if (!rc)
121 rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
122
123 if (rc && rc != ISCSI_ERR_NO_SCSI_CMD) 117 if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
124 goto error; 118 goto error;
125 119
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 08dc81c46f41..b82a5f2d4d37 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -537,13 +537,11 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
537{ 537{
538 struct iser_dto *dto = &rx_desc->dto; 538 struct iser_dto *dto = &rx_desc->dto;
539 struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn; 539 struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
540 struct iscsi_session *session = conn->iscsi_conn->session;
541 struct iscsi_cmd_task *ctask; 540 struct iscsi_cmd_task *ctask;
542 struct iscsi_iser_cmd_task *iser_ctask; 541 struct iscsi_iser_cmd_task *iser_ctask;
543 struct iscsi_hdr *hdr; 542 struct iscsi_hdr *hdr;
544 char *rx_data = NULL; 543 char *rx_data = NULL;
545 int rx_data_len = 0; 544 int rx_data_len = 0;
546 unsigned int itt;
547 unsigned char opcode; 545 unsigned char opcode;
548 546
549 hdr = &rx_desc->iscsi_header; 547 hdr = &rx_desc->iscsi_header;
@@ -559,19 +557,18 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
559 opcode = hdr->opcode & ISCSI_OPCODE_MASK; 557 opcode = hdr->opcode & ISCSI_OPCODE_MASK;
560 558
561 if (opcode == ISCSI_OP_SCSI_CMD_RSP) { 559 if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
562 itt = get_itt(hdr->itt); /* mask out cid and age bits */ 560 ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
563 if (!(itt < session->cmds_max)) 561 if (!ctask)
564 iser_err("itt can't be matched to task!!! " 562 iser_err("itt can't be matched to task!!! "
565 "conn %p opcode %d cmds_max %d itt %d\n", 563 "conn %p opcode %d itt %d\n",
566 conn->iscsi_conn,opcode,session->cmds_max,itt); 564 conn->iscsi_conn, opcode, hdr->itt);
567 /* use the mapping given with the cmds array indexed by itt */ 565 else {
568 ctask = (struct iscsi_cmd_task *)session->cmds[itt]; 566 iser_ctask = ctask->dd_data;
569 iser_ctask = ctask->dd_data; 567 iser_dbg("itt %d ctask %p\n",hdr->itt, ctask);
570 iser_dbg("itt %d ctask %p\n",itt,ctask); 568 iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
571 iser_ctask->status = ISER_TASK_STATUS_COMPLETED; 569 iser_ctask_rdma_finalize(iser_ctask);
572 iser_ctask_rdma_finalize(iser_ctask); 570 }
573 } 571 }
574
575 iser_dto_buffs_release(dto); 572 iser_dto_buffs_release(dto);
576 573
577 iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len); 574 iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index dfaf9fa57340..f2a08f7ed902 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -740,7 +740,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
740 struct iscsi_session *session = conn->session; 740 struct iscsi_session *session = conn->session;
741 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 741 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
742 struct iscsi_cmd_task *ctask; 742 struct iscsi_cmd_task *ctask;
743 uint32_t itt;
744 743
745 /* verify PDU length */ 744 /* verify PDU length */
746 tcp_conn->in.datalen = ntoh24(hdr->dlength); 745 tcp_conn->in.datalen = ntoh24(hdr->dlength);
@@ -758,7 +757,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
758 757
759 opcode = hdr->opcode & ISCSI_OPCODE_MASK; 758 opcode = hdr->opcode & ISCSI_OPCODE_MASK;
760 /* verify itt (itt encoding: age+cid+itt) */ 759 /* verify itt (itt encoding: age+cid+itt) */
761 rc = iscsi_verify_itt(conn, hdr, &itt); 760 rc = iscsi_verify_itt(conn, hdr->itt);
762 if (rc) 761 if (rc)
763 return rc; 762 return rc;
764 763
@@ -767,7 +766,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
767 766
768 switch(opcode) { 767 switch(opcode) {
769 case ISCSI_OP_SCSI_DATA_IN: 768 case ISCSI_OP_SCSI_DATA_IN:
770 ctask = session->cmds[itt]; 769 ctask = iscsi_itt_to_ctask(conn, hdr->itt);
770 if (!ctask)
771 return ISCSI_ERR_BAD_ITT;
772
771 spin_lock(&conn->session->lock); 773 spin_lock(&conn->session->lock);
772 rc = iscsi_data_rsp(conn, ctask); 774 rc = iscsi_data_rsp(conn, ctask);
773 spin_unlock(&conn->session->lock); 775 spin_unlock(&conn->session->lock);
@@ -810,7 +812,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
810 rc = iscsi_complete_pdu(conn, hdr, NULL, 0); 812 rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
811 break; 813 break;
812 case ISCSI_OP_R2T: 814 case ISCSI_OP_R2T:
813 ctask = session->cmds[itt]; 815 ctask = iscsi_itt_to_ctask(conn, hdr->itt);
816 if (!ctask)
817 return ISCSI_ERR_BAD_ITT;
818
814 if (ahslen) 819 if (ahslen)
815 rc = ISCSI_ERR_AHSLEN; 820 rc = ISCSI_ERR_AHSLEN;
816 else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { 821 else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 79bc49fd7f12..4bc63c4b3c10 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -640,6 +640,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
640 uint32_t itt; 640 uint32_t itt;
641 641
642 conn->last_recv = jiffies; 642 conn->last_recv = jiffies;
643 rc = iscsi_verify_itt(conn, hdr->itt);
644 if (rc)
645 return rc;
646
643 if (hdr->itt != RESERVED_ITT) 647 if (hdr->itt != RESERVED_ITT)
644 itt = get_itt(hdr->itt); 648 itt = get_itt(hdr->itt);
645 else 649 else
@@ -776,27 +780,22 @@ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
776} 780}
777EXPORT_SYMBOL_GPL(iscsi_complete_pdu); 781EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
778 782
779/* verify itt (itt encoding: age+cid+itt) */ 783int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
780int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
781 uint32_t *ret_itt)
782{ 784{
783 struct iscsi_session *session = conn->session; 785 struct iscsi_session *session = conn->session;
784 struct iscsi_cmd_task *ctask; 786 struct iscsi_cmd_task *ctask;
785 uint32_t itt;
786 787
787 if (hdr->itt != RESERVED_ITT) { 788 if (itt == RESERVED_ITT)
788 if (((__force u32)hdr->itt & ISCSI_AGE_MASK) != 789 return 0;
789 (session->age << ISCSI_AGE_SHIFT)) {
790 iscsi_conn_printk(KERN_ERR, conn,
791 "received itt %x expected session "
792 "age (%x)\n", (__force u32)hdr->itt,
793 session->age & ISCSI_AGE_MASK);
794 return ISCSI_ERR_BAD_ITT;
795 }
796 790
797 itt = get_itt(hdr->itt); 791 if (((__force u32)itt & ISCSI_AGE_MASK) !=
798 } else 792 (session->age << ISCSI_AGE_SHIFT)) {
799 itt = ~0U; 793 iscsi_conn_printk(KERN_ERR, conn,
794 "received itt %x expected session age (%x)\n",
795 (__force u32)itt,
796 session->age & ISCSI_AGE_MASK);
797 return ISCSI_ERR_BAD_ITT;
798 }
800 799
801 if (itt < session->cmds_max) { 800 if (itt < session->cmds_max) {
802 ctask = session->cmds[itt]; 801 ctask = session->cmds[itt];
@@ -817,11 +816,38 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
817 } 816 }
818 } 817 }
819 818
820 *ret_itt = itt;
821 return 0; 819 return 0;
822} 820}
823EXPORT_SYMBOL_GPL(iscsi_verify_itt); 821EXPORT_SYMBOL_GPL(iscsi_verify_itt);
824 822
823struct iscsi_cmd_task *
824iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
825{
826 struct iscsi_session *session = conn->session;
827 struct iscsi_cmd_task *ctask;
828 uint32_t i;
829
830 if (iscsi_verify_itt(conn, itt))
831 return NULL;
832
833 if (itt == RESERVED_ITT)
834 return NULL;
835
836 i = get_itt(itt);
837 if (i >= session->cmds_max)
838 return NULL;
839
840 ctask = session->cmds[i];
841 if (!ctask->sc)
842 return NULL;
843
844 if (ctask->sc->SCp.phase != session->age)
845 return NULL;
846
847 return ctask;
848}
849EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
850
825void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) 851void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
826{ 852{
827 struct iscsi_session *session = conn->session; 853 struct iscsi_session *session = conn->session;