diff options
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 0e8f26baca6..f9539af28f0 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -633,6 +633,40 @@ out: | |||
633 | __iscsi_put_task(task); | 633 | __iscsi_put_task(task); |
634 | } | 634 | } |
635 | 635 | ||
636 | /** | ||
637 | * iscsi_data_in_rsp - SCSI Data-In Response processing | ||
638 | * @conn: iscsi connection | ||
639 | * @hdr: iscsi pdu | ||
640 | * @task: scsi command task | ||
641 | **/ | ||
642 | static void | ||
643 | iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | ||
644 | struct iscsi_task *task) | ||
645 | { | ||
646 | struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)hdr; | ||
647 | struct scsi_cmnd *sc = task->sc; | ||
648 | |||
649 | if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS)) | ||
650 | return; | ||
651 | |||
652 | sc->result = (DID_OK << 16) | rhdr->cmd_status; | ||
653 | conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; | ||
654 | if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW | | ||
655 | ISCSI_FLAG_DATA_OVERFLOW)) { | ||
656 | int res_count = be32_to_cpu(rhdr->residual_count); | ||
657 | |||
658 | if (res_count > 0 && | ||
659 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || | ||
660 | res_count <= scsi_in(sc)->length)) | ||
661 | scsi_in(sc)->resid = res_count; | ||
662 | else | ||
663 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | ||
664 | } | ||
665 | |||
666 | conn->scsirsp_pdus_cnt++; | ||
667 | __iscsi_put_task(task); | ||
668 | } | ||
669 | |||
636 | static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | 670 | static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) |
637 | { | 671 | { |
638 | struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; | 672 | struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; |
@@ -818,12 +852,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
818 | iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); | 852 | iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); |
819 | break; | 853 | break; |
820 | case ISCSI_OP_SCSI_DATA_IN: | 854 | case ISCSI_OP_SCSI_DATA_IN: |
821 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { | 855 | iscsi_data_in_rsp(conn, hdr, task); |
822 | conn->scsirsp_pdus_cnt++; | ||
823 | iscsi_update_cmdsn(session, | ||
824 | (struct iscsi_nopin*) hdr); | ||
825 | __iscsi_put_task(task); | ||
826 | } | ||
827 | break; | 856 | break; |
828 | case ISCSI_OP_LOGOUT_RSP: | 857 | case ISCSI_OP_LOGOUT_RSP: |
829 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | 858 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); |