1// SPDX-License-Identifier: GPL-2.0-only 2 3#include <linux/kernel.h> 4#include <linux/export.h> 5#include <linux/ide.h> 6 7#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \ 8 defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) 9#include <asm/ide.h> 10#else 11#include <asm-generic/ide_iops.h> 12#endif 13 14/* 15 * Conventional PIO operations for ATA devices 16 */ 17 18static u8 ide_inb(unsigned long port) 19{ 20 return (u8) inb(port); 21} 22 23static void ide_outb(u8 val, unsigned long port) 24{ 25 outb(val, port); 26} 27 28/* 29 * MMIO operations, typically used for SATA controllers 30 */ 31 32static u8 ide_mm_inb(unsigned long port) 33{ 34 return (u8) readb((void __iomem *) port); 35} 36 37static void ide_mm_outb(u8 value, unsigned long port) 38{ 39 writeb(value, (void __iomem *) port); 40} 41 42void ide_exec_command(ide_hwif_t *hwif, u8 cmd) 43{ 44 if (hwif->host_flags & IDE_HFLAG_MMIO) 45 writeb(cmd, (void __iomem *)hwif->io_ports.command_addr); 46 else 47 outb(cmd, hwif->io_ports.command_addr); 48} 49EXPORT_SYMBOL_GPL(ide_exec_command); 50 51u8 ide_read_status(ide_hwif_t *hwif) 52{ 53 if (hwif->host_flags & IDE_HFLAG_MMIO) 54 return readb((void __iomem *)hwif->io_ports.status_addr); 55 else 56 return inb(hwif->io_ports.status_addr); 57} 58EXPORT_SYMBOL_GPL(ide_read_status); 59 60u8 ide_read_altstatus(ide_hwif_t *hwif) 61{ 62 if (hwif->host_flags & IDE_HFLAG_MMIO) 63 return readb((void __iomem *)hwif->io_ports.ctl_addr); 64 else 65 return inb(hwif->io_ports.ctl_addr); 66} 67EXPORT_SYMBOL_GPL(ide_read_altstatus); 68 69void ide_write_devctl(ide_hwif_t *hwif, u8 ctl) 70{ 71 if (hwif->host_flags & IDE_HFLAG_MMIO) 72 writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); 73 else 74 outb(ctl, hwif->io_ports.ctl_addr); 75} 76EXPORT_SYMBOL_GPL(ide_write_devctl); 77 78void ide_dev_select(ide_drive_t *drive) 79{ 80 ide_hwif_t *hwif = drive->hwif; 81 u8 select = drive->select | ATA_DEVICE_OBS; 82 83 if (hwif->host_flags & IDE_HFLAG_MMIO) 84 writeb(select, (void __iomem *)hwif->io_ports.device_addr); 85 else 86 outb(select, hwif->io_ports.device_addr); 87} 88EXPORT_SYMBOL_GPL(ide_dev_select); 89 90void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) 91{ 92 ide_hwif_t *hwif = drive->hwif; 93 struct ide_io_ports *io_ports = &hwif->io_ports; 94 void (*tf_outb)(u8 addr, unsigned long port); 95 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 96 97 if (mmio) 98 tf_outb = ide_mm_outb; 99 else 100 tf_outb = ide_outb; 101 102 if (valid & IDE_VALID_FEATURE) 103 tf_outb(tf->feature, io_ports->feature_addr); 104 if (valid & IDE_VALID_NSECT) 105 tf_outb(tf->nsect, io_ports->nsect_addr); 106 if (valid & IDE_VALID_LBAL) 107 tf_outb(tf->lbal, io_ports->lbal_addr); 108 if (valid & IDE_VALID_LBAM) 109 tf_outb(tf->lbam, io_ports->lbam_addr); 110 if (valid & IDE_VALID_LBAH) 111 tf_outb(tf->lbah, io_ports->lbah_addr); 112 if (valid & IDE_VALID_DEVICE) 113 tf_outb(tf->device, io_ports->device_addr); 114} 115EXPORT_SYMBOL_GPL(ide_tf_load); 116 117void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) 118{ 119 ide_hwif_t *hwif = drive->hwif; 120 struct ide_io_ports *io_ports = &hwif->io_ports; 121 u8 (*tf_inb)(unsigned long port); 122 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 123 124 if (mmio) 125 tf_inb = ide_mm_inb; 126 else 127 tf_inb = ide_inb; 128 129 if (valid & IDE_VALID_ERROR) 130 tf->error = tf_inb(io_ports->feature_addr); 131 if (valid & IDE_VALID_NSECT) 132 tf->nsect = tf_inb(io_ports->nsect_addr); 133 if (valid & IDE_VALID_LBAL) 134 tf->lbal = tf_inb(io_ports->lbal_addr); 135 if (valid & IDE_VALID_LBAM) 136 tf->lbam = tf_inb(io_ports->lbam_addr); 137 if (valid & IDE_VALID_LBAH) 138 tf->lbah = tf_inb(io_ports->lbah_addr); 139 if (valid & IDE_VALID_DEVICE) 140 tf->device = tf_inb(io_ports->device_addr); 141} 142EXPORT_SYMBOL_GPL(ide_tf_read); 143 144/* 145 * Some localbus EIDE interfaces require a special access sequence 146 * when using 32-bit I/O instructions to transfer data. We call this 147 * the "vlb_sync" sequence, which consists of three successive reads 148 * of the sector count register location, with interrupts disabled 149 * to ensure that the reads all happen together. 150 */ 151static void ata_vlb_sync(unsigned long port) 152{ 153 (void)inb(port); 154 (void)inb(port); 155 (void)inb(port); 156} 157 158/* 159 * This is used for most PIO data transfers *from* the IDE interface 160 * 161 * These routines will round up any request for an odd number of bytes, 162 * so if an odd len is specified, be sure that there's at least one 163 * extra byte allocated for the buffer. 164 */ 165void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, 166 unsigned int len) 167{ 168 ide_hwif_t *hwif = drive->hwif; 169 struct ide_io_ports *io_ports = &hwif->io_ports; 170 unsigned long data_addr = io_ports->data_addr; 171 unsigned int words = (len + 1) >> 1; 172 u8 io_32bit = drive->io_32bit; 173 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 174 175 if (io_32bit) { 176 unsigned long flags; 177 178 if ((io_32bit & 2) && !mmio) { 179 local_irq_save(flags); 180 ata_vlb_sync(io_ports->nsect_addr); 181 } 182 183 words >>= 1; 184 if (mmio) 185 __ide_mm_insl((void __iomem *)data_addr, buf, words); 186 else 187 insl(data_addr, buf, words); 188 189 if ((io_32bit & 2) && !mmio) 190 local_irq_restore(flags); 191 192 if (((len + 1) & 3) < 2) 193 return; 194 195 buf += len & ~3; 196 words = 1; 197 } 198 199 if (mmio) 200 __ide_mm_insw((void __iomem *)data_addr, buf, words); 201 else 202 insw(data_addr, buf, words); 203} 204EXPORT_SYMBOL_GPL(ide_input_data); 205 206/* 207 * This is used for most PIO data transfers *to* the IDE interface 208 */ 209void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, 210 unsigned int len) 211{ 212 ide_hwif_t *hwif = drive->hwif; 213 struct ide_io_ports *io_ports = &hwif->io_ports; 214 unsigned long data_addr = io_ports->data_addr; 215 unsigned int words = (len + 1) >> 1; 216 u8 io_32bit = drive->io_32bit; 217 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 218 219 if (io_32bit) { 220 unsigned long flags; 221 222 if ((io_32bit & 2) && !mmio) { 223 local_irq_save(flags); 224 ata_vlb_sync(io_ports->nsect_addr); 225 } 226 227 words >>= 1; 228 if (mmio) 229 __ide_mm_outsl((void __iomem *)data_addr, buf, words); 230 else 231 outsl(data_addr, buf, words); 232 233 if ((io_32bit & 2) && !mmio) 234 local_irq_restore(flags); 235 236 if (((len + 1) & 3) < 2) 237 return; 238 239 buf += len & ~3; 240 words = 1; 241 } 242 243 if (mmio) 244 __ide_mm_outsw((void __iomem *)data_addr, buf, words); 245 else 246 outsw(data_addr, buf, words); 247} 248EXPORT_SYMBOL_GPL(ide_output_data); 249 250const struct ide_tp_ops default_tp_ops = { 251 .exec_command = ide_exec_command, 252 .read_status = ide_read_status, 253 .read_altstatus = ide_read_altstatus, 254 .write_devctl = ide_write_devctl, 255 256 .dev_select = ide_dev_select, 257 .tf_load = ide_tf_load, 258 .tf_read = ide_tf_read, 259 260 .input_data = ide_input_data, 261 .output_data = ide_output_data, 262}; 263