diff options
author | Tejun Heo <tj@kernel.org> | 2009-04-19 08:46:02 +0900 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-04-19 08:46:02 +0900 |
commit | b3071d190d6757b14af002a9d79832f12de61bce (patch) | |
tree | b31e5d2ca6c9a86110b64811faf817bbb49d0d9c /drivers/ide/ide-tape.c | |
parent | ea7066afcd590e4663e6dc010f93704164050f48 (diff) | |
download | op-kernel-dev-b3071d190d6757b14af002a9d79832f12de61bce.zip op-kernel-dev-b3071d190d6757b14af002a9d79832f12de61bce.tar.gz |
ide-atapi,tape,floppy: allow ->pc_callback() to change rq->data_len
Impact: allow residual count implementation in ->pc_callback()
rq->data_len has two duties - carrying the number of input bytes on
issue and carrying residual count back to the issuer on completion.
ide-atapi completion callback ->pc_callback() is the right place to do
this but currently ide-atapi depends on rq->data_len carrying the
original request size after calling ->pc_callback() to complete the pc
request.
This patch makes ide_pc_intr(), ide_tape_issue_pc() and
ide_floppy_issue_pc() cache length to complete before calling
->pc_callback() so that it can modify rq->data_len as necessary.
Note: As using rq->data_len for two purposes can make cases like this
incorrect in subtle ways, future changes will introduce separate
field for residual count.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2b9a136..8226d52 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -622,6 +622,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, if (pc->retries > IDETAPE_MAX_PC_RETRIES || (pc->flags & PC_FLAG_ABORT)) { + unsigned int done = blk_rq_bytes(drive->hwif->rq); + /* * We will "abort" retrying a packet command in case legitimate * error code was received (crossing a filemark, or end of the @@ -641,9 +643,10 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, /* Giving up */ pc->error = IDE_DRV_ERROR_GENERAL; } + drive->failed_pc = NULL; drive->pc_callback(drive, 0); - ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); + ide_complete_rq(drive, -EIO, done); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); |