root/drivers/ide/ide-io-std.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ide_inb
  2. ide_outb
  3. ide_mm_inb
  4. ide_mm_outb
  5. ide_exec_command
  6. ide_read_status
  7. ide_read_altstatus
  8. ide_write_devctl
  9. ide_dev_select
  10. ide_tf_load
  11. ide_tf_read
  12. ata_vlb_sync
  13. ide_input_data
  14. ide_output_data

   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 
  18 static u8 ide_inb(unsigned long port)
  19 {
  20         return (u8) inb(port);
  21 }
  22 
  23 static 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 
  32 static u8 ide_mm_inb(unsigned long port)
  33 {
  34         return (u8) readb((void __iomem *) port);
  35 }
  36 
  37 static void ide_mm_outb(u8 value, unsigned long port)
  38 {
  39         writeb(value, (void __iomem *) port);
  40 }
  41 
  42 void 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 }
  49 EXPORT_SYMBOL_GPL(ide_exec_command);
  50 
  51 u8 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 }
  58 EXPORT_SYMBOL_GPL(ide_read_status);
  59 
  60 u8 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 }
  67 EXPORT_SYMBOL_GPL(ide_read_altstatus);
  68 
  69 void 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 }
  76 EXPORT_SYMBOL_GPL(ide_write_devctl);
  77 
  78 void 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 }
  88 EXPORT_SYMBOL_GPL(ide_dev_select);
  89 
  90 void 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 }
 115 EXPORT_SYMBOL_GPL(ide_tf_load);
 116 
 117 void 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 }
 142 EXPORT_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  */
 151 static 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  */
 165 void 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 uninitialized_var(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 }
 204 EXPORT_SYMBOL_GPL(ide_input_data);
 205 
 206 /*
 207  * This is used for most PIO data transfers *to* the IDE interface
 208  */
 209 void 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 uninitialized_var(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 }
 248 EXPORT_SYMBOL_GPL(ide_output_data);
 249 
 250 const 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 };

/* [<][>][^][v][top][bottom][index][help] */