2 * H8/300 generic IDE interface
5 #include <linux/init.h>
14 __asm__("mov.b %w1,r1h\n\t" \
23 static void mm_outw(u16 d
, unsigned long a
)
25 __asm__("mov.b %w0,r2h\n\t"
33 static u16
mm_inw(unsigned long a
)
35 register u16 r
__asm__("er0");
36 __asm__("mov.w @%1,r2\n\t"
45 static void h8300_tf_load(ide_drive_t
*drive
, ide_task_t
*task
)
47 ide_hwif_t
*hwif
= drive
->hwif
;
48 struct ide_io_ports
*io_ports
= &hwif
->io_ports
;
49 struct ide_taskfile
*tf
= &task
->tf
;
50 u8 HIHI
= (task
->tf_flags
& IDE_TFLAG_LBA48
) ? 0xE0 : 0xEF;
52 if (task
->tf_flags
& IDE_TFLAG_FLAGGED
)
55 ide_set_irq(drive
, 1);
57 if (task
->tf_flags
& IDE_TFLAG_OUT_DATA
)
58 mm_outw((tf
->hob_data
<< 8) | tf
->data
, io_ports
->data_addr
);
60 if (task
->tf_flags
& IDE_TFLAG_OUT_HOB_FEATURE
)
61 outb(tf
->hob_feature
, io_ports
->feature_addr
);
62 if (task
->tf_flags
& IDE_TFLAG_OUT_HOB_NSECT
)
63 outb(tf
->hob_nsect
, io_ports
->nsect_addr
);
64 if (task
->tf_flags
& IDE_TFLAG_OUT_HOB_LBAL
)
65 outb(tf
->hob_lbal
, io_ports
->lbal_addr
);
66 if (task
->tf_flags
& IDE_TFLAG_OUT_HOB_LBAM
)
67 outb(tf
->hob_lbam
, io_ports
->lbam_addr
);
68 if (task
->tf_flags
& IDE_TFLAG_OUT_HOB_LBAH
)
69 outb(tf
->hob_lbah
, io_ports
->lbah_addr
);
71 if (task
->tf_flags
& IDE_TFLAG_OUT_FEATURE
)
72 outb(tf
->feature
, io_ports
->feature_addr
);
73 if (task
->tf_flags
& IDE_TFLAG_OUT_NSECT
)
74 outb(tf
->nsect
, io_ports
->nsect_addr
);
75 if (task
->tf_flags
& IDE_TFLAG_OUT_LBAL
)
76 outb(tf
->lbal
, io_ports
->lbal_addr
);
77 if (task
->tf_flags
& IDE_TFLAG_OUT_LBAM
)
78 outb(tf
->lbam
, io_ports
->lbam_addr
);
79 if (task
->tf_flags
& IDE_TFLAG_OUT_LBAH
)
80 outb(tf
->lbah
, io_ports
->lbah_addr
);
82 if (task
->tf_flags
& IDE_TFLAG_OUT_DEVICE
)
83 outb((tf
->device
& HIHI
) | drive
->select
.all
,
84 io_ports
->device_addr
);
87 static void h8300_tf_read(ide_drive_t
*drive
, ide_task_t
*task
)
89 ide_hwif_t
*hwif
= drive
->hwif
;
90 struct ide_io_ports
*io_ports
= &hwif
->io_ports
;
91 struct ide_taskfile
*tf
= &task
->tf
;
93 if (task
->tf_flags
& IDE_TFLAG_IN_DATA
) {
94 u16 data
= mm_inw(io_ports
->data_addr
);
96 tf
->data
= data
& 0xff;
97 tf
->hob_data
= (data
>> 8) & 0xff;
100 /* be sure we're looking at the low order bits */
101 outb(drive
->ctl
& ~0x80, io_ports
->ctl_addr
);
103 if (task
->tf_flags
& IDE_TFLAG_IN_NSECT
)
104 tf
->nsect
= inb(io_ports
->nsect_addr
);
105 if (task
->tf_flags
& IDE_TFLAG_IN_LBAL
)
106 tf
->lbal
= inb(io_ports
->lbal_addr
);
107 if (task
->tf_flags
& IDE_TFLAG_IN_LBAM
)
108 tf
->lbam
= inb(io_ports
->lbam_addr
);
109 if (task
->tf_flags
& IDE_TFLAG_IN_LBAH
)
110 tf
->lbah
= inb(io_ports
->lbah_addr
);
111 if (task
->tf_flags
& IDE_TFLAG_IN_DEVICE
)
112 tf
->device
= inb(io_ports
->device_addr
);
114 if (task
->tf_flags
& IDE_TFLAG_LBA48
) {
115 outb(drive
->ctl
| 0x80, io_ports
->ctl_addr
);
117 if (task
->tf_flags
& IDE_TFLAG_IN_HOB_FEATURE
)
118 tf
->hob_feature
= inb(io_ports
->feature_addr
);
119 if (task
->tf_flags
& IDE_TFLAG_IN_HOB_NSECT
)
120 tf
->hob_nsect
= inb(io_ports
->nsect_addr
);
121 if (task
->tf_flags
& IDE_TFLAG_IN_HOB_LBAL
)
122 tf
->hob_lbal
= inb(io_ports
->lbal_addr
);
123 if (task
->tf_flags
& IDE_TFLAG_IN_HOB_LBAM
)
124 tf
->hob_lbam
= inb(io_ports
->lbam_addr
);
125 if (task
->tf_flags
& IDE_TFLAG_IN_HOB_LBAH
)
126 tf
->hob_lbah
= inb(io_ports
->lbah_addr
);
130 static void mm_outsw(unsigned long addr
, void *buf
, u32 len
)
132 unsigned short *bp
= (unsigned short *)buf
;
133 for (; len
> 0; len
--, bp
++)
134 *(volatile u16
*)addr
= bswap(*bp
);
137 static void mm_insw(unsigned long addr
, void *buf
, u32 len
)
139 unsigned short *bp
= (unsigned short *)buf
;
140 for (; len
> 0; len
--, bp
++)
141 *bp
= bswap(*(volatile u16
*)addr
);
144 static void h8300_input_data(ide_drive_t
*drive
, struct request
*rq
,
145 void *buf
, unsigned int len
)
147 mm_insw(drive
->hwif
->io_ports
.data_addr
, buf
, (len
+ 1) / 2);
150 static void h8300_output_data(ide_drive_t
*drive
, struct request
*rq
,
151 void *buf
, unsigned int len
)
153 mm_outsw(drive
->hwif
->io_ports
.data_addr
, buf
, (len
+ 1) / 2);
156 #define H8300_IDE_GAP (2)
158 static inline void hw_setup(hw_regs_t
*hw
)
162 memset(hw
, 0, sizeof(hw_regs_t
));
163 for (i
= 0; i
<= 7; i
++)
164 hw
->io_ports_array
[i
] = CONFIG_H8300_IDE_BASE
+ H8300_IDE_GAP
*i
;
165 hw
->io_ports
.ctl_addr
= CONFIG_H8300_IDE_ALT
;
166 hw
->irq
= EXT_IRQ0
+ CONFIG_H8300_IDE_IRQ
;
167 hw
->chipset
= ide_generic
;
170 static inline void hwif_setup(ide_hwif_t
*hwif
)
172 default_hwif_iops(hwif
);
174 hwif
->tf_load
= h8300_tf_load
;
175 hwif
->tf_read
= h8300_tf_read
;
177 hwif
->input_data
= h8300_input_data
;
178 hwif
->output_data
= h8300_output_data
;
181 static int __init
h8300_ide_init(void)
186 u8 idx
[4] = { 0xff, 0xff, 0xff, 0xff };
188 if (!request_region(CONFIG_H8300_IDE_BASE
, H8300_IDE_GAP
*8, "ide-h8300"))
190 if (!request_region(CONFIG_H8300_IDE_ALT
, H8300_IDE_GAP
, "ide-h8300")) {
191 release_region(CONFIG_H8300_IDE_BASE
, H8300_IDE_GAP
*8);
197 hwif
= ide_find_port();
199 printk(KERN_ERR
"ide-h8300: IDE I/F register failed\n");
204 ide_init_port_data(hwif
, index
);
205 ide_init_port_hw(hwif
, &hw
);
207 hwif
->host_flags
= IDE_HFLAG_NO_IO_32BIT
;
208 printk(KERN_INFO
"ide%d: H8/300 generic IDE interface\n", index
);
212 ide_device_add(idx
, NULL
);
217 printk(KERN_ERR
"ide-h8300: IDE I/F resource already used.\n");
222 module_init(h8300_ide_init
);
224 MODULE_LICENSE("GPL");