Commit eb017a89 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz Committed by Linus Torvalds

[PATCH] ide: PIO-out fixes for ide-taskfile.c (CONFIG_IDE_TASKFILE_IO=n)

 - in task_out_intr() fix off-by-1 bug and (stat & DRQ_STAT) check,
   previously "if" was always true for rq->current_nr_sectors == 1
 - fail request if DRQ_STAT is not set and rq->current_nr_sectors != 0
   (instead of setting handler and waiting for the next IRQ) or if DRQ_STAT
   is set but !rq->current_nr_sectors (in task_mulout_intr() this was OK)
 - in task_mulout_intr() check also DRIVE_READY and WRERR_STAT status bits
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 93bd9868
...@@ -409,6 +409,10 @@ ide_startstop_t task_out_intr (ide_drive_t *drive) ...@@ -409,6 +409,10 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) { if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) {
return DRIVER(drive)->error(drive, "task_out_intr", stat); return DRIVER(drive)->error(drive, "task_out_intr", stat);
} }
if (((stat & DRQ_STAT) == 0) ^ !rq->current_nr_sectors)
return DRIVER(drive)->error(drive, __FUNCTION__, stat);
/* /*
* Safe to update request for partial completions. * Safe to update request for partial completions.
* We have a good STATUS CHECK!!! * We have a good STATUS CHECK!!!
...@@ -416,9 +420,8 @@ ide_startstop_t task_out_intr (ide_drive_t *drive) ...@@ -416,9 +420,8 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
if (!rq->current_nr_sectors) if (!rq->current_nr_sectors)
if (!DRIVER(drive)->end_request(drive, 1, 0)) if (!DRIVER(drive)->end_request(drive, 1, 0))
return ide_stopped; return ide_stopped;
if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) {
task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT);
}
ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
return ide_started; return ide_started;
} }
...@@ -461,19 +464,17 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive) ...@@ -461,19 +464,17 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive)
u8 stat = hwif->INB(IDE_STATUS_REG); u8 stat = hwif->INB(IDE_STATUS_REG);
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
if (!OK_STAT(stat, DATA_READY, BAD_R_STAT) || !rq->current_nr_sectors) { if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
if (stat & (ERR_STAT|DRQ_STAT)) { return DRIVER(drive)->error(drive, __FUNCTION__, stat);
return DRIVER(drive)->error(drive, "task_mulout_intr", stat);
} if (((stat & DRQ_STAT) == 0) ^ !rq->current_nr_sectors)
return DRIVER(drive)->error(drive, __FUNCTION__, stat);
/* Handle last IRQ, occurs after all data was sent. */ /* Handle last IRQ, occurs after all data was sent. */
if (!rq->current_nr_sectors) { if (!rq->current_nr_sectors) {
DRIVER(drive)->end_request(drive, 1, 0); DRIVER(drive)->end_request(drive, 1, 0);
return ide_stopped; return ide_stopped;
} }
/* no data yet, so wait for another interrupt */
ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
return ide_started;
}
task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT);
ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment