diff options
| author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-25 16:17:16 -0500 |
|---|---|---|
| committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-25 16:17:16 -0500 |
| commit | f6e29e35cc0f9facf2eb0b0454f9b09021b5aa6f (patch) | |
| tree | 66f022af5e3b1a7ef5a0854c684604b6d2b64a9c | |
| parent | ba76ae3883ad9faa32a6b35271c6a407d6c96ca9 (diff) | |
ide-disk: use do_rw_taskfile() (take 2)
* Add IDE_TFLAG_DMA_PIO_FALLBACK taskfile flag to indicate the need
to skip loading taskfile registers in do_rw_taskfile().
* Export do_rw_taskfile().
* Convert __ide_do_rw_disk() to use do_rw_taskfile().
* Unexport ide_tf_load().
* Unexport {pre_task_out,task_in}_intr() and make it static.
* Remove incorrect comment about do_rw_taskfile() from <linux/ide.h>.
There should be no functionality changes caused by this patch.
v2:
* Add missing blk_fs_request() check to task_dma_ok() (for VDMA).
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
| -rw-r--r-- | drivers/ide/ide-disk.c | 29 | ||||
| -rw-r--r-- | drivers/ide/ide-taskfile.c | 16 | ||||
| -rw-r--r-- | include/linux/ide.h | 9 |
3 files changed, 20 insertions, 34 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 97abc91db7d0..3d7127ba67a0 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
| @@ -185,6 +185,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
| 185 | u8 lba48 = (drive->addressing == 1) ? 1 : 0; | 185 | u8 lba48 = (drive->addressing == 1) ? 1 : 0; |
| 186 | ide_task_t task; | 186 | ide_task_t task; |
| 187 | struct ide_taskfile *tf = &task.tf; | 187 | struct ide_taskfile *tf = &task.tf; |
| 188 | ide_startstop_t rc; | ||
| 188 | 189 | ||
| 189 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { | 190 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { |
| 190 | if (block + rq->nr_sectors > 1ULL << 28) | 191 | if (block + rq->nr_sectors > 1ULL << 28) |
| @@ -252,32 +253,22 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
| 252 | task.tf_flags |= IDE_TFLAG_WRITE; | 253 | task.tf_flags |= IDE_TFLAG_WRITE; |
| 253 | 254 | ||
| 254 | ide_tf_set_cmd(drive, &task, dma); | 255 | ide_tf_set_cmd(drive, &task, dma); |
| 256 | if (!dma) | ||
| 257 | hwif->data_phase = task.data_phase; | ||
| 258 | task.rq = rq; | ||
| 255 | 259 | ||
| 256 | ide_tf_load(drive, &task); | 260 | rc = do_rw_taskfile(drive, &task); |
| 257 | 261 | ||
| 258 | if (dma) { | 262 | if (rc == ide_stopped && dma) { |
| 259 | if (!hwif->dma_setup(drive)) { | ||
| 260 | hwif->dma_exec_cmd(drive, tf->command); | ||
| 261 | hwif->dma_start(drive); | ||
| 262 | return ide_started; | ||
| 263 | } | ||
| 264 | /* fallback to PIO */ | 263 | /* fallback to PIO */ |
| 264 | task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK; | ||
| 265 | ide_tf_set_cmd(drive, &task, 0); | 265 | ide_tf_set_cmd(drive, &task, 0); |
| 266 | hwif->data_phase = task.data_phase; | ||
| 266 | ide_init_sg_cmd(drive, rq); | 267 | ide_init_sg_cmd(drive, rq); |
| 268 | rc = do_rw_taskfile(drive, &task); | ||
| 267 | } | 269 | } |
| 268 | 270 | ||
| 269 | hwif->data_phase = task.data_phase; | 271 | return rc; |
| 270 | |||
| 271 | if (rq_data_dir(rq) == READ) { | ||
| 272 | ide_execute_command(drive, tf->command, &task_in_intr, | ||
| 273 | WAIT_WORSTCASE, NULL); | ||
| 274 | return ide_started; | ||
| 275 | } else { | ||
| 276 | hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG); | ||
| 277 | ndelay(400); /* FIXME */ | ||
| 278 | |||
| 279 | return pre_task_out_intr(drive, rq); | ||
| 280 | } | ||
| 281 | } | 272 | } |
| 282 | 273 | ||
| 283 | /* | 274 | /* |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 236f91f11a73..2d63ea9ee61b 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
| @@ -114,8 +114,6 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | |||
| 114 | hwif->OUTB((tf->device & HIHI) | drive->select.all, IDE_SELECT_REG); | 114 | hwif->OUTB((tf->device & HIHI) | drive->select.all, IDE_SELECT_REG); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | EXPORT_SYMBOL_GPL(ide_tf_load); | ||
| 118 | |||
| 119 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | 117 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) |
| 120 | { | 118 | { |
| 121 | ide_task_t args; | 119 | ide_task_t args; |
| @@ -133,7 +131,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | |||
| 133 | 131 | ||
| 134 | static int inline task_dma_ok(ide_task_t *task) | 132 | static int inline task_dma_ok(ide_task_t *task) |
| 135 | { | 133 | { |
| 136 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | 134 | if (blk_fs_request(task->rq) || (task->tf_flags & IDE_TFLAG_FLAGGED)) |
| 137 | return 1; | 135 | return 1; |
| 138 | 136 | ||
| 139 | switch (task->tf.command) { | 137 | switch (task->tf.command) { |
| @@ -154,6 +152,8 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *); | |||
| 154 | static ide_startstop_t set_geometry_intr(ide_drive_t *); | 152 | static ide_startstop_t set_geometry_intr(ide_drive_t *); |
| 155 | static ide_startstop_t recal_intr(ide_drive_t *); | 153 | static ide_startstop_t recal_intr(ide_drive_t *); |
| 156 | static ide_startstop_t set_multmode_intr(ide_drive_t *); | 154 | static ide_startstop_t set_multmode_intr(ide_drive_t *); |
| 155 | static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); | ||
| 156 | static ide_startstop_t task_in_intr(ide_drive_t *); | ||
| 157 | 157 | ||
| 158 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | 158 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) |
| 159 | { | 159 | { |
| @@ -173,7 +173,8 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
| 173 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | 173 | if (task->tf_flags & IDE_TFLAG_FLAGGED) |
| 174 | task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; | 174 | task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; |
| 175 | 175 | ||
| 176 | ide_tf_load(drive, task); | 176 | if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) |
| 177 | ide_tf_load(drive, task); | ||
| 177 | 178 | ||
| 178 | switch (task->data_phase) { | 179 | switch (task->data_phase) { |
| 179 | case TASKFILE_MULTI_OUT: | 180 | case TASKFILE_MULTI_OUT: |
| @@ -208,6 +209,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
| 208 | return ide_started; | 209 | return ide_started; |
| 209 | } | 210 | } |
| 210 | } | 211 | } |
| 212 | EXPORT_SYMBOL_GPL(do_rw_taskfile); | ||
| 211 | 213 | ||
| 212 | /* | 214 | /* |
| 213 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. | 215 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. |
| @@ -446,7 +448,7 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | |||
| 446 | /* | 448 | /* |
| 447 | * Handler for command with PIO data-in phase (Read/Read Multiple). | 449 | * Handler for command with PIO data-in phase (Read/Read Multiple). |
| 448 | */ | 450 | */ |
| 449 | ide_startstop_t task_in_intr (ide_drive_t *drive) | 451 | static ide_startstop_t task_in_intr(ide_drive_t *drive) |
| 450 | { | 452 | { |
| 451 | ide_hwif_t *hwif = drive->hwif; | 453 | ide_hwif_t *hwif = drive->hwif; |
| 452 | struct request *rq = HWGROUP(drive)->rq; | 454 | struct request *rq = HWGROUP(drive)->rq; |
| @@ -477,7 +479,6 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) | |||
| 477 | 479 | ||
| 478 | return ide_started; | 480 | return ide_started; |
| 479 | } | 481 | } |
| 480 | EXPORT_SYMBOL(task_in_intr); | ||
| 481 | 482 | ||
| 482 | /* | 483 | /* |
| 483 | * Handler for command with PIO data-out phase (Write/Write Multiple). | 484 | * Handler for command with PIO data-out phase (Write/Write Multiple). |
| @@ -507,7 +508,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive) | |||
| 507 | return ide_started; | 508 | return ide_started; |
| 508 | } | 509 | } |
| 509 | 510 | ||
| 510 | ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) | 511 | static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) |
| 511 | { | 512 | { |
| 512 | ide_startstop_t startstop; | 513 | ide_startstop_t startstop; |
| 513 | 514 | ||
| @@ -528,7 +529,6 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) | |||
| 528 | 529 | ||
| 529 | return ide_started; | 530 | return ide_started; |
| 530 | } | 531 | } |
| 531 | EXPORT_SYMBOL(pre_task_out_intr); | ||
| 532 | 532 | ||
| 533 | int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) | 533 | int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) |
| 534 | { | 534 | { |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 721c9d8f41a2..c333a7528d94 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -912,6 +912,7 @@ enum { | |||
| 912 | IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), | 912 | IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), |
| 913 | IDE_TFLAG_IN_DATA = (1 << 17), | 913 | IDE_TFLAG_IN_DATA = (1 << 17), |
| 914 | IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), | 914 | IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), |
| 915 | IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 19), | ||
| 915 | }; | 916 | }; |
| 916 | 917 | ||
| 917 | struct ide_taskfile { | 918 | struct ide_taskfile { |
| @@ -965,13 +966,7 @@ extern int drive_is_ready(ide_drive_t *); | |||
| 965 | 966 | ||
| 966 | void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); | 967 | void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); |
| 967 | 968 | ||
| 968 | /* | 969 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); |
| 969 | * taskfile io for disks for now...and builds request from ide_ioctl | ||
| 970 | */ | ||
| 971 | extern ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); | ||
| 972 | |||
| 973 | extern ide_startstop_t task_in_intr(ide_drive_t *); | ||
| 974 | extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); | ||
| 975 | 970 | ||
| 976 | int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); | 971 | int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); |
| 977 | int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); | 972 | int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); |
