diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
| -rw-r--r-- | drivers/ide/ide-iops.c | 236 |
1 files changed, 158 insertions, 78 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 44aaec256a30..8aae91764513 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
| @@ -42,18 +42,6 @@ static void ide_outb (u8 val, unsigned long port) | |||
| 42 | outb(val, port); | 42 | outb(val, port); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static void ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port) | ||
| 46 | { | ||
| 47 | outb(addr, port); | ||
| 48 | } | ||
| 49 | |||
| 50 | void default_hwif_iops (ide_hwif_t *hwif) | ||
| 51 | { | ||
| 52 | hwif->OUTB = ide_outb; | ||
| 53 | hwif->OUTBSYNC = ide_outbsync; | ||
| 54 | hwif->INB = ide_inb; | ||
| 55 | } | ||
| 56 | |||
| 57 | /* | 45 | /* |
| 58 | * MMIO operations, typically used for SATA controllers | 46 | * MMIO operations, typically used for SATA controllers |
| 59 | */ | 47 | */ |
| @@ -68,31 +56,19 @@ static void ide_mm_outb (u8 value, unsigned long port) | |||
| 68 | writeb(value, (void __iomem *) port); | 56 | writeb(value, (void __iomem *) port); |
| 69 | } | 57 | } |
| 70 | 58 | ||
| 71 | static void ide_mm_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port) | ||
| 72 | { | ||
| 73 | writeb(value, (void __iomem *) port); | ||
| 74 | } | ||
| 75 | |||
| 76 | void default_hwif_mmiops (ide_hwif_t *hwif) | ||
| 77 | { | ||
| 78 | hwif->OUTB = ide_mm_outb; | ||
| 79 | /* Most systems will need to override OUTBSYNC, alas however | ||
| 80 | this one is controller specific! */ | ||
| 81 | hwif->OUTBSYNC = ide_mm_outbsync; | ||
| 82 | hwif->INB = ide_mm_inb; | ||
| 83 | } | ||
| 84 | |||
| 85 | EXPORT_SYMBOL(default_hwif_mmiops); | ||
| 86 | |||
| 87 | void SELECT_DRIVE (ide_drive_t *drive) | 59 | void SELECT_DRIVE (ide_drive_t *drive) |
| 88 | { | 60 | { |
| 89 | ide_hwif_t *hwif = drive->hwif; | 61 | ide_hwif_t *hwif = drive->hwif; |
| 90 | const struct ide_port_ops *port_ops = hwif->port_ops; | 62 | const struct ide_port_ops *port_ops = hwif->port_ops; |
| 63 | ide_task_t task; | ||
| 91 | 64 | ||
| 92 | if (port_ops && port_ops->selectproc) | 65 | if (port_ops && port_ops->selectproc) |
| 93 | port_ops->selectproc(drive); | 66 | port_ops->selectproc(drive); |
| 94 | 67 | ||
| 95 | hwif->OUTB(drive->select.all, hwif->io_ports.device_addr); | 68 | memset(&task, 0, sizeof(task)); |
| 69 | task.tf_flags = IDE_TFLAG_OUT_DEVICE; | ||
| 70 | |||
| 71 | drive->hwif->tp_ops->tf_load(drive, &task); | ||
| 96 | } | 72 | } |
| 97 | 73 | ||
| 98 | void SELECT_MASK(ide_drive_t *drive, int mask) | 74 | void SELECT_MASK(ide_drive_t *drive, int mask) |
| @@ -103,7 +79,61 @@ void SELECT_MASK(ide_drive_t *drive, int mask) | |||
| 103 | port_ops->maskproc(drive, mask); | 79 | port_ops->maskproc(drive, mask); |
| 104 | } | 80 | } |
| 105 | 81 | ||
| 106 | static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | 82 | void ide_exec_command(ide_hwif_t *hwif, u8 cmd) |
| 83 | { | ||
| 84 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
| 85 | writeb(cmd, (void __iomem *)hwif->io_ports.command_addr); | ||
| 86 | else | ||
| 87 | outb(cmd, hwif->io_ports.command_addr); | ||
| 88 | } | ||
| 89 | EXPORT_SYMBOL_GPL(ide_exec_command); | ||
| 90 | |||
| 91 | u8 ide_read_status(ide_hwif_t *hwif) | ||
| 92 | { | ||
| 93 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
| 94 | return readb((void __iomem *)hwif->io_ports.status_addr); | ||
| 95 | else | ||
| 96 | return inb(hwif->io_ports.status_addr); | ||
| 97 | } | ||
| 98 | EXPORT_SYMBOL_GPL(ide_read_status); | ||
| 99 | |||
| 100 | u8 ide_read_altstatus(ide_hwif_t *hwif) | ||
| 101 | { | ||
| 102 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
| 103 | return readb((void __iomem *)hwif->io_ports.ctl_addr); | ||
| 104 | else | ||
| 105 | return inb(hwif->io_ports.ctl_addr); | ||
| 106 | } | ||
| 107 | EXPORT_SYMBOL_GPL(ide_read_altstatus); | ||
| 108 | |||
| 109 | u8 ide_read_sff_dma_status(ide_hwif_t *hwif) | ||
| 110 | { | ||
| 111 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
| 112 | return readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
| 113 | else | ||
| 114 | return inb(hwif->dma_base + ATA_DMA_STATUS); | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL_GPL(ide_read_sff_dma_status); | ||
| 117 | |||
| 118 | void ide_set_irq(ide_hwif_t *hwif, int on) | ||
| 119 | { | ||
| 120 | u8 ctl = ATA_DEVCTL_OBS; | ||
| 121 | |||
| 122 | if (on == 4) { /* hack for SRST */ | ||
| 123 | ctl |= 4; | ||
| 124 | on &= ~4; | ||
| 125 | } | ||
| 126 | |||
| 127 | ctl |= on ? 0 : 2; | ||
| 128 | |||
| 129 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
| 130 | writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); | ||
| 131 | else | ||
| 132 | outb(ctl, hwif->io_ports.ctl_addr); | ||
| 133 | } | ||
| 134 | EXPORT_SYMBOL_GPL(ide_set_irq); | ||
| 135 | |||
| 136 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | ||
| 107 | { | 137 | { |
| 108 | ide_hwif_t *hwif = drive->hwif; | 138 | ide_hwif_t *hwif = drive->hwif; |
| 109 | struct ide_io_ports *io_ports = &hwif->io_ports; | 139 | struct ide_io_ports *io_ports = &hwif->io_ports; |
| @@ -155,8 +185,9 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | |||
| 155 | tf_outb((tf->device & HIHI) | drive->select.all, | 185 | tf_outb((tf->device & HIHI) | drive->select.all, |
| 156 | io_ports->device_addr); | 186 | io_ports->device_addr); |
| 157 | } | 187 | } |
| 188 | EXPORT_SYMBOL_GPL(ide_tf_load); | ||
| 158 | 189 | ||
| 159 | static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | 190 | void ide_tf_read(ide_drive_t *drive, ide_task_t *task) |
| 160 | { | 191 | { |
| 161 | ide_hwif_t *hwif = drive->hwif; | 192 | ide_hwif_t *hwif = drive->hwif; |
| 162 | struct ide_io_ports *io_ports = &hwif->io_ports; | 193 | struct ide_io_ports *io_ports = &hwif->io_ports; |
| @@ -188,6 +219,8 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | |||
| 188 | /* be sure we're looking at the low order bits */ | 219 | /* be sure we're looking at the low order bits */ |
| 189 | tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); | 220 | tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); |
| 190 | 221 | ||
| 222 | if (task->tf_flags & IDE_TFLAG_IN_FEATURE) | ||
| 223 | tf->feature = tf_inb(io_ports->feature_addr); | ||
| 191 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | 224 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) |
| 192 | tf->nsect = tf_inb(io_ports->nsect_addr); | 225 | tf->nsect = tf_inb(io_ports->nsect_addr); |
| 193 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | 226 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) |
| @@ -214,6 +247,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | |||
| 214 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); | 247 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); |
| 215 | } | 248 | } |
| 216 | } | 249 | } |
| 250 | EXPORT_SYMBOL_GPL(ide_tf_read); | ||
| 217 | 251 | ||
| 218 | /* | 252 | /* |
| 219 | * Some localbus EIDE interfaces require a special access sequence | 253 | * Some localbus EIDE interfaces require a special access sequence |
| @@ -236,8 +270,8 @@ static void ata_vlb_sync(unsigned long port) | |||
| 236 | * so if an odd len is specified, be sure that there's at least one | 270 | * so if an odd len is specified, be sure that there's at least one |
| 237 | * extra byte allocated for the buffer. | 271 | * extra byte allocated for the buffer. |
| 238 | */ | 272 | */ |
| 239 | static void ata_input_data(ide_drive_t *drive, struct request *rq, | 273 | void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, |
| 240 | void *buf, unsigned int len) | 274 | unsigned int len) |
| 241 | { | 275 | { |
| 242 | ide_hwif_t *hwif = drive->hwif; | 276 | ide_hwif_t *hwif = drive->hwif; |
| 243 | struct ide_io_ports *io_ports = &hwif->io_ports; | 277 | struct ide_io_ports *io_ports = &hwif->io_ports; |
| @@ -277,12 +311,13 @@ static void ata_input_data(ide_drive_t *drive, struct request *rq, | |||
| 277 | insw(data_addr, buf, len / 2); | 311 | insw(data_addr, buf, len / 2); |
| 278 | } | 312 | } |
| 279 | } | 313 | } |
| 314 | EXPORT_SYMBOL_GPL(ide_input_data); | ||
| 280 | 315 | ||
| 281 | /* | 316 | /* |
| 282 | * This is used for most PIO data transfers *to* the IDE interface | 317 | * This is used for most PIO data transfers *to* the IDE interface |
| 283 | */ | 318 | */ |
| 284 | static void ata_output_data(ide_drive_t *drive, struct request *rq, | 319 | void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, |
| 285 | void *buf, unsigned int len) | 320 | unsigned int len) |
| 286 | { | 321 | { |
| 287 | ide_hwif_t *hwif = drive->hwif; | 322 | ide_hwif_t *hwif = drive->hwif; |
| 288 | struct ide_io_ports *io_ports = &hwif->io_ports; | 323 | struct ide_io_ports *io_ports = &hwif->io_ports; |
| @@ -320,15 +355,50 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq, | |||
| 320 | outsw(data_addr, buf, len / 2); | 355 | outsw(data_addr, buf, len / 2); |
| 321 | } | 356 | } |
| 322 | } | 357 | } |
| 358 | EXPORT_SYMBOL_GPL(ide_output_data); | ||
| 359 | |||
| 360 | u8 ide_read_error(ide_drive_t *drive) | ||
| 361 | { | ||
| 362 | ide_task_t task; | ||
| 363 | |||
| 364 | memset(&task, 0, sizeof(task)); | ||
| 365 | task.tf_flags = IDE_TFLAG_IN_FEATURE; | ||
| 366 | |||
| 367 | drive->hwif->tp_ops->tf_read(drive, &task); | ||
| 368 | |||
| 369 | return task.tf.error; | ||
| 370 | } | ||
| 371 | EXPORT_SYMBOL_GPL(ide_read_error); | ||
| 323 | 372 | ||
| 324 | void default_hwif_transport(ide_hwif_t *hwif) | 373 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) |
| 325 | { | 374 | { |
| 326 | hwif->tf_load = ide_tf_load; | 375 | ide_task_t task; |
| 327 | hwif->tf_read = ide_tf_read; | ||
| 328 | 376 | ||
| 329 | hwif->input_data = ata_input_data; | 377 | memset(&task, 0, sizeof(task)); |
| 330 | hwif->output_data = ata_output_data; | 378 | task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | |
| 379 | IDE_TFLAG_IN_NSECT; | ||
| 380 | |||
| 381 | drive->hwif->tp_ops->tf_read(drive, &task); | ||
| 382 | |||
| 383 | *bcount = (task.tf.lbah << 8) | task.tf.lbam; | ||
| 384 | *ireason = task.tf.nsect & 3; | ||
| 331 | } | 385 | } |
| 386 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); | ||
| 387 | |||
| 388 | const struct ide_tp_ops default_tp_ops = { | ||
| 389 | .exec_command = ide_exec_command, | ||
| 390 | .read_status = ide_read_status, | ||
| 391 | .read_altstatus = ide_read_altstatus, | ||
| 392 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
| 393 | |||
| 394 | .set_irq = ide_set_irq, | ||
| 395 | |||
| 396 | .tf_load = ide_tf_load, | ||
| 397 | .tf_read = ide_tf_read, | ||
| 398 | |||
| 399 | .input_data = ide_input_data, | ||
| 400 | .output_data = ide_output_data, | ||
| 401 | }; | ||
| 332 | 402 | ||
| 333 | void ide_fix_driveid (struct hd_driveid *id) | 403 | void ide_fix_driveid (struct hd_driveid *id) |
| 334 | { | 404 | { |
| @@ -440,10 +510,8 @@ void ide_fixstring (u8 *s, const int bytecount, const int byteswap) | |||
| 440 | 510 | ||
| 441 | if (byteswap) { | 511 | if (byteswap) { |
| 442 | /* convert from big-endian to host byte order */ | 512 | /* convert from big-endian to host byte order */ |
| 443 | for (p = end ; p != s;) { | 513 | for (p = end ; p != s;) |
| 444 | unsigned short *pp = (unsigned short *) (p -= 2); | 514 | be16_to_cpus((u16 *)(p -= 2)); |
| 445 | *pp = ntohs(*pp); | ||
| 446 | } | ||
| 447 | } | 515 | } |
| 448 | /* strip leading blanks */ | 516 | /* strip leading blanks */ |
| 449 | while (s != end && *s == ' ') | 517 | while (s != end && *s == ' ') |
| @@ -483,10 +551,10 @@ int drive_is_ready (ide_drive_t *drive) | |||
| 483 | * about possible isa-pnp and pci-pnp issues yet. | 551 | * about possible isa-pnp and pci-pnp issues yet. |
| 484 | */ | 552 | */ |
| 485 | if (hwif->io_ports.ctl_addr) | 553 | if (hwif->io_ports.ctl_addr) |
| 486 | stat = ide_read_altstatus(drive); | 554 | stat = hwif->tp_ops->read_altstatus(hwif); |
| 487 | else | 555 | else |
| 488 | /* Note: this may clear a pending IRQ!! */ | 556 | /* Note: this may clear a pending IRQ!! */ |
| 489 | stat = ide_read_status(drive); | 557 | stat = hwif->tp_ops->read_status(hwif); |
| 490 | 558 | ||
| 491 | if (stat & BUSY_STAT) | 559 | if (stat & BUSY_STAT) |
| 492 | /* drive busy: definitely not interrupting */ | 560 | /* drive busy: definitely not interrupting */ |
| @@ -511,24 +579,26 @@ EXPORT_SYMBOL(drive_is_ready); | |||
| 511 | */ | 579 | */ |
| 512 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) | 580 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) |
| 513 | { | 581 | { |
| 582 | ide_hwif_t *hwif = drive->hwif; | ||
| 583 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
| 514 | unsigned long flags; | 584 | unsigned long flags; |
| 515 | int i; | 585 | int i; |
| 516 | u8 stat; | 586 | u8 stat; |
| 517 | 587 | ||
| 518 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ | 588 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ |
| 519 | stat = ide_read_status(drive); | 589 | stat = tp_ops->read_status(hwif); |
| 520 | 590 | ||
| 521 | if (stat & BUSY_STAT) { | 591 | if (stat & BUSY_STAT) { |
| 522 | local_irq_set(flags); | 592 | local_irq_set(flags); |
| 523 | timeout += jiffies; | 593 | timeout += jiffies; |
| 524 | while ((stat = ide_read_status(drive)) & BUSY_STAT) { | 594 | while ((stat = tp_ops->read_status(hwif)) & BUSY_STAT) { |
| 525 | if (time_after(jiffies, timeout)) { | 595 | if (time_after(jiffies, timeout)) { |
| 526 | /* | 596 | /* |
| 527 | * One last read after the timeout in case | 597 | * One last read after the timeout in case |
| 528 | * heavy interrupt load made us not make any | 598 | * heavy interrupt load made us not make any |
| 529 | * progress during the timeout.. | 599 | * progress during the timeout.. |
| 530 | */ | 600 | */ |
| 531 | stat = ide_read_status(drive); | 601 | stat = tp_ops->read_status(hwif); |
| 532 | if (!(stat & BUSY_STAT)) | 602 | if (!(stat & BUSY_STAT)) |
| 533 | break; | 603 | break; |
| 534 | 604 | ||
| @@ -548,7 +618,7 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti | |||
| 548 | */ | 618 | */ |
| 549 | for (i = 0; i < 10; i++) { | 619 | for (i = 0; i < 10; i++) { |
| 550 | udelay(1); | 620 | udelay(1); |
| 551 | stat = ide_read_status(drive); | 621 | stat = tp_ops->read_status(hwif); |
| 552 | 622 | ||
| 553 | if (OK_STAT(stat, good, bad)) { | 623 | if (OK_STAT(stat, good, bad)) { |
| 554 | *rstat = stat; | 624 | *rstat = stat; |
| @@ -674,6 +744,7 @@ no_80w: | |||
| 674 | int ide_driveid_update(ide_drive_t *drive) | 744 | int ide_driveid_update(ide_drive_t *drive) |
| 675 | { | 745 | { |
| 676 | ide_hwif_t *hwif = drive->hwif; | 746 | ide_hwif_t *hwif = drive->hwif; |
| 747 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
| 677 | struct hd_driveid *id; | 748 | struct hd_driveid *id; |
| 678 | unsigned long timeout, flags; | 749 | unsigned long timeout, flags; |
| 679 | u8 stat; | 750 | u8 stat; |
| @@ -684,9 +755,9 @@ int ide_driveid_update(ide_drive_t *drive) | |||
| 684 | */ | 755 | */ |
| 685 | 756 | ||
| 686 | SELECT_MASK(drive, 1); | 757 | SELECT_MASK(drive, 1); |
| 687 | ide_set_irq(drive, 0); | 758 | tp_ops->set_irq(hwif, 0); |
| 688 | msleep(50); | 759 | msleep(50); |
| 689 | hwif->OUTBSYNC(hwif, WIN_IDENTIFY, hwif->io_ports.command_addr); | 760 | tp_ops->exec_command(hwif, WIN_IDENTIFY); |
| 690 | timeout = jiffies + WAIT_WORSTCASE; | 761 | timeout = jiffies + WAIT_WORSTCASE; |
| 691 | do { | 762 | do { |
| 692 | if (time_after(jiffies, timeout)) { | 763 | if (time_after(jiffies, timeout)) { |
| @@ -695,11 +766,11 @@ int ide_driveid_update(ide_drive_t *drive) | |||
| 695 | } | 766 | } |
| 696 | 767 | ||
| 697 | msleep(50); /* give drive a breather */ | 768 | msleep(50); /* give drive a breather */ |
| 698 | stat = ide_read_altstatus(drive); | 769 | stat = tp_ops->read_altstatus(hwif); |
| 699 | } while (stat & BUSY_STAT); | 770 | } while (stat & BUSY_STAT); |
| 700 | 771 | ||
| 701 | msleep(50); /* wait for IRQ and DRQ_STAT */ | 772 | msleep(50); /* wait for IRQ and DRQ_STAT */ |
| 702 | stat = ide_read_status(drive); | 773 | stat = tp_ops->read_status(hwif); |
| 703 | 774 | ||
| 704 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { | 775 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { |
| 705 | SELECT_MASK(drive, 0); | 776 | SELECT_MASK(drive, 0); |
| @@ -713,8 +784,8 @@ int ide_driveid_update(ide_drive_t *drive) | |||
| 713 | local_irq_restore(flags); | 784 | local_irq_restore(flags); |
| 714 | return 0; | 785 | return 0; |
| 715 | } | 786 | } |
| 716 | hwif->input_data(drive, NULL, id, SECTOR_SIZE); | 787 | tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); |
| 717 | (void)ide_read_status(drive); /* clear drive IRQ */ | 788 | (void)tp_ops->read_status(hwif); /* clear drive IRQ */ |
| 718 | local_irq_enable(); | 789 | local_irq_enable(); |
| 719 | local_irq_restore(flags); | 790 | local_irq_restore(flags); |
| 720 | ide_fix_driveid(id); | 791 | ide_fix_driveid(id); |
| @@ -735,9 +806,10 @@ int ide_driveid_update(ide_drive_t *drive) | |||
| 735 | int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | 806 | int ide_config_drive_speed(ide_drive_t *drive, u8 speed) |
| 736 | { | 807 | { |
| 737 | ide_hwif_t *hwif = drive->hwif; | 808 | ide_hwif_t *hwif = drive->hwif; |
| 738 | struct ide_io_ports *io_ports = &hwif->io_ports; | 809 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
| 739 | int error = 0; | 810 | int error = 0; |
| 740 | u8 stat; | 811 | u8 stat; |
| 812 | ide_task_t task; | ||
| 741 | 813 | ||
| 742 | #ifdef CONFIG_BLK_DEV_IDEDMA | 814 | #ifdef CONFIG_BLK_DEV_IDEDMA |
| 743 | if (hwif->dma_ops) /* check if host supports DMA */ | 815 | if (hwif->dma_ops) /* check if host supports DMA */ |
| @@ -770,12 +842,19 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
| 770 | SELECT_DRIVE(drive); | 842 | SELECT_DRIVE(drive); |
| 771 | SELECT_MASK(drive, 0); | 843 | SELECT_MASK(drive, 0); |
| 772 | udelay(1); | 844 | udelay(1); |
| 773 | ide_set_irq(drive, 0); | 845 | tp_ops->set_irq(hwif, 0); |
| 774 | hwif->OUTB(speed, io_ports->nsect_addr); | 846 | |
| 775 | hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr); | 847 | memset(&task, 0, sizeof(task)); |
| 776 | hwif->OUTBSYNC(hwif, WIN_SETFEATURES, io_ports->command_addr); | 848 | task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT; |
| 849 | task.tf.feature = SETFEATURES_XFER; | ||
| 850 | task.tf.nsect = speed; | ||
| 851 | |||
| 852 | tp_ops->tf_load(drive, &task); | ||
| 853 | |||
| 854 | tp_ops->exec_command(hwif, WIN_SETFEATURES); | ||
| 855 | |||
| 777 | if (drive->quirk_list == 2) | 856 | if (drive->quirk_list == 2) |
| 778 | ide_set_irq(drive, 1); | 857 | tp_ops->set_irq(hwif, 1); |
| 779 | 858 | ||
| 780 | error = __ide_wait_stat(drive, drive->ready_stat, | 859 | error = __ide_wait_stat(drive, drive->ready_stat, |
| 781 | BUSY_STAT|DRQ_STAT|ERR_STAT, | 860 | BUSY_STAT|DRQ_STAT|ERR_STAT, |
| @@ -796,8 +875,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
| 796 | 875 | ||
| 797 | skip: | 876 | skip: |
| 798 | #ifdef CONFIG_BLK_DEV_IDEDMA | 877 | #ifdef CONFIG_BLK_DEV_IDEDMA |
| 799 | if ((speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA)) && | 878 | if (speed >= XFER_SW_DMA_0 && drive->using_dma) |
| 800 | drive->using_dma) | ||
| 801 | hwif->dma_ops->dma_host_set(drive, 1); | 879 | hwif->dma_ops->dma_host_set(drive, 1); |
| 802 | else if (hwif->dma_ops) /* check if host supports DMA */ | 880 | else if (hwif->dma_ops) /* check if host supports DMA */ |
| 803 | ide_dma_off_quietly(drive); | 881 | ide_dma_off_quietly(drive); |
| @@ -881,7 +959,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, | |||
| 881 | 959 | ||
| 882 | spin_lock_irqsave(&ide_lock, flags); | 960 | spin_lock_irqsave(&ide_lock, flags); |
| 883 | __ide_set_handler(drive, handler, timeout, expiry); | 961 | __ide_set_handler(drive, handler, timeout, expiry); |
| 884 | hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr); | 962 | hwif->tp_ops->exec_command(hwif, cmd); |
| 885 | /* | 963 | /* |
| 886 | * Drive takes 400nS to respond, we must avoid the IRQ being | 964 | * Drive takes 400nS to respond, we must avoid the IRQ being |
| 887 | * serviced before that. | 965 | * serviced before that. |
| @@ -899,7 +977,7 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) | |||
| 899 | unsigned long flags; | 977 | unsigned long flags; |
| 900 | 978 | ||
| 901 | spin_lock_irqsave(&ide_lock, flags); | 979 | spin_lock_irqsave(&ide_lock, flags); |
| 902 | hwif->OUTBSYNC(hwif, WIN_PACKETCMD, hwif->io_ports.command_addr); | 980 | hwif->tp_ops->exec_command(hwif, WIN_PACKETCMD); |
| 903 | ndelay(400); | 981 | ndelay(400); |
| 904 | spin_unlock_irqrestore(&ide_lock, flags); | 982 | spin_unlock_irqrestore(&ide_lock, flags); |
| 905 | } | 983 | } |
| @@ -924,12 +1002,13 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int); | |||
| 924 | */ | 1002 | */ |
| 925 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | 1003 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) |
| 926 | { | 1004 | { |
| 927 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 1005 | ide_hwif_t *hwif = drive->hwif; |
| 1006 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
| 928 | u8 stat; | 1007 | u8 stat; |
| 929 | 1008 | ||
| 930 | SELECT_DRIVE(drive); | 1009 | SELECT_DRIVE(drive); |
| 931 | udelay (10); | 1010 | udelay (10); |
| 932 | stat = ide_read_status(drive); | 1011 | stat = hwif->tp_ops->read_status(hwif); |
| 933 | 1012 | ||
| 934 | if (OK_STAT(stat, 0, BUSY_STAT)) | 1013 | if (OK_STAT(stat, 0, BUSY_STAT)) |
| 935 | printk("%s: ATAPI reset complete\n", drive->name); | 1014 | printk("%s: ATAPI reset complete\n", drive->name); |
| @@ -975,7 +1054,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
| 975 | } | 1054 | } |
| 976 | } | 1055 | } |
| 977 | 1056 | ||
| 978 | tmp = ide_read_status(drive); | 1057 | tmp = hwif->tp_ops->read_status(hwif); |
| 979 | 1058 | ||
| 980 | if (!OK_STAT(tmp, 0, BUSY_STAT)) { | 1059 | if (!OK_STAT(tmp, 0, BUSY_STAT)) { |
| 981 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 1060 | if (time_before(jiffies, hwgroup->poll_timeout)) { |
| @@ -1089,8 +1168,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
| 1089 | ide_hwif_t *hwif; | 1168 | ide_hwif_t *hwif; |
| 1090 | ide_hwgroup_t *hwgroup; | 1169 | ide_hwgroup_t *hwgroup; |
| 1091 | struct ide_io_ports *io_ports; | 1170 | struct ide_io_ports *io_ports; |
| 1171 | const struct ide_tp_ops *tp_ops; | ||
| 1092 | const struct ide_port_ops *port_ops; | 1172 | const struct ide_port_ops *port_ops; |
| 1093 | u8 ctl; | ||
| 1094 | 1173 | ||
| 1095 | spin_lock_irqsave(&ide_lock, flags); | 1174 | spin_lock_irqsave(&ide_lock, flags); |
| 1096 | hwif = HWIF(drive); | 1175 | hwif = HWIF(drive); |
| @@ -1098,6 +1177,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
| 1098 | 1177 | ||
| 1099 | io_ports = &hwif->io_ports; | 1178 | io_ports = &hwif->io_ports; |
| 1100 | 1179 | ||
| 1180 | tp_ops = hwif->tp_ops; | ||
| 1181 | |||
| 1101 | /* We must not reset with running handlers */ | 1182 | /* We must not reset with running handlers */ |
| 1102 | BUG_ON(hwgroup->handler != NULL); | 1183 | BUG_ON(hwgroup->handler != NULL); |
| 1103 | 1184 | ||
| @@ -1106,7 +1187,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
| 1106 | pre_reset(drive); | 1187 | pre_reset(drive); |
| 1107 | SELECT_DRIVE(drive); | 1188 | SELECT_DRIVE(drive); |
| 1108 | udelay (20); | 1189 | udelay (20); |
| 1109 | hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr); | 1190 | tp_ops->exec_command(hwif, WIN_SRST); |
| 1110 | ndelay(400); | 1191 | ndelay(400); |
| 1111 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | 1192 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; |
| 1112 | hwgroup->polling = 1; | 1193 | hwgroup->polling = 1; |
| @@ -1135,16 +1216,15 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
| 1135 | * immediate interrupt due to the edge transition it produces. | 1216 | * immediate interrupt due to the edge transition it produces. |
| 1136 | * This single interrupt gives us a "fast poll" for drives that | 1217 | * This single interrupt gives us a "fast poll" for drives that |
| 1137 | * recover from reset very quickly, saving us the first 50ms wait time. | 1218 | * recover from reset very quickly, saving us the first 50ms wait time. |
| 1219 | * | ||
| 1220 | * TODO: add ->softreset method and stop abusing ->set_irq | ||
| 1138 | */ | 1221 | */ |
| 1139 | /* set SRST and nIEN */ | 1222 | /* set SRST and nIEN */ |
| 1140 | hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | 6, io_ports->ctl_addr); | 1223 | tp_ops->set_irq(hwif, 4); |
| 1141 | /* more than enough time */ | 1224 | /* more than enough time */ |
| 1142 | udelay(10); | 1225 | udelay(10); |
| 1143 | if (drive->quirk_list == 2) | 1226 | /* clear SRST, leave nIEN (unless device is on the quirk list) */ |
| 1144 | ctl = ATA_DEVCTL_OBS; /* clear SRST and nIEN */ | 1227 | tp_ops->set_irq(hwif, drive->quirk_list == 2); |
| 1145 | else | ||
| 1146 | ctl = ATA_DEVCTL_OBS | 2; /* clear SRST, leave nIEN */ | ||
| 1147 | hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr); | ||
| 1148 | /* more than enough time */ | 1228 | /* more than enough time */ |
| 1149 | udelay(10); | 1229 | udelay(10); |
| 1150 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | 1230 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; |
| @@ -1189,7 +1269,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) | |||
| 1189 | * about locking issues (2.5 work ?). | 1269 | * about locking issues (2.5 work ?). |
| 1190 | */ | 1270 | */ |
| 1191 | mdelay(1); | 1271 | mdelay(1); |
| 1192 | stat = hwif->INB(hwif->io_ports.status_addr); | 1272 | stat = hwif->tp_ops->read_status(hwif); |
| 1193 | if ((stat & BUSY_STAT) == 0) | 1273 | if ((stat & BUSY_STAT) == 0) |
| 1194 | return 0; | 1274 | return 0; |
| 1195 | /* | 1275 | /* |
