aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-05-07 09:24:37 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-05-11 03:50:53 -0400
commitc3a4d78c580de4edc9ef0f7c59812fb02ceb037f (patch)
tree916ca44287100707508678e2cc0eff0c43b9ca39 /drivers/ide
parent9720aef2539c10e3a872e9a92beec225030d99db (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.c9
-rw-r--r--drivers/ide/ide-cd.c13
-rw-r--r--drivers/ide/ide-tape.c4
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
708out_end: 708out_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;