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