]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ide: merge CONFIG_IDE_TASKFILE_IO=y|n PIO handlers together
authorBartlomiej Zolnierkiewicz <b.zolnierkiewicz@elka.pw.edu.pl>
Wed, 14 Jul 2004 10:42:19 +0000 (03:42 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 14 Jul 2004 10:42:19 +0000 (03:42 -0700)
This fixes a couple of CONFIG_IDE_TASKFILE_IO=n issues:
 - check status after last sector for PIO-in transfers
 - handle drive->unmask properly in PIO-out prehandlers
 - use rq->[hard]_nr_sectors where appropriate

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/ide/ide-taskfile.c

index 6111e673cee6d38a7e53b5fa65ba6e20d4fc5cdc..557909f6d385be856e8f25149b0e123a02d7dea0 100644 (file)
@@ -303,176 +303,7 @@ static inline void task_buffer_multi_sectors(ide_drive_t *drive,
        task_buffer_sectors(drive, rq, nsect, rw);
 }
 
-/*
- * old taskfile PIO handlers, to be killed as soon as possible.
- */
-#ifndef CONFIG_IDE_TASKFILE_IO
-
-/*
- * Handler for command with PIO data-in phase, READ
- */
-ide_startstop_t task_in_intr (ide_drive_t *drive)
-{
-       struct request *rq      = HWGROUP(drive)->rq;
-       ide_hwif_t *hwif        = HWIF(drive);
-       u8 stat;
-
-       if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
-               if (stat & (ERR_STAT|DRQ_STAT)) {
-                       return DRIVER(drive)->error(drive, "task_in_intr", stat);
-               }
-               ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
-               return ide_started;
-       }
-
-       task_buffer_sectors(drive, rq, 1, IDE_PIO_IN);
-
-       /* FIXME: check drive status */
-       if (!rq->current_nr_sectors)
-               if (!DRIVER(drive)->end_request(drive, 1, 0))
-                       return ide_stopped;
-       ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
-       return ide_started;
-}
-
-EXPORT_SYMBOL(task_in_intr);
-
-/*
- * Handler for command with Read Multiple
- */
-ide_startstop_t task_mulin_intr (ide_drive_t *drive)
-{
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct request *rq      = HWGROUP(drive)->rq;
-       u8 stat;
-
-       if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
-               if (stat & (ERR_STAT|DRQ_STAT)) {
-                       return DRIVER(drive)->error(drive, "task_mulin_intr", stat);
-               }
-               /* no data yet, so wait for another interrupt */
-               ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL);
-               return ide_started;
-       }
-
-       task_buffer_multi_sectors(drive, rq, IDE_PIO_IN);
-
-       /* FIXME: check drive status */
-       if (!rq->current_nr_sectors) {
-               DRIVER(drive)->end_request(drive, 1, 0);
-               return ide_stopped;
-       }
-
-       ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL);
-       return ide_started;
-}
-
-EXPORT_SYMBOL(task_mulin_intr);
-
-ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
-{
-       ide_startstop_t startstop;
-
-       if (ide_wait_stat(&startstop, drive, DATA_READY,
-                       drive->bad_wstat, WAIT_DRQ)) {
-               printk(KERN_ERR "%s: no DRQ after issuing WRITE%s\n",
-                       drive->name,
-                       drive->addressing ? "_EXT" : "");
-               return startstop;
-       }
-       /* For Write_sectors we need to stuff the first sector */
-       ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
-       task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT);
-
-       return ide_started;
-}
-
-EXPORT_SYMBOL(pre_task_out_intr);
-
-/*
- * Handler for command with PIO data-out phase WRITE
- *
- * WOOHOO this is a CORRECT STATE DIAGRAM NOW, <andre@linux-ide.org>
- */
-ide_startstop_t task_out_intr (ide_drive_t *drive)
-{
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct request *rq      = HWGROUP(drive)->rq;
-       u8 stat;
-
-       if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) {
-               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.
-        * We have a good STATUS CHECK!!!
-        */
-       if (!rq->current_nr_sectors)
-               if (!DRIVER(drive)->end_request(drive, 1, 0))
-                       return ide_stopped;
-
-       task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT);
-       ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
-       return ide_started;
-}
-
-EXPORT_SYMBOL(task_out_intr);
-
-ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
-{
-       ide_startstop_t startstop;
-
-       if (ide_wait_stat(&startstop, drive, DATA_READY,
-                       drive->bad_wstat, WAIT_DRQ)) {
-               printk(KERN_ERR "%s: no DRQ after issuing %s\n",
-                       drive->name,
-                       drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE");
-               return startstop;
-       }
-
-       ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
-       task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT);
-
-       return ide_started;
-}
-
-EXPORT_SYMBOL(pre_task_mulout_intr);
-
-/*
- * Handler for command write multiple
- */
-ide_startstop_t task_mulout_intr (ide_drive_t *drive)
-{
-       ide_hwif_t *hwif                = HWIF(drive);
-       u8 stat                         = hwif->INB(IDE_STATUS_REG);
-       struct request *rq              = HWGROUP(drive)->rq;
-
-       if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
-               return DRIVER(drive)->error(drive, __FUNCTION__, 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. */
-       if (!rq->current_nr_sectors) {
-               DRIVER(drive)->end_request(drive, 1, 0);
-               return ide_stopped;
-       }
-
-       task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT);
-       ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
-
-       return ide_started;
-}
-
-EXPORT_SYMBOL(task_mulout_intr);
-
-#else /* !CONFIG_IDE_TASKFILE_IO */
-
+#ifdef CONFIG_IDE_TASKFILE_IO
 static void task_sectors(ide_drive_t *drive, struct request *rq,
                         unsigned nsect, unsigned rw)
 {
@@ -511,6 +342,10 @@ static void task_multi_sectors(ide_drive_t *drive,
        } else          /* task request */
                task_buffer_multi_sectors(drive, rq, rw);
 }
