diff options
author | Tejun Heo <tj@kernel.org> | 2009-05-07 09:24:37 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-05-11 03:50:53 -0400 |
commit | c3a4d78c580de4edc9ef0f7c59812fb02ceb037f (patch) | |
tree | 916ca44287100707508678e2cc0eff0c43b9ca39 /drivers/ide | |
parent | 9720aef2539c10e3a872e9a92beec225030d99db (diff) |
block: add rq->resid_len
rq->data_len served two purposes - the length of data buffer on issue
and the residual count on completion. This duality creates some
headaches.
First of all, block layer and low level drivers can't really determine
what rq->data_len contains while a request is executing. It could be
the total request length or it coulde be anything else one of the
lower layers is using to keep track of residual count. This
complicates things because blk_rq_bytes() and thus
[__]blk_end_request_all() relies on rq->data_len for PC commands.
Drivers which want to report residual count should first cache the
total request length, update rq->data_len and then complete the
request with the cached data length.
Secondly, it makes requests default to reporting full residual count,
ie. reporting that no data transfer occurred. The residual count is
an exception not the norm; however, the driver should clear
rq->data_len to zero to signify the normal cases while leaving it
alone means no data transfer occurred at all. This reverse default
behavior complicates code unnecessarily and renders block PC on some
drivers (ide-tape/floppy) unuseable.
This patch adds rq->resid_len which is used only for residual count.
While at it, remove now unnecessasry blk_rq_bytes() caching in
ide_pc_intr() as rq->data_len is not changed anymore.
Boaz : spotted missing conversion in osd
Sergei : spotted too early conversion to blk_rq_bytes() in ide-tape
[ Impact: cleanup residual count handling, report 0 resid by default ]
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Borislav Petkov <petkovbb@googlemail.com>
Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Mike Miller <mike.miller@hp.com>
Cc: Eric Moore <Eric.Moore@lsi.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Doug Gilbert <dgilbert@interlog.com>
Cc: Mike Miller <mike.miller@hp.com>
Cc: Eric Moore <Eric.Moore@lsi.com>
Cc: Darrick J. Wong <djwong@us.ibm.com>
Cc: Pete Zaitcev <zaitcev@redhat.com>
Cc: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-atapi.c | 9 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 13 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 4 |
3 files changed, 8 insertions, 18 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index afe5a4323879..e4a02a05fc81 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -367,7 +367,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
367 | /* No more interrupts */ | 367 | /* No more interrupts */ |
368 | if ((stat & ATA_DRQ) == 0) { | 368 | if ((stat & ATA_DRQ) == 0) { |
369 | int uptodate, error; | 369 | int uptodate, error; |
370 | unsigned int done; | ||
371 | 370 | ||
372 | debug_log("Packet command completed, %d bytes transferred\n", | 371 | debug_log("Packet command completed, %d bytes transferred\n", |
373 | pc->xferred); | 372 | pc->xferred); |
@@ -406,12 +405,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
406 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) | 405 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) |
407 | dsc = 1; | 406 | dsc = 1; |
408 | 407 | ||
409 | /* | ||
410 | * ->pc_callback() might change rq->data_len for | ||
411 | * residual count, cache total length. | ||
412 | */ | ||
413 | done = blk_rq_bytes(rq); | ||
414 | |||
415 | /* Command finished - Call the callback function */ | 408 | /* Command finished - Call the callback function */ |
416 | uptodate = drive->pc_callback(drive, dsc); | 409 | uptodate = drive->pc_callback(drive, dsc); |
417 | 410 | ||
@@ -431,7 +424,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
431 | error = uptodate ? 0 : -EIO; | 424 | error = uptodate ? 0 : -EIO; |
432 | } | 425 | } |
433 | 426 | ||
434 | ide_complete_rq(drive, error, done); | 427 | ide_complete_rq(drive, error, blk_rq_bytes(rq)); |
435 | return ide_stopped; | 428 | return ide_stopped; |
436 | } | 429 | } |
437 | 430 | ||
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 673628790f10..8bbe222c5e42 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -519,7 +519,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | |||
519 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); | 519 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); |
520 | 520 | ||
521 | if (buffer) | 521 | if (buffer) |
522 | *bufflen = rq->data_len; | 522 | *bufflen = rq->resid_len; |
523 | 523 | ||
524 | flags = rq->cmd_flags; | 524 | flags = rq->cmd_flags; |
525 | blk_put_request(rq); | 525 | blk_put_request(rq); |
@@ -707,11 +707,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
707 | 707 | ||
708 | out_end: | 708 | out_end: |
709 | if (blk_pc_request(rq) && rc == 0) { | 709 | if (blk_pc_request(rq) && rc == 0) { |
710 | unsigned int dlen = rq->data_len; | 710 | if (blk_end_request(rq, 0, rq->data_len)) |
711 | |||
712 | rq->data_len = 0; | ||
713 | |||
714 | if (blk_end_request(rq, 0, dlen)) | ||
715 | BUG(); | 711 | BUG(); |
716 | 712 | ||
717 | hwif->rq = NULL; | 713 | hwif->rq = NULL; |
@@ -740,9 +736,10 @@ out_end: | |||
740 | nsectors = 1; | 736 | nsectors = 1; |
741 | 737 | ||
742 | if (blk_fs_request(rq) == 0) { | 738 | if (blk_fs_request(rq) == 0) { |
743 | rq->data_len -= (cmd->nbytes - cmd->nleft); | 739 | rq->resid_len = rq->data_len - |
740 | (cmd->nbytes - cmd->nleft); | ||
744 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) | 741 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) |
745 | rq->data_len += cmd->last_xfer_len; | 742 | rq->resid_len += cmd->last_xfer_len; |
746 | } | 743 | } |
747 | 744 | ||
748 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); | 745 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7149224d1fe9..65c5b705883a 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -380,7 +380,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
380 | } | 380 | } |
381 | 381 | ||
382 | tape->first_frame += blocks; | 382 | tape->first_frame += blocks; |
383 | rq->data_len -= blocks * tape->blk_size; | 383 | rq->resid_len = rq->data_len - blocks * tape->blk_size; |
384 | 384 | ||
385 | if (pc->error) { | 385 | if (pc->error) { |
386 | uptodate = 0; | 386 | uptodate = 0; |
@@ -903,7 +903,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) | |||
903 | blk_execute_rq(drive->queue, tape->disk, rq, 0); | 903 | blk_execute_rq(drive->queue, tape->disk, rq, 0); |
904 | 904 | ||
905 | /* calculate the number of transferred bytes and update buffer state */ | 905 | /* calculate the number of transferred bytes and update buffer state */ |
906 | size -= rq->data_len; | 906 | size -= rq->resid_len; |
907 | tape->cur = tape->buf; | 907 | tape->cur = tape->buf; |
908 | if (cmd == REQ_IDETAPE_READ) | 908 | if (cmd == REQ_IDETAPE_READ) |
909 | tape->valid = size; | 909 | tape->valid = size; |