diff options
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r-- | drivers/ide/ide-taskfile.c | 83 |
1 files changed, 34 insertions, 49 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 647216c772d9..0c9d71485728 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -47,8 +47,8 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | |||
47 | cmd.tf.command = ATA_CMD_ID_ATA; | 47 | cmd.tf.command = ATA_CMD_ID_ATA; |
48 | else | 48 | else |
49 | cmd.tf.command = ATA_CMD_ID_ATAPI; | 49 | cmd.tf.command = ATA_CMD_ID_ATAPI; |
50 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 50 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
51 | cmd.data_phase = TASKFILE_IN; | 51 | cmd.protocol = ATA_PROT_PIO; |
52 | 52 | ||
53 | return ide_raw_taskfile(drive, &cmd, buf, 1); | 53 | return ide_raw_taskfile(drive, &cmd, buf, 1); |
54 | } | 54 | } |
@@ -66,13 +66,11 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) | |||
66 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 66 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
67 | const struct ide_dma_ops *dma_ops = hwif->dma_ops; | 67 | const struct ide_dma_ops *dma_ops = hwif->dma_ops; |
68 | 68 | ||
69 | if (orig_cmd->data_phase == TASKFILE_MULTI_IN || | 69 | if (orig_cmd->protocol == ATA_PROT_PIO && |
70 | orig_cmd->data_phase == TASKFILE_MULTI_OUT) { | 70 | (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) && |
71 | if (!drive->mult_count) { | 71 | drive->mult_count == 0) { |
72 | printk(KERN_ERR "%s: multimode not set!\n", | 72 | printk(KERN_ERR "%s: multimode not set!\n", drive->name); |
73 | drive->name); | 73 | return ide_stopped; |
74 | return ide_stopped; | ||
75 | } | ||
76 | } | 74 | } |
77 | 75 | ||
78 | if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | 76 | if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED) |
@@ -87,17 +85,16 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) | |||
87 | tp_ops->tf_load(drive, cmd); | 85 | tp_ops->tf_load(drive, cmd); |
88 | } | 86 | } |
89 | 87 | ||
90 | switch (cmd->data_phase) { | 88 | switch (cmd->protocol) { |
91 | case TASKFILE_MULTI_OUT: | 89 | case ATA_PROT_PIO: |
92 | case TASKFILE_OUT: | 90 | if (cmd->tf_flags & IDE_TFLAG_WRITE) { |
93 | tp_ops->exec_command(hwif, tf->command); | 91 | tp_ops->exec_command(hwif, tf->command); |
94 | ndelay(400); /* FIXME */ | 92 | ndelay(400); /* FIXME */ |
95 | return pre_task_out_intr(drive, cmd); | 93 | return pre_task_out_intr(drive, cmd); |
96 | case TASKFILE_MULTI_IN: | 94 | } |
97 | case TASKFILE_IN: | ||
98 | handler = task_in_intr; | 95 | handler = task_in_intr; |
99 | /* fall-through */ | 96 | /* fall-through */ |
100 | case TASKFILE_NO_DATA: | 97 | case ATA_PROT_NODATA: |
101 | if (handler == NULL) | 98 | if (handler == NULL) |
102 | handler = task_no_data_intr; | 99 | handler = task_no_data_intr; |
103 | ide_execute_command(drive, tf->command, handler, | 100 | ide_execute_command(drive, tf->command, handler, |
@@ -115,9 +112,6 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) | |||
115 | } | 112 | } |
116 | EXPORT_SYMBOL_GPL(do_rw_taskfile); | 113 | EXPORT_SYMBOL_GPL(do_rw_taskfile); |
117 | 114 | ||
118 | /* | ||
119 | * Handler for commands without a data phase | ||
120 | */ | ||
121 | static ide_startstop_t task_no_data_intr(ide_drive_t *drive) | 115 | static ide_startstop_t task_no_data_intr(ide_drive_t *drive) |
122 | { | 116 | { |
123 | ide_hwif_t *hwif = drive->hwif; | 117 | ide_hwif_t *hwif = drive->hwif; |
@@ -278,15 +272,10 @@ static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, | |||
278 | 272 | ||
279 | touch_softlockup_watchdog(); | 273 | touch_softlockup_watchdog(); |
280 | 274 | ||
281 | switch (cmd->data_phase) { | 275 | if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) |
282 | case TASKFILE_MULTI_IN: | ||
283 | case TASKFILE_MULTI_OUT: | ||
284 | ide_pio_multi(drive, cmd, write); | 276 | ide_pio_multi(drive, cmd, write); |
285 | break; | 277 | else |
286 | default: | ||
287 | ide_pio_sector(drive, cmd, write); | 278 | ide_pio_sector(drive, cmd, write); |
288 | break; | ||
289 | } | ||
290 | 279 | ||
291 | drive->io_32bit = saved_io_32bit; | 280 | drive->io_32bit = saved_io_32bit; |
292 | } | 281 | } |
@@ -297,22 +286,12 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct ide_cmd *cmd, | |||
297 | if (cmd->tf_flags & IDE_TFLAG_FS) { | 286 | if (cmd->tf_flags & IDE_TFLAG_FS) { |
298 | int sectors = cmd->nsect - cmd->nleft; | 287 | int sectors = cmd->nsect - cmd->nleft; |
299 | 288 | ||
300 | switch (cmd->data_phase) { | 289 | if (cmd->protocol == ATA_PROT_PIO && |
301 | case TASKFILE_IN: | 290 | ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) { |
302 | if (cmd->nleft) | 291 | if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) |
303 | break; | 292 | sectors -= drive->mult_count; |
304 | /* fall through */ | 293 | else |
305 | case TASKFILE_OUT: | 294 | sectors--; |
306 | sectors--; | ||
307 | break; | ||
308 | case TASKFILE_MULTI_IN: | ||
309 | if (cmd->nleft) | ||
310 | break; | ||
311 | /* fall through */ | ||
312 | case TASKFILE_MULTI_OUT: | ||
313 | sectors -= drive->mult_count; | ||
314 | default: | ||
315 | break; | ||
316 | } | 295 | } |
317 | 296 | ||
318 | if (sectors > 0) | 297 | if (sectors > 0) |
@@ -425,7 +404,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, | |||
425 | drive->bad_wstat, WAIT_DRQ)) { | 404 | drive->bad_wstat, WAIT_DRQ)) { |
426 | printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", | 405 | printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", |
427 | drive->name, | 406 | drive->name, |
428 | cmd->data_phase == TASKFILE_MULTI_OUT ? "MULT" : "", | 407 | (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "", |
429 | (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); | 408 | (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); |
430 | return startstop; | 409 | return startstop; |
431 | } | 410 | } |
@@ -474,7 +453,7 @@ EXPORT_SYMBOL(ide_raw_taskfile); | |||
474 | 453 | ||
475 | int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) | 454 | int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) |
476 | { | 455 | { |
477 | cmd->data_phase = TASKFILE_NO_DATA; | 456 | cmd->protocol = ATA_PROT_NODATA; |
478 | 457 | ||
479 | return ide_raw_taskfile(drive, cmd, NULL, 0); | 458 | return ide_raw_taskfile(drive, cmd, NULL, 0); |
480 | } | 459 | } |
@@ -545,7 +524,6 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
545 | memcpy(&cmd.tf_array[6], req_task->io_ports, | 524 | memcpy(&cmd.tf_array[6], req_task->io_ports, |
546 | HDIO_DRIVE_TASK_HDR_SIZE); | 525 | HDIO_DRIVE_TASK_HDR_SIZE); |
547 | 526 | ||
548 | cmd.data_phase = req_task->data_phase; | ||
549 | cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | | 527 | cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | |
550 | IDE_TFLAG_IN_TF; | 528 | IDE_TFLAG_IN_TF; |
551 | 529 | ||
@@ -590,10 +568,12 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
590 | /* fixup data phase if needed */ | 568 | /* fixup data phase if needed */ |
591 | if (req_task->data_phase == TASKFILE_IN_DMAQ || | 569 | if (req_task->data_phase == TASKFILE_IN_DMAQ || |
592 | req_task->data_phase == TASKFILE_IN_DMA) | 570 | req_task->data_phase == TASKFILE_IN_DMA) |
593 | cmd.data_phase = TASKFILE_OUT_DMA; | 571 | cmd.tf_flags |= IDE_TFLAG_WRITE; |
594 | } | 572 | } |
595 | 573 | ||
596 | switch (cmd.data_phase) { | 574 | cmd.protocol = ATA_PROT_DMA; |
575 | |||
576 | switch (req_task->data_phase) { | ||
597 | case TASKFILE_MULTI_OUT: | 577 | case TASKFILE_MULTI_OUT: |
598 | if (!drive->mult_count) { | 578 | if (!drive->mult_count) { |
599 | /* (hs): give up if multcount is not set */ | 579 | /* (hs): give up if multcount is not set */ |
@@ -603,8 +583,10 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
603 | err = -EPERM; | 583 | err = -EPERM; |
604 | goto abort; | 584 | goto abort; |
605 | } | 585 | } |
586 | cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; | ||
606 | /* fall through */ | 587 | /* fall through */ |
607 | case TASKFILE_OUT: | 588 | case TASKFILE_OUT: |
589 | cmd.protocol = ATA_PROT_PIO; | ||
608 | /* fall through */ | 590 | /* fall through */ |
609 | case TASKFILE_OUT_DMAQ: | 591 | case TASKFILE_OUT_DMAQ: |
610 | case TASKFILE_OUT_DMA: | 592 | case TASKFILE_OUT_DMA: |
@@ -621,8 +603,10 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
621 | err = -EPERM; | 603 | err = -EPERM; |
622 | goto abort; | 604 | goto abort; |
623 | } | 605 | } |
606 | cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; | ||
624 | /* fall through */ | 607 | /* fall through */ |
625 | case TASKFILE_IN: | 608 | case TASKFILE_IN: |
609 | cmd.protocol = ATA_PROT_PIO; | ||
626 | /* fall through */ | 610 | /* fall through */ |
627 | case TASKFILE_IN_DMAQ: | 611 | case TASKFILE_IN_DMAQ: |
628 | case TASKFILE_IN_DMA: | 612 | case TASKFILE_IN_DMA: |
@@ -630,6 +614,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
630 | data_buf = inbuf; | 614 | data_buf = inbuf; |
631 | break; | 615 | break; |
632 | case TASKFILE_NO_DATA: | 616 | case TASKFILE_NO_DATA: |
617 | cmd.protocol = ATA_PROT_NODATA; | ||
633 | break; | 618 | break; |
634 | default: | 619 | default: |
635 | err = -EFAULT; | 620 | err = -EFAULT; |