diff options
Diffstat (limited to 'drivers/ide/legacy')
-rw-r--r-- | drivers/ide/legacy/ali14xx.c | 3 | ||||
-rw-r--r-- | drivers/ide/legacy/buddha.c | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/falconide.c | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/gayle.c | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/hd.c | 815 | ||||
-rw-r--r-- | drivers/ide/legacy/ht6560b.c | 15 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-4drives.c | 25 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-cs.c | 9 | ||||
-rw-r--r-- | drivers/ide/legacy/ide_platform.c | 9 | ||||
-rw-r--r-- | drivers/ide/legacy/macide.c | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/q40ide.c | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/qd65xx.c | 19 |
12 files changed, 48 insertions, 852 deletions
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index 052125fafcfa..4ec19737f3c5 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c | |||
@@ -117,10 +117,11 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
117 | u8 param1, param2, param3, param4; | 117 | u8 param1, param2, param3, param4; |
118 | unsigned long flags; | 118 | unsigned long flags; |
119 | int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; | 119 | int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; |
120 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
120 | 121 | ||
121 | /* calculate timing, according to PIO mode */ | 122 | /* calculate timing, according to PIO mode */ |
122 | time1 = ide_pio_cycle_time(drive, pio); | 123 | time1 = ide_pio_cycle_time(drive, pio); |
123 | time2 = ide_pio_timings[pio].active_time; | 124 | time2 = t->active; |
124 | param3 = param1 = (time2 * bus_speed + 999) / 1000; | 125 | param3 = param1 = (time2 * bus_speed + 999) / 1000; |
125 | param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1; | 126 | param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1; |
126 | if (pio < 3) { | 127 | if (pio < 3) { |
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index 9a1d27ef3f8a..0497e7f85b09 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c | |||
@@ -227,7 +227,6 @@ fail_base2: | |||
227 | if (hwif) { | 227 | if (hwif) { |
228 | u8 index = hwif->index; | 228 | u8 index = hwif->index; |
229 | 229 | ||
230 | ide_init_port_data(hwif, index); | ||
231 | ide_init_port_hw(hwif, &hw); | 230 | ide_init_port_hw(hwif, &hw); |
232 | 231 | ||
233 | idx[i] = index; | 232 | idx[i] = index; |
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index af11028b4794..129a812bb57f 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -111,7 +111,6 @@ static int __init falconide_init(void) | |||
111 | u8 index = hwif->index; | 111 | u8 index = hwif->index; |
112 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 112 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
113 | 113 | ||
114 | ide_init_port_data(hwif, index); | ||
115 | ide_init_port_hw(hwif, &hw); | 114 | ide_init_port_hw(hwif, &hw); |
116 | 115 | ||
117 | /* Atari has a byte-swapped IDE interface */ | 116 | /* Atari has a byte-swapped IDE interface */ |
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index b78941680c32..7e74b20202df 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c | |||
@@ -185,7 +185,6 @@ found: | |||
185 | if (hwif) { | 185 | if (hwif) { |
186 | u8 index = hwif->index; | 186 | u8 index = hwif->index; |
187 | 187 | ||
188 | ide_init_port_data(hwif, index); | ||
189 | ide_init_port_hw(hwif, &hw); | 188 | ide_init_port_hw(hwif, &hw); |
190 | 189 | ||
191 | idx[i] = index; | 190 | idx[i] = index; |
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c deleted file mode 100644 index abdedf56643e..000000000000 --- a/drivers/ide/legacy/hd.c +++ /dev/null | |||
@@ -1,815 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
3 | * | ||
4 | * This is the low-level hd interrupt support. It traverses the | ||
5 | * request-list, using interrupts to jump between functions. As | ||
6 | * all the functions are called within interrupts, we may not | ||
7 | * sleep. Special care is recommended. | ||
8 | * | ||
9 | * modified by Drew Eckhardt to check nr of hd's from the CMOS. | ||
10 | * | ||
11 | * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug | ||
12 | * in the early extended-partition checks and added DM partitions | ||
13 | * | ||
14 | * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", | ||
15 | * and general streamlining by Mark Lord. | ||
16 | * | ||
17 | * Removed 99% of above. Use Mark's ide driver for those options. | ||
18 | * This is now a lightweight ST-506 driver. (Paul Gortmaker) | ||
19 | * | ||
20 | * Modified 1995 Russell King for ARM processor. | ||
21 | * | ||
22 | * Bugfix: max_sectors must be <= 255 or the wheels tend to come | ||
23 | * off in a hurry once you queue things up - Paul G. 02/2001 | ||
24 | */ | ||
25 | |||
26 | /* Uncomment the following if you want verbose error reports. */ | ||
27 | /* #define VERBOSE_ERRORS */ | ||
28 | |||
29 | #include <linux/blkdev.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/signal.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/genhd.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/string.h> | ||
39 | #include <linux/ioport.h> | ||
40 | #include <linux/mc146818rtc.h> /* CMOS defines */ | ||
41 | #include <linux/init.h> | ||
42 | #include <linux/blkpg.h> | ||
43 | #include <linux/hdreg.h> | ||
44 | |||
45 | #define REALLY_SLOW_IO | ||
46 | #include <asm/system.h> | ||
47 | #include <asm/io.h> | ||
48 | #include <asm/uaccess.h> | ||
49 | |||
50 | #ifdef __arm__ | ||
51 | #undef HD_IRQ | ||
52 | #endif | ||
53 | #include <asm/irq.h> | ||
54 | #ifdef __arm__ | ||
55 | #define HD_IRQ IRQ_HARDDISK | ||
56 | #endif | ||
57 | |||
58 | /* Hd controller regster ports */ | ||
59 | |||
60 | #define HD_DATA 0x1f0 /* _CTL when writing */ | ||
61 | #define HD_ERROR 0x1f1 /* see err-bits */ | ||
62 | #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ | ||
63 | #define HD_SECTOR 0x1f3 /* starting sector */ | ||
64 | #define HD_LCYL 0x1f4 /* starting cylinder */ | ||
65 | #define HD_HCYL 0x1f5 /* high byte of starting cyl */ | ||
66 | #define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ | ||
67 | #define HD_STATUS 0x1f7 /* see status-bits */ | ||
68 | #define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ | ||
69 | #define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ | ||
70 | #define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ | ||
71 | |||
72 | #define HD_CMD 0x3f6 /* used for resets */ | ||
73 | #define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ | ||
74 | |||
75 | /* Bits of HD_STATUS */ | ||
76 | #define ERR_STAT 0x01 | ||
77 | #define INDEX_STAT 0x02 | ||
78 | #define ECC_STAT 0x04 /* Corrected error */ | ||
79 | #define DRQ_STAT 0x08 | ||
80 | #define SEEK_STAT 0x10 | ||
81 | #define SERVICE_STAT SEEK_STAT | ||
82 | #define WRERR_STAT 0x20 | ||
83 | #define READY_STAT 0x40 | ||
84 | #define BUSY_STAT 0x80 | ||
85 | |||
86 | /* Bits for HD_ERROR */ | ||
87 | #define MARK_ERR 0x01 /* Bad address mark */ | ||
88 | #define TRK0_ERR 0x02 /* couldn't find track 0 */ | ||
89 | #define ABRT_ERR 0x04 /* Command aborted */ | ||
90 | #define MCR_ERR 0x08 /* media change request */ | ||
91 | #define ID_ERR 0x10 /* ID field not found */ | ||
92 | #define MC_ERR 0x20 /* media changed */ | ||
93 | #define ECC_ERR 0x40 /* Uncorrectable ECC error */ | ||
94 | #define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ | ||
95 | #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ | ||
96 | |||
97 | static DEFINE_SPINLOCK(hd_lock); | ||
98 | static struct request_queue *hd_queue; | ||
99 | |||
100 | #define MAJOR_NR HD_MAJOR | ||
101 | #define QUEUE (hd_queue) | ||
102 | #define CURRENT elv_next_request(hd_queue) | ||
103 | |||
104 | #define TIMEOUT_VALUE (6*HZ) | ||
105 | #define HD_DELAY 0 | ||
106 | |||
107 | #define MAX_ERRORS 16 /* Max read/write errors/sector */ | ||
108 | #define RESET_FREQ 8 /* Reset controller every 8th retry */ | ||
109 | #define RECAL_FREQ 4 /* Recalibrate every 4th retry */ | ||
110 | #define MAX_HD 2 | ||
111 | |||
112 | #define STAT_OK (READY_STAT|SEEK_STAT) | ||
113 | #define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK) | ||
114 | |||
115 | static void recal_intr(void); | ||
116 | static void bad_rw_intr(void); | ||
117 | |||
118 | static int reset; | ||
119 | static int hd_error; | ||
120 | |||
121 | /* | ||
122 | * This struct defines the HD's and their types. | ||
123 | */ | ||
124 | struct hd_i_struct { | ||
125 | unsigned int head, sect, cyl, wpcom, lzone, ctl; | ||
126 | int unit; | ||
127 | int recalibrate; | ||
128 | int special_op; | ||
129 | }; | ||
130 | |||
131 | #ifdef HD_TYPE | ||
132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; | ||
133 | static int NR_HD = ARRAY_SIZE(hd_info); | ||
134 | #else | ||
135 | static struct hd_i_struct hd_info[MAX_HD]; | ||
136 | static int NR_HD; | ||
137 | #endif | ||
138 | |||
139 | static struct gendisk *hd_gendisk[MAX_HD]; | ||
140 | |||
141 | static struct timer_list device_timer; | ||
142 | |||
143 | #define TIMEOUT_VALUE (6*HZ) | ||
144 | |||
145 | #define SET_TIMER \ | ||
146 | do { \ | ||
147 | mod_timer(&device_timer, jiffies + TIMEOUT_VALUE); \ | ||
148 | } while (0) | ||
149 | |||
150 | static void (*do_hd)(void) = NULL; | ||
151 | #define SET_HANDLER(x) \ | ||
152 | if ((do_hd = (x)) != NULL) \ | ||
153 | SET_TIMER; \ | ||
154 | else \ | ||
155 | del_timer(&device_timer); | ||
156 | |||
157 | |||
158 | #if (HD_DELAY > 0) | ||
159 | |||
160 | #include <asm/i8253.h> | ||
161 | |||
162 | unsigned long last_req; | ||
163 | |||
164 | unsigned long read_timer(void) | ||
165 | { | ||
166 | unsigned long t, flags; | ||
167 | int i; | ||
168 | |||
169 | spin_lock_irqsave(&i8253_lock, flags); | ||
170 | t = jiffies * 11932; | ||
171 | outb_p(0, 0x43); | ||
172 | i = inb_p(0x40); | ||
173 | i |= inb(0x40) << 8; | ||
174 | spin_unlock_irqrestore(&i8253_lock, flags); | ||
175 | return(t - i); | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | static void __init hd_setup(char *str, int *ints) | ||
180 | { | ||
181 | int hdind = 0; | ||
182 | |||
183 | if (ints[0] != 3) | ||
184 | return; | ||
185 | if (hd_info[0].head != 0) | ||
186 | hdind = 1; | ||
187 | hd_info[hdind].head = ints[2]; | ||
188 | hd_info[hdind].sect = ints[3]; | ||
189 | hd_info[hdind].cyl = ints[1]; | ||
190 | hd_info[hdind].wpcom = 0; | ||
191 | hd_info[hdind].lzone = ints[1]; | ||
192 | hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0); | ||
193 | NR_HD = hdind+1; | ||
194 | } | ||
195 | |||
196 | static void dump_status(const char *msg, unsigned int stat) | ||
197 | { | ||
198 | char *name = "hd?"; | ||
199 | if (CURRENT) | ||
200 | name = CURRENT->rq_disk->disk_name; | ||
201 | |||
202 | #ifdef VERBOSE_ERRORS | ||
203 | printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff); | ||
204 | if (stat & BUSY_STAT) printk("Busy "); | ||
205 | if (stat & READY_STAT) printk("DriveReady "); | ||
206 | if (stat & WRERR_STAT) printk("WriteFault "); | ||
207 | if (stat & SEEK_STAT) printk("SeekComplete "); | ||
208 | if (stat & DRQ_STAT) printk("DataRequest "); | ||
209 | if (stat & ECC_STAT) printk("CorrectedError "); | ||
210 | if (stat & INDEX_STAT) printk("Index "); | ||
211 | if (stat & ERR_STAT) printk("Error "); | ||
212 | printk("}\n"); | ||
213 | if ((stat & ERR_STAT) == 0) { | ||
214 | hd_error = 0; | ||
215 | } else { | ||
216 | hd_error = inb(HD_ERROR); | ||
217 | printk("%s: %s: error=0x%02x { ", name, msg, hd_error & 0xff); | ||
218 | if (hd_error & BBD_ERR) printk("BadSector "); | ||
219 | if (hd_error & ECC_ERR) printk("UncorrectableError "); | ||
220 | if (hd_error & ID_ERR) printk("SectorIdNotFound "); | ||
221 | if (hd_error & ABRT_ERR) printk("DriveStatusError "); | ||
222 | if (hd_error & TRK0_ERR) printk("TrackZeroNotFound "); | ||
223 | if (hd_error & MARK_ERR) printk("AddrMarkNotFound "); | ||
224 | printk("}"); | ||
225 | if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) { | ||
226 | printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL), | ||
227 | inb(HD_CURRENT) & 0xf, inb(HD_SECTOR)); | ||
228 | if (CURRENT) | ||
229 | printk(", sector=%ld", CURRENT->sector); | ||
230 | } | ||
231 | printk("\n"); | ||
232 | } | ||
233 | #else | ||
234 | printk("%s: %s: status=0x%02x.\n", name, msg, stat & 0xff); | ||
235 | if ((stat & ERR_STAT) == 0) { | ||
236 | hd_error = 0; | ||
237 | } else { | ||
238 | hd_error = inb(HD_ERROR); | ||
239 | printk("%s: %s: error=0x%02x.\n", name, msg, hd_error & 0xff); | ||
240 | } | ||
241 | #endif | ||
242 | } | ||
243 | |||
244 | static void check_status(void) | ||
245 | { | ||
246 | int i = inb_p(HD_STATUS); | ||
247 | |||
248 | if (!OK_STATUS(i)) { | ||
249 | dump_status("check_status", i); | ||
250 | bad_rw_intr(); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | static int controller_busy(void) | ||
255 | { | ||
256 | int retries = 100000; | ||
257 | unsigned char status; | ||
258 | |||
259 | do { | ||
260 | status = inb_p(HD_STATUS); | ||
261 | } while ((status & BUSY_STAT) && --retries); | ||
262 | return status; | ||
263 | } | ||
264 | |||
265 | static int status_ok(void) | ||
266 | { | ||
267 | unsigned char status = inb_p(HD_STATUS); | ||
268 | |||
269 | if (status & BUSY_STAT) | ||
270 | return 1; /* Ancient, but does it make sense??? */ | ||
271 | if (status & WRERR_STAT) | ||
272 | return 0; | ||
273 | if (!(status & READY_STAT)) | ||
274 | return 0; | ||
275 | if (!(status & SEEK_STAT)) | ||
276 | return 0; | ||
277 | return 1; | ||
278 | } | ||
279 | |||
280 | static int controller_ready(unsigned int drive, unsigned int head) | ||
281 | { | ||
282 | int retry = 100; | ||
283 | |||
284 | do { | ||
285 | if (controller_busy() & BUSY_STAT) | ||
286 | return 0; | ||
287 | outb_p(0xA0 | (drive<<4) | head, HD_CURRENT); | ||
288 | if (status_ok()) | ||
289 | return 1; | ||
290 | } while (--retry); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static void hd_out(struct hd_i_struct *disk, | ||
295 | unsigned int nsect, | ||
296 | unsigned int sect, | ||
297 | unsigned int head, | ||
298 | unsigned int cyl, | ||
299 | unsigned int cmd, | ||
300 | void (*intr_addr)(void)) | ||
301 | { | ||
302 | unsigned short port; | ||
303 | |||
304 | #if (HD_DELAY > 0) | ||
305 | while (read_timer() - last_req < HD_DELAY) | ||
306 | /* nothing */; | ||
307 | #endif | ||
308 | if (reset) | ||
309 | return; | ||
310 | if (!controller_ready(disk->unit, head)) { | ||
311 | reset = 1; | ||
312 | return; | ||
313 | } | ||
314 | SET_HANDLER(intr_addr); | ||
315 | outb_p(disk->ctl, HD_CMD); | ||
316 | port = HD_DATA; | ||
317 | outb_p(disk->wpcom >> 2, ++port); | ||
318 | outb_p(nsect, ++port); | ||
319 | outb_p(sect, ++port); | ||
320 | outb_p(cyl, ++port); | ||
321 | outb_p(cyl >> 8, ++port); | ||
322 | outb_p(0xA0 | (disk->unit << 4) | head, ++port); | ||
323 | outb_p(cmd, ++port); | ||
324 | } | ||
325 | |||
326 | static void hd_request (void); | ||
327 | |||
328 | static int drive_busy(void) | ||
329 | { | ||
330 | unsigned int i; | ||
331 | unsigned char c; | ||
332 | |||
333 | for (i = 0; i < 500000 ; i++) { | ||
334 | c = inb_p(HD_STATUS); | ||
335 | if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK) | ||
336 | return 0; | ||
337 | } | ||
338 | dump_status("reset timed out", c); | ||
339 | return 1; | ||
340 | } | ||
341 | |||
342 | static void reset_controller(void) | ||
343 | { | ||
344 | int i; | ||
345 | |||
346 | outb_p(4, HD_CMD); | ||
347 | for (i = 0; i < 1000; i++) barrier(); | ||
348 | outb_p(hd_info[0].ctl & 0x0f, HD_CMD); | ||
349 | for (i = 0; i < 1000; i++) barrier(); | ||
350 | if (drive_busy()) | ||
351 | printk("hd: controller still busy\n"); | ||
352 | else if ((hd_error = inb(HD_ERROR)) != 1) | ||
353 | printk("hd: controller reset failed: %02x\n", hd_error); | ||
354 | } | ||
355 | |||
356 | static void reset_hd(void) | ||
357 | { | ||
358 | static int i; | ||
359 | |||
360 | repeat: | ||
361 | if (reset) { | ||
362 | reset = 0; | ||
363 | i = -1; | ||
364 | reset_controller(); | ||
365 | } else { | ||
366 | check_status(); | ||
367 | if (reset) | ||
368 | goto repeat; | ||
369 | } | ||
370 | if (++i < NR_HD) { | ||
371 | struct hd_i_struct *disk = &hd_info[i]; | ||
372 | disk->special_op = disk->recalibrate = 1; | ||
373 | hd_out(disk, disk->sect, disk->sect, disk->head-1, | ||
374 | disk->cyl, WIN_SPECIFY, &reset_hd); | ||
375 | if (reset) | ||
376 | goto repeat; | ||
377 | } else | ||
378 | hd_request(); | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Ok, don't know what to do with the unexpected interrupts: on some machines | ||
383 | * doing a reset and a retry seems to result in an eternal loop. Right now I | ||
384 | * ignore it, and just set the timeout. | ||
385 | * | ||
386 | * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the | ||
387 | * drive enters "idle", "standby", or "sleep" mode, so if the status looks | ||
388 | * "good", we just ignore the interrupt completely. | ||
389 | */ | ||
390 | static void unexpected_hd_interrupt(void) | ||
391 | { | ||
392 | unsigned int stat = inb_p(HD_STATUS); | ||
393 | |||
394 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { | ||
395 | dump_status("unexpected interrupt", stat); | ||
396 | SET_TIMER; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * bad_rw_intr() now tries to be a bit smarter and does things | ||
402 | * according to the error returned by the controller. | ||
403 | * -Mika Liljeberg (liljeber@cs.Helsinki.FI) | ||
404 | */ | ||
405 | static void bad_rw_intr(void) | ||
406 | { | ||
407 | struct request *req = CURRENT; | ||
408 | if (req != NULL) { | ||
409 | struct hd_i_struct *disk = req->rq_disk->private_data; | ||
410 | if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { | ||
411 | end_request(req, 0); | ||
412 | disk->special_op = disk->recalibrate = 1; | ||
413 | } else if (req->errors % RESET_FREQ == 0) | ||
414 | reset = 1; | ||
415 | else if ((hd_error & TRK0_ERR) || req->errors % RECAL_FREQ == 0) | ||
416 | disk->special_op = disk->recalibrate = 1; | ||
417 | /* Otherwise just retry */ | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static inline int wait_DRQ(void) | ||
422 | { | ||
423 | int retries; | ||
424 | int stat; | ||
425 | |||
426 | for (retries = 0; retries < 100000; retries++) { | ||
427 | stat = inb_p(HD_STATUS); | ||
428 | if (stat & DRQ_STAT) | ||
429 | return 0; | ||
430 | } | ||
431 | dump_status("wait_DRQ", stat); | ||
432 | return -1; | ||
433 | } | ||
434 | |||
435 | static void read_intr(void) | ||
436 | { | ||
437 | struct request *req; | ||
438 | int i, retries = 100000; | ||
439 | |||
440 | do { | ||
441 | i = (unsigned) inb_p(HD_STATUS); | ||
442 | if (i & BUSY_STAT) | ||
443 | continue; | ||
444 | if (!OK_STATUS(i)) | ||
445 | break; | ||
446 | if (i & DRQ_STAT) | ||
447 | goto ok_to_read; | ||
448 | } while (--retries > 0); | ||
449 | dump_status("read_intr", i); | ||
450 | bad_rw_intr(); | ||
451 | hd_request(); | ||
452 | return; | ||
453 | ok_to_read: | ||
454 | req = CURRENT; | ||
455 | insw(HD_DATA, req->buffer, 256); | ||
456 | req->sector++; | ||
457 | req->buffer += 512; | ||
458 | req->errors = 0; | ||
459 | i = --req->nr_sectors; | ||
460 | --req->current_nr_sectors; | ||
461 | #ifdef DEBUG | ||
462 | printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", | ||
463 | req->rq_disk->disk_name, req->sector, req->nr_sectors, | ||
464 | req->buffer+512); | ||
465 | #endif | ||
466 | if (req->current_nr_sectors <= 0) | ||
467 | end_request(req, 1); | ||
468 | if (i > 0) { | ||
469 | SET_HANDLER(&read_intr); | ||
470 | return; | ||
471 | } | ||
472 | (void) inb_p(HD_STATUS); | ||
473 | #if (HD_DELAY > 0) | ||
474 | last_req = read_timer(); | ||
475 | #endif | ||
476 | if (elv_next_request(QUEUE)) | ||
477 | hd_request(); | ||
478 | return; | ||
479 | } | ||
480 | |||
481 | static void write_intr(void) | ||
482 | { | ||
483 | struct request *req = CURRENT; | ||
484 | int i; | ||
485 | int retries = 100000; | ||
486 | |||
487 | do { | ||
488 | i = (unsigned) inb_p(HD_STATUS); | ||
489 | if (i & BUSY_STAT) | ||
490 | continue; | ||
491 | if (!OK_STATUS(i)) | ||
492 | break; | ||
493 | if ((req->nr_sectors <= 1) || (i & DRQ_STAT)) | ||
494 | goto ok_to_write; | ||
495 | } while (--retries > 0); | ||
496 | dump_status("write_intr", i); | ||
497 | bad_rw_intr(); | ||
498 | hd_request(); | ||
499 | return; | ||
500 | ok_to_write: | ||
501 | req->sector++; | ||
502 | i = --req->nr_sectors; | ||
503 | --req->current_nr_sectors; | ||
504 | req->buffer += 512; | ||
505 | if (!i || (req->bio && req->current_nr_sectors <= 0)) | ||
506 | end_request(req, 1); | ||
507 | if (i > 0) { | ||
508 | SET_HANDLER(&write_intr); | ||
509 | outsw(HD_DATA, req->buffer, 256); | ||
510 | local_irq_enable(); | ||
511 | } else { | ||
512 | #if (HD_DELAY > 0) | ||
513 | last_req = read_timer(); | ||
514 | #endif | ||
515 | hd_request(); | ||
516 | } | ||
517 | return; | ||
518 | } | ||
519 | |||
520 | static void recal_intr(void) | ||
521 | { | ||
522 | check_status(); | ||
523 | #if (HD_DELAY > 0) | ||
524 | last_req = read_timer(); | ||
525 | #endif | ||
526 | hd_request(); | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | * This is another of the error-routines I don't know what to do with. The | ||
531 | * best idea seems to just set reset, and start all over again. | ||
532 | */ | ||
533 | static void hd_times_out(unsigned long dummy) | ||
534 | { | ||
535 | char *name; | ||
536 | |||
537 | do_hd = NULL; | ||
538 | |||
539 | if (!CURRENT) | ||
540 | return; | ||
541 | |||
542 | disable_irq(HD_IRQ); | ||
543 | local_irq_enable(); | ||
544 | reset = 1; | ||
545 | name = CURRENT->rq_disk->disk_name; | ||
546 | printk("%s: timeout\n", name); | ||
547 | if (++CURRENT->errors >= MAX_ERRORS) { | ||
548 | #ifdef DEBUG | ||
549 | printk("%s: too many errors\n", name); | ||
550 | #endif | ||
551 | end_request(CURRENT, 0); | ||
552 | } | ||
553 | local_irq_disable(); | ||
554 | hd_request(); | ||
555 | enable_irq(HD_IRQ); | ||
556 | } | ||
557 | |||
558 | static int do_special_op(struct hd_i_struct *disk, struct request *req) | ||
559 | { | ||
560 | if (disk->recalibrate) { | ||
561 | disk->recalibrate = 0; | ||
562 | hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr); | ||
563 | return reset; | ||
564 | } | ||
565 | if (disk->head > 16) { | ||
566 | printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); | ||
567 | end_request(req, 0); | ||
568 | } | ||
569 | disk->special_op = 0; | ||
570 | return 1; | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * The driver enables interrupts as much as possible. In order to do this, | ||
575 | * (a) the device-interrupt is disabled before entering hd_request(), | ||
576 | * and (b) the timeout-interrupt is disabled before the sti(). | ||
577 | * | ||
578 | * Interrupts are still masked (by default) whenever we are exchanging | ||
579 | * data/cmds with a drive, because some drives seem to have very poor | ||
580 | * tolerance for latency during I/O. The IDE driver has support to unmask | ||
581 | * interrupts for non-broken hardware, so use that driver if required. | ||
582 | */ | ||
583 | static void hd_request(void) | ||
584 | { | ||
585 | unsigned int block, nsect, sec, track, head, cyl; | ||
586 | struct hd_i_struct *disk; | ||
587 | struct request *req; | ||
588 | |||
589 | if (do_hd) | ||
590 | return; | ||
591 | repeat: | ||
592 | del_timer(&device_timer); | ||
593 | local_irq_enable(); | ||
594 | |||
595 | req = CURRENT; | ||
596 | if (!req) { | ||
597 | do_hd = NULL; | ||
598 | return; | ||
599 | } | ||
600 | |||
601 | if (reset) { | ||
602 | local_irq_disable(); | ||
603 | reset_hd(); | ||
604 | return; | ||
605 | } | ||
606 | disk = req->rq_disk->private_data; | ||
607 | block = req->sector; | ||
608 | nsect = req->nr_sectors; | ||
609 | if (block >= get_capacity(req->rq_disk) || | ||
610 | ((block+nsect) > get_capacity(req->rq_disk))) { | ||
611 | printk("%s: bad access: block=%d, count=%d\n", | ||
612 | req->rq_disk->disk_name, block, nsect); | ||
613 | end_request(req, 0); | ||
614 | goto repeat; | ||
615 | } | ||
616 | |||
617 | if (disk->special_op) { | ||
618 | if (do_special_op(disk, req)) | ||
619 | goto repeat; | ||
620 | return; | ||
621 | } | ||
622 | sec = block % disk->sect + 1; | ||
623 | track = block / disk->sect; | ||
624 | head = track % disk->head; | ||
625 | cyl = track / disk->head; | ||
626 | #ifdef DEBUG | ||
627 | printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n", | ||
628 | req->rq_disk->disk_name, | ||
629 | req_data_dir(req) == READ ? "read" : "writ", | ||
630 | cyl, head, sec, nsect, req->buffer); | ||
631 | #endif | ||
632 | if (blk_fs_request(req)) { | ||
633 | switch (rq_data_dir(req)) { | ||
634 | case READ: | ||
635 | hd_out(disk, nsect, sec, head, cyl, WIN_READ, | ||
636 | &read_intr); | ||
637 | if (reset) | ||
638 | goto repeat; | ||
639 | break; | ||
640 | case WRITE: | ||
641 | hd_out(disk, nsect, sec, head, cyl, WIN_WRITE, | ||
642 | &write_intr); | ||
643 | if (reset) | ||
644 | goto repeat; | ||
645 | if (wait_DRQ()) { | ||
646 | bad_rw_intr(); | ||
647 | goto repeat; | ||
648 | } | ||
649 | outsw(HD_DATA, req->buffer, 256); | ||
650 | break; | ||
651 | default: | ||
652 | printk("unknown hd-command\n"); | ||
653 | end_request(req, 0); | ||
654 | break; | ||
655 | } | ||
656 | } | ||
657 | } | ||
658 | |||
659 | static void do_hd_request(struct request_queue *q) | ||
660 | { | ||
661 | disable_irq(HD_IRQ); | ||
662 | hd_request(); | ||
663 | enable_irq(HD_IRQ); | ||
664 | } | ||
665 | |||
666 | static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
667 | { | ||
668 | struct hd_i_struct *disk = bdev->bd_disk->private_data; | ||
669 | |||
670 | geo->heads = disk->head; | ||
671 | geo->sectors = disk->sect; | ||
672 | geo->cylinders = disk->cyl; | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | /* | ||
677 | * Releasing a block device means we sync() it, so that it can safely | ||
678 | * be forgotten about... | ||
679 | */ | ||
680 | |||
681 | static irqreturn_t hd_interrupt(int irq, void *dev_id) | ||
682 | { | ||
683 | void (*handler)(void) = do_hd; | ||
684 | |||
685 | do_hd = NULL; | ||
686 | del_timer(&device_timer); | ||
687 | if (!handler) | ||
688 | handler = unexpected_hd_interrupt; | ||
689 | handler(); | ||
690 | local_irq_enable(); | ||
691 | return IRQ_HANDLED; | ||
692 | } | ||
693 | |||
694 | static struct block_device_operations hd_fops = { | ||
695 | .getgeo = hd_getgeo, | ||
696 | }; | ||
697 | |||
698 | /* | ||
699 | * This is the hard disk IRQ description. The IRQF_DISABLED in sa_flags | ||
700 | * means we run the IRQ-handler with interrupts disabled: this is bad for | ||
701 | * interrupt latency, but anything else has led to problems on some | ||
702 | * machines. | ||
703 | * | ||
704 | * We enable interrupts in some of the routines after making sure it's | ||
705 | * safe. | ||
706 | */ | ||
707 | |||
708 | static int __init hd_init(void) | ||
709 | { | ||
710 | int drive; | ||
711 | |||
712 | if (register_blkdev(MAJOR_NR, "hd")) | ||
713 | return -1; | ||
714 | |||
715 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); | ||
716 | if (!hd_queue) { | ||
717 | unregister_blkdev(MAJOR_NR, "hd"); | ||
718 | return -ENOMEM; | ||
719 | } | ||
720 | |||
721 | blk_queue_max_sectors(hd_queue, 255); | ||
722 | init_timer(&device_timer); | ||
723 | device_timer.function = hd_times_out; | ||
724 | blk_queue_hardsect_size(hd_queue, 512); | ||
725 | |||
726 | if (!NR_HD) { | ||
727 | /* | ||
728 | * We don't know anything about the drive. This means | ||
729 | * that you *MUST* specify the drive parameters to the | ||
730 | * kernel yourself. | ||
731 | * | ||
732 | * If we were on an i386, we used to read this info from | ||
733 | * the BIOS or CMOS. This doesn't work all that well, | ||
734 | * since this assumes that this is a primary or secondary | ||
735 | * drive, and if we're using this legacy driver, it's | ||
736 | * probably an auxilliary controller added to recover | ||
737 | * legacy data off an ST-506 drive. Either way, it's | ||
738 | * definitely safest to have the user explicitly specify | ||
739 | * the information. | ||
740 | */ | ||
741 | printk("hd: no drives specified - use hd=cyl,head,sectors" | ||
742 | " on kernel command line\n"); | ||
743 | goto out; | ||
744 | } | ||
745 | |||
746 | for (drive = 0 ; drive < NR_HD ; drive++) { | ||
747 | struct gendisk *disk = alloc_disk(64); | ||
748 | struct hd_i_struct *p = &hd_info[drive]; | ||
749 | if (!disk) | ||
750 | goto Enomem; | ||
751 | disk->major = MAJOR_NR; | ||
752 | disk->first_minor = drive << 6; | ||
753 | disk->fops = &hd_fops; | ||
754 | sprintf(disk->disk_name, "hd%c", 'a'+drive); | ||
755 | disk->private_data = p; | ||
756 | set_capacity(disk, p->head * p->sect * p->cyl); | ||
757 | disk->queue = hd_queue; | ||
758 | p->unit = drive; | ||
759 | hd_gendisk[drive] = disk; | ||
760 | printk("%s: %luMB, CHS=%d/%d/%d\n", | ||
761 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, | ||
762 | p->cyl, p->head, p->sect); | ||
763 | } | ||
764 | |||
765 | if (request_irq(HD_IRQ, hd_interrupt, IRQF_DISABLED, "hd", NULL)) { | ||
766 | printk("hd: unable to get IRQ%d for the hard disk driver\n", | ||
767 | HD_IRQ); | ||
768 | goto out1; | ||
769 | } | ||
770 | if (!request_region(HD_DATA, 8, "hd")) { | ||
771 | printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); | ||
772 | goto out2; | ||
773 | } | ||
774 | if (!request_region(HD_CMD, 1, "hd(cmd)")) { | ||
775 | printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD); | ||
776 | goto out3; | ||
777 | } | ||
778 | |||
779 | /* Let them fly */ | ||
780 | for (drive = 0; drive < NR_HD; drive++) | ||
781 | add_disk(hd_gendisk[drive]); | ||
782 | |||
783 | return 0; | ||
784 | |||
785 | out3: | ||
786 | release_region(HD_DATA, 8); | ||
787 | out2: | ||
788 | free_irq(HD_IRQ, NULL); | ||
789 | out1: | ||
790 | for (drive = 0; drive < NR_HD; drive++) | ||
791 | put_disk(hd_gendisk[drive]); | ||
792 | NR_HD = 0; | ||
793 | out: | ||
794 | del_timer(&device_timer); | ||
795 | unregister_blkdev(MAJOR_NR, "hd"); | ||
796 | blk_cleanup_queue(hd_queue); | ||
797 | return -1; | ||
798 | Enomem: | ||
799 | while (drive--) | ||
800 | put_disk(hd_gendisk[drive]); | ||
801 | goto out; | ||
802 | } | ||
803 | |||
804 | static int __init parse_hd_setup(char *line) | ||
805 | { | ||
806 | int ints[6]; | ||
807 | |||
808 | (void) get_options(line, ARRAY_SIZE(ints), ints); | ||
809 | hd_setup(NULL, ints); | ||
810 | |||
811 | return 1; | ||
812 | } | ||
813 | __setup("hd=", parse_hd_setup); | ||
814 | |||
815 | module_init(hd_init); | ||
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index dd6dfb32e853..7bc8fd59ea9e 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c | |||
@@ -216,6 +216,7 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) | |||
216 | 216 | ||
217 | if (pio) { | 217 | if (pio) { |
218 | unsigned int cycle_time; | 218 | unsigned int cycle_time; |
219 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
219 | 220 | ||
220 | cycle_time = ide_pio_cycle_time(drive, pio); | 221 | cycle_time = ide_pio_cycle_time(drive, pio); |
221 | 222 | ||
@@ -224,10 +225,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) | |||
224 | * actual cycle time for recovery and activity | 225 | * actual cycle time for recovery and activity |
225 | * according system bus speed. | 226 | * according system bus speed. |
226 | */ | 227 | */ |
227 | active_time = ide_pio_timings[pio].active_time; | 228 | active_time = t->active; |
228 | recovery_time = cycle_time | 229 | recovery_time = cycle_time - active_time - t->setup; |
229 | - active_time | ||
230 | - ide_pio_timings[pio].setup_time; | ||
231 | /* | 230 | /* |
232 | * Cycle times should be Vesa bus cycles | 231 | * Cycle times should be Vesa bus cycles |
233 | */ | 232 | */ |
@@ -311,16 +310,16 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
311 | #endif | 310 | #endif |
312 | } | 311 | } |
313 | 312 | ||
314 | static void __init ht6560b_port_init_devs(ide_hwif_t *hwif) | 313 | static void __init ht6560b_init_dev(ide_drive_t *drive) |
315 | { | 314 | { |
315 | ide_hwif_t *hwif = drive->hwif; | ||
316 | /* Setting default configurations for drives. */ | 316 | /* Setting default configurations for drives. */ |
317 | int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT; | 317 | int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT; |
318 | 318 | ||
319 | if (hwif->channel) | 319 | if (hwif->channel) |
320 | t |= (HT_SECONDARY_IF << 8); | 320 | t |= (HT_SECONDARY_IF << 8); |
321 | 321 | ||
322 | hwif->drives[0].drive_data = t; | 322 | drive->drive_data = t; |
323 | hwif->drives[1].drive_data = t; | ||
324 | } | 323 | } |
325 | 324 | ||
326 | static int probe_ht6560b; | 325 | static int probe_ht6560b; |
@@ -329,7 +328,7 @@ module_param_named(probe, probe_ht6560b, bool, 0); | |||
329 | MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); | 328 | MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); |
330 | 329 | ||
331 | static const struct ide_port_ops ht6560b_port_ops = { | 330 | static const struct ide_port_ops ht6560b_port_ops = { |
332 | .port_init_devs = ht6560b_port_init_devs, | 331 | .init_dev = ht6560b_init_dev, |
333 | .set_pio_mode = ht6560b_set_pio_mode, | 332 | .set_pio_mode = ht6560b_set_pio_mode, |
334 | .selectproc = ht6560b_selectproc, | 333 | .selectproc = ht6560b_selectproc, |
335 | }; | 334 | }; |
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c index ecae916a3385..89c8ff0a4d08 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/legacy/ide-4drives.c | |||
@@ -11,6 +11,21 @@ static int probe_4drives; | |||
11 | module_param_named(probe, probe_4drives, bool, 0); | 11 | module_param_named(probe, probe_4drives, bool, 0); |
12 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); | 12 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); |
13 | 13 | ||
14 | static void ide_4drives_init_dev(ide_drive_t *drive) | ||
15 | { | ||
16 | if (drive->hwif->channel) | ||
17 | drive->select.all ^= 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 | |||
14 | static int __init ide_4drives_init(void) | 29 | static int __init ide_4drives_init(void) |
15 | { | 30 | { |
16 | ide_hwif_t *hwif, *mate; | 31 | ide_hwif_t *hwif, *mate; |
@@ -49,18 +64,10 @@ static int __init ide_4drives_init(void) | |||
49 | mate = ide_find_port(); | 64 | mate = ide_find_port(); |
50 | if (mate) { | 65 | if (mate) { |
51 | ide_init_port_hw(mate, &hw); | 66 | ide_init_port_hw(mate, &hw); |
52 | mate->drives[0].select.all ^= 0x20; | ||
53 | mate->drives[1].select.all ^= 0x20; | ||
54 | idx[1] = mate->index; | 67 | idx[1] = mate->index; |
55 | |||
56 | if (hwif) { | ||
57 | hwif->mate = mate; | ||
58 | mate->mate = hwif; | ||
59 | hwif->serialized = mate->serialized = 1; | ||
60 | } | ||
61 | } | 68 | } |
62 | 69 | ||
63 | ide_device_add(idx, NULL); | 70 | ide_device_add(idx, &ide_4drives_port_info); |
64 | 71 | ||
65 | return 0; | 72 | return 0; |
66 | } | 73 | } |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 8dbf4d9b6447..fc53dcfbfe38 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -154,6 +154,11 @@ static const struct ide_port_ops idecs_port_ops = { | |||
154 | .quirkproc = ide_undecoded_slave, | 154 | .quirkproc = ide_undecoded_slave, |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static const struct ide_port_info idecs_port_info = { | ||
158 | .port_ops = &idecs_port_ops, | ||
159 | .host_flags = IDE_HFLAG_NO_DMA, | ||
160 | }; | ||
161 | |||
157 | static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, | 162 | static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, |
158 | unsigned long irq, struct pcmcia_device *handle) | 163 | unsigned long irq, struct pcmcia_device *handle) |
159 | { | 164 | { |
@@ -187,13 +192,11 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, | |||
187 | 192 | ||
188 | i = hwif->index; | 193 | i = hwif->index; |
189 | 194 | ||
190 | ide_init_port_data(hwif, i); | ||
191 | ide_init_port_hw(hwif, &hw); | 195 | ide_init_port_hw(hwif, &hw); |
192 | hwif->port_ops = &idecs_port_ops; | ||
193 | 196 | ||
194 | idx[0] = i; | 197 | idx[0] = i; |
195 | 198 | ||
196 | ide_device_add(idx, NULL); | 199 | ide_device_add(idx, &idecs_port_info); |
197 | 200 | ||
198 | if (hwif->present) | 201 | if (hwif->present) |
199 | return hwif; | 202 | return hwif; |
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index d3bc3f24e05d..a249562b34b5 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c | |||
@@ -44,6 +44,10 @@ static void __devinit plat_ide_setup_ports(hw_regs_t *hw, | |||
44 | hw->chipset = ide_generic; | 44 | hw->chipset = ide_generic; |
45 | } | 45 | } |
46 | 46 | ||
47 | static const struct ide_port_info platform_ide_port_info = { | ||
48 | .host_flags = IDE_HFLAG_NO_DMA, | ||
49 | }; | ||
50 | |||
47 | static int __devinit plat_ide_probe(struct platform_device *pdev) | 51 | static int __devinit plat_ide_probe(struct platform_device *pdev) |
48 | { | 52 | { |
49 | struct resource *res_base, *res_alt, *res_irq; | 53 | struct resource *res_base, *res_alt, *res_irq; |
@@ -54,6 +58,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
54 | int ret = 0; | 58 | int ret = 0; |
55 | int mmio = 0; | 59 | int mmio = 0; |
56 | hw_regs_t hw; | 60 | hw_regs_t hw; |
61 | struct ide_port_info d = platform_ide_port_info; | ||
57 | 62 | ||
58 | pdata = pdev->dev.platform_data; | 63 | pdata = pdev->dev.platform_data; |
59 | 64 | ||
@@ -102,13 +107,13 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
102 | ide_init_port_hw(hwif, &hw); | 107 | ide_init_port_hw(hwif, &hw); |
103 | 108 | ||
104 | if (mmio) { | 109 | if (mmio) { |
105 | hwif->host_flags = IDE_HFLAG_MMIO; | 110 | d.host_flags |= IDE_HFLAG_MMIO; |
106 | default_hwif_mmiops(hwif); | 111 | default_hwif_mmiops(hwif); |
107 | } | 112 | } |
108 | 113 | ||
109 | idx[0] = hwif->index; | 114 | idx[0] = hwif->index; |
110 | 115 | ||
111 | ide_device_add(idx, NULL); | 116 | ide_device_add(idx, &d); |
112 | 117 | ||
113 | platform_set_drvdata(pdev, hwif); | 118 | platform_set_drvdata(pdev, hwif); |
114 | 119 | ||
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index 2e84290d0bcc..0a6195bcfeda 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c | |||
@@ -130,7 +130,6 @@ static int __init macide_init(void) | |||
130 | u8 index = hwif->index; | 130 | u8 index = hwif->index; |
131 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 131 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
132 | 132 | ||
133 | ide_init_port_data(hwif, index); | ||
134 | ide_init_port_hw(hwif, &hw); | 133 | ide_init_port_hw(hwif, &hw); |
135 | 134 | ||
136 | ide_device_add(idx, NULL); | 135 | ide_device_add(idx, NULL); |
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 8ff6e2d20834..9c2b9d078f69 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -142,7 +142,6 @@ static int __init q40ide_init(void) | |||
142 | 142 | ||
143 | hwif = ide_find_port(); | 143 | hwif = ide_find_port(); |
144 | if (hwif) { | 144 | if (hwif) { |
145 | ide_init_port_data(hwif, hwif->index); | ||
146 | ide_init_port_hw(hwif, &hw); | 145 | ide_init_port_hw(hwif, &hw); |
147 | 146 | ||
148 | /* Q40 has a byte-swapped IDE interface */ | 147 | /* Q40 has a byte-swapped IDE interface */ |
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 51dba82f8812..2338f344ea24 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c | |||
@@ -207,6 +207,7 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
207 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | 207 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) |
208 | { | 208 | { |
209 | ide_hwif_t *hwif = drive->hwif; | 209 | ide_hwif_t *hwif = drive->hwif; |
210 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
210 | unsigned int cycle_time; | 211 | unsigned int cycle_time; |
211 | int active_time = 175; | 212 | int active_time = 175; |
212 | int recovery_time = 415; /* worst case values from the dos driver */ | 213 | int recovery_time = 415; /* worst case values from the dos driver */ |
@@ -236,7 +237,7 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
236 | active_time = 110; | 237 | active_time = 110; |
237 | recovery_time = cycle_time - 120; | 238 | recovery_time = cycle_time - 120; |
238 | } else { | 239 | } else { |
239 | active_time = ide_pio_timings[pio].active_time; | 240 | active_time = t->active; |
240 | recovery_time = cycle_time - active_time; | 241 | recovery_time = cycle_time - active_time; |
241 | } | 242 | } |
242 | } | 243 | } |
@@ -281,17 +282,18 @@ static int __init qd_testreg(int port) | |||
281 | return (readreg != QD_TESTVAL); | 282 | return (readreg != QD_TESTVAL); |
282 | } | 283 | } |
283 | 284 | ||
284 | static void __init qd6500_port_init_devs(ide_hwif_t *hwif) | 285 | static void __init qd6500_init_dev(ide_drive_t *drive) |
285 | { | 286 | { |
287 | ide_hwif_t *hwif = drive->hwif; | ||
286 | u8 base = (hwif->config_data & 0xff00) >> 8; | 288 | u8 base = (hwif->config_data & 0xff00) >> 8; |
287 | u8 config = QD_CONFIG(hwif); | 289 | u8 config = QD_CONFIG(hwif); |
288 | 290 | ||
289 | hwif->drives[0].drive_data = QD6500_DEF_DATA; | 291 | drive->drive_data = QD6500_DEF_DATA; |
290 | hwif->drives[1].drive_data = QD6500_DEF_DATA; | ||
291 | } | 292 | } |
292 | 293 | ||
293 | static void __init qd6580_port_init_devs(ide_hwif_t *hwif) | 294 | static void __init qd6580_init_dev(ide_drive_t *drive) |
294 | { | 295 | { |
296 | ide_hwif_t *hwif = drive->hwif; | ||
295 | u16 t1, t2; | 297 | u16 t1, t2; |
296 | u8 base = (hwif->config_data & 0xff00) >> 8; | 298 | u8 base = (hwif->config_data & 0xff00) >> 8; |
297 | u8 config = QD_CONFIG(hwif); | 299 | u8 config = QD_CONFIG(hwif); |
@@ -302,18 +304,17 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif) | |||
302 | } else | 304 | } else |
303 | t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; | 305 | t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; |
304 | 306 | ||
305 | hwif->drives[0].drive_data = t1; | 307 | drive->drive_data = drive->select.b.unit ? t2 : t1; |
306 | hwif->drives[1].drive_data = t2; | ||
307 | } | 308 | } |
308 | 309 | ||
309 | static const struct ide_port_ops qd6500_port_ops = { | 310 | static const struct ide_port_ops qd6500_port_ops = { |
310 | .port_init_devs = qd6500_port_init_devs, | 311 | .init_dev = qd6500_init_dev, |
311 | .set_pio_mode = qd6500_set_pio_mode, | 312 | .set_pio_mode = qd6500_set_pio_mode, |
312 | .selectproc = qd65xx_select, | 313 | .selectproc = qd65xx_select, |
313 | }; | 314 | }; |
314 | 315 | ||
315 | static const struct ide_port_ops qd6580_port_ops = { | 316 | static const struct ide_port_ops qd6580_port_ops = { |
316 | .port_init_devs = qd6580_port_init_devs, | 317 | .init_dev = qd6580_init_dev, |
317 | .set_pio_mode = qd6580_set_pio_mode, | 318 | .set_pio_mode = qd6580_set_pio_mode, |
318 | .selectproc = qd65xx_select, | 319 | .selectproc = qd65xx_select, |
319 | }; | 320 | }; |