+#else
+# define task_sectors(d, rq, nsect, rw)        task_buffer_sectors(d, rq, nsect, rw)
+# define task_multi_sectors(d, rq, rw) task_buffer_multi_sectors(d, rq, rw)
+#endif /* CONFIG_IDE_TASKFILE_IO */
 
 static u8 wait_drive_not_busy(ide_drive_t *drive)
 {
@@ -532,6 +367,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
        return stat;
 }
 
+#ifdef CONFIG_IDE_TASKFILE_IO
 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
                                  const char *s, u8 stat, unsigned cur_bad)
 {
@@ -543,6 +379,9 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
        }
        return drive->driver->error(drive, s, stat);
 }
+#else
+# define task_error(d, rq, s, stat, cur_bad) drive->driver->error(d, s, stat)
+#endif
 
 /*
  * Handler for command with PIO data-in phase (Read).
@@ -555,7 +394,7 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
        if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
                if (stat & (ERR_STAT | DRQ_STAT))
                        return task_error(drive, rq, __FUNCTION__, stat, 0);
-               /* BUSY_STAT: No data yet, so wait for another IRQ. */
+               /* No data yet, so wait for another IRQ. */
                ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
                return ide_started;
        }
@@ -589,7 +428,7 @@ ide_startstop_t task_mulin_intr (ide_drive_t *drive)
        if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
                if (stat & (ERR_STAT | DRQ_STAT))
                        return task_error(drive, rq, __FUNCTION__, stat, 0);
-               /* BUSY_STAT: No data yet, so wait for another IRQ. */
+               /* No data yet, so wait for another IRQ. */
                ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL);
                return ide_started;
        }
@@ -625,8 +464,7 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
                return task_error(drive, rq, __FUNCTION__, stat, 1);
 
        /* Deal with unexpected ATA data phase. */
-       if ((!(stat & DATA_READY) && rq->nr_sectors) ||
-           ((stat & DATA_READY) && !rq->nr_sectors))
+       if (((stat & DRQ_STAT) == 0) ^ !rq->nr_sectors)
                return task_error(drive, rq, __FUNCTION__, stat, 1);
 
        if (!rq->nr_sectors) {
@@ -635,8 +473,8 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
        }
 
        /* Still data left to transfer. */
-       ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
        task_sectors(drive, rq, 1, IDE_PIO_OUT);
+       ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
 
        return ide_started;
 }
@@ -677,8 +515,7 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive)
                return task_error(drive, rq, __FUNCTION__, stat, drive->mult_count);
 
        /* Deal with unexpected ATA data phase. */
-       if ((!(stat & DATA_READY) && rq->nr_sectors) ||
-           ((stat & DATA_READY) && !rq->nr_sectors))
+       if (((stat & DRQ_STAT) == 0) ^ !rq->nr_sectors)
                return task_error(drive, rq, __FUNCTION__, stat, drive->mult_count);
 
        if (!rq->nr_sectors) {
@@ -687,8 +524,8 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive)
        }
 
        /* Still data left to transfer. */
-       ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
        task_multi_sectors(drive, rq, IDE_PIO_OUT);
+       ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
 
        return ide_started;
 }
@@ -715,8 +552,6 @@ ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
 }
 EXPORT_SYMBOL(pre_task_mulout_intr);
 
-#endif /* !CONFIG_IDE_TASKFILE_IO */
-
 int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf)
 {
        struct request rq;