1
2
3
4
5#include <linux/module.h>
6#include <linux/types.h>
7#include <linux/kernel.h>
8#include <linux/delay.h>
9#include <linux/timer.h>
10#include <linux/mm.h>
11#include <linux/ioport.h>
12#include <linux/blkdev.h>
13#include <linux/ide.h>
14#include <linux/init.h>
15
16#include <asm/io.h>
17
18#define DRV_NAME "dtc2278"
19
20
21
22
23#undef ALWAYS_SET_DTC2278_PIO_MODE
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51static void sub22 (char b, char c)
52{
53 int i;
54
55 for(i = 0; i < 3; ++i) {
56 inb(0x3f6);
57 outb_p(b,0xb0);
58 inb(0x3f6);
59 outb_p(c,0xb4);
60 inb(0x3f6);
61 if(inb(0xb4) == c) {
62 outb_p(7,0xb0);
63 inb(0x3f6);
64 return;
65 }
66 }
67}
68
69static DEFINE_SPINLOCK(dtc2278_lock);
70
71static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
72{
73 unsigned long flags;
74
75 if (pio >= 3) {
76 spin_lock_irqsave(&dtc2278_lock, flags);
77
78
79
80 sub22(1,0xc3);
81 sub22(0,0xa0);
82 spin_unlock_irqrestore(&dtc2278_lock, flags);
83 } else {
84
85
86
87 }
88}
89
90static const struct ide_port_ops dtc2278_port_ops = {
91 .set_pio_mode = dtc2278_set_pio_mode,
92};
93
94static const struct ide_port_info dtc2278_port_info __initdata = {
95 .name = DRV_NAME,
96 .chipset = ide_dtc2278,
97 .port_ops = &dtc2278_port_ops,
98 .host_flags = IDE_HFLAG_SERIALIZE |
99 IDE_HFLAG_NO_UNMASK_IRQS |
100 IDE_HFLAG_IO_32BIT |
101
102 IDE_HFLAG_NO_IO_32BIT |
103 IDE_HFLAG_NO_DMA,
104 .pio_mask = ATA_PIO4,
105};
106
107static int __init dtc2278_probe(void)
108{
109 unsigned long flags;
110
111 local_irq_save(flags);
112
113
114
115 outb_p(4,0xb0);
116 inb(0x3f6);
117 outb_p(0x20,0xb4);
118 inb(0x3f6);
119#ifdef ALWAYS_SET_DTC2278_PIO_MODE
120
121
122
123
124 sub22(1,0xc3);
125 sub22(0,0xa0);
126#endif
127 local_irq_restore(flags);
128
129 return ide_legacy_device_add(&dtc2278_port_info, 0);
130}
131
132static int probe_dtc2278;
133
134module_param_named(probe, probe_dtc2278, bool, 0);
135MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets");
136
137static int __init dtc2278_init(void)
138{
139 if (probe_dtc2278 == 0)
140 return -ENODEV;
141
142 if (dtc2278_probe()) {
143 printk(KERN_ERR "dtc2278: ide interfaces already in use!\n");
144 return -EBUSY;
145 }
146 return 0;
147}
148
149module_init(dtc2278_init);
150
151MODULE_AUTHOR("See Local File");
152MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets");
153MODULE_LICENSE("GPL");
154