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

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
17static u8 ide_inb(unsigned long port)
18{
19    return (u8) inb(port);
20}
21
22static 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
31static u8 ide_mm_inb(unsigned long port)
32{
33    return (u8) readb((void __iomem *) port);
34}
35
36static void ide_mm_outb(u8 value, unsigned long port)
37{
38    writeb(value, (void __iomem *) port);
39}
40
41void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
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}
48EXPORT_SYMBOL_GPL(ide_exec_command);
49
50u8 ide_read_status(ide_hwif_t *hwif)
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}
57EXPORT_SYMBOL_GPL(ide_read_status);
58
59u8 ide_read_altstatus(ide_hwif_t *hwif)
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}
66EXPORT_SYMBOL_GPL(ide_read_altstatus);
67
68void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
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}
75EXPORT_SYMBOL_GPL(ide_write_devctl);
76
77void ide_dev_select(ide_drive_t *drive)
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}
87EXPORT_SYMBOL_GPL(ide_dev_select);
88
89void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
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}
114EXPORT_SYMBOL_GPL(ide_tf_load);
115
116void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
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}
141EXPORT_SYMBOL_GPL(ide_tf_read);
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 */
150static 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 */
164void 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) {
178            local_irq_save(flags);
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)
189            local_irq_restore(flags);
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}
203EXPORT_SYMBOL_GPL(ide_input_data);
204
205/*
206 * This is used for most PIO data transfers *to* the IDE interface
207 */
208void 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) {
222            local_irq_save(flags);
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)
233            local_irq_restore(flags);
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}
247EXPORT_SYMBOL_GPL(ide_output_data);
248
249const 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};
262

Archive Download this file



interactive