ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = HWIF(drive); struct ide_taskfile *tf = &task->tf; ide_handler_t *handler = NULL; if (task->data_phase == TASKFILE_MULTI_IN || task->data_phase == TASKFILE_MULTI_OUT) { if (!drive->mult_count) { printk(KERN_ERR "%s: multimode not set!\n", drive->name); return ide_stopped; } } if (task->tf_flags & IDE_TFLAG_FLAGGED) task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) ide_tf_load(drive, task); switch (task->data_phase) { case TASKFILE_MULTI_OUT: case TASKFILE_OUT: hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG); ndelay(400); /* FIXME */ return pre_task_out_intr(drive, task->rq); case TASKFILE_MULTI_IN: case TASKFILE_IN: handler = task_in_intr; /* fall-through */ case TASKFILE_NO_DATA: if (handler == NULL) handler = task_no_data_intr; /* WIN_{SPECIFY,RESTORE,SETMULT} use custom handlers */ if (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) { switch (tf->command) { case WIN_SPECIFY: handler = set_geometry_intr; break; case WIN_RESTORE: handler = recal_intr; break; case WIN_SETMULT: handler = set_multmode_intr; break; } } ide_execute_command(drive, tf->command, handler, WAIT_WORSTCASE, NULL); return ide_started; default: if (task_dma_ok(task) == 0 || drive->using_dma == 0 || hwif->dma_setup(drive)) return ide_stopped; hwif->dma_exec_cmd(drive, tf->command); hwif->dma_start(drive); return ide_started; } }
/* * tf load function for emxx_ide */ static void emxx_ide_tf_load(ide_drive_t *drive, ide_task_t *task) { if (emxx_cfi_connect) ide_tf_load(drive, task); }