aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-04-18 19:46:02 -0400
committerTejun Heo <tj@kernel.org>2009-04-18 19:46:02 -0400
commitb3071d190d6757b14af002a9d79832f12de61bce (patch)
treeb31e5d2ca6c9a86110b64811faf817bbb49d0d9c
parentea7066afcd590e4663e6dc010f93704164050f48 (diff)
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>
-rw-r--r--drivers/ide/ide-atapi.c16
-rw-r--r--drivers/ide/ide-floppy.c5
-rw-r--r--drivers/ide/ide-tape.c5
3 files changed, 18 insertions, 8 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 5cefe12f5622..3df5442de710 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -409,6 +409,16 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
409 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) 409 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
410 dsc = 1; 410 dsc = 1;
411 411
412 /*
413 * ->pc_callback() might change rq->data_len for
414 * residual count, cache total length.
415 */
416 if (!blk_special_request(rq) &&
417 (drive->media == ide_tape && !rq->bio))
418 done = ide_rq_bytes(rq); /* FIXME */
419 else
420 done = blk_rq_bytes(rq);
421
412 /* Command finished - Call the callback function */ 422 /* Command finished - Call the callback function */
413 uptodate = drive->pc_callback(drive, dsc); 423 uptodate = drive->pc_callback(drive, dsc);
414 424
@@ -417,7 +427,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
417 427
418 if (blk_special_request(rq)) { 428 if (blk_special_request(rq)) {
419 rq->errors = 0; 429 rq->errors = 0;
420 done = blk_rq_bytes(rq);
421 error = 0; 430 error = 0;
422 } else { 431 } else {
423 432
@@ -426,11 +435,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
426 rq->errors = -EIO; 435 rq->errors = -EIO;
427 } 436 }
428 437
429 if (drive->media == ide_tape && !rq->bio)
430 done = ide_rq_bytes(rq); /* FIXME */
431 else
432 done = blk_rq_bytes(rq);
433
434 error = uptodate ? 0 : -EIO; 438 error = uptodate ? 0 : -EIO;
435 } 439 }
436 440
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index d20704ac3183..537b7c558033 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -134,14 +134,17 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
134 drive->pc = pc; 134 drive->pc = pc;
135 135
136 if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { 136 if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) {
137 unsigned int done = blk_rq_bytes(drive->hwif->rq);
138
137 if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) 139 if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
138 ide_floppy_report_error(floppy, pc); 140 ide_floppy_report_error(floppy, pc);
141
139 /* Giving up */ 142 /* Giving up */
140 pc->error = IDE_DRV_ERROR_GENERAL; 143 pc->error = IDE_DRV_ERROR_GENERAL;
141 144
142 drive->failed_pc = NULL; 145 drive->failed_pc = NULL;
143 drive->pc_callback(drive, 0); 146 drive->pc_callback(drive, 0);
144 ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); 147 ide_complete_rq(drive, -EIO, done);
145 return ide_stopped; 148 return ide_stopped;
146 } 149 }
147 150
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 2b9a13671c5f..8226d52504d0 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,
622 622
623 if (pc->retries > IDETAPE_MAX_PC_RETRIES || 623 if (pc->retries > IDETAPE_MAX_PC_RETRIES ||
624 (pc->flags & PC_FLAG_ABORT)) { 624 (pc->flags & PC_FLAG_ABORT)) {
625 unsigned int done = blk_rq_bytes(drive->hwif->rq);
626
625 /* 627 /*
626 * We will "abort" retrying a packet command in case legitimate 628 * We will "abort" retrying a packet command in case legitimate
627 * error code was received (crossing a filemark, or end of the 629 * 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,
641 /* Giving up */ 643 /* Giving up */
642 pc->error = IDE_DRV_ERROR_GENERAL; 644 pc->error = IDE_DRV_ERROR_GENERAL;
643 } 645 }
646
644 drive->failed_pc = NULL; 647 drive->failed_pc = NULL;
645 drive->pc_callback(drive, 0); 648 drive->pc_callback(drive, 0);
646 ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); 649 ide_complete_rq(drive, -EIO, done);
647 return ide_stopped; 650 return ide_stopped;
648 } 651 }
649 debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); 652 debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);