2 * H8/300 generic IDE interface
5 #include <linux/init.h>
11 #define DRV_NAME "ide-h8300"
16 __asm__("mov.b %w1,r1h\n\t" \
25 static void mm_outw(u16 d
, unsigned long a
)
27 __asm__("mov.b %w0,r2h\n\t"
35 static u16
mm_inw(unsigned long a
)
37 register u16 r
__asm__("er0");
38 __asm__("mov.w @%1,r2\n\t"
47 static void h8300_tf_load(ide_drive_t
*drive
, struct ide_cmd
*cmd
)
49 ide_hwif_t
*hwif
= drive
->hwif
;
50 struct ide_io_ports
*io_ports
= &hwif
->io_ports
;
51 struct ide_taskfile
*tf
= &cmd
->tf
;
52 u8 HIHI
= (cmd
->tf_flags
& IDE_TFLAG_LBA48
) ? 0xE0 : 0xEF;
54 if (cmd
->ftf_flags
& IDE_FTFLAG_FLAGGED
)
57 if (cmd
->ftf_flags
& IDE_FTFLAG_OUT_DATA
) {
58 u8 data
[2] = { tf
->data
, tf
->hob_data
};
60 h8300_output_data(drive
, cmd
, data
, 2);
63 if (cmd
->tf_flags
& IDE_TFLAG_OUT_HOB_FEATURE
)
64 outb(tf
->hob_feature
, io_ports
->feature_addr
);
65 if (cmd
->tf_flags
& IDE_TFLAG_OUT_HOB_NSECT
)
66 outb(tf
->hob_nsect
, io_ports
->nsect_addr
);
67 if (cmd
->tf_flags
& IDE_TFLAG_OUT_HOB_LBAL
)
68 outb(tf
->hob_lbal
, io_ports
->lbal_addr
);
69 if (cmd
->tf_flags
& IDE_TFLAG_OUT_HOB_LBAM
)
70 outb(tf
->hob_lbam
, io_ports
->lbam_addr
);
71 if (cmd
->tf_flags
& IDE_TFLAG_OUT_HOB_LBAH
)
72 outb(tf
->hob_lbah
, io_ports
->lbah_addr
);
74 if (cmd
->tf_flags
& IDE_TFLAG_OUT_FEATURE
)
75 outb(tf
->feature
, io_ports
->feature_addr
);
76 if (cmd
->tf_flags
& IDE_TFLAG_OUT_NSECT
)
77 outb(tf
->nsect
, io_ports
->nsect_addr
);
78 if (cmd
->tf_flags
& IDE_TFLAG_OUT_LBAL
)
79 outb(tf
->lbal
, io_ports
->lbal_addr
);
80 if (cmd
->tf_flags
& IDE_TFLAG_OUT_LBAM
)
81 outb(tf
->lbam
, io_ports
->lbam_addr
);
82 if (cmd
->tf_flags
& IDE_TFLAG_OUT_LBAH
)
83 outb(tf
->lbah
, io_ports
->lbah_addr
);
85 if (cmd
->tf_flags
& IDE_TFLAG_OUT_DEVICE
)
86 outb((tf
->device
& HIHI
) | drive
->select
,
87 io_ports
->device_addr
);
90 static void h8300_tf_read(ide_drive_t
*drive
, struct ide_cmd
*cmd
)
92 ide_hwif_t
*hwif
= drive
->hwif
;
93 struct ide_io_ports
*io_ports
= &hwif
->io_ports
;
94 struct ide_taskfile
*tf
= &cmd
->tf
;
96 if (cmd
->ftf_flags
& IDE_FTFLAG_IN_DATA
) {
99 h8300_input_data(drive
, cmd
, data
, 2);
102 tf
->hob_data
= data
[1];
105 /* be sure we're looking at the low order bits */
106 outb(ATA_DEVCTL_OBS
, io_ports
->ctl_addr
);
108 if (cmd
->tf_flags
& IDE_TFLAG_IN_ERROR
)
109 tf
->error
= inb(io_ports
->feature_addr
);
110 if (cmd
->tf_flags
& IDE_TFLAG_IN_NSECT
)
111 tf
->nsect
= inb(io_ports
->nsect_addr
);
112 if (cmd
->tf_flags
& IDE_TFLAG_IN_LBAL
)
113 tf
->lbal
= inb(io_ports
->lbal_addr
);
114 if (cmd
->tf_flags
& IDE_TFLAG_IN_LBAM
)
115 tf
->lbam
= inb(io_ports
->lbam_addr
);
116 if (cmd
->tf_flags
& IDE_TFLAG_IN_LBAH
)
117 tf
->lbah
= inb(io_ports
->lbah_addr
);
118 if (cmd
->tf_flags
& IDE_TFLAG_IN_DEVICE
)
119 tf
->device
= inb(io_ports
->device_addr
);
121 if (cmd
->tf_flags
& IDE_TFLAG_LBA48
) {
122 outb(ATA_HOB
| ATA_DEVCTL_OBS
, io_ports
->ctl_addr
);
124 if (cmd
->tf_flags
& IDE_TFLAG_IN_HOB_ERROR
)
125 tf
->hob_error
= inb(io_ports
->feature_addr
);
126 if (cmd
->tf_flags
& IDE_TFLAG_IN_HOB_NSECT
)
127 tf
->hob_nsect
= inb(io_ports
->nsect_addr
);
128 if (cmd
->tf_flags
& IDE_TFLAG_IN_HOB_LBAL
)
129 tf
->hob_lbal
= inb(io_ports
->lbal_addr
);
130 if (cmd
->tf_flags
& IDE_TFLAG_IN_HOB_LBAM
)
131 tf
->hob_lbam
= inb(io_ports
->lbam_addr
);
132 if (cmd
->tf_flags
& IDE_TFLAG_IN_HOB_LBAH
)
133 tf
->hob_lbah
= inb(io_ports
->lbah_addr
);
137 static void mm_outsw(unsigned long addr
, void *buf
, u32 len
)
139 unsigned short *bp
= (unsigned short *)buf
;
140 for (; len
> 0; len
--, bp
++)
141 *(volatile u16
*)addr
= bswap(*bp
);
144 static void mm_insw(unsigned long addr
, void *buf
, u32 len
)
146 unsigned short *bp
= (unsigned short *)buf
;
147 for (; len
> 0; len
--, bp
++)
148 *bp
= bswap(*(volatile u16
*)addr
);
151 static void h8300_input_data(ide_drive_t
*drive
, struct ide_cmd
*cmd
,
152 void *buf
, unsigned int len
)
154 mm_insw(drive
->hwif
->io_ports
.data_addr
, buf
, (len
+ 1) / 2);
157 static void h8300_output_data(ide_drive_t
*drive
, struct ide_cmd
*cmd
,
158 void *buf
, unsigned int len
)
160 mm_outsw(drive
->hwif
->io_ports
.data_addr
, buf
, (len
+ 1) / 2);
163 static const struct ide_tp_ops h8300_tp_ops
= {
164 .exec_command
= ide_exec_command
,
165 .read_status
= ide_read_status
,
166 .read_altstatus
= ide_read_altstatus
,
167 .write_devctl
= ide_write_devctl
,
169 .tf_load
= h8300_tf_load
,
170 .tf_read
= h8300_tf_read
,
172 .input_data
= h8300_input_data
,
173 .output_data
= h8300_output_data
,
176 #define H8300_IDE_GAP (2)
178 static inline void hw_setup(hw_regs_t
*hw
)
182 memset(hw
, 0, sizeof(hw_regs_t
));
183 for (i
= 0; i
<= 7; i
++)
184 hw
->io_ports_array
[i
] = CONFIG_H8300_IDE_BASE
+ H8300_IDE_GAP
*i
;
185 hw
->io_ports
.ctl_addr
= CONFIG_H8300_IDE_ALT
;
186 hw
->irq
= EXT_IRQ0
+ CONFIG_H8300_IDE_IRQ
;
187 hw
->chipset
= ide_generic
;
190 static const struct ide_port_info h8300_port_info
= {
191 .tp_ops
= &h8300_tp_ops
,
192 .host_flags
= IDE_HFLAG_NO_IO_32BIT
| IDE_HFLAG_NO_DMA
,
195 static int __init
h8300_ide_init(void)
197 hw_regs_t hw
, *hws
[] = { &hw
, NULL
, NULL
, NULL
};
199 printk(KERN_INFO DRV_NAME
": H8/300 generic IDE interface\n");
201 if (!request_region(CONFIG_H8300_IDE_BASE
, H8300_IDE_GAP
*8, "ide-h8300"))
203 if (!request_region(CONFIG_H8300_IDE_ALT
, H8300_IDE_GAP
, "ide-h8300")) {
204 release_region(CONFIG_H8300_IDE_BASE
, H8300_IDE_GAP
*8);
210 return ide_host_add(&h8300_port_info
, hws
, NULL
);
213 printk(KERN_ERR
"ide-h8300: IDE I/F resource already used.\n");
218 module_init(h8300_ide_init
);
220 MODULE_LICENSE("GPL");