diff options
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r-- | drivers/ide/ide-taskfile.c | 77 |
1 files changed, 27 insertions, 50 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 0c908ca3ff7..1fbdb746dc8 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -8,28 +8,18 @@ * The big the bad and the ugly. */ -#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/kernel.h> -#include <linux/timer.h> -#include <linux/mm.h> #include <linux/sched.h> #include <linux/interrupt.h> -#include <linux/major.h> #include <linux/errno.h> -#include <linux/genhd.h> -#include <linux/blkpg.h> #include <linux/slab.h> -#include <linux/pci.h> #include <linux/delay.h> #include <linux/hdreg.h> #include <linux/ide.h> -#include <linux/bitops.h> #include <linux/scatterlist.h> -#include <asm/byteorder.h> -#include <asm/irq.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -62,25 +52,6 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) return ide_raw_taskfile(drive, &args, buf, 1); } -static int inline task_dma_ok(ide_task_t *task) -{ - if (blk_fs_request(task->rq) || (task->tf_flags & IDE_TFLAG_FLAGGED)) - return 1; - - switch (task->tf.command) { - case WIN_WRITEDMA_ONCE: - case WIN_WRITEDMA: - case WIN_WRITEDMA_EXT: - case WIN_READDMA_ONCE: - case WIN_READDMA: - case WIN_READDMA_EXT: - case WIN_IDENTIFY_DMA: - return 1; - } - - return 0; -} - static ide_startstop_t task_no_data_intr(ide_drive_t *); static ide_startstop_t set_geometry_intr(ide_drive_t *); static ide_startstop_t recal_intr(ide_drive_t *); @@ -109,13 +80,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, tf); + ide_set_irq(drive, 1); + SELECT_MASK(drive, 0); hwif->tf_load(drive, task); } switch (task->data_phase) { case TASKFILE_MULTI_OUT: case TASKFILE_OUT: - hwif->OUTBSYNC(drive, tf->command, hwif->io_ports.command_addr); + hwif->OUTBSYNC(hwif, tf->command, hwif->io_ports.command_addr); ndelay(400); /* FIXME */ return pre_task_out_intr(drive, task->rq); case TASKFILE_MULTI_IN: @@ -137,8 +110,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) WAIT_WORSTCASE, NULL); return ide_started; default: - if (task_dma_ok(task) == 0 || drive->using_dma == 0 || - dma_ops->dma_setup(drive)) + if (drive->using_dma == 0 || dma_ops->dma_setup(drive)) return ide_stopped; dma_ops->dma_exec_cmd(drive, tf->command); dma_ops->dma_start(drive); @@ -181,7 +153,6 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive) if (stat & (ERR_STAT|DRQ_STAT)) return ide_error(drive, "set_geometry_intr", stat); - BUG_ON(HWGROUP(drive)->handler != NULL); ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL); return ide_started; } @@ -225,10 +196,10 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) u8 stat; /* - * Last sector was transfered, wait until drive is ready. - * This can take up to 10 usec, but we will wait max 1 ms. + * Last sector was transfered, wait until device is ready. This can + * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms. */ - for (retries = 0; retries < 100; retries++) { + for (retries = 0; retries < 1000; retries++) { stat = ide_read_status(drive); if (stat & BUSY_STAT) @@ -492,11 +463,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) { - struct request rq; + struct request *rq; + int error; - blk_rq_init(NULL, &rq); - rq.cmd_type = REQ_TYPE_ATA_TASKFILE; - rq.buffer = buf; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_ATA_TASKFILE; + rq->buffer = buf; /* * (ks) We transfer currently only whole sectors. @@ -504,16 +476,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) * if we would find a solution to transfer any size. * To support special commands like READ LONG. */ - rq.hard_nr_sectors = rq.nr_sectors = nsect; - rq.hard_cur_sectors = rq.current_nr_sectors = nsect; + rq->hard_nr_sectors = rq->nr_sectors = nsect; + rq->hard_cur_sectors = rq->current_nr_sectors = nsect; if (task->tf_flags & IDE_TFLAG_WRITE) - rq.cmd_flags |= REQ_RW; + rq->cmd_flags |= REQ_RW; + + rq->special = task; + task->rq = rq; - rq.special = task; - task->rq = &rq; + error = blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); - return ide_do_drive_cmd(drive, &rq, ide_wait); + return error; } EXPORT_SYMBOL(ide_raw_taskfile); @@ -739,12 +714,14 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) struct hd_driveid *id = drive->id; if (NULL == (void *) arg) { - struct request rq; + struct request *rq; - ide_init_drive_cmd(&rq); - rq.cmd_type = REQ_TYPE_ATA_TASKFILE; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_ATA_TASKFILE; + err = blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); - return ide_do_drive_cmd(drive, &rq, ide_wait); + return err; } if (copy_from_user(args, (void __user *)arg, 4)) |