diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-14 11:32:23 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-14 11:32:30 +0200 |
commit | 05cfbd66d07c44865983c8b65ae9d0037d874206 (patch) | |
tree | 084b665cc97b47d1592fe76ea0a39a7753288a02 /drivers/ide/ide-io-std.c | |
parent | 31c9a24ec82926fcae49483e53566d231e705057 (diff) | |
parent | ef631b0ca01655d24e9ca7e199262c4a46416a26 (diff) | |
download | kernel-crypto-05cfbd66d07c44865983c8b65ae9d0037d874206.tar.gz kernel-crypto-05cfbd66d07c44865983c8b65ae9d0037d874206.tar.xz kernel-crypto-05cfbd66d07c44865983c8b65ae9d0037d874206.zip |
Merge branch 'core/urgent' into core/rcu
Merge reason: new patches to be queued up depend on:
ef631b0: rcu: Make hierarchical RCU less IPI-happy
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/ide/ide-io-std.c')
-rw-r--r-- | drivers/ide/ide-io-std.c | 187 |
1 files changed, 62 insertions, 125 deletions
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c index 2d9c6dc3f95..46721c45451 100644 --- a/drivers/ide/ide-io-std.c +++ b/drivers/ide/ide-io-std.c @@ -64,137 +64,78 @@ u8 ide_read_altstatus(ide_hwif_t *hwif) } EXPORT_SYMBOL_GPL(ide_read_altstatus); -void ide_set_irq(ide_hwif_t *hwif, int on) +void ide_write_devctl(ide_hwif_t *hwif, u8 ctl) { - u8 ctl = ATA_DEVCTL_OBS; - - if (on == 4) { /* hack for SRST */ - ctl |= 4; - on &= ~4; - } - - ctl |= on ? 0 : 2; - if (hwif->host_flags & IDE_HFLAG_MMIO) writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); else outb(ctl, hwif->io_ports.ctl_addr); } -EXPORT_SYMBOL_GPL(ide_set_irq); +EXPORT_SYMBOL_GPL(ide_write_devctl); -void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_dev_select(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 select = drive->select | ATA_DEVICE_OBS; + + if (hwif->host_flags & IDE_HFLAG_MMIO) + writeb(select, (void __iomem *)hwif->io_ports.device_addr); + else + outb(select, hwif->io_ports.device_addr); +} +EXPORT_SYMBOL_GPL(ide_dev_select); + +void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; void (*tf_outb)(u8 addr, unsigned long port); u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; if (mmio) tf_outb = ide_mm_outb; else tf_outb = ide_outb; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) - HIHI = 0xFF; - - if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { - u16 data = (tf->hob_data << 8) | tf->data; - - if (mmio) - writew(data, (void __iomem *)io_ports->data_addr); - else - outw(data, io_ports->data_addr); - } - - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) - tf_outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) - tf_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) - tf_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) - tf_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) - tf_outb(tf->hob_lbah, io_ports->lbah_addr); - - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (valid & IDE_VALID_FEATURE) tf_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (valid & IDE_VALID_NSECT) tf_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (valid & IDE_VALID_LBAL) tf_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (valid & IDE_VALID_LBAM) tf_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (valid & IDE_VALID_LBAH) tf_outb(tf->lbah, io_ports->lbah_addr); - - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) - tf_outb((tf->device & HIHI) | drive->select, - io_ports->device_addr); + if (valid & IDE_VALID_DEVICE) + tf_outb(tf->device, io_ports->device_addr); } EXPORT_SYMBOL_GPL(ide_tf_load); -void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - void (*tf_outb)(u8 addr, unsigned long port); u8 (*tf_inb)(unsigned long port); u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - if (mmio) { - tf_outb = ide_mm_outb; + if (mmio) tf_inb = ide_mm_inb; - } else { - tf_outb = ide_outb; + else tf_inb = ide_inb; - } - - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { - u16 data; - if (mmio) - data = readw((void __iomem *)io_ports->data_addr); - else - data = inw(io_ports->data_addr); - - tf->data = data & 0xff; - tf->hob_data = (data >> 8) & 0xff; - } - - /* be sure we're looking at the low order bits */ - tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) - tf->feature = tf_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (valid & IDE_VALID_ERROR) + tf->error = tf_inb(io_ports->feature_addr); + if (valid & IDE_VALID_NSECT) tf->nsect = tf_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (valid & IDE_VALID_LBAL) tf->lbal = tf_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (valid & IDE_VALID_LBAM) tf->lbam = tf_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (valid & IDE_VALID_LBAH) tf->lbah = tf_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (valid & IDE_VALID_DEVICE) tf->device = tf_inb(io_ports->device_addr); - - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) - tf->hob_feature = tf_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = tf_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = tf_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = tf_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = tf_inb(io_ports->lbah_addr); - } } EXPORT_SYMBOL_GPL(ide_tf_read); @@ -225,11 +166,10 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; + unsigned int words = (len + 1) >> 1; u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - len++; - if (io_32bit) { unsigned long uninitialized_var(flags); @@ -238,27 +178,26 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, ata_vlb_sync(io_ports->nsect_addr); } + words >>= 1; if (mmio) - __ide_mm_insl((void __iomem *)data_addr, buf, len / 4); + __ide_mm_insl((void __iomem *)data_addr, buf, words); else - insl(data_addr, buf, len / 4); + insl(data_addr, buf, words); if ((io_32bit & 2) && !mmio) local_irq_restore(flags); - if ((len & 3) >= 2) { - if (mmio) - __ide_mm_insw((void __iomem *)data_addr, - (u8 *)buf + (len & ~3), 1); - else - insw(data_addr, (u8 *)buf + (len & ~3), 1); - } - } else { - if (mmio) - __ide_mm_insw((void __iomem *)data_addr, buf, len / 2); - else - insw(data_addr, buf, len / 2); + if (((len + 1) & 3) < 2) + return; + + buf += len & ~3; + words = 1; } + + if (mmio) + __ide_mm_insw((void __iomem *)data_addr, buf, words); + else + insw(data_addr, buf, words); } EXPORT_SYMBOL_GPL(ide_input_data); @@ -271,11 +210,10 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; + unsigned int words = (len + 1) >> 1; u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - len++; - if (io_32bit) { unsigned long uninitialized_var(flags); @@ -284,27 +222,26 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, ata_vlb_sync(io_ports->nsect_addr); } + words >>= 1; if (mmio) - __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4); + __ide_mm_outsl((void __iomem *)data_addr, buf, words); else - outsl(data_addr, buf, len / 4); + outsl(data_addr, buf, words); if ((io_32bit & 2) && !mmio) local_irq_restore(flags); - if ((len & 3) >= 2) { - if (mmio) - __ide_mm_outsw((void __iomem *)data_addr, - (u8 *)buf + (len & ~3), 1); - else - outsw(data_addr, (u8 *)buf + (len & ~3), 1); - } - } else { - if (mmio) - __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2); - else - outsw(data_addr, buf, len / 2); + if (((len + 1) & 3) < 2) + return; + + buf += len & ~3; + words = 1; } + + if (mmio) + __ide_mm_outsw((void __iomem *)data_addr, buf, words); + else + outsw(data_addr, buf, words); } EXPORT_SYMBOL_GPL(ide_output_data); @@ -312,9 +249,9 @@ const struct ide_tp_ops default_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, + .write_devctl = ide_write_devctl, - .set_irq = ide_set_irq, - + .dev_select = ide_dev_select, .tf_load = ide_tf_load, .tf_read = ide_tf_read, |