diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-21 14:57:23 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-21 14:57:23 -0400 |
commit | 2bfba3c444fe8b2ab1c38112a89d8f03b61136ca (patch) | |
tree | 17580eee63d868c9d6b97a6bc956a08f25631532 /drivers/ide/legacy | |
parent | 2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4 (diff) |
ide: remove useless subdirs from drivers/ide/
Suggested-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/legacy')
-rw-r--r-- | drivers/ide/legacy/Makefile | 25 | ||||
-rw-r--r-- | drivers/ide/legacy/ali14xx.c | 248 | ||||
-rw-r--r-- | drivers/ide/legacy/buddha.c | 235 | ||||
-rw-r--r-- | drivers/ide/legacy/dtc2278.c | 153 | ||||
-rw-r--r-- | drivers/ide/legacy/falconide.c | 153 | ||||
-rw-r--r-- | drivers/ide/legacy/gayle.c | 190 | ||||
-rw-r--r-- | drivers/ide/legacy/ht6560b.c | 351 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-4drives.c | 63 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-cs.c | 472 | ||||
-rw-r--r-- | drivers/ide/legacy/ide_platform.c | 147 | ||||
-rw-r--r-- | drivers/ide/legacy/macide.c | 131 | ||||
-rw-r--r-- | drivers/ide/legacy/q40ide.c | 165 | ||||
-rw-r--r-- | drivers/ide/legacy/qd65xx.c | 429 | ||||
-rw-r--r-- | drivers/ide/legacy/qd65xx.h | 137 | ||||
-rw-r--r-- | drivers/ide/legacy/umc8672.c | 180 |
15 files changed, 0 insertions, 3079 deletions
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile deleted file mode 100644 index 6939329f89e8..000000000000 --- a/drivers/ide/legacy/Makefile +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | |||
2 | # link order is important here | ||
3 | |||
4 | obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o | ||
5 | obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o | ||
6 | obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o | ||
7 | obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o | ||
8 | obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o | ||
9 | obj-$(CONFIG_BLK_DEV_4DRIVES) += ide-4drives.o | ||
10 | |||
11 | obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o | ||
12 | obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o | ||
13 | obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o | ||
14 | obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o | ||
15 | obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o | ||
16 | |||
17 | ifeq ($(CONFIG_BLK_DEV_IDECS), m) | ||
18 | obj-m += ide-cs.o | ||
19 | endif | ||
20 | |||
21 | ifeq ($(CONFIG_BLK_DEV_PLATFORM), m) | ||
22 | obj-m += ide_platform.o | ||
23 | endif | ||
24 | |||
25 | EXTRA_CFLAGS := -Idrivers/ide | ||
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c deleted file mode 100644 index 90da1f953ed0..000000000000 --- a/drivers/ide/legacy/ali14xx.c +++ /dev/null | |||
@@ -1,248 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996 Linus Torvalds & author (see below) | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * ALI M14xx chipset EIDE controller | ||
7 | * | ||
8 | * Works for ALI M1439/1443/1445/1487/1489 chipsets. | ||
9 | * | ||
10 | * Adapted from code developed by derekn@vw.ece.cmu.edu. -ml | ||
11 | * Derek's notes follow: | ||
12 | * | ||
13 | * I think the code should be pretty understandable, | ||
14 | * but I'll be happy to (try to) answer questions. | ||
15 | * | ||
16 | * The critical part is in the setupDrive function. The initRegisters | ||
17 | * function doesn't seem to be necessary, but the DOS driver does it, so | ||
18 | * I threw it in. | ||
19 | * | ||
20 | * I've only tested this on my system, which only has one disk. I posted | ||
21 | * it to comp.sys.linux.hardware, so maybe some other people will try it | ||
22 | * out. | ||
23 | * | ||
24 | * Derek Noonburg (derekn@ece.cmu.edu) | ||
25 | * 95-sep-26 | ||
26 | * | ||
27 | * Update 96-jul-13: | ||
28 | * | ||
29 | * I've since upgraded to two disks and a CD-ROM, with no trouble, and | ||
30 | * I've also heard from several others who have used it successfully. | ||
31 | * This driver appears to work with both the 1443/1445 and the 1487/1489 | ||
32 | * chipsets. I've added support for PIO mode 4 for the 1487. This | ||
33 | * seems to work just fine on the 1443 also, although I'm not sure it's | ||
34 | * advertised as supporting mode 4. (I've been running a WDC AC21200 in | ||
35 | * mode 4 for a while now with no trouble.) -Derek | ||
36 | */ | ||
37 | |||
38 | #include <linux/module.h> | ||
39 | #include <linux/types.h> | ||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/delay.h> | ||
42 | #include <linux/timer.h> | ||
43 | #include <linux/mm.h> | ||
44 | #include <linux/ioport.h> | ||
45 | #include <linux/blkdev.h> | ||
46 | #include <linux/ide.h> | ||
47 | #include <linux/init.h> | ||
48 | |||
49 | #include <asm/io.h> | ||
50 | |||
51 | #define DRV_NAME "ali14xx" | ||
52 | |||
53 | /* port addresses for auto-detection */ | ||
54 | #define ALI_NUM_PORTS 4 | ||
55 | static const int ports[ALI_NUM_PORTS] __initdata = | ||
56 | { 0x074, 0x0f4, 0x034, 0x0e4 }; | ||
57 | |||
58 | /* register initialization data */ | ||
59 | typedef struct { u8 reg, data; } RegInitializer; | ||
60 | |||
61 | static const RegInitializer initData[] __initdata = { | ||
62 | {0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00}, | ||
63 | {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f}, | ||
64 | {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00}, | ||
65 | {0x29, 0x00}, {0x2a, 0x00}, {0x2f, 0x00}, {0x2b, 0x00}, | ||
66 | {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x30, 0x00}, | ||
67 | {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, {0x34, 0xff}, | ||
68 | {0x35, 0x03}, {0x00, 0x00} | ||
69 | }; | ||
70 | |||
71 | /* timing parameter registers for each drive */ | ||
72 | static struct { u8 reg1, reg2, reg3, reg4; } regTab[4] = { | ||
73 | {0x03, 0x26, 0x04, 0x27}, /* drive 0 */ | ||
74 | {0x05, 0x28, 0x06, 0x29}, /* drive 1 */ | ||
75 | {0x2b, 0x30, 0x2c, 0x31}, /* drive 2 */ | ||
76 | {0x2d, 0x32, 0x2e, 0x33}, /* drive 3 */ | ||
77 | }; | ||
78 | |||
79 | static int basePort; /* base port address */ | ||
80 | static int regPort; /* port for register number */ | ||
81 | static int dataPort; /* port for register data */ | ||
82 | static u8 regOn; /* output to base port to access registers */ | ||
83 | static u8 regOff; /* output to base port to close registers */ | ||
84 | |||
85 | /*------------------------------------------------------------------------*/ | ||
86 | |||
87 | /* | ||
88 | * Read a controller register. | ||
89 | */ | ||
90 | static inline u8 inReg(u8 reg) | ||
91 | { | ||
92 | outb_p(reg, regPort); | ||
93 | return inb(dataPort); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Write a controller register. | ||
98 | */ | ||
99 | static void outReg(u8 data, u8 reg) | ||
100 | { | ||
101 | outb_p(reg, regPort); | ||
102 | outb_p(data, dataPort); | ||
103 | } | ||
104 | |||
105 | static DEFINE_SPINLOCK(ali14xx_lock); | ||
106 | |||
107 | /* | ||
108 | * Set PIO mode for the specified drive. | ||
109 | * This function computes timing parameters | ||
110 | * and sets controller registers accordingly. | ||
111 | */ | ||
112 | static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
113 | { | ||
114 | int driveNum; | ||
115 | int time1, time2; | ||
116 | u8 param1, param2, param3, param4; | ||
117 | unsigned long flags; | ||
118 | int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; | ||
119 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
120 | |||
121 | /* calculate timing, according to PIO mode */ | ||
122 | time1 = ide_pio_cycle_time(drive, pio); | ||
123 | time2 = t->active; | ||
124 | param3 = param1 = (time2 * bus_speed + 999) / 1000; | ||
125 | param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1; | ||
126 | if (pio < 3) { | ||
127 | param3 += 8; | ||
128 | param4 += 8; | ||
129 | } | ||
130 | printk(KERN_DEBUG "%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n", | ||
131 | drive->name, pio, time1, time2, param1, param2, param3, param4); | ||
132 | |||
133 | /* stuff timing parameters into controller registers */ | ||
134 | driveNum = (drive->hwif->index << 1) + (drive->dn & 1); | ||
135 | spin_lock_irqsave(&ali14xx_lock, flags); | ||
136 | outb_p(regOn, basePort); | ||
137 | outReg(param1, regTab[driveNum].reg1); | ||
138 | outReg(param2, regTab[driveNum].reg2); | ||
139 | outReg(param3, regTab[driveNum].reg3); | ||
140 | outReg(param4, regTab[driveNum].reg4); | ||
141 | outb_p(regOff, basePort); | ||
142 | spin_unlock_irqrestore(&ali14xx_lock, flags); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Auto-detect the IDE controller port. | ||
147 | */ | ||
148 | static int __init findPort(void) | ||
149 | { | ||
150 | int i; | ||
151 | u8 t; | ||
152 | unsigned long flags; | ||
153 | |||
154 | local_irq_save(flags); | ||
155 | for (i = 0; i < ALI_NUM_PORTS; ++i) { | ||
156 | basePort = ports[i]; | ||
157 | regOff = inb(basePort); | ||
158 | for (regOn = 0x30; regOn <= 0x33; ++regOn) { | ||
159 | outb_p(regOn, basePort); | ||
160 | if (inb(basePort) == regOn) { | ||
161 | regPort = basePort + 4; | ||
162 | dataPort = basePort + 8; | ||
163 | t = inReg(0) & 0xf0; | ||
164 | outb_p(regOff, basePort); | ||
165 | local_irq_restore(flags); | ||
166 | if (t != 0x50) | ||
167 | return 0; | ||
168 | return 1; /* success */ | ||
169 | } | ||
170 | } | ||
171 | outb_p(regOff, basePort); | ||
172 | } | ||
173 | local_irq_restore(flags); | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Initialize controller registers with default values. | ||
179 | */ | ||
180 | static int __init initRegisters(void) | ||
181 | { | ||
182 | const RegInitializer *p; | ||
183 | u8 t; | ||
184 | unsigned long flags; | ||
185 | |||
186 | local_irq_save(flags); | ||
187 | outb_p(regOn, basePort); | ||
188 | for (p = initData; p->reg != 0; ++p) | ||
189 | outReg(p->data, p->reg); | ||
190 | outb_p(0x01, regPort); | ||
191 | t = inb(regPort) & 0x01; | ||
192 | outb_p(regOff, basePort); | ||
193 | local_irq_restore(flags); | ||
194 | return t; | ||
195 | } | ||
196 | |||
197 | static const struct ide_port_ops ali14xx_port_ops = { | ||
198 | .set_pio_mode = ali14xx_set_pio_mode, | ||
199 | }; | ||
200 | |||
201 | static const struct ide_port_info ali14xx_port_info = { | ||
202 | .name = DRV_NAME, | ||
203 | .chipset = ide_ali14xx, | ||
204 | .port_ops = &ali14xx_port_ops, | ||
205 | .host_flags = IDE_HFLAG_NO_DMA, | ||
206 | .pio_mask = ATA_PIO4, | ||
207 | }; | ||
208 | |||
209 | static int __init ali14xx_probe(void) | ||
210 | { | ||
211 | printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n", | ||
212 | basePort, regOn); | ||
213 | |||
214 | /* initialize controller registers */ | ||
215 | if (!initRegisters()) { | ||
216 | printk(KERN_ERR "ali14xx: Chip initialization failed.\n"); | ||
217 | return 1; | ||
218 | } | ||
219 | |||
220 | return ide_legacy_device_add(&ali14xx_port_info, 0); | ||
221 | } | ||
222 | |||
223 | static int probe_ali14xx; | ||
224 | |||
225 | module_param_named(probe, probe_ali14xx, bool, 0); | ||
226 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); | ||
227 | |||
228 | static int __init ali14xx_init(void) | ||
229 | { | ||
230 | if (probe_ali14xx == 0) | ||
231 | goto out; | ||
232 | |||
233 | /* auto-detect IDE controller port */ | ||
234 | if (findPort()) { | ||
235 | if (ali14xx_probe()) | ||
236 | return -ENODEV; | ||
237 | return 0; | ||
238 | } | ||
239 | printk(KERN_ERR "ali14xx: not found.\n"); | ||
240 | out: | ||
241 | return -ENODEV; | ||
242 | } | ||
243 | |||
244 | module_init(ali14xx_init); | ||
245 | |||
246 | MODULE_AUTHOR("see local file"); | ||
247 | MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets"); | ||
248 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c deleted file mode 100644 index c5a3c9ef6a5d..000000000000 --- a/drivers/ide/legacy/buddha.c +++ /dev/null | |||
@@ -1,235 +0,0 @@ | |||
1 | /* | ||
2 | * Amiga Buddha, Catweasel and X-Surf IDE Driver | ||
3 | * | ||
4 | * Copyright (C) 1997, 2001 by Geert Uytterhoeven and others | ||
5 | * | ||
6 | * This driver was written based on the specifications in README.buddha and | ||
7 | * the X-Surf info from Inside_XSurf.txt available at | ||
8 | * http://www.jschoenfeld.com | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file COPYING in the main directory of this archive for | ||
12 | * more details. | ||
13 | * | ||
14 | * TODO: | ||
15 | * - test it :-) | ||
16 | * - tune the timings using the speed-register | ||
17 | */ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/blkdev.h> | ||
23 | #include <linux/zorro.h> | ||
24 | #include <linux/ide.h> | ||
25 | #include <linux/init.h> | ||
26 | |||
27 | #include <asm/amigahw.h> | ||
28 | #include <asm/amigaints.h> | ||
29 | |||
30 | |||
31 | /* | ||
32 | * The Buddha has 2 IDE interfaces, the Catweasel has 3, X-Surf has 2 | ||
33 | */ | ||
34 | |||
35 | #define BUDDHA_NUM_HWIFS 2 | ||
36 | #define CATWEASEL_NUM_HWIFS 3 | ||
37 | #define XSURF_NUM_HWIFS 2 | ||
38 | |||
39 | #define MAX_NUM_HWIFS 3 | ||
40 | |||
41 | /* | ||
42 | * Bases of the IDE interfaces (relative to the board address) | ||
43 | */ | ||
44 | |||
45 | #define BUDDHA_BASE1 0x800 | ||
46 | #define BUDDHA_BASE2 0xa00 | ||
47 | #define BUDDHA_BASE3 0xc00 | ||
48 | |||
49 | #define XSURF_BASE1 0xb000 /* 2.5" Interface */ | ||
50 | #define XSURF_BASE2 0xd000 /* 3.5" Interface */ | ||
51 | |||
52 | static u_int buddha_bases[CATWEASEL_NUM_HWIFS] __initdata = { | ||
53 | BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 | ||
54 | }; | ||
55 | |||
56 | static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = { | ||
57 | XSURF_BASE1, XSURF_BASE2 | ||
58 | }; | ||
59 | |||
60 | /* | ||
61 | * Offsets from one of the above bases | ||
62 | */ | ||
63 | |||
64 | #define BUDDHA_CONTROL 0x11a | ||
65 | |||
66 | /* | ||
67 | * Other registers | ||
68 | */ | ||
69 | |||
70 | #define BUDDHA_IRQ1 0xf00 /* MSB = 1, Harddisk is source of */ | ||
71 | #define BUDDHA_IRQ2 0xf40 /* interrupt */ | ||
72 | #define BUDDHA_IRQ3 0xf80 | ||
73 | |||
74 | #define XSURF_IRQ1 0x7e | ||
75 | #define XSURF_IRQ2 0x7e | ||
76 | |||
77 | static int buddha_irqports[CATWEASEL_NUM_HWIFS] __initdata = { | ||
78 | BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3 | ||
79 | }; | ||
80 | |||
81 | static int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = { | ||
82 | XSURF_IRQ1, XSURF_IRQ2 | ||
83 | }; | ||
84 | |||
85 | #define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */ | ||
86 | |||
87 | |||
88 | /* | ||
89 | * Board information | ||
90 | */ | ||
91 | |||
92 | typedef enum BuddhaType_Enum { | ||
93 | BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF | ||
94 | } BuddhaType; | ||
95 | |||
96 | static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" }; | ||
97 | |||
98 | /* | ||
99 | * Check and acknowledge the interrupt status | ||
100 | */ | ||
101 | |||
102 | static int buddha_ack_intr(ide_hwif_t *hwif) | ||
103 | { | ||
104 | unsigned char ch; | ||
105 | |||
106 | ch = z_readb(hwif->io_ports.irq_addr); | ||
107 | if (!(ch & 0x80)) | ||
108 | return 0; | ||
109 | return 1; | ||
110 | } | ||
111 | |||
112 | static int xsurf_ack_intr(ide_hwif_t *hwif) | ||
113 | { | ||
114 | unsigned char ch; | ||
115 | |||
116 | ch = z_readb(hwif->io_ports.irq_addr); | ||
117 | /* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */ | ||
118 | z_writeb(0, hwif->io_ports.irq_addr); | ||
119 | if (!(ch & 0x80)) | ||
120 | return 0; | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, | ||
125 | unsigned long ctl, unsigned long irq_port, | ||
126 | ide_ack_intr_t *ack_intr) | ||
127 | { | ||
128 | int i; | ||
129 | |||
130 | memset(hw, 0, sizeof(*hw)); | ||
131 | |||
132 | hw->io_ports.data_addr = base; | ||
133 | |||
134 | for (i = 1; i < 8; i++) | ||
135 | hw->io_ports_array[i] = base + 2 + i * 4; | ||
136 | |||
137 | hw->io_ports.ctl_addr = ctl; | ||
138 | hw->io_ports.irq_addr = irq_port; | ||
139 | |||
140 | hw->irq = IRQ_AMIGA_PORTS; | ||
141 | hw->ack_intr = ack_intr; | ||
142 | |||
143 | hw->chipset = ide_generic; | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * Probe for a Buddha or Catweasel IDE interface | ||
148 | */ | ||
149 | |||
150 | static int __init buddha_init(void) | ||
151 | { | ||
152 | struct zorro_dev *z = NULL; | ||
153 | u_long buddha_board = 0; | ||
154 | BuddhaType type; | ||
155 | int buddha_num_hwifs, i; | ||
156 | |||
157 | while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { | ||
158 | unsigned long board; | ||
159 | hw_regs_t hw[MAX_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL }; | ||
160 | |||
161 | if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { | ||
162 | buddha_num_hwifs = BUDDHA_NUM_HWIFS; | ||
163 | type=BOARD_BUDDHA; | ||
164 | } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { | ||
165 | buddha_num_hwifs = CATWEASEL_NUM_HWIFS; | ||
166 | type=BOARD_CATWEASEL; | ||
167 | } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) { | ||
168 | buddha_num_hwifs = XSURF_NUM_HWIFS; | ||
169 | type=BOARD_XSURF; | ||
170 | } else | ||
171 | continue; | ||
172 | |||
173 | board = z->resource.start; | ||
174 | |||
175 | /* | ||
176 | * FIXME: we now have selectable mmio v/s iomio transports. | ||
177 | */ | ||
178 | |||
179 | if(type != BOARD_XSURF) { | ||
180 | if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) | ||
181 | continue; | ||
182 | } else { | ||
183 | if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE")) | ||
184 | continue; | ||
185 | if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE")) | ||
186 | goto fail_base2; | ||
187 | if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) { | ||
188 | release_mem_region(board+XSURF_BASE2, 0x1000); | ||
189 | fail_base2: | ||
190 | release_mem_region(board+XSURF_BASE1, 0x1000); | ||
191 | continue; | ||
192 | } | ||
193 | } | ||
194 | buddha_board = ZTWO_VADDR(board); | ||
195 | |||
196 | /* write to BUDDHA_IRQ_MR to enable the board IRQ */ | ||
197 | /* X-Surf doesn't have this. IRQs are always on */ | ||
198 | if (type != BOARD_XSURF) | ||
199 | z_writeb(0, buddha_board+BUDDHA_IRQ_MR); | ||
200 | |||
201 | printk(KERN_INFO "ide: %s IDE controller\n", | ||
202 | buddha_board_name[type]); | ||
203 | |||
204 | for (i = 0; i < buddha_num_hwifs; i++) { | ||
205 | unsigned long base, ctl, irq_port; | ||
206 | ide_ack_intr_t *ack_intr; | ||
207 | |||
208 | if (type != BOARD_XSURF) { | ||
209 | base = buddha_board + buddha_bases[i]; | ||
210 | ctl = base + BUDDHA_CONTROL; | ||
211 | irq_port = buddha_board + buddha_irqports[i]; | ||
212 | ack_intr = buddha_ack_intr; | ||
213 | } else { | ||
214 | base = buddha_board + xsurf_bases[i]; | ||
215 | /* X-Surf has no CS1* (Control/AltStat) */ | ||
216 | ctl = 0; | ||
217 | irq_port = buddha_board + xsurf_irqports[i]; | ||
218 | ack_intr = xsurf_ack_intr; | ||
219 | } | ||
220 | |||
221 | buddha_setup_ports(&hw[i], base, ctl, irq_port, | ||
222 | ack_intr); | ||
223 | |||
224 | hws[i] = &hw[i]; | ||
225 | } | ||
226 | |||
227 | ide_host_add(NULL, hws, NULL); | ||
228 | } | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | module_init(buddha_init); | ||
234 | |||
235 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c deleted file mode 100644 index 689b2e493413..000000000000 --- a/drivers/ide/legacy/dtc2278.c +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996 Linus Torvalds & author (see below) | ||
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 | * Changing this #undef to #define may solve start up problems in some systems. | ||
22 | */ | ||
23 | #undef ALWAYS_SET_DTC2278_PIO_MODE | ||
24 | |||
25 | /* | ||
26 | * From: andy@cercle.cts.com (Dyan Wile) | ||
27 | * | ||
28 | * Below is a patch for DTC-2278 - alike software-programmable controllers | ||
29 | * The code enables the secondary IDE controller and the PIO4 (3?) timings on | ||
30 | * the primary (EIDE). You may probably have to enable the 32-bit support to | ||
31 | * get the full speed. You better get the disk interrupts disabled ( hdparm -u0 | ||
32 | * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my | ||
33 | * filesystem corrupted with -u1, but under heavy disk load only :-) | ||
34 | * | ||
35 | * This card is now forced to use the "serialize" feature, | ||
36 | * and irq-unmasking is disallowed. If io_32bit is enabled, | ||
37 | * it must be done for BOTH drives on each interface. | ||
38 | * | ||
39 | * This code was written for the DTC2278E, but might work with any of these: | ||
40 | * | ||
41 | * DTC2278S has only a single IDE interface. | ||
42 | * DTC2278D has two IDE interfaces and is otherwise identical to the S version. | ||
43 | * DTC2278E also has serial ports and a printer port | ||
44 | * DTC2278EB: has onboard BIOS, and "works like a charm" -- Kent Bradford <kent@theory.caltech.edu> | ||
45 | * | ||
46 | * There may be a fourth controller type. The S and D versions use the | ||
47 | * Winbond chip, and I think the E version does also. | ||
48 | * | ||
49 | */ | ||
50 | |||
51 | static 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; /* success */ | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | static DEFINE_SPINLOCK(dtc2278_lock); | ||
70 | |||
71 | static 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 | * This enables PIO mode4 (3?) on the first interface | ||
79 | */ | ||
80 | sub22(1,0xc3); | ||
81 | sub22(0,0xa0); | ||
82 | spin_unlock_irqrestore(&dtc2278_lock, flags); | ||
83 | } else { | ||
84 | /* we don't know how to set it back again.. */ | ||
85 | /* Actually we do - there is a data sheet available for the | ||
86 | Winbond but does anyone actually care */ | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static const struct ide_port_ops dtc2278_port_ops = { | ||
91 | .set_pio_mode = dtc2278_set_pio_mode, | ||
92 | }; | ||
93 | |||
94 | static 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 | /* disallow ->io_32bit changes */ | ||
102 | IDE_HFLAG_NO_IO_32BIT | | ||
103 | IDE_HFLAG_NO_DMA, | ||
104 | .pio_mask = ATA_PIO4, | ||
105 | }; | ||
106 | |||
107 | static int __init dtc2278_probe(void) | ||
108 | { | ||
109 | unsigned long flags; | ||
110 | |||
111 | local_irq_save(flags); | ||
112 | /* | ||
113 | * This enables the second interface | ||
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 | * This enables PIO mode4 (3?) on the first interface | ||
122 | * and may solve start-up problems for some people. | ||
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 | |||
132 | static int probe_dtc2278; | ||
133 | |||
134 | module_param_named(probe, probe_dtc2278, bool, 0); | ||
135 | MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets"); | ||
136 | |||
137 | static 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 | |||
149 | module_init(dtc2278_init); | ||
150 | |||
151 | MODULE_AUTHOR("See Local File"); | ||
152 | MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets"); | ||
153 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c deleted file mode 100644 index 39d500d84b07..000000000000 --- a/drivers/ide/legacy/falconide.c +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | /* | ||
2 | * Atari Falcon IDE Driver | ||
3 | * | ||
4 | * Created 12 Jul 1997 by Geert Uytterhoeven | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive for | ||
8 | * more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/mm.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/blkdev.h> | ||
16 | #include <linux/ide.h> | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <asm/setup.h> | ||
20 | #include <asm/atarihw.h> | ||
21 | #include <asm/atariints.h> | ||
22 | #include <asm/atari_stdma.h> | ||
23 | |||
24 | #define DRV_NAME "falconide" | ||
25 | |||
26 | /* | ||
27 | * Base of the IDE interface | ||
28 | */ | ||
29 | |||
30 | #define ATA_HD_BASE 0xfff00000 | ||
31 | |||
32 | /* | ||
33 | * Offsets from the above base | ||
34 | */ | ||
35 | |||
36 | #define ATA_HD_CONTROL 0x39 | ||
37 | |||
38 | /* | ||
39 | * falconide_intr_lock is used to obtain access to the IDE interrupt, | ||
40 | * which is shared between several drivers. | ||
41 | */ | ||
42 | |||
43 | int falconide_intr_lock; | ||
44 | EXPORT_SYMBOL(falconide_intr_lock); | ||
45 | |||
46 | static void falconide_input_data(ide_drive_t *drive, struct request *rq, | ||
47 | void *buf, unsigned int len) | ||
48 | { | ||
49 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
50 | |||
51 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
52 | return insw(data_addr, buf, (len + 1) / 2); | ||
53 | |||
54 | insw_swapw(data_addr, buf, (len + 1) / 2); | ||
55 | } | ||
56 | |||
57 | static void falconide_output_data(ide_drive_t *drive, struct request *rq, | ||
58 | void *buf, unsigned int len) | ||
59 | { | ||
60 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
61 | |||
62 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
63 | return outsw(data_addr, buf, (len + 1) / 2); | ||
64 | |||
65 | outsw_swapw(data_addr, buf, (len + 1) / 2); | ||
66 | } | ||
67 | |||
68 | /* Atari has a byte-swapped IDE interface */ | ||
69 | static const struct ide_tp_ops falconide_tp_ops = { | ||
70 | .exec_command = ide_exec_command, | ||
71 | .read_status = ide_read_status, | ||
72 | .read_altstatus = ide_read_altstatus, | ||
73 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
74 | |||
75 | .set_irq = ide_set_irq, | ||
76 | |||
77 | .tf_load = ide_tf_load, | ||
78 | .tf_read = ide_tf_read, | ||
79 | |||
80 | .input_data = falconide_input_data, | ||
81 | .output_data = falconide_output_data, | ||
82 | }; | ||
83 | |||
84 | static const struct ide_port_info falconide_port_info = { | ||
85 | .tp_ops = &falconide_tp_ops, | ||
86 | .host_flags = IDE_HFLAG_NO_DMA, | ||
87 | }; | ||
88 | |||
89 | static void __init falconide_setup_ports(hw_regs_t *hw) | ||
90 | { | ||
91 | int i; | ||
92 | |||
93 | memset(hw, 0, sizeof(*hw)); | ||
94 | |||
95 | hw->io_ports.data_addr = ATA_HD_BASE; | ||
96 | |||
97 | for (i = 1; i < 8; i++) | ||
98 | hw->io_ports_array[i] = ATA_HD_BASE + 1 + i * 4; | ||
99 | |||
100 | hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL; | ||
101 | |||
102 | hw->irq = IRQ_MFP_IDE; | ||
103 | hw->ack_intr = NULL; | ||
104 | |||
105 | hw->chipset = ide_generic; | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Probe for a Falcon IDE interface | ||
110 | */ | ||
111 | |||
112 | static int __init falconide_init(void) | ||
113 | { | ||
114 | struct ide_host *host; | ||
115 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | ||
116 | int rc; | ||
117 | |||
118 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE)) | ||
119 | return -ENODEV; | ||
120 | |||
121 | printk(KERN_INFO "ide: Falcon IDE controller\n"); | ||
122 | |||
123 | if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) { | ||
124 | printk(KERN_ERR "%s: resources busy\n", DRV_NAME); | ||
125 | return -EBUSY; | ||
126 | } | ||
127 | |||
128 | falconide_setup_ports(&hw); | ||
129 | |||
130 | host = ide_host_alloc(&falconide_port_info, hws); | ||
131 | if (host == NULL) { | ||
132 | rc = -ENOMEM; | ||
133 | goto err; | ||
134 | } | ||
135 | |||
136 | ide_get_lock(NULL, NULL); | ||
137 | rc = ide_host_register(host, &falconide_port_info, hws); | ||
138 | ide_release_lock(); | ||
139 | |||
140 | if (rc) | ||
141 | goto err_free; | ||
142 | |||
143 | return 0; | ||
144 | err_free: | ||
145 | ide_host_free(host); | ||
146 | err: | ||
147 | release_mem_region(ATA_HD_BASE, 0x40); | ||
148 | return rc; | ||
149 | } | ||
150 | |||
151 | module_init(falconide_init); | ||
152 | |||
153 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c deleted file mode 100644 index 691506886561..000000000000 --- a/drivers/ide/legacy/gayle.c +++ /dev/null | |||
@@ -1,190 +0,0 @@ | |||
1 | /* | ||
2 | * Amiga Gayle IDE Driver | ||
3 | * | ||
4 | * Created 9 Jul 1997 by Geert Uytterhoeven | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive for | ||
8 | * more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/blkdev.h> | ||
15 | #include <linux/ide.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/zorro.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | #include <asm/setup.h> | ||
21 | #include <asm/amigahw.h> | ||
22 | #include <asm/amigaints.h> | ||
23 | #include <asm/amigayle.h> | ||
24 | |||
25 | |||
26 | /* | ||
27 | * Bases of the IDE interfaces | ||
28 | */ | ||
29 | |||
30 | #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ | ||
31 | #define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */ | ||
32 | |||
33 | #define GAYLE_IDEREG_SIZE 0x2000 | ||
34 | |||
35 | /* | ||
36 | * Offsets from one of the above bases | ||
37 | */ | ||
38 | |||
39 | #define GAYLE_CONTROL 0x101a | ||
40 | |||
41 | /* | ||
42 | * These are at different offsets from the base | ||
43 | */ | ||
44 | |||
45 | #define GAYLE_IRQ_4000 0xdd3020 /* MSB = 1, Harddisk is source of */ | ||
46 | #define GAYLE_IRQ_1200 0xda9000 /* interrupt */ | ||
47 | |||
48 | |||
49 | /* | ||
50 | * Offset of the secondary port for IDE doublers | ||
51 | * Note that GAYLE_CONTROL is NOT available then! | ||
52 | */ | ||
53 | |||
54 | #define GAYLE_NEXT_PORT 0x1000 | ||
55 | |||
56 | #ifndef CONFIG_BLK_DEV_IDEDOUBLER | ||
57 | #define GAYLE_NUM_HWIFS 1 | ||
58 | #define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS | ||
59 | #define GAYLE_HAS_CONTROL_REG 1 | ||
60 | #else /* CONFIG_BLK_DEV_IDEDOUBLER */ | ||
61 | #define GAYLE_NUM_HWIFS 2 | ||
62 | #define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \ | ||
63 | GAYLE_NUM_HWIFS-1) | ||
64 | #define GAYLE_HAS_CONTROL_REG (!ide_doubler) | ||
65 | |||
66 | static int ide_doubler; | ||
67 | module_param_named(doubler, ide_doubler, bool, 0); | ||
68 | MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); | ||
69 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ | ||
70 | |||
71 | |||
72 | /* | ||
73 | * Check and acknowledge the interrupt status | ||
74 | */ | ||
75 | |||
76 | static int gayle_ack_intr_a4000(ide_hwif_t *hwif) | ||
77 | { | ||
78 | unsigned char ch; | ||
79 | |||
80 | ch = z_readb(hwif->io_ports.irq_addr); | ||
81 | if (!(ch & GAYLE_IRQ_IDE)) | ||
82 | return 0; | ||
83 | return 1; | ||
84 | } | ||
85 | |||
86 | static int gayle_ack_intr_a1200(ide_hwif_t *hwif) | ||
87 | { | ||
88 | unsigned char ch; | ||
89 | |||
90 | ch = z_readb(hwif->io_ports.irq_addr); | ||
91 | if (!(ch & GAYLE_IRQ_IDE)) | ||
92 | return 0; | ||
93 | (void)z_readb(hwif->io_ports.status_addr); | ||
94 | z_writeb(0x7c, hwif->io_ports.irq_addr); | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, | ||
99 | unsigned long ctl, unsigned long irq_port, | ||
100 | ide_ack_intr_t *ack_intr) | ||
101 | { | ||
102 | int i; | ||
103 | |||
104 | memset(hw, 0, sizeof(*hw)); | ||
105 | |||
106 | hw->io_ports.data_addr = base; | ||
107 | |||
108 | for (i = 1; i < 8; i++) | ||
109 | hw->io_ports_array[i] = base + 2 + i * 4; | ||
110 | |||
111 | hw->io_ports.ctl_addr = ctl; | ||
112 | hw->io_ports.irq_addr = irq_port; | ||
113 | |||
114 | hw->irq = IRQ_AMIGA_PORTS; | ||
115 | hw->ack_intr = ack_intr; | ||
116 | |||
117 | hw->chipset = ide_generic; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Probe for a Gayle IDE interface (and optionally for an IDE doubler) | ||
122 | */ | ||
123 | |||
124 | static int __init gayle_init(void) | ||
125 | { | ||
126 | unsigned long phys_base, res_start, res_n; | ||
127 | unsigned long base, ctrlport, irqport; | ||
128 | ide_ack_intr_t *ack_intr; | ||
129 | int a4000, i, rc; | ||
130 | hw_regs_t hw[GAYLE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL }; | ||
131 | |||
132 | if (!MACH_IS_AMIGA) | ||
133 | return -ENODEV; | ||
134 | |||
135 | if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) | ||
136 | goto found; | ||
137 | |||
138 | #ifdef CONFIG_ZORRO | ||
139 | if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE, | ||
140 | NULL)) | ||
141 | goto found; | ||
142 | #endif | ||
143 | return -ENODEV; | ||
144 | |||
145 | found: | ||
146 | printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n", | ||
147 | a4000 ? 4000 : 1200, | ||
148 | #ifdef CONFIG_BLK_DEV_IDEDOUBLER | ||
149 | ide_doubler ? ", IDE doubler" : | ||
150 | #endif | ||
151 | ""); | ||
152 | |||
153 | if (a4000) { | ||
154 | phys_base = GAYLE_BASE_4000; | ||
155 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000); | ||
156 | ack_intr = gayle_ack_intr_a4000; | ||
157 | } else { | ||
158 | phys_base = GAYLE_BASE_1200; | ||
159 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); | ||
160 | ack_intr = gayle_ack_intr_a1200; | ||
161 | } | ||
162 | /* | ||
163 | * FIXME: we now have selectable modes between mmio v/s iomio | ||
164 | */ | ||
165 | |||
166 | res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); | ||
167 | res_n = GAYLE_IDEREG_SIZE; | ||
168 | |||
169 | if (!request_mem_region(res_start, res_n, "IDE")) | ||
170 | return -EBUSY; | ||
171 | |||
172 | for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { | ||
173 | base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT); | ||
174 | ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; | ||
175 | |||
176 | gayle_setup_ports(&hw[i], base, ctrlport, irqport, ack_intr); | ||
177 | |||
178 | hws[i] = &hw[i]; | ||
179 | } | ||
180 | |||
181 | rc = ide_host_add(NULL, hws, NULL); | ||
182 | if (rc) | ||
183 | release_mem_region(res_start, res_n); | ||
184 | |||
185 | return rc; | ||
186 | } | ||
187 | |||
188 | module_init(gayle_init); | ||
189 | |||
190 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c deleted file mode 100644 index c7e5c2246b79..000000000000 --- a/drivers/ide/legacy/ht6560b.c +++ /dev/null | |||
@@ -1,351 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1995-2000 Linus Torvalds & author (see below) | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * HT-6560B EIDE-controller support | ||
7 | * To activate controller support use kernel parameter "ide0=ht6560b". | ||
8 | * Use hdparm utility to enable PIO mode support. | ||
9 | * | ||
10 | * Author: Mikko Ala-Fossi <maf@iki.fi> | ||
11 | * Jan Evert van Grootheest <j.e.van.grootheest@caiway.nl> | ||
12 | * | ||
13 | * Try: http://www.maf.iki.fi/~maf/ht6560b/ | ||
14 | */ | ||
15 | |||
16 | #define DRV_NAME "ht6560b" | ||
17 | #define HT6560B_VERSION "v0.08" | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/timer.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/blkdev.h> | ||
27 | #include <linux/ide.h> | ||
28 | #include <linux/init.h> | ||
29 | |||
30 | #include <asm/io.h> | ||
31 | |||
32 | /* #define DEBUG */ /* remove comments for DEBUG messages */ | ||
33 | |||
34 | /* | ||
35 | * The special i/o-port that HT-6560B uses to configuration: | ||
36 | * bit0 (0x01): "1" selects secondary interface | ||
37 | * bit2 (0x04): "1" enables FIFO function | ||
38 | * bit5 (0x20): "1" enables prefetched data read function (???) | ||
39 | * | ||
40 | * The special i/o-port that HT-6560A uses to configuration: | ||
41 | * bit0 (0x01): "1" selects secondary interface | ||
42 | * bit1 (0x02): "1" enables prefetched data read function | ||
43 | * bit2 (0x04): "0" enables multi-master system (?) | ||
44 | * bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time (?) | ||
45 | */ | ||
46 | #define HT_CONFIG_PORT 0x3e6 | ||
47 | #define HT_CONFIG(drivea) (u8)(((drivea)->drive_data & 0xff00) >> 8) | ||
48 | /* | ||
49 | * FIFO + PREFETCH (both a/b-model) | ||
50 | */ | ||
51 | #define HT_CONFIG_DEFAULT 0x1c /* no prefetch */ | ||
52 | /* #define HT_CONFIG_DEFAULT 0x3c */ /* with prefetch */ | ||
53 | #define HT_SECONDARY_IF 0x01 | ||
54 | #define HT_PREFETCH_MODE 0x20 | ||
55 | |||
56 | /* | ||
57 | * ht6560b Timing values: | ||
58 | * | ||
59 | * I reviewed some assembler source listings of htide drivers and found | ||
60 | * out how they setup those cycle time interfacing values, as they at Holtek | ||
61 | * call them. IDESETUP.COM that is supplied with the drivers figures out | ||
62 | * optimal values and fetches those values to drivers. I found out that | ||
63 | * they use Select register to fetch timings to the ide board right after | ||
64 | * interface switching. After that it was quite easy to add code to | ||
65 | * ht6560b.c. | ||
66 | * | ||
67 | * IDESETUP.COM gave me values 0x24, 0x45, 0xaa, 0xff that worked fine | ||
68 | * for hda and hdc. But hdb needed higher values to work, so I guess | ||
69 | * that sometimes it is necessary to give higher value than IDESETUP | ||
70 | * gives. [see cmd640.c for an extreme example of this. -ml] | ||
71 | * | ||
72 | * Perhaps I should explain something about these timing values: | ||
73 | * The higher nibble of value is the Recovery Time (rt) and the lower nibble | ||
74 | * of the value is the Active Time (at). Minimum value 2 is the fastest and | ||
75 | * the maximum value 15 is the slowest. Default values should be 15 for both. | ||
76 | * So 0x24 means 2 for rt and 4 for at. Each of the drives should have | ||
77 | * both values, and IDESETUP gives automatically rt=15 st=15 for CDROMs or | ||
78 | * similar. If value is too small there will be all sorts of failures. | ||
79 | * | ||
80 | * Timing byte consists of | ||
81 | * High nibble: Recovery Cycle Time (rt) | ||
82 | * The valid values range from 2 to 15. The default is 15. | ||
83 | * | ||
84 | * Low nibble: Active Cycle Time (at) | ||
85 | * The valid values range from 2 to 15. The default is 15. | ||
86 | * | ||
87 | * You can obtain optimized timing values by running Holtek IDESETUP.COM | ||
88 | * for DOS. DOS drivers get their timing values from command line, where | ||
89 | * the first value is the Recovery Time and the second value is the | ||
90 | * Active Time for each drive. Smaller value gives higher speed. | ||
91 | * In case of failures you should probably fall back to a higher value. | ||
92 | */ | ||
93 | #define HT_TIMING(drivea) (u8)((drivea)->drive_data & 0x00ff) | ||
94 | #define HT_TIMING_DEFAULT 0xff | ||
95 | |||
96 | /* | ||
97 | * This routine handles interface switching for the peculiar hardware design | ||
98 | * on the F.G.I./Holtek HT-6560B VLB IDE interface. | ||
99 | * The HT-6560B can only enable one IDE port at a time, and requires a | ||
100 | * silly sequence (below) whenever we switch between primary and secondary. | ||
101 | */ | ||
102 | |||
103 | /* | ||
104 | * This routine is invoked from ide.c to prepare for access to a given drive. | ||
105 | */ | ||
106 | static void ht6560b_selectproc (ide_drive_t *drive) | ||
107 | { | ||
108 | ide_hwif_t *hwif = drive->hwif; | ||
109 | unsigned long flags; | ||
110 | static u8 current_select = 0; | ||
111 | static u8 current_timing = 0; | ||
112 | u8 select, timing; | ||
113 | |||
114 | local_irq_save(flags); | ||
115 | |||
116 | select = HT_CONFIG(drive); | ||
117 | timing = HT_TIMING(drive); | ||
118 | |||
119 | /* | ||
120 | * Need to enforce prefetch sometimes because otherwise | ||
121 | * it'll hang (hard). | ||
122 | */ | ||
123 | if (drive->media != ide_disk || | ||
124 | (drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | ||
125 | select |= HT_PREFETCH_MODE; | ||
126 | |||
127 | if (select != current_select || timing != current_timing) { | ||
128 | current_select = select; | ||
129 | current_timing = timing; | ||
130 | (void)inb(HT_CONFIG_PORT); | ||
131 | (void)inb(HT_CONFIG_PORT); | ||
132 | (void)inb(HT_CONFIG_PORT); | ||
133 | (void)inb(HT_CONFIG_PORT); | ||
134 | outb(select, HT_CONFIG_PORT); | ||
135 | /* | ||
136 | * Set timing for this drive: | ||
137 | */ | ||
138 | outb(timing, hwif->io_ports.device_addr); | ||
139 | (void)inb(hwif->io_ports.status_addr); | ||
140 | #ifdef DEBUG | ||
141 | printk("ht6560b: %s: select=%#x timing=%#x\n", | ||
142 | drive->name, select, timing); | ||
143 | #endif | ||
144 | } | ||
145 | local_irq_restore(flags); | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Autodetection and initialization of ht6560b | ||
150 | */ | ||
151 | static int __init try_to_init_ht6560b(void) | ||
152 | { | ||
153 | u8 orig_value; | ||
154 | int i; | ||
155 | |||
156 | /* Autodetect ht6560b */ | ||
157 | if ((orig_value = inb(HT_CONFIG_PORT)) == 0xff) | ||
158 | return 0; | ||
159 | |||
160 | for (i=3;i>0;i--) { | ||
161 | outb(0x00, HT_CONFIG_PORT); | ||
162 | if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) { | ||
163 | outb(orig_value, HT_CONFIG_PORT); | ||
164 | return 0; | ||
165 | } | ||
166 | } | ||
167 | outb(0x00, HT_CONFIG_PORT); | ||
168 | if ((~inb(HT_CONFIG_PORT))& 0x3f) { | ||
169 | outb(orig_value, HT_CONFIG_PORT); | ||
170 | return 0; | ||
171 | } | ||
172 | /* | ||
173 | * Ht6560b autodetected | ||
174 | */ | ||
175 | outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT); | ||
176 | outb(HT_TIMING_DEFAULT, 0x1f6); /* Select register */ | ||
177 | (void)inb(0x1f7); /* Status register */ | ||
178 | |||
179 | printk("ht6560b " HT6560B_VERSION | ||
180 | ": chipset detected and initialized" | ||
181 | #ifdef DEBUG | ||
182 | " with debug enabled" | ||
183 | #endif | ||
184 | "\n" | ||
185 | ); | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) | ||
190 | { | ||
191 | int active_time, recovery_time; | ||
192 | int active_cycles, recovery_cycles; | ||
193 | int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; | ||
194 | |||
195 | if (pio) { | ||
196 | unsigned int cycle_time; | ||
197 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
198 | |||
199 | cycle_time = ide_pio_cycle_time(drive, pio); | ||
200 | |||
201 | /* | ||
202 | * Just like opti621.c we try to calculate the | ||
203 | * actual cycle time for recovery and activity | ||
204 | * according system bus speed. | ||
205 | */ | ||
206 | active_time = t->active; | ||
207 | recovery_time = cycle_time - active_time - t->setup; | ||
208 | /* | ||
209 | * Cycle times should be Vesa bus cycles | ||
210 | */ | ||
211 | active_cycles = (active_time * bus_speed + 999) / 1000; | ||
212 | recovery_cycles = (recovery_time * bus_speed + 999) / 1000; | ||
213 | /* | ||
214 | * Upper and lower limits | ||
215 | */ | ||
216 | if (active_cycles < 2) active_cycles = 2; | ||
217 | if (recovery_cycles < 2) recovery_cycles = 2; | ||
218 | if (active_cycles > 15) active_cycles = 15; | ||
219 | if (recovery_cycles > 15) recovery_cycles = 0; /* 0==16 */ | ||
220 | |||
221 | #ifdef DEBUG | ||
222 | printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time); | ||
223 | #endif | ||
224 | |||
225 | return (u8)((recovery_cycles << 4) | active_cycles); | ||
226 | } else { | ||
227 | |||
228 | #ifdef DEBUG | ||
229 | printk("ht6560b: drive %s setting pio=0\n", drive->name); | ||
230 | #endif | ||
231 | |||
232 | return HT_TIMING_DEFAULT; /* default setting */ | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static DEFINE_SPINLOCK(ht6560b_lock); | ||
237 | |||
238 | /* | ||
239 | * Enable/Disable so called prefetch mode | ||
240 | */ | ||
241 | static void ht_set_prefetch(ide_drive_t *drive, u8 state) | ||
242 | { | ||
243 | unsigned long flags; | ||
244 | int t = HT_PREFETCH_MODE << 8; | ||
245 | |||
246 | spin_lock_irqsave(&ht6560b_lock, flags); | ||
247 | |||
248 | /* | ||
249 | * Prefetch mode and unmask irq seems to conflict | ||
250 | */ | ||
251 | if (state) { | ||
252 | drive->drive_data |= t; /* enable prefetch mode */ | ||
253 | drive->dev_flags |= IDE_DFLAG_NO_UNMASK; | ||
254 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; | ||
255 | } else { | ||
256 | drive->drive_data &= ~t; /* disable prefetch mode */ | ||
257 | drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK; | ||
258 | } | ||
259 | |||
260 | spin_unlock_irqrestore(&ht6560b_lock, flags); | ||
261 | |||
262 | #ifdef DEBUG | ||
263 | printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis")); | ||
264 | #endif | ||
265 | } | ||
266 | |||
267 | static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
268 | { | ||
269 | unsigned long flags; | ||
270 | u8 timing; | ||
271 | |||
272 | switch (pio) { | ||
273 | case 8: /* set prefetch off */ | ||
274 | case 9: /* set prefetch on */ | ||
275 | ht_set_prefetch(drive, pio & 1); | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | timing = ht_pio2timings(drive, pio); | ||
280 | |||
281 | spin_lock_irqsave(&ht6560b_lock, flags); | ||
282 | drive->drive_data &= 0xff00; | ||
283 | drive->drive_data |= timing; | ||
284 | spin_unlock_irqrestore(&ht6560b_lock, flags); | ||
285 | |||
286 | #ifdef DEBUG | ||
287 | printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing); | ||
288 | #endif | ||
289 | } | ||
290 | |||
291 | static void __init ht6560b_init_dev(ide_drive_t *drive) | ||
292 | { | ||
293 | ide_hwif_t *hwif = drive->hwif; | ||
294 | /* Setting default configurations for drives. */ | ||
295 | int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT; | ||
296 | |||
297 | if (hwif->channel) | ||
298 | t |= (HT_SECONDARY_IF << 8); | ||
299 | |||
300 | drive->drive_data = t; | ||
301 | } | ||
302 | |||
303 | static int probe_ht6560b; | ||
304 | |||
305 | module_param_named(probe, probe_ht6560b, bool, 0); | ||
306 | MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); | ||
307 | |||
308 | static const struct ide_port_ops ht6560b_port_ops = { | ||
309 | .init_dev = ht6560b_init_dev, | ||
310 | .set_pio_mode = ht6560b_set_pio_mode, | ||
311 | .selectproc = ht6560b_selectproc, | ||
312 | }; | ||
313 | |||
314 | static const struct ide_port_info ht6560b_port_info __initdata = { | ||
315 | .name = DRV_NAME, | ||
316 | .chipset = ide_ht6560b, | ||
317 | .port_ops = &ht6560b_port_ops, | ||
318 | .host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */ | ||
319 | IDE_HFLAG_NO_DMA | | ||
320 | IDE_HFLAG_ABUSE_PREFETCH, | ||
321 | .pio_mask = ATA_PIO4, | ||
322 | }; | ||
323 | |||
324 | static int __init ht6560b_init(void) | ||
325 | { | ||
326 | if (probe_ht6560b == 0) | ||
327 | return -ENODEV; | ||
328 | |||
329 | if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) { | ||
330 | printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n", | ||
331 | __func__); | ||
332 | return -ENODEV; | ||
333 | } | ||
334 | |||
335 | if (!try_to_init_ht6560b()) { | ||
336 | printk(KERN_NOTICE "%s: HBA not found\n", __func__); | ||
337 | goto release_region; | ||
338 | } | ||
339 | |||
340 | return ide_legacy_device_add(&ht6560b_port_info, 0); | ||
341 | |||
342 | release_region: | ||
343 | release_region(HT_CONFIG_PORT, 1); | ||
344 | return -ENODEV; | ||
345 | } | ||
346 | |||
347 | module_init(ht6560b_init); | ||
348 | |||
349 | MODULE_AUTHOR("See Local File"); | ||
350 | MODULE_DESCRIPTION("HT-6560B EIDE-controller support"); | ||
351 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c deleted file mode 100644 index 9e85b1ec9607..000000000000 --- a/drivers/ide/legacy/ide-4drives.c +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | |||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/init.h> | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/ide.h> | ||
6 | |||
7 | #define DRV_NAME "ide-4drives" | ||
8 | |||
9 | static int probe_4drives; | ||
10 | |||
11 | module_param_named(probe, probe_4drives, bool, 0); | ||
12 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); | ||
13 | |||
14 | static void ide_4drives_init_dev(ide_drive_t *drive) | ||
15 | { | ||
16 | if (drive->hwif->channel) | ||
17 | drive->select ^= 0x20; | ||
18 | } | ||
19 | |||
20 | static const struct ide_port_ops ide_4drives_port_ops = { | ||
21 | .init_dev = ide_4drives_init_dev, | ||
22 | }; | ||
23 | |||
24 | static const struct ide_port_info ide_4drives_port_info = { | ||
25 | .port_ops = &ide_4drives_port_ops, | ||
26 | .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA, | ||
27 | }; | ||
28 | |||
29 | static int __init ide_4drives_init(void) | ||
30 | { | ||
31 | unsigned long base = 0x1f0, ctl = 0x3f6; | ||
32 | hw_regs_t hw, *hws[] = { &hw, &hw, NULL, NULL }; | ||
33 | |||
34 | if (probe_4drives == 0) | ||
35 | return -ENODEV; | ||
36 | |||
37 | if (!request_region(base, 8, DRV_NAME)) { | ||
38 | printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", | ||
39 | DRV_NAME, base, base + 7); | ||
40 | return -EBUSY; | ||
41 | } | ||
42 | |||
43 | if (!request_region(ctl, 1, DRV_NAME)) { | ||
44 | printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", | ||
45 | DRV_NAME, ctl); | ||
46 | release_region(base, 8); | ||
47 | return -EBUSY; | ||
48 | } | ||
49 | |||
50 | memset(&hw, 0, sizeof(hw)); | ||
51 | |||
52 | ide_std_init_ports(&hw, base, ctl); | ||
53 | hw.irq = 14; | ||
54 | hw.chipset = ide_4drives; | ||
55 | |||
56 | return ide_host_add(&ide_4drives_port_info, hws, NULL); | ||
57 | } | ||
58 | |||
59 | module_init(ide_4drives_init); | ||
60 | |||
61 | MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); | ||
62 | MODULE_DESCRIPTION("generic IDE chipset with 4 drives/port support"); | ||
63 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c deleted file mode 100644 index cb199c815b53..000000000000 --- a/drivers/ide/legacy/ide-cs.c +++ /dev/null | |||
@@ -1,472 +0,0 @@ | |||
1 | /*====================================================================== | ||
2 | |||
3 | A driver for PCMCIA IDE/ATA disk cards | ||
4 | |||
5 | The contents of this file are subject to the Mozilla Public | ||
6 | License Version 1.1 (the "License"); you may not use this file | ||
7 | except in compliance with the License. You may obtain a copy of | ||
8 | the License at http://www.mozilla.org/MPL/ | ||
9 | |||
10 | Software distributed under the License is distributed on an "AS | ||
11 | IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | ||
12 | implied. See the License for the specific language governing | ||
13 | rights and limitations under the License. | ||
14 | |||
15 | The initial developer of the original code is David A. Hinds | ||
16 | <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
17 | are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
18 | |||
19 | Alternatively, the contents of this file may be used under the | ||
20 | terms of the GNU General Public License version 2 (the "GPL"), in | ||
21 | which case the provisions of the GPL are applicable instead of the | ||
22 | above. If you wish to allow the use of your version of this file | ||
23 | only under the terms of the GPL and not to allow others to use | ||
24 | your version of this file under the MPL, indicate your decision | ||
25 | by deleting the provisions above and replace them with the notice | ||
26 | and other provisions required by the GPL. If you do not delete | ||
27 | the provisions above, a recipient may use your version of this | ||
28 | file under either the MPL or the GPL. | ||
29 | |||
30 | ======================================================================*/ | ||
31 | |||
32 | #include <linux/module.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/ptrace.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/string.h> | ||
38 | #include <linux/timer.h> | ||
39 | #include <linux/ioport.h> | ||
40 | #include <linux/ide.h> | ||
41 | #include <linux/major.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <asm/io.h> | ||
44 | #include <asm/system.h> | ||
45 | |||
46 | #include <pcmcia/cs_types.h> | ||
47 | #include <pcmcia/cs.h> | ||
48 | #include <pcmcia/cistpl.h> | ||
49 | #include <pcmcia/ds.h> | ||
50 | #include <pcmcia/cisreg.h> | ||
51 | #include <pcmcia/ciscode.h> | ||
52 | |||
53 | #define DRV_NAME "ide-cs" | ||
54 | |||
55 | /*====================================================================*/ | ||
56 | |||
57 | /* Module parameters */ | ||
58 | |||
59 | MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); | ||
60 | MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver"); | ||
61 | MODULE_LICENSE("Dual MPL/GPL"); | ||
62 | |||
63 | #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0) | ||
64 | |||
65 | #ifdef CONFIG_PCMCIA_DEBUG | ||
66 | INT_MODULE_PARM(pc_debug, 0); | ||
67 | #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) | ||
68 | #else | ||
69 | #define DEBUG(n, args...) | ||
70 | #endif | ||
71 | |||
72 | /*====================================================================*/ | ||
73 | |||
74 | typedef struct ide_info_t { | ||
75 | struct pcmcia_device *p_dev; | ||
76 | struct ide_host *host; | ||
77 | int ndev; | ||
78 | dev_node_t node; | ||
79 | } ide_info_t; | ||
80 | |||
81 | static void ide_release(struct pcmcia_device *); | ||
82 | static int ide_config(struct pcmcia_device *); | ||
83 | |||
84 | static void ide_detach(struct pcmcia_device *p_dev); | ||
85 | |||
86 | |||
87 | |||
88 | |||
89 | /*====================================================================== | ||
90 | |||
91 | ide_attach() creates an "instance" of the driver, allocating | ||
92 | local data structures for one device. The device is registered | ||
93 | with Card Services. | ||
94 | |||
95 | ======================================================================*/ | ||
96 | |||
97 | static int ide_probe(struct pcmcia_device *link) | ||
98 | { | ||
99 | ide_info_t *info; | ||
100 | |||
101 | DEBUG(0, "ide_attach()\n"); | ||
102 | |||
103 | /* Create new ide device */ | ||
104 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
105 | if (!info) | ||
106 | return -ENOMEM; | ||
107 | |||
108 | info->p_dev = link; | ||
109 | link->priv = info; | ||
110 | |||
111 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
112 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | ||
113 | link->io.IOAddrLines = 3; | ||
114 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
115 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | ||
116 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
117 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
118 | |||
119 | return ide_config(link); | ||
120 | } /* ide_attach */ | ||
121 | |||
122 | /*====================================================================== | ||
123 | |||
124 | This deletes a driver "instance". The device is de-registered | ||
125 | with Card Services. If it has been released, all local data | ||
126 | structures are freed. Otherwise, the structures will be freed | ||
127 | when the device is released. | ||
128 | |||
129 | ======================================================================*/ | ||
130 | |||
131 | static void ide_detach(struct pcmcia_device *link) | ||
132 | { | ||
133 | ide_info_t *info = link->priv; | ||
134 | ide_hwif_t *hwif = info->host->ports[0]; | ||
135 | unsigned long data_addr, ctl_addr; | ||
136 | |||
137 | DEBUG(0, "ide_detach(0x%p)\n", link); | ||
138 | |||
139 | data_addr = hwif->io_ports.data_addr; | ||
140 | ctl_addr = hwif->io_ports.ctl_addr; | ||
141 | |||
142 | ide_release(link); | ||
143 | |||
144 | release_region(ctl_addr, 1); | ||
145 | release_region(data_addr, 8); | ||
146 | |||
147 | kfree(info); | ||
148 | } /* ide_detach */ | ||
149 | |||
150 | static const struct ide_port_ops idecs_port_ops = { | ||
151 | .quirkproc = ide_undecoded_slave, | ||
152 | }; | ||
153 | |||
154 | static const struct ide_port_info idecs_port_info = { | ||
155 | .port_ops = &idecs_port_ops, | ||
156 | .host_flags = IDE_HFLAG_NO_DMA, | ||
157 | }; | ||
158 | |||
159 | static struct ide_host *idecs_register(unsigned long io, unsigned long ctl, | ||
160 | unsigned long irq, struct pcmcia_device *handle) | ||
161 | { | ||
162 | struct ide_host *host; | ||
163 | ide_hwif_t *hwif; | ||
164 | int i, rc; | ||
165 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | ||
166 | |||
167 | if (!request_region(io, 8, DRV_NAME)) { | ||
168 | printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", | ||
169 | DRV_NAME, io, io + 7); | ||
170 | return NULL; | ||
171 | } | ||
172 | |||
173 | if (!request_region(ctl, 1, DRV_NAME)) { | ||
174 | printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", | ||
175 | DRV_NAME, ctl); | ||
176 | release_region(io, 8); | ||
177 | return NULL; | ||
178 | } | ||
179 | |||
180 | memset(&hw, 0, sizeof(hw)); | ||
181 | ide_std_init_ports(&hw, io, ctl); | ||
182 | hw.irq = irq; | ||
183 | hw.chipset = ide_pci; | ||
184 | hw.dev = &handle->dev; | ||
185 | |||
186 | rc = ide_host_add(&idecs_port_info, hws, &host); | ||
187 | if (rc) | ||
188 | goto out_release; | ||
189 | |||
190 | hwif = host->ports[0]; | ||
191 | |||
192 | if (hwif->present) | ||
193 | return host; | ||
194 | |||
195 | /* retry registration in case device is still spinning up */ | ||
196 | for (i = 0; i < 10; i++) { | ||
197 | msleep(100); | ||
198 | ide_port_scan(hwif); | ||
199 | if (hwif->present) | ||
200 | return host; | ||
201 | } | ||
202 | |||
203 | return host; | ||
204 | |||
205 | out_release: | ||
206 | release_region(ctl, 1); | ||
207 | release_region(io, 8); | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
211 | /*====================================================================== | ||
212 | |||
213 | ide_config() is scheduled to run after a CARD_INSERTION event | ||
214 | is received, to configure the PCMCIA socket, and to make the | ||
215 | ide device available to the system. | ||
216 | |||
217 | ======================================================================*/ | ||
218 | |||
219 | #define CS_CHECK(fn, ret) \ | ||
220 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | ||
221 | |||
222 | struct pcmcia_config_check { | ||
223 | unsigned long ctl_base; | ||
224 | int skip_vcc; | ||
225 | int is_kme; | ||
226 | }; | ||
227 | |||
228 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, | ||
229 | cistpl_cftable_entry_t *cfg, | ||
230 | cistpl_cftable_entry_t *dflt, | ||
231 | unsigned int vcc, | ||
232 | void *priv_data) | ||
233 | { | ||
234 | struct pcmcia_config_check *stk = priv_data; | ||
235 | |||
236 | /* Check for matching Vcc, unless we're desperate */ | ||
237 | if (!stk->skip_vcc) { | ||
238 | if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { | ||
239 | if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) | ||
240 | return -ENODEV; | ||
241 | } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { | ||
242 | if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) | ||
243 | return -ENODEV; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) | ||
248 | pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; | ||
249 | else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) | ||
250 | pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; | ||
251 | |||
252 | if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { | ||
253 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; | ||
254 | pdev->conf.ConfigIndex = cfg->index; | ||
255 | pdev->io.BasePort1 = io->win[0].base; | ||
256 | pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
257 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
258 | pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
259 | if (io->nwin == 2) { | ||
260 | pdev->io.NumPorts1 = 8; | ||
261 | pdev->io.BasePort2 = io->win[1].base; | ||
262 | pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; | ||
263 | if (pcmcia_request_io(pdev, &pdev->io) != 0) | ||
264 | return -ENODEV; | ||
265 | stk->ctl_base = pdev->io.BasePort2; | ||
266 | } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { | ||
267 | pdev->io.NumPorts1 = io->win[0].len; | ||
268 | pdev->io.NumPorts2 = 0; | ||
269 | if (pcmcia_request_io(pdev, &pdev->io) != 0) | ||
270 | return -ENODEV; | ||
271 | stk->ctl_base = pdev->io.BasePort1 + 0x0e; | ||
272 | } else | ||
273 | return -ENODEV; | ||
274 | /* If we've got this far, we're done */ | ||
275 | return 0; | ||
276 | } | ||
277 | return -ENODEV; | ||
278 | } | ||
279 | |||
280 | static int ide_config(struct pcmcia_device *link) | ||
281 | { | ||
282 | ide_info_t *info = link->priv; | ||
283 | struct pcmcia_config_check *stk = NULL; | ||
284 | int last_ret = 0, last_fn = 0, is_kme = 0; | ||
285 | unsigned long io_base, ctl_base; | ||
286 | struct ide_host *host; | ||
287 | |||
288 | DEBUG(0, "ide_config(0x%p)\n", link); | ||
289 | |||
290 | is_kme = ((link->manf_id == MANFID_KME) && | ||
291 | ((link->card_id == PRODID_KME_KXLC005_A) || | ||
292 | (link->card_id == PRODID_KME_KXLC005_B))); | ||
293 | |||
294 | stk = kzalloc(sizeof(*stk), GFP_KERNEL); | ||
295 | if (!stk) | ||
296 | goto err_mem; | ||
297 | stk->is_kme = is_kme; | ||
298 | stk->skip_vcc = io_base = ctl_base = 0; | ||
299 | |||
300 | if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) { | ||
301 | stk->skip_vcc = 1; | ||
302 | if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) | ||
303 | goto failed; /* No suitable config found */ | ||
304 | } | ||
305 | io_base = link->io.BasePort1; | ||
306 | ctl_base = stk->ctl_base; | ||
307 | |||
308 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); | ||
309 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); | ||
310 | |||
311 | /* disable drive interrupts during IDE probe */ | ||
312 | outb(0x02, ctl_base); | ||
313 | |||
314 | /* special setup for KXLC005 card */ | ||
315 | if (is_kme) | ||
316 | outb(0x81, ctl_base+1); | ||
317 | |||
318 | host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); | ||
319 | if (host == NULL && link->io.NumPorts1 == 0x20) { | ||
320 | outb(0x02, ctl_base + 0x10); | ||
321 | host = idecs_register(io_base + 0x10, ctl_base + 0x10, | ||
322 | link->irq.AssignedIRQ, link); | ||
323 | } | ||
324 | |||
325 | if (host == NULL) | ||
326 | goto failed; | ||
327 | |||
328 | info->ndev = 1; | ||
329 | sprintf(info->node.dev_name, "hd%c", 'a' + host->ports[0]->index * 2); | ||
330 | info->node.major = host->ports[0]->major; | ||
331 | info->node.minor = 0; | ||
332 | info->host = host; | ||
333 | link->dev_node = &info->node; | ||
334 | printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n", | ||
335 | info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10); | ||
336 | |||
337 | kfree(stk); | ||
338 | return 0; | ||
339 | |||
340 | err_mem: | ||
341 | printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n"); | ||
342 | goto failed; | ||
343 | |||
344 | cs_failed: | ||
345 | cs_error(link, last_fn, last_ret); | ||
346 | failed: | ||
347 | kfree(stk); | ||
348 | ide_release(link); | ||
349 | return -ENODEV; | ||
350 | } /* ide_config */ | ||
351 | |||
352 | /*====================================================================== | ||
353 | |||
354 | After a card is removed, ide_release() will unregister the net | ||
355 | device, and release the PCMCIA configuration. If the device is | ||
356 | still open, this will be postponed until it is closed. | ||
357 | |||
358 | ======================================================================*/ | ||
359 | |||
360 | static void ide_release(struct pcmcia_device *link) | ||
361 | { | ||
362 | ide_info_t *info = link->priv; | ||
363 | struct ide_host *host = info->host; | ||
364 | |||
365 | DEBUG(0, "ide_release(0x%p)\n", link); | ||
366 | |||
367 | if (info->ndev) | ||
368 | /* FIXME: if this fails we need to queue the cleanup somehow | ||
369 | -- need to investigate the required PCMCIA magic */ | ||
370 | ide_host_remove(host); | ||
371 | |||
372 | info->ndev = 0; | ||
373 | |||
374 | pcmcia_disable_device(link); | ||
375 | } /* ide_release */ | ||
376 | |||
377 | |||
378 | /*====================================================================== | ||
379 | |||
380 | The card status event handler. Mostly, this schedules other | ||
381 | stuff to run after an event is received. A CARD_REMOVAL event | ||
382 | also sets some flags to discourage the ide drivers from | ||
383 | talking to the ports. | ||
384 | |||
385 | ======================================================================*/ | ||
386 | |||
387 | static struct pcmcia_device_id ide_ids[] = { | ||
388 | PCMCIA_DEVICE_FUNC_ID(4), | ||
389 | PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */ | ||
390 | PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */ | ||
391 | PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */ | ||
392 | PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */ | ||
393 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), | ||
394 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), | ||
395 | PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ | ||
396 | PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */ | ||
397 | PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ | ||
398 | PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ | ||
399 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), | ||
400 | PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ | ||
401 | PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */ | ||
402 | PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), | ||
403 | PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100), /* Viking CFA */ | ||
404 | PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar, Viking CFA */ | ||
405 | PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), | ||
406 | PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74), | ||
407 | PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), | ||
408 | PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591), | ||
409 | PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728), | ||
410 | PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), | ||
411 | PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), | ||
412 | PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), | ||
413 | PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf), | ||
414 | PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), | ||
415 | PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), | ||
416 | PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), | ||
417 | PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), | ||
418 | PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), | ||
419 | PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420), | ||
420 | PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178), | ||
421 | PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), | ||
422 | PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e), | ||
423 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), | ||
424 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), | ||
425 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), | ||
426 | PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), | ||
427 | PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee), | ||
428 | PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c), | ||
429 | PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), | ||
430 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), | ||
431 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), | ||
432 | PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), | ||
433 | PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883), | ||
434 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d), | ||
435 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), | ||
436 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), | ||
437 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), | ||
438 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32), | ||
439 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), | ||
440 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2), | ||
441 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), | ||
442 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), | ||
443 | PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), | ||
444 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | ||
445 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | ||
446 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), | ||
447 | PCMCIA_DEVICE_NULL, | ||
448 | }; | ||
449 | MODULE_DEVICE_TABLE(pcmcia, ide_ids); | ||
450 | |||
451 | static struct pcmcia_driver ide_cs_driver = { | ||
452 | .owner = THIS_MODULE, | ||
453 | .drv = { | ||
454 | .name = "ide-cs", | ||
455 | }, | ||
456 | .probe = ide_probe, | ||
457 | .remove = ide_detach, | ||
458 | .id_table = ide_ids, | ||
459 | }; | ||
460 | |||
461 | static int __init init_ide_cs(void) | ||
462 | { | ||
463 | return pcmcia_register_driver(&ide_cs_driver); | ||
464 | } | ||
465 | |||
466 | static void __exit exit_ide_cs(void) | ||
467 | { | ||
468 | pcmcia_unregister_driver(&ide_cs_driver); | ||
469 | } | ||
470 | |||
471 | late_initcall(init_ide_cs); | ||
472 | module_exit(exit_ide_cs); | ||
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c deleted file mode 100644 index 051b4ab0f359..000000000000 --- a/drivers/ide/legacy/ide_platform.c +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
1 | /* | ||
2 | * Platform IDE driver | ||
3 | * | ||
4 | * Copyright (C) 2007 MontaVista Software | ||
5 | * | ||
6 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/ide.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/ata_platform.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/io.h> | ||
23 | |||
24 | static void __devinit plat_ide_setup_ports(hw_regs_t *hw, | ||
25 | void __iomem *base, | ||
26 | void __iomem *ctrl, | ||
27 | struct pata_platform_info *pdata, | ||
28 | int irq) | ||
29 | { | ||
30 | unsigned long port = (unsigned long)base; | ||
31 | int i; | ||
32 | |||
33 | hw->io_ports.data_addr = port; | ||
34 | |||
35 | port += (1 << pdata->ioport_shift); | ||
36 | for (i = 1; i <= 7; | ||
37 | i++, port += (1 << pdata->ioport_shift)) | ||
38 | hw->io_ports_array[i] = port; | ||
39 | |||
40 | hw->io_ports.ctl_addr = (unsigned long)ctrl; | ||
41 | |||
42 | hw->irq = irq; | ||
43 | |||
44 | hw->chipset = ide_generic; | ||
45 | } | ||
46 | |||
47 | static const struct ide_port_info platform_ide_port_info = { | ||
48 | .host_flags = IDE_HFLAG_NO_DMA, | ||
49 | }; | ||
50 | |||
51 | static int __devinit plat_ide_probe(struct platform_device *pdev) | ||
52 | { | ||
53 | struct resource *res_base, *res_alt, *res_irq; | ||
54 | void __iomem *base, *alt_base; | ||
55 | struct pata_platform_info *pdata; | ||
56 | struct ide_host *host; | ||
57 | int ret = 0, mmio = 0; | ||
58 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | ||
59 | struct ide_port_info d = platform_ide_port_info; | ||
60 | |||
61 | pdata = pdev->dev.platform_data; | ||
62 | |||
63 | /* get a pointer to the register memory */ | ||
64 | res_base = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
65 | res_alt = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
66 | |||
67 | if (!res_base || !res_alt) { | ||
68 | res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
69 | res_alt = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
70 | if (!res_base || !res_alt) { | ||
71 | ret = -ENOMEM; | ||
72 | goto out; | ||
73 | } | ||
74 | mmio = 1; | ||
75 | } | ||
76 | |||
77 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
78 | if (!res_irq) { | ||
79 | ret = -EINVAL; | ||
80 | goto out; | ||
81 | } | ||
82 | |||
83 | if (mmio) { | ||
84 | base = devm_ioremap(&pdev->dev, | ||
85 | res_base->start, res_base->end - res_base->start + 1); | ||
86 | alt_base = devm_ioremap(&pdev->dev, | ||
87 | res_alt->start, res_alt->end - res_alt->start + 1); | ||
88 | } else { | ||
89 | base = devm_ioport_map(&pdev->dev, | ||
90 | res_base->start, res_base->end - res_base->start + 1); | ||
91 | alt_base = devm_ioport_map(&pdev->dev, | ||
92 | res_alt->start, res_alt->end - res_alt->start + 1); | ||
93 | } | ||
94 | |||
95 | memset(&hw, 0, sizeof(hw)); | ||
96 | plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start); | ||
97 | hw.dev = &pdev->dev; | ||
98 | |||
99 | if (mmio) | ||
100 | d.host_flags |= IDE_HFLAG_MMIO; | ||
101 | |||
102 | ret = ide_host_add(&d, hws, &host); | ||
103 | if (ret) | ||
104 | goto out; | ||
105 | |||
106 | platform_set_drvdata(pdev, host); | ||
107 | |||
108 | return 0; | ||
109 | |||
110 | out: | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | static int __devexit plat_ide_remove(struct platform_device *pdev) | ||
115 | { | ||
116 | struct ide_host *host = pdev->dev.driver_data; | ||
117 | |||
118 | ide_host_remove(host); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static struct platform_driver platform_ide_driver = { | ||
124 | .driver = { | ||
125 | .name = "pata_platform", | ||
126 | .owner = THIS_MODULE, | ||
127 | }, | ||
128 | .probe = plat_ide_probe, | ||
129 | .remove = __devexit_p(plat_ide_remove), | ||
130 | }; | ||
131 | |||
132 | static int __init platform_ide_init(void) | ||
133 | { | ||
134 | return platform_driver_register(&platform_ide_driver); | ||
135 | } | ||
136 | |||
137 | static void __exit platform_ide_exit(void) | ||
138 | { | ||
139 | platform_driver_unregister(&platform_ide_driver); | ||
140 | } | ||
141 | |||
142 | MODULE_DESCRIPTION("Platform IDE driver"); | ||
143 | MODULE_LICENSE("GPL"); | ||
144 | MODULE_ALIAS("platform:pata_platform"); | ||
145 | |||
146 | module_init(platform_ide_init); | ||
147 | module_exit(platform_ide_exit); | ||
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c deleted file mode 100644 index 43f97cc1d30e..000000000000 --- a/drivers/ide/legacy/macide.c +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * Macintosh IDE Driver | ||
3 | * | ||
4 | * Copyright (C) 1998 by Michael Schmitz | ||
5 | * | ||
6 | * This driver was written based on information obtained from the MacOS IDE | ||
7 | * driver binary by Mikael Forselius | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file COPYING in the main directory of this archive for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/blkdev.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/ide.h> | ||
20 | |||
21 | #include <asm/machw.h> | ||
22 | #include <asm/macintosh.h> | ||
23 | #include <asm/macints.h> | ||
24 | #include <asm/mac_baboon.h> | ||
25 | |||
26 | #define IDE_BASE 0x50F1A000 /* Base address of IDE controller */ | ||
27 | |||
28 | /* | ||
29 | * Generic IDE registers as offsets from the base | ||
30 | * These match MkLinux so they should be correct. | ||
31 | */ | ||
32 | |||
33 | #define IDE_CONTROL 0x38 /* control/altstatus */ | ||
34 | |||
35 | /* | ||
36 | * Mac-specific registers | ||
37 | */ | ||
38 | |||
39 | /* | ||
40 | * this register is odd; it doesn't seem to do much and it's | ||
41 | * not word-aligned like virtually every other hardware register | ||
42 | * on the Mac... | ||
43 | */ | ||
44 | |||
45 | #define IDE_IFR 0x101 /* (0x101) IDE interrupt flags on Quadra: | ||
46 | * | ||
47 | * Bit 0+1: some interrupt flags | ||
48 | * Bit 2+3: some interrupt enable | ||
49 | * Bit 4: ?? | ||
50 | * Bit 5: IDE interrupt flag (any hwif) | ||
51 | * Bit 6: maybe IDE interrupt enable (any hwif) ?? | ||
52 | * Bit 7: Any interrupt condition | ||
53 | */ | ||
54 | |||
55 | volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR); | ||
56 | |||
57 | int macide_ack_intr(ide_hwif_t* hwif) | ||
58 | { | ||
59 | if (*ide_ifr & 0x20) { | ||
60 | *ide_ifr &= ~0x20; | ||
61 | return 1; | ||
62 | } | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, | ||
67 | int irq, ide_ack_intr_t *ack_intr) | ||
68 | { | ||
69 | int i; | ||
70 | |||
71 | memset(hw, 0, sizeof(*hw)); | ||
72 | |||
73 | for (i = 0; i < 8; i++) | ||
74 | hw->io_ports_array[i] = base + i * 4; | ||
75 | |||
76 | hw->io_ports.ctl_addr = base + IDE_CONTROL; | ||
77 | |||
78 | hw->irq = irq; | ||
79 | hw->ack_intr = ack_intr; | ||
80 | |||
81 | hw->chipset = ide_generic; | ||
82 | } | ||
83 | |||
84 | static const char *mac_ide_name[] = | ||
85 | { "Quadra", "Powerbook", "Powerbook Baboon" }; | ||
86 | |||
87 | /* | ||
88 | * Probe for a Macintosh IDE interface | ||
89 | */ | ||
90 | |||
91 | static int __init macide_init(void) | ||
92 | { | ||
93 | ide_ack_intr_t *ack_intr; | ||
94 | unsigned long base; | ||
95 | int irq; | ||
96 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | ||
97 | |||
98 | if (!MACH_IS_MAC) | ||
99 | return -ENODEV; | ||
100 | |||
101 | switch (macintosh_config->ide_type) { | ||
102 | case MAC_IDE_QUADRA: | ||
103 | base = IDE_BASE; | ||
104 | ack_intr = macide_ack_intr; | ||
105 | irq = IRQ_NUBUS_F; | ||
106 | break; | ||
107 | case MAC_IDE_PB: | ||
108 | base = IDE_BASE; | ||
109 | ack_intr = macide_ack_intr; | ||
110 | irq = IRQ_NUBUS_C; | ||
111 | break; | ||
112 | case MAC_IDE_BABOON: | ||
113 | base = BABOON_BASE; | ||
114 | ack_intr = NULL; | ||
115 | irq = IRQ_BABOON_1; | ||
116 | break; | ||
117 | default: | ||
118 | return -ENODEV; | ||
119 | } | ||
120 | |||
121 | printk(KERN_INFO "ide: Macintosh %s IDE controller\n", | ||
122 | mac_ide_name[macintosh_config->ide_type - 1]); | ||
123 | |||
124 | macide_setup_ports(&hw, base, irq, ack_intr); | ||
125 | |||
126 | return ide_host_add(NULL, hws, NULL); | ||
127 | } | ||
128 | |||
129 | module_init(macide_init); | ||
130 | |||
131 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c deleted file mode 100644 index 4af4a8ce4cdf..000000000000 --- a/drivers/ide/legacy/q40ide.c +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | * Q40 I/O port IDE Driver | ||
3 | * | ||
4 | * (c) Richard Zidlicky | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive for | ||
8 | * more details. | ||
9 | * | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/types.h> | ||
14 | #include <linux/mm.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/blkdev.h> | ||
17 | #include <linux/ide.h> | ||
18 | |||
19 | /* | ||
20 | * Bases of the IDE interfaces | ||
21 | */ | ||
22 | |||
23 | #define Q40IDE_NUM_HWIFS 2 | ||
24 | |||
25 | #define PCIDE_BASE1 0x1f0 | ||
26 | #define PCIDE_BASE2 0x170 | ||
27 | #define PCIDE_BASE3 0x1e8 | ||
28 | #define PCIDE_BASE4 0x168 | ||
29 | #define PCIDE_BASE5 0x1e0 | ||
30 | #define PCIDE_BASE6 0x160 | ||
31 | |||
32 | static const unsigned long pcide_bases[Q40IDE_NUM_HWIFS] = { | ||
33 | PCIDE_BASE1, PCIDE_BASE2, /* PCIDE_BASE3, PCIDE_BASE4 , PCIDE_BASE5, | ||
34 | PCIDE_BASE6 */ | ||
35 | }; | ||
36 | |||
37 | static int q40ide_default_irq(unsigned long base) | ||
38 | { | ||
39 | switch (base) { | ||
40 | case 0x1f0: return 14; | ||
41 | case 0x170: return 15; | ||
42 | case 0x1e8: return 11; | ||
43 | default: | ||
44 | return 0; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | |||
49 | /* | ||
50 | * Addresses are pretranslated for Q40 ISA access. | ||
51 | */ | ||
52 | static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, | ||
53 | ide_ack_intr_t *ack_intr, | ||
54 | int irq) | ||
55 | { | ||
56 | memset(hw, 0, sizeof(hw_regs_t)); | ||
57 | /* BIG FAT WARNING: | ||
58 | assumption: only DATA port is ever used in 16 bit mode */ | ||
59 | hw->io_ports.data_addr = Q40_ISA_IO_W(base); | ||
60 | hw->io_ports.error_addr = Q40_ISA_IO_B(base + 1); | ||
61 | hw->io_ports.nsect_addr = Q40_ISA_IO_B(base + 2); | ||
62 | hw->io_ports.lbal_addr = Q40_ISA_IO_B(base + 3); | ||
63 | hw->io_ports.lbam_addr = Q40_ISA_IO_B(base + 4); | ||
64 | hw->io_ports.lbah_addr = Q40_ISA_IO_B(base + 5); | ||
65 | hw->io_ports.device_addr = Q40_ISA_IO_B(base + 6); | ||
66 | hw->io_ports.status_addr = Q40_ISA_IO_B(base + 7); | ||
67 | hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206); | ||
68 | |||
69 | hw->irq = irq; | ||
70 | hw->ack_intr = ack_intr; | ||
71 | |||
72 | hw->chipset = ide_generic; | ||
73 | } | ||
74 | |||
75 | static void q40ide_input_data(ide_drive_t *drive, struct request *rq, | ||
76 | void *buf, unsigned int len) | ||
77 | { | ||
78 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
79 | |||
80 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
81 | return insw(data_addr, buf, (len + 1) / 2); | ||
82 | |||
83 | insw_swapw(data_addr, buf, (len + 1) / 2); | ||
84 | } | ||
85 | |||
86 | static void q40ide_output_data(ide_drive_t *drive, struct request *rq, | ||
87 | void *buf, unsigned int len) | ||
88 | { | ||
89 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
90 | |||
91 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
92 | return outsw(data_addr, buf, (len + 1) / 2); | ||
93 | |||
94 | outsw_swapw(data_addr, buf, (len + 1) / 2); | ||
95 | } | ||
96 | |||
97 | /* Q40 has a byte-swapped IDE interface */ | ||
98 | static const struct ide_tp_ops q40ide_tp_ops = { | ||
99 | .exec_command = ide_exec_command, | ||
100 | .read_status = ide_read_status, | ||
101 | .read_altstatus = ide_read_altstatus, | ||
102 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
103 | |||
104 | .set_irq = ide_set_irq, | ||
105 | |||
106 | .tf_load = ide_tf_load, | ||
107 | .tf_read = ide_tf_read, | ||
108 | |||
109 | .input_data = q40ide_input_data, | ||
110 | .output_data = q40ide_output_data, | ||
111 | }; | ||
112 | |||
113 | static const struct ide_port_info q40ide_port_info = { | ||
114 | .tp_ops = &q40ide_tp_ops, | ||
115 | .host_flags = IDE_HFLAG_NO_DMA, | ||
116 | }; | ||
117 | |||
118 | /* | ||
119 | * the static array is needed to have the name reported in /proc/ioports, | ||
120 | * hwif->name unfortunately isn't available yet | ||
121 | */ | ||
122 | static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={ | ||
123 | "ide0", "ide1" | ||
124 | }; | ||
125 | |||
126 | /* | ||
127 | * Probe for Q40 IDE interfaces | ||
128 | */ | ||
129 | |||
130 | static int __init q40ide_init(void) | ||
131 | { | ||
132 | int i; | ||
133 | hw_regs_t hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL }; | ||
134 | |||
135 | if (!MACH_IS_Q40) | ||
136 | return -ENODEV; | ||
137 | |||
138 | printk(KERN_INFO "ide: Q40 IDE controller\n"); | ||
139 | |||
140 | for (i = 0; i < Q40IDE_NUM_HWIFS; i++) { | ||
141 | const char *name = q40_ide_names[i]; | ||
142 | |||
143 | if (!request_region(pcide_bases[i], 8, name)) { | ||
144 | printk("could not reserve ports %lx-%lx for %s\n", | ||
145 | pcide_bases[i],pcide_bases[i]+8,name); | ||
146 | continue; | ||
147 | } | ||
148 | if (!request_region(pcide_bases[i]+0x206, 1, name)) { | ||
149 | printk("could not reserve port %lx for %s\n", | ||
150 | pcide_bases[i]+0x206,name); | ||
151 | release_region(pcide_bases[i], 8); | ||
152 | continue; | ||
153 | } | ||
154 | q40_ide_setup_ports(&hw[i], pcide_bases[i], NULL, | ||
155 | q40ide_default_irq(pcide_bases[i])); | ||
156 | |||
157 | hws[i] = &hw[i]; | ||
158 | } | ||
159 | |||
160 | return ide_host_add(&q40ide_port_info, hws, NULL); | ||
161 | } | ||
162 | |||
163 | module_init(q40ide_init); | ||
164 | |||
165 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c deleted file mode 100644 index bc27c7aba936..000000000000 --- a/drivers/ide/legacy/qd65xx.c +++ /dev/null | |||
@@ -1,429 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996-2001 Linus Torvalds & author (see below) | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * Version 0.03 Cleaned auto-tune, added probe | ||
7 | * Version 0.04 Added second channel tuning | ||
8 | * Version 0.05 Enhanced tuning ; added qd6500 support | ||
9 | * Version 0.06 Added dos driver's list | ||
10 | * Version 0.07 Second channel bug fix | ||
11 | * | ||
12 | * QDI QD6500/QD6580 EIDE controller fast support | ||
13 | * | ||
14 | * To activate controller support, use "ide0=qd65xx" | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by | ||
19 | * Samuel Thibault <samuel.thibault@fnac.net> | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/timer.h> | ||
27 | #include <linux/mm.h> | ||
28 | #include <linux/ioport.h> | ||
29 | #include <linux/blkdev.h> | ||
30 | #include <linux/ide.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <asm/system.h> | ||
33 | #include <asm/io.h> | ||
34 | |||
35 | #define DRV_NAME "qd65xx" | ||
36 | |||
37 | #include "qd65xx.h" | ||
38 | |||
39 | /* | ||
40 | * I/O ports are 0x30-0x31 (and 0x32-0x33 for qd6580) | ||
41 | * or 0xb0-0xb1 (and 0xb2-0xb3 for qd6580) | ||
42 | * -- qd6500 is a single IDE interface | ||
43 | * -- qd6580 is a dual IDE interface | ||
44 | * | ||
45 | * More research on qd6580 being done by willmore@cig.mot.com (David) | ||
46 | * More Information given by Petr Soucek (petr@ryston.cz) | ||
47 | * http://www.ryston.cz/petr/vlb | ||
48 | */ | ||
49 | |||
50 | /* | ||
51 | * base: Timer1 | ||
52 | * | ||
53 | * | ||
54 | * base+0x01: Config (R/O) | ||
55 | * | ||
56 | * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170 (only useful for qd6500) | ||
57 | * bit 1: qd65xx baseport: 1 = 0xb0 ; 0 = 0x30 | ||
58 | * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz | ||
59 | * bit 3: qd6500: 1 = disabled, 0 = enabled | ||
60 | * qd6580: 1 | ||
61 | * upper nibble: | ||
62 | * qd6500: 1100 | ||
63 | * qd6580: either 1010 or 0101 | ||
64 | * | ||
65 | * | ||
66 | * base+0x02: Timer2 (qd6580 only) | ||
67 | * | ||
68 | * | ||
69 | * base+0x03: Control (qd6580 only) | ||
70 | * | ||
71 | * bits 0-3 must always be set 1 | ||
72 | * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock | ||
73 | * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb | ||
74 | * 0 = Primary and Secondary ports enabled : channel 0 for hda & hdb | ||
75 | * channel 1 for hdc & hdd | ||
76 | * bit 1 : 1 = only disks on primary port | ||
77 | * 0 = disks & ATAPI devices on primary port | ||
78 | * bit 2-4 : always 0 | ||
79 | * bit 5 : status, but of what ? | ||
80 | * bit 6 : always set 1 by dos driver | ||
81 | * bit 7 : set 1 for non-ATAPI devices on primary port | ||
82 | * (maybe read-ahead and post-write buffer ?) | ||
83 | */ | ||
84 | |||
85 | static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ | ||
86 | |||
87 | /* | ||
88 | * qd65xx_select: | ||
89 | * | ||
90 | * This routine is invoked to prepare for access to a given drive. | ||
91 | */ | ||
92 | |||
93 | static void qd65xx_select(ide_drive_t *drive) | ||
94 | { | ||
95 | u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | | ||
96 | (QD_TIMREG(drive) & 0x02); | ||
97 | |||
98 | if (timings[index] != QD_TIMING(drive)) | ||
99 | outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive)); | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * qd6500_compute_timing | ||
104 | * | ||
105 | * computes the timing value where | ||
106 | * lower nibble represents active time, in count of VLB clocks | ||
107 | * upper nibble represents recovery time, in count of VLB clocks | ||
108 | */ | ||
109 | |||
110 | static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time) | ||
111 | { | ||
112 | int clk = ide_vlb_clk ? ide_vlb_clk : 50; | ||
113 | u8 act_cyc, rec_cyc; | ||
114 | |||
115 | if (clk <= 33) { | ||
116 | act_cyc = 9 - IDE_IN(active_time * clk / 1000 + 1, 2, 9); | ||
117 | rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 0, 15); | ||
118 | } else { | ||
119 | act_cyc = 8 - IDE_IN(active_time * clk / 1000 + 1, 1, 8); | ||
120 | rec_cyc = 18 - IDE_IN(recovery_time * clk / 1000 + 1, 3, 18); | ||
121 | } | ||
122 | |||
123 | return (rec_cyc << 4) | 0x08 | act_cyc; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * qd6580_compute_timing | ||
128 | * | ||
129 | * idem for qd6580 | ||
130 | */ | ||
131 | |||
132 | static u8 qd6580_compute_timing (int active_time, int recovery_time) | ||
133 | { | ||
134 | int clk = ide_vlb_clk ? ide_vlb_clk : 50; | ||
135 | u8 act_cyc, rec_cyc; | ||
136 | |||
137 | act_cyc = 17 - IDE_IN(active_time * clk / 1000 + 1, 2, 17); | ||
138 | rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 2, 15); | ||
139 | |||
140 | return (rec_cyc << 4) | act_cyc; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * qd_find_disk_type | ||
145 | * | ||
146 | * tries to find timing from dos driver's table | ||
147 | */ | ||
148 | |||
149 | static int qd_find_disk_type (ide_drive_t *drive, | ||
150 | int *active_time, int *recovery_time) | ||
151 | { | ||
152 | struct qd65xx_timing_s *p; | ||
153 | char *m = (char *)&drive->id[ATA_ID_PROD]; | ||
154 | char model[ATA_ID_PROD_LEN]; | ||
155 | |||
156 | if (*m == 0) | ||
157 | return 0; | ||
158 | |||
159 | strncpy(model, m, ATA_ID_PROD_LEN); | ||
160 | ide_fixstring(model, ATA_ID_PROD_LEN, 1); /* byte-swap */ | ||
161 | |||
162 | for (p = qd65xx_timing ; p->offset != -1 ; p++) { | ||
163 | if (!strncmp(p->model, model+p->offset, 4)) { | ||
164 | printk(KERN_DEBUG "%s: listed !\n", drive->name); | ||
165 | *active_time = p->active; | ||
166 | *recovery_time = p->recovery; | ||
167 | return 1; | ||
168 | } | ||
169 | } | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * qd_set_timing: | ||
175 | * | ||
176 | * records the timing | ||
177 | */ | ||
178 | |||
179 | static void qd_set_timing (ide_drive_t *drive, u8 timing) | ||
180 | { | ||
181 | drive->drive_data &= 0xff00; | ||
182 | drive->drive_data |= timing; | ||
183 | |||
184 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); | ||
185 | } | ||
186 | |||
187 | static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
188 | { | ||
189 | u16 *id = drive->id; | ||
190 | int active_time = 175; | ||
191 | int recovery_time = 415; /* worst case values from the dos driver */ | ||
192 | |||
193 | /* | ||
194 | * FIXME: use "pio" value | ||
195 | */ | ||
196 | if (!qd_find_disk_type(drive, &active_time, &recovery_time) && | ||
197 | (id[ATA_ID_OLD_PIO_MODES] & 0xff) && (id[ATA_ID_FIELD_VALID] & 2) && | ||
198 | id[ATA_ID_EIDE_PIO] >= 240) { | ||
199 | printk(KERN_INFO "%s: PIO mode%d\n", drive->name, | ||
200 | id[ATA_ID_OLD_PIO_MODES] & 0xff); | ||
201 | active_time = 110; | ||
202 | recovery_time = drive->id[ATA_ID_EIDE_PIO] - 120; | ||
203 | } | ||
204 | |||
205 | qd_set_timing(drive, qd6500_compute_timing(HWIF(drive), active_time, recovery_time)); | ||
206 | } | ||
207 | |||
208 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
209 | { | ||
210 | ide_hwif_t *hwif = drive->hwif; | ||
211 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
212 | unsigned int cycle_time; | ||
213 | int active_time = 175; | ||
214 | int recovery_time = 415; /* worst case values from the dos driver */ | ||
215 | u8 base = (hwif->config_data & 0xff00) >> 8; | ||
216 | |||
217 | if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { | ||
218 | cycle_time = ide_pio_cycle_time(drive, pio); | ||
219 | |||
220 | switch (pio) { | ||
221 | case 0: break; | ||
222 | case 3: | ||
223 | if (cycle_time >= 110) { | ||
224 | active_time = 86; | ||
225 | recovery_time = cycle_time - 102; | ||
226 | } else | ||
227 | printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name); | ||
228 | break; | ||
229 | case 4: | ||
230 | if (cycle_time >= 69) { | ||
231 | active_time = 70; | ||
232 | recovery_time = cycle_time - 61; | ||
233 | } else | ||
234 | printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name); | ||
235 | break; | ||
236 | default: | ||
237 | if (cycle_time >= 180) { | ||
238 | active_time = 110; | ||
239 | recovery_time = cycle_time - 120; | ||
240 | } else { | ||
241 | active_time = t->active; | ||
242 | recovery_time = cycle_time - active_time; | ||
243 | } | ||
244 | } | ||
245 | printk(KERN_INFO "%s: PIO mode%d\n", drive->name,pio); | ||
246 | } | ||
247 | |||
248 | if (!HWIF(drive)->channel && drive->media != ide_disk) { | ||
249 | outb(0x5f, QD_CONTROL_PORT); | ||
250 | printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO " | ||
251 | "and post-write buffer on %s.\n", | ||
252 | drive->name, HWIF(drive)->name); | ||
253 | } | ||
254 | |||
255 | qd_set_timing(drive, qd6580_compute_timing(active_time, recovery_time)); | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * qd_testreg | ||
260 | * | ||
261 | * tests if the given port is a register | ||
262 | */ | ||
263 | |||
264 | static int __init qd_testreg(int port) | ||
265 | { | ||
266 | unsigned long flags; | ||
267 | u8 savereg, readreg; | ||
268 | |||
269 | local_irq_save(flags); | ||
270 | savereg = inb_p(port); | ||
271 | outb_p(QD_TESTVAL, port); /* safe value */ | ||
272 | readreg = inb_p(port); | ||
273 | outb(savereg, port); | ||
274 | local_irq_restore(flags); | ||
275 | |||
276 | if (savereg == QD_TESTVAL) { | ||
277 | printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n"); | ||
278 | printk(KERN_ERR "Please contact maintainers to tell about your hardware\n"); | ||
279 | printk(KERN_ERR "Assuming qd65xx is not present.\n"); | ||
280 | return 1; | ||
281 | } | ||
282 | |||
283 | return (readreg != QD_TESTVAL); | ||
284 | } | ||
285 | |||
286 | static void __init qd6500_init_dev(ide_drive_t *drive) | ||
287 | { | ||
288 | ide_hwif_t *hwif = drive->hwif; | ||
289 | u8 base = (hwif->config_data & 0xff00) >> 8; | ||
290 | u8 config = QD_CONFIG(hwif); | ||
291 | |||
292 | drive->drive_data = QD6500_DEF_DATA; | ||
293 | } | ||
294 | |||
295 | static void __init qd6580_init_dev(ide_drive_t *drive) | ||
296 | { | ||
297 | ide_hwif_t *hwif = drive->hwif; | ||
298 | u16 t1, t2; | ||
299 | u8 base = (hwif->config_data & 0xff00) >> 8; | ||
300 | u8 config = QD_CONFIG(hwif); | ||
301 | |||
302 | if (hwif->host_flags & IDE_HFLAG_SINGLE) { | ||
303 | t1 = QD6580_DEF_DATA; | ||
304 | t2 = QD6580_DEF_DATA2; | ||
305 | } else | ||
306 | t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; | ||
307 | |||
308 | drive->drive_data = (drive->dn & 1) ? t2 : t1; | ||
309 | } | ||
310 | |||
311 | static const struct ide_port_ops qd6500_port_ops = { | ||
312 | .init_dev = qd6500_init_dev, | ||
313 | .set_pio_mode = qd6500_set_pio_mode, | ||
314 | .selectproc = qd65xx_select, | ||
315 | }; | ||
316 | |||
317 | static const struct ide_port_ops qd6580_port_ops = { | ||
318 | .init_dev = qd6580_init_dev, | ||
319 | .set_pio_mode = qd6580_set_pio_mode, | ||
320 | .selectproc = qd65xx_select, | ||
321 | }; | ||
322 | |||
323 | static const struct ide_port_info qd65xx_port_info __initdata = { | ||
324 | .name = DRV_NAME, | ||
325 | .chipset = ide_qd65xx, | ||
326 | .host_flags = IDE_HFLAG_IO_32BIT | | ||
327 | IDE_HFLAG_NO_DMA, | ||
328 | .pio_mask = ATA_PIO4, | ||
329 | }; | ||
330 | |||
331 | /* | ||
332 | * qd_probe: | ||
333 | * | ||
334 | * looks at the specified baseport, and if qd found, registers & initialises it | ||
335 | * return 1 if another qd may be probed | ||
336 | */ | ||
337 | |||
338 | static int __init qd_probe(int base) | ||
339 | { | ||
340 | int rc; | ||
341 | u8 config, unit, control; | ||
342 | struct ide_port_info d = qd65xx_port_info; | ||
343 | |||
344 | config = inb(QD_CONFIG_PORT); | ||
345 | |||
346 | if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) | ||
347 | return -ENODEV; | ||
348 | |||
349 | unit = ! (config & QD_CONFIG_IDE_BASEPORT); | ||
350 | |||
351 | if (unit) | ||
352 | d.host_flags |= IDE_HFLAG_QD_2ND_PORT; | ||
353 | |||
354 | switch (config & 0xf0) { | ||
355 | case QD_CONFIG_QD6500: | ||
356 | if (qd_testreg(base)) | ||
357 | return -ENODEV; /* bad register */ | ||
358 | |||
359 | if (config & QD_CONFIG_DISABLED) { | ||
360 | printk(KERN_WARNING "qd6500 is disabled !\n"); | ||
361 | return -ENODEV; | ||
362 | } | ||
363 | |||
364 | printk(KERN_NOTICE "qd6500 at %#x\n", base); | ||
365 | printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n", | ||
366 | config, QD_ID3); | ||
367 | |||
368 | d.port_ops = &qd6500_port_ops; | ||
369 | d.host_flags |= IDE_HFLAG_SINGLE; | ||
370 | break; | ||
371 | case QD_CONFIG_QD6580_A: | ||
372 | case QD_CONFIG_QD6580_B: | ||
373 | if (qd_testreg(base) || qd_testreg(base + 0x02)) | ||
374 | return -ENODEV; /* bad registers */ | ||
375 | |||
376 | control = inb(QD_CONTROL_PORT); | ||
377 | |||
378 | printk(KERN_NOTICE "qd6580 at %#x\n", base); | ||
379 | printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n", | ||
380 | config, control, QD_ID3); | ||
381 | |||
382 | outb(QD_DEF_CONTR, QD_CONTROL_PORT); | ||
383 | |||
384 | d.port_ops = &qd6580_port_ops; | ||
385 | if (control & QD_CONTR_SEC_DISABLED) | ||
386 | d.host_flags |= IDE_HFLAG_SINGLE; | ||
387 | |||
388 | printk(KERN_INFO "qd6580: %s IDE board\n", | ||
389 | (control & QD_CONTR_SEC_DISABLED) ? "single" : "dual"); | ||
390 | break; | ||
391 | default: | ||
392 | return -ENODEV; | ||
393 | } | ||
394 | |||
395 | rc = ide_legacy_device_add(&d, (base << 8) | config); | ||
396 | |||
397 | if (d.host_flags & IDE_HFLAG_SINGLE) | ||
398 | return (rc == 0) ? 1 : rc; | ||
399 | |||
400 | return rc; | ||
401 | } | ||
402 | |||
403 | static int probe_qd65xx; | ||
404 | |||
405 | module_param_named(probe, probe_qd65xx, bool, 0); | ||
406 | MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); | ||
407 | |||
408 | static int __init qd65xx_init(void) | ||
409 | { | ||
410 | int rc1, rc2 = -ENODEV; | ||
411 | |||
412 | if (probe_qd65xx == 0) | ||
413 | return -ENODEV; | ||
414 | |||
415 | rc1 = qd_probe(0x30); | ||
416 | if (rc1) | ||
417 | rc2 = qd_probe(0xb0); | ||
418 | |||
419 | if (rc1 < 0 && rc2 < 0) | ||
420 | return -ENODEV; | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | module_init(qd65xx_init); | ||
426 | |||
427 | MODULE_AUTHOR("Samuel Thibault"); | ||
428 | MODULE_DESCRIPTION("support of qd65xx vlb ide chipset"); | ||
429 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/legacy/qd65xx.h deleted file mode 100644 index c83dea85e621..000000000000 --- a/drivers/ide/legacy/qd65xx.h +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Linus Torvalds & authors | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * Authors: Petr Soucek <petr@ryston.cz> | ||
7 | * Samuel Thibault <samuel.thibault@fnac.net> | ||
8 | */ | ||
9 | |||
10 | /* truncates a in [b,c] */ | ||
11 | #define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) ) | ||
12 | |||
13 | #define IDE_IMPLY(a,b) ((!(a)) || (b)) | ||
14 | |||
15 | #define QD_TIM1_PORT (base) | ||
16 | #define QD_CONFIG_PORT (base+0x01) | ||
17 | #define QD_TIM2_PORT (base+0x02) | ||
18 | #define QD_CONTROL_PORT (base+0x03) | ||
19 | |||
20 | #define QD_CONFIG_IDE_BASEPORT 0x01 | ||
21 | #define QD_CONFIG_BASEPORT 0x02 | ||
22 | #define QD_CONFIG_ID3 0x04 | ||
23 | #define QD_CONFIG_DISABLED 0x08 | ||
24 | #define QD_CONFIG_QD6500 0xc0 | ||
25 | #define QD_CONFIG_QD6580_A 0xa0 | ||
26 | #define QD_CONFIG_QD6580_B 0x50 | ||
27 | |||
28 | #define QD_CONTR_SEC_DISABLED 0x01 | ||
29 | |||
30 | #define QD_ID3 ((config & QD_CONFIG_ID3)!=0) | ||
31 | |||
32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) | ||
33 | |||
34 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) | ||
35 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) | ||
36 | |||
37 | #define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08)) | ||
38 | #define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) | ||
39 | #define QD6580_DEF_DATA2 ((QD_TIM2_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) | ||
40 | #define QD_DEF_CONTR (0x40 | ((control & 0x02) ? 0x9f : 0x1f)) | ||
41 | |||
42 | #define QD_TESTVAL 0x19 /* safe value */ | ||
43 | |||
44 | /* Drive specific timing taken from DOS driver v3.7 */ | ||
45 | |||
46 | static struct qd65xx_timing_s { | ||
47 | s8 offset; /* ofset from the beginning of Model Number" */ | ||
48 | char model[4]; /* 4 chars from Model number, no conversion */ | ||
49 | s16 active; /* active time */ | ||
50 | s16 recovery; /* recovery time */ | ||
51 | } qd65xx_timing [] = { | ||
52 | { 30, "2040", 110, 225 }, /* Conner CP30204 */ | ||
53 | { 30, "2045", 135, 225 }, /* Conner CP30254 */ | ||
54 | { 30, "1040", 155, 325 }, /* Conner CP30104 */ | ||
55 | { 30, "1047", 135, 265 }, /* Conner CP30174 */ | ||
56 | { 30, "5344", 135, 225 }, /* Conner CP3544 */ | ||
57 | { 30, "01 4", 175, 405 }, /* Conner CP-3104 */ | ||
58 | { 27, "C030", 175, 375 }, /* Conner CP3000 */ | ||
59 | { 8, "PL42", 110, 295 }, /* Quantum LP240 */ | ||
60 | { 8, "PL21", 110, 315 }, /* Quantum LP120 */ | ||
61 | { 8, "PL25", 175, 385 }, /* Quantum LP52 */ | ||
62 | { 4, "PA24", 110, 285 }, /* WD Piranha SP4200 */ | ||
63 | { 6, "2200", 110, 260 }, /* WD Caviar AC2200 */ | ||
64 | { 6, "3204", 110, 235 }, /* WD Caviar AC2340 */ | ||
65 | { 6, "1202", 110, 265 }, /* WD Caviar AC2120 */ | ||
66 | { 0, "DS3-", 135, 315 }, /* Teac SD340 */ | ||
67 | { 8, "KM32", 175, 355 }, /* Toshiba MK234 */ | ||
68 | { 2, "53A1", 175, 355 }, /* Seagate ST351A */ | ||
69 | { 2, "4108", 175, 295 }, /* Seagate ST1480A */ | ||
70 | { 2, "1344", 175, 335 }, /* Seagate ST3144A */ | ||
71 | { 6, "7 12", 110, 225 }, /* Maxtor 7213A */ | ||
72 | { 30, "02F4", 145, 295 }, /* Conner 3204F */ | ||
73 | { 2, "1302", 175, 335 }, /* Seagate ST3120A */ | ||
74 | { 2, "2334", 145, 265 }, /* Seagate ST3243A */ | ||
75 | { 2, "2338", 145, 275 }, /* Seagate ST3283A */ | ||
76 | { 2, "3309", 145, 275 }, /* Seagate ST3390A */ | ||
77 | { 2, "5305", 145, 275 }, /* Seagate ST3550A */ | ||
78 | { 2, "4100", 175, 295 }, /* Seagate ST1400A */ | ||
79 | { 2, "4110", 175, 295 }, /* Seagate ST1401A */ | ||
80 | { 2, "6300", 135, 265 }, /* Seagate ST3600A */ | ||
81 | { 2, "5300", 135, 265 }, /* Seagate ST3500A */ | ||
82 | { 6, "7 31", 135, 225 }, /* Maxtor 7131 AT */ | ||
83 | { 6, "7 43", 115, 265 }, /* Maxtor 7345 AT */ | ||
84 | { 6, "7 42", 110, 255 }, /* Maxtor 7245 AT */ | ||
85 | { 6, "3 04", 135, 265 }, /* Maxtor 340 AT */ | ||
86 | { 6, "61 0", 135, 285 }, /* WD AC160 */ | ||
87 | { 6, "1107", 135, 235 }, /* WD AC1170 */ | ||
88 | { 6, "2101", 110, 220 }, /* WD AC1210 */ | ||
89 | { 6, "4202", 135, 245 }, /* WD AC2420 */ | ||
90 | { 6, "41 0", 175, 355 }, /* WD Caviar 140 */ | ||
91 | { 6, "82 0", 175, 355 }, /* WD Caviar 280 */ | ||
92 | { 8, "PL01", 175, 375 }, /* Quantum LP105 */ | ||
93 | { 8, "PL25", 110, 295 }, /* Quantum LP525 */ | ||
94 | { 10, "4S 2", 175, 385 }, /* Quantum ELS42 */ | ||
95 | { 10, "8S 5", 175, 385 }, /* Quantum ELS85 */ | ||
96 | { 10, "1S72", 175, 385 }, /* Quantum ELS127 */ | ||
97 | { 10, "1S07", 175, 385 }, /* Quantum ELS170 */ | ||
98 | { 8, "ZE42", 135, 295 }, /* Quantum EZ240 */ | ||
99 | { 8, "ZE21", 175, 385 }, /* Quantum EZ127 */ | ||
100 | { 8, "ZE58", 175, 385 }, /* Quantum EZ85 */ | ||
101 | { 8, "ZE24", 175, 385 }, /* Quantum EZ42 */ | ||
102 | { 27, "C036", 155, 325 }, /* Conner CP30064 */ | ||
103 | { 27, "C038", 155, 325 }, /* Conner CP30084 */ | ||
104 | { 6, "2205", 110, 255 }, /* WDC AC2250 */ | ||
105 | { 2, " CHA", 140, 415 }, /* WDC AH series; WDC AH260, WDC */ | ||
106 | { 2, " CLA", 140, 415 }, /* WDC AL series: WDC AL2120, 2170, */ | ||
107 | { 4, "UC41", 140, 415 }, /* WDC CU140 */ | ||
108 | { 6, "1207", 130, 275 }, /* WDC AC2170 */ | ||
109 | { 6, "2107", 130, 275 }, /* WDC AC1270 */ | ||
110 | { 6, "5204", 130, 275 }, /* WDC AC2540 */ | ||
111 | { 30, "3004", 110, 235 }, /* Conner CP30340 */ | ||
112 | { 30, "0345", 135, 255 }, /* Conner CP30544 */ | ||
113 | { 12, "12A3", 175, 320 }, /* MAXTOR LXT-213A */ | ||
114 | { 12, "43A0", 145, 240 }, /* MAXTOR LXT-340A */ | ||
115 | { 6, "7 21", 180, 290 }, /* Maxtor 7120 AT */ | ||
116 | { 6, "7 71", 135, 240 }, /* Maxtor 7170 AT */ | ||
117 | { 12, "45\0000", 110, 205 }, /* MAXTOR MXT-540 */ | ||
118 | { 8, "PL11", 180, 290 }, /* QUANTUM LP110A */ | ||
119 | { 8, "OG21", 150, 275 }, /* QUANTUM GO120 */ | ||
120 | { 12, "42A5", 175, 320 }, /* MAXTOR LXT-245A */ | ||
121 | { 2, "2309", 175, 295 }, /* ST3290A */ | ||
122 | { 2, "3358", 180, 310 }, /* ST3385A */ | ||
123 | { 2, "6355", 180, 310 }, /* ST3655A */ | ||
124 | { 2, "1900", 175, 270 }, /* ST9100A */ | ||
125 | { 2, "1954", 175, 270 }, /* ST9145A */ | ||
126 | { 2, "1909", 175, 270 }, /* ST9190AG */ | ||
127 | { 2, "2953", 175, 270 }, /* ST9235A */ | ||
128 | { 2, "1359", 175, 270 }, /* ST3195A */ | ||
129 | { 24, "3R11", 175, 290 }, /* ALPS ELECTRIC Co.,LTD, DR311C */ | ||
130 | { 0, "2M26", 175, 215 }, /* M262XT-0Ah */ | ||
131 | { 4, "2253", 175, 300 }, /* HP C2235A */ | ||
132 | { 4, "-32A", 145, 245 }, /* H3133-A2 */ | ||
133 | { 30, "0326", 150, 270 }, /* Samsung Electronics 120MB */ | ||
134 | { 30, "3044", 110, 195 }, /* Conner CFA340A */ | ||
135 | { 30, "43A0", 110, 195 }, /* Conner CFA340A */ | ||
136 | { -1, " ", 175, 415 } /* unknown disk name */ | ||
137 | }; | ||
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c deleted file mode 100644 index 1da076e0c917..000000000000 --- a/drivers/ide/legacy/umc8672.c +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1995-1996 Linus Torvalds & author (see below) | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * Principal Author/Maintainer: PODIEN@hml2.atlas.de (Wolfram Podien) | ||
7 | * | ||
8 | * This file provides support for the advanced features | ||
9 | * of the UMC 8672 IDE interface. | ||
10 | * | ||
11 | * Version 0.01 Initial version, hacked out of ide.c, | ||
12 | * and #include'd rather than compiled separately. | ||
13 | * This will get cleaned up in a subsequent release. | ||
14 | * | ||
15 | * Version 0.02 now configs/compiles separate from ide.c -ml | ||
16 | * Version 0.03 enhanced auto-tune, fix display bug | ||
17 | * Version 0.05 replace sti() with restore_flags() -ml | ||
18 | * add detection of possible race condition -ml | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * VLB Controller Support from | ||
23 | * Wolfram Podien | ||
24 | * Rohoefe 3 | ||
25 | * D28832 Achim | ||
26 | * Germany | ||
27 | * | ||
28 | * To enable UMC8672 support there must a lilo line like | ||
29 | * append="ide0=umc8672"... | ||
30 | * To set the speed according to the abilities of the hardware there must be a | ||
31 | * line like | ||
32 | * #define UMC_DRIVE0 11 | ||
33 | * in the beginning of the driver, which sets the speed of drive 0 to 11 (there | ||
34 | * are some lines present). 0 - 11 are allowed speed values. These values are | ||
35 | * the results from the DOS speed test program supplied from UMC. 11 is the | ||
36 | * highest speed (about PIO mode 3) | ||
37 | */ | ||
38 | #define REALLY_SLOW_IO /* some systems can safely undef this */ | ||
39 | |||
40 | #include <linux/module.h> | ||
41 | #include <linux/types.h> | ||
42 | #include <linux/kernel.h> | ||
43 | #include <linux/delay.h> | ||
44 | #include <linux/timer.h> | ||
45 | #include <linux/mm.h> | ||
46 | #include <linux/ioport.h> | ||
47 | #include <linux/blkdev.h> | ||
48 | #include <linux/ide.h> | ||
49 | #include <linux/init.h> | ||
50 | |||
51 | #include <asm/io.h> | ||
52 | |||
53 | #define DRV_NAME "umc8672" | ||
54 | |||
55 | /* | ||
56 | * Default speeds. These can be changed with "auto-tune" and/or hdparm. | ||
57 | */ | ||
58 | #define UMC_DRIVE0 1 /* DOS measured drive speeds */ | ||
59 | #define UMC_DRIVE1 1 /* 0 to 11 allowed */ | ||
60 | #define UMC_DRIVE2 1 /* 11 = Fastest Speed */ | ||
61 | #define UMC_DRIVE3 1 /* In case of crash reduce speed */ | ||
62 | |||
63 | static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; | ||
64 | static const u8 pio_to_umc [5] = {0, 3, 7, 10, 11}; /* rough guesses */ | ||
65 | |||
66 | /* 0 1 2 3 4 5 6 7 8 9 10 11 */ | ||
67 | static const u8 speedtab [3][12] = { | ||
68 | {0x0f, 0x0b, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, | ||
69 | {0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, | ||
70 | {0xff, 0xcb, 0xc0, 0x58, 0x36, 0x33, 0x23, 0x22, 0x21, 0x11, 0x10, 0x0} | ||
71 | }; | ||
72 | |||
73 | static void out_umc(char port, char wert) | ||
74 | { | ||
75 | outb_p(port, 0x108); | ||
76 | outb_p(wert, 0x109); | ||
77 | } | ||
78 | |||
79 | static inline u8 in_umc(char port) | ||
80 | { | ||
81 | outb_p(port, 0x108); | ||
82 | return inb_p(0x109); | ||
83 | } | ||
84 | |||
85 | static void umc_set_speeds(u8 speeds[]) | ||
86 | { | ||
87 | int i, tmp; | ||
88 | |||
89 | outb_p(0x5A, 0x108); /* enable umc */ | ||
90 | |||
91 | out_umc(0xd7, (speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); | ||
92 | out_umc(0xd6, (speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); | ||
93 | tmp = 0; | ||
94 | for (i = 3; i >= 0; i--) | ||
95 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; | ||
96 | out_umc(0xdc, tmp); | ||
97 | for (i = 0; i < 4; i++) { | ||
98 | out_umc(0xd0 + i, speedtab[2][speeds[i]]); | ||
99 | out_umc(0xd8 + i, speedtab[2][speeds[i]]); | ||
100 | } | ||
101 | outb_p(0xa5, 0x108); /* disable umc */ | ||
102 | |||
103 | printk("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", | ||
104 | speeds[0], speeds[1], speeds[2], speeds[3]); | ||
105 | } | ||
106 | |||
107 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
108 | { | ||
109 | ide_hwif_t *hwif = drive->hwif; | ||
110 | unsigned long flags; | ||
111 | |||
112 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", | ||
113 | drive->name, pio, pio_to_umc[pio]); | ||
114 | spin_lock_irqsave(&ide_lock, flags); | ||
115 | if (hwif->mate && hwif->mate->hwgroup->handler) { | ||
116 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); | ||
117 | } else { | ||
118 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; | ||
119 | umc_set_speeds(current_speeds); | ||
120 | } | ||
121 | spin_unlock_irqrestore(&ide_lock, flags); | ||
122 | } | ||
123 | |||
124 | static const struct ide_port_ops umc8672_port_ops = { | ||
125 | .set_pio_mode = umc_set_pio_mode, | ||
126 | }; | ||
127 | |||
128 | static const struct ide_port_info umc8672_port_info __initdata = { | ||
129 | .name = DRV_NAME, | ||
130 | .chipset = ide_umc8672, | ||
131 | .port_ops = &umc8672_port_ops, | ||
132 | .host_flags = IDE_HFLAG_NO_DMA, | ||
133 | .pio_mask = ATA_PIO4, | ||
134 | }; | ||
135 | |||
136 | static int __init umc8672_probe(void) | ||
137 | { | ||
138 | unsigned long flags; | ||
139 | |||
140 | if (!request_region(0x108, 2, "umc8672")) { | ||
141 | printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n"); | ||
142 | return 1; | ||
143 | } | ||
144 | local_irq_save(flags); | ||
145 | outb_p(0x5A, 0x108); /* enable umc */ | ||
146 | if (in_umc (0xd5) != 0xa0) { | ||
147 | local_irq_restore(flags); | ||
148 | printk(KERN_ERR "umc8672: not found\n"); | ||
149 | release_region(0x108, 2); | ||
150 | return 1; | ||
151 | } | ||
152 | outb_p(0xa5, 0x108); /* disable umc */ | ||
153 | |||
154 | umc_set_speeds(current_speeds); | ||
155 | local_irq_restore(flags); | ||
156 | |||
157 | return ide_legacy_device_add(&umc8672_port_info, 0); | ||
158 | } | ||
159 | |||
160 | static int probe_umc8672; | ||
161 | |||
162 | module_param_named(probe, probe_umc8672, bool, 0); | ||
163 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); | ||
164 | |||
165 | static int __init umc8672_init(void) | ||
166 | { | ||
167 | if (probe_umc8672 == 0) | ||
168 | goto out; | ||
169 | |||
170 | if (umc8672_probe() == 0) | ||
171 | return 0;; | ||
172 | out: | ||
173 | return -ENODEV;; | ||
174 | } | ||
175 | |||
176 | module_init(umc8672_init); | ||
177 | |||
178 | MODULE_AUTHOR("Wolfram Podien"); | ||
179 | MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset"); | ||
180 | MODULE_LICENSE("GPL"); | ||