aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-taskfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r--drivers/ide/ide-taskfile.c83
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}
116EXPORT_SYMBOL_GPL(do_rw_taskfile); 113EXPORT_SYMBOL_GPL(do_rw_taskfile);
117 114
118/*
119 * Handler for commands without a data phase
120 */
121static ide_startstop_t task_no_data_intr(ide_drive_t *drive) 115static 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
475int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) 454int 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;