diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-disk.c | 29 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 16 |
2 files changed, 18 insertions, 27 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 | { |