ide-h8300: remove mm_{inw|outw}()
[safe/jmp/linux-2.6] / drivers / ide / ide-h8300.c
1 /*
2  * H8/300 generic IDE interface
3  */
4
5 #include <linux/init.h>
6 #include <linux/ide.h>
7
8 #include <asm/io.h>
9 #include <asm/irq.h>
10
11 #define DRV_NAME "ide-h8300"
12
13 #define bswap(d) \
14 ({                                      \
15         u16 r;                          \
16         __asm__("mov.b %w1,r1h\n\t"     \
17                 "mov.b %x1,r1l\n\t"     \
18                 "mov.w r1,%0"           \
19                 :"=r"(r)                \
20                 :"r"(d)                 \
21                 :"er1");                \
22         (r);                            \
23 })
24
25 static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
26 {
27         ide_hwif_t *hwif = drive->hwif;
28         struct ide_io_ports *io_ports = &hwif->io_ports;
29         struct ide_taskfile *tf = &cmd->tf;
30         u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
31
32         if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
33                 HIHI = 0xFF;
34
35         if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
36                 outb(tf->hob_feature, io_ports->feature_addr);
37         if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
38                 outb(tf->hob_nsect, io_ports->nsect_addr);
39         if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
40                 outb(tf->hob_lbal, io_ports->lbal_addr);
41         if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
42                 outb(tf->hob_lbam, io_ports->lbam_addr);
43         if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
44                 outb(tf->hob_lbah, io_ports->lbah_addr);
45
46         if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
47                 outb(tf->feature, io_ports->feature_addr);
48         if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
49                 outb(tf->nsect, io_ports->nsect_addr);
50         if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
51                 outb(tf->lbal, io_ports->lbal_addr);
52         if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
53                 outb(tf->lbam, io_ports->lbam_addr);
54         if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
55                 outb(tf->lbah, io_ports->lbah_addr);
56
57         if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
58                 outb((tf->device & HIHI) | drive->select,
59                      io_ports->device_addr);
60 }
61
62 static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
63 {
64         ide_hwif_t *hwif = drive->hwif;
65         struct ide_io_ports *io_ports = &hwif->io_ports;
66         struct ide_taskfile *tf = &cmd->tf;
67
68         /* be sure we're looking at the low order bits */
69         outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
70
71         if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
72                 tf->error  = inb(io_ports->feature_addr);
73         if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
74                 tf->nsect  = inb(io_ports->nsect_addr);
75         if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
76                 tf->lbal   = inb(io_ports->lbal_addr);
77         if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
78                 tf->lbam   = inb(io_ports->lbam_addr);
79         if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
80                 tf->lbah   = inb(io_ports->lbah_addr);
81         if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
82                 tf->device = inb(io_ports->device_addr);
83
84         if (cmd->tf_flags & IDE_TFLAG_LBA48) {
85                 outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
86
87                 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
88                         tf->hob_error = inb(io_ports->feature_addr);
89                 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
90                         tf->hob_nsect = inb(io_ports->nsect_addr);
91                 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
92                         tf->hob_lbal  = inb(io_ports->lbal_addr);
93                 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
94                         tf->hob_lbam  = inb(io_ports->lbam_addr);
95                 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
96                         tf->hob_lbah  = inb(io_ports->lbah_addr);
97         }
98 }
99
100 static void mm_outsw(unsigned long addr, void *buf, u32 len)
101 {
102         unsigned short *bp = (unsigned short *)buf;
103         for (; len > 0; len--, bp++)
104                 *(volatile u16 *)addr = bswap(*bp);
105 }
106
107 static void mm_insw(unsigned long addr, void *buf, u32 len)
108 {
109         unsigned short *bp = (unsigned short *)buf;
110         for (; len > 0; len--, bp++)
111                 *bp = bswap(*(volatile u16 *)addr);
112 }
113
114 static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
115                              void *buf, unsigned int len)
116 {
117         mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
118 }
119
120 static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
121                               void *buf, unsigned int len)
122 {
123         mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
124 }
125
126 static const struct ide_tp_ops h8300_tp_ops = {
127         .exec_command           = ide_exec_command,
128         .read_status            = ide_read_status,
129         .read_altstatus         = ide_read_altstatus,
130         .write_devctl           = ide_write_devctl,
131
132         .dev_select             = ide_dev_select,
133         .tf_load                = h8300_tf_load,
134         .tf_read                = h8300_tf_read,
135
136         .input_data             = h8300_input_data,
137         .output_data            = h8300_output_data,
138 };
139
140 #define H8300_IDE_GAP (2)
141
142 static inline void hw_setup(hw_regs_t *hw)
143 {
144         int i;
145
146         memset(hw, 0, sizeof(hw_regs_t));
147         for (i = 0; i <= 7; i++)
148                 hw->io_ports_array[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
149         hw->io_ports.ctl_addr = CONFIG_H8300_IDE_ALT;
150         hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ;
151         hw->chipset = ide_generic;
152 }
153
154 static const struct ide_port_info h8300_port_info = {
155         .tp_ops                 = &h8300_tp_ops,
156         .host_flags             = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA,
157 };
158
159 static int __init h8300_ide_init(void)
160 {
161         hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
162
163         printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n");
164
165         if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300"))
166                 goto out_busy;
167         if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) {
168                 release_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8);
169                 goto out_busy;
170         }
171
172         hw_setup(&hw);
173
174         return ide_host_add(&h8300_port_info, hws, NULL);
175
176 out_busy:
177         printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n");
178
179         return -EBUSY;
180 }
181
182 module_init(h8300_ide_init);
183
184 MODULE_LICENSE("GPL");