diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/st.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 26e13dc7bcdb..2096d137f5ee 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -511,9 +511,11 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd | |||
511 | 511 | ||
512 | if (scsi_execute_async(STp->device, cmd, direction, | 512 | if (scsi_execute_async(STp->device, cmd, direction, |
513 | &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs, | 513 | &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs, |
514 | timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) | 514 | timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) { |
515 | /* could not allocate the buffer or request was too large */ | 515 | /* could not allocate the buffer or request was too large */ |
516 | (STp->buffer)->syscall_result = (-EBUSY); | 516 | (STp->buffer)->syscall_result = (-EBUSY); |
517 | (STp->buffer)->last_SRpnt = NULL; | ||
518 | } | ||
517 | else if (do_wait) { | 519 | else if (do_wait) { |
518 | wait_for_completion(waiting); | 520 | wait_for_completion(waiting); |
519 | SRpnt->waiting = NULL; | 521 | SRpnt->waiting = NULL; |
@@ -1449,14 +1451,15 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, | |||
1449 | 1451 | ||
1450 | 1452 | ||
1451 | /* Can be called more than once after each setup_buffer() */ | 1453 | /* Can be called more than once after each setup_buffer() */ |
1452 | static void release_buffering(struct scsi_tape *STp) | 1454 | static void release_buffering(struct scsi_tape *STp, int is_read) |
1453 | { | 1455 | { |
1454 | struct st_buffer *STbp; | 1456 | struct st_buffer *STbp; |
1455 | 1457 | ||
1456 | STbp = STp->buffer; | 1458 | STbp = STp->buffer; |
1457 | if (STbp->do_dio) { | 1459 | if (STbp->do_dio) { |
1458 | sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, 0); | 1460 | sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read); |
1459 | STbp->do_dio = 0; | 1461 | STbp->do_dio = 0; |
1462 | STbp->sg_segs = 0; | ||
1460 | } | 1463 | } |
1461 | } | 1464 | } |
1462 | 1465 | ||
@@ -1729,7 +1732,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1729 | out: | 1732 | out: |
1730 | if (SRpnt != NULL) | 1733 | if (SRpnt != NULL) |
1731 | st_release_request(SRpnt); | 1734 | st_release_request(SRpnt); |
1732 | release_buffering(STp); | 1735 | release_buffering(STp, 0); |
1733 | up(&STp->lock); | 1736 | up(&STp->lock); |
1734 | 1737 | ||
1735 | return retval; | 1738 | return retval; |
@@ -1787,7 +1790,7 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1787 | SRpnt = *aSRpnt; | 1790 | SRpnt = *aSRpnt; |
1788 | SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE, | 1791 | SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE, |
1789 | STp->device->timeout, MAX_RETRIES, 1); | 1792 | STp->device->timeout, MAX_RETRIES, 1); |
1790 | release_buffering(STp); | 1793 | release_buffering(STp, 1); |
1791 | *aSRpnt = SRpnt; | 1794 | *aSRpnt = SRpnt; |
1792 | if (!SRpnt) | 1795 | if (!SRpnt) |
1793 | return STbp->syscall_result; | 1796 | return STbp->syscall_result; |
@@ -2058,7 +2061,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) | |||
2058 | SRpnt = NULL; | 2061 | SRpnt = NULL; |
2059 | } | 2062 | } |
2060 | if (do_dio) { | 2063 | if (do_dio) { |
2061 | release_buffering(STp); | 2064 | release_buffering(STp, 1); |
2062 | STbp->buffer_bytes = 0; | 2065 | STbp->buffer_bytes = 0; |
2063 | } | 2066 | } |
2064 | up(&STp->lock); | 2067 | up(&STp->lock); |