diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 43 |
1 files changed, 13 insertions, 30 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index b12750f82169..a54bec994386 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -673,33 +673,6 @@ void scsi_release_buffers(struct scsi_cmnd *cmd) | |||
673 | EXPORT_SYMBOL(scsi_release_buffers); | 673 | EXPORT_SYMBOL(scsi_release_buffers); |
674 | 674 | ||
675 | /* | 675 | /* |
676 | * Bidi commands Must be complete as a whole, both sides at once. If | ||
677 | * part of the bytes were written and lld returned scsi_in()->resid | ||
678 | * and/or scsi_out()->resid this information will be left in | ||
679 | * req->resid_len and req->next_rq->resid_len. The upper-layer driver | ||
680 | * can decide what to do with this information. | ||
681 | */ | ||
682 | static void scsi_end_bidi_request(struct scsi_cmnd *cmd) | ||
683 | { | ||
684 | struct request *req = cmd->request; | ||
685 | |||
686 | req->resid_len = scsi_out(cmd)->resid; | ||
687 | req->next_rq->resid_len = scsi_in(cmd)->resid; | ||
688 | |||
689 | /* The req and req->next_rq have not been completed */ | ||
690 | BUG_ON(blk_end_bidi_request(req, 0, blk_rq_bytes(req), | ||
691 | blk_rq_bytes(req->next_rq))); | ||
692 | |||
693 | scsi_release_buffers(cmd); | ||
694 | |||
695 | /* | ||
696 | * This will goose the queue request function at the end, so we don't | ||
697 | * need to worry about launching another command. | ||
698 | */ | ||
699 | scsi_next_command(cmd); | ||
700 | } | ||
701 | |||
702 | /* | ||
703 | * Function: scsi_io_completion() | 676 | * Function: scsi_io_completion() |
704 | * | 677 | * |
705 | * Purpose: Completion processing for block device I/O requests. | 678 | * Purpose: Completion processing for block device I/O requests. |
@@ -772,12 +745,22 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
772 | if (!sense_deferred) | 745 | if (!sense_deferred) |
773 | error = -EIO; | 746 | error = -EIO; |
774 | } | 747 | } |
748 | |||
749 | req->resid_len = scsi_get_resid(cmd); | ||
750 | |||
775 | if (scsi_bidi_cmnd(cmd)) { | 751 | if (scsi_bidi_cmnd(cmd)) { |
776 | /* will also release_buffers */ | 752 | /* |
777 | scsi_end_bidi_request(cmd); | 753 | * Bidi commands Must be complete as a whole, |
754 | * both sides at once. | ||
755 | */ | ||
756 | req->next_rq->resid_len = scsi_in(cmd)->resid; | ||
757 | |||
758 | blk_end_request_all(req, 0); | ||
759 | |||
760 | scsi_release_buffers(cmd); | ||
761 | scsi_next_command(cmd); | ||
778 | return; | 762 | return; |
779 | } | 763 | } |
780 | req->resid_len = scsi_get_resid(cmd); | ||
781 | } | 764 | } |
782 | 765 | ||
783 | BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */ | 766 | BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */ |