diff options
Diffstat (limited to 'drivers/ide/legacy')
-rw-r--r-- | drivers/ide/legacy/ali14xx.c | 30 | ||||
-rw-r--r-- | drivers/ide/legacy/buddha.c | 2 | ||||
-rw-r--r-- | drivers/ide/legacy/dtc2278.c | 22 | ||||
-rw-r--r-- | drivers/ide/legacy/falconide.c | 9 | ||||
-rw-r--r-- | drivers/ide/legacy/gayle.c | 2 | ||||
-rw-r--r-- | drivers/ide/legacy/hd.c | 78 | ||||
-rw-r--r-- | drivers/ide/legacy/ht6560b.c | 34 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-4drives.c | 36 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-cs.c | 2 | ||||
-rw-r--r-- | drivers/ide/legacy/ide_platform.c | 7 | ||||
-rw-r--r-- | drivers/ide/legacy/macide.c | 2 | ||||
-rw-r--r-- | drivers/ide/legacy/q40ide.c | 2 | ||||
-rw-r--r-- | drivers/ide/legacy/qd65xx.c | 165 | ||||
-rw-r--r-- | drivers/ide/legacy/qd65xx.h | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/umc8672.c | 81 |
15 files changed, 251 insertions, 222 deletions
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index bc8b1f8de614..33bb7b87be5d 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c | |||
@@ -86,7 +86,7 @@ static u8 regOff; /* output to base port to close registers */ | |||
86 | /* | 86 | /* |
87 | * Read a controller register. | 87 | * Read a controller register. |
88 | */ | 88 | */ |
89 | static inline u8 inReg (u8 reg) | 89 | static inline u8 inReg(u8 reg) |
90 | { | 90 | { |
91 | outb_p(reg, regPort); | 91 | outb_p(reg, regPort); |
92 | return inb(dataPort); | 92 | return inb(dataPort); |
@@ -95,7 +95,7 @@ static inline u8 inReg (u8 reg) | |||
95 | /* | 95 | /* |
96 | * Write a controller register. | 96 | * Write a controller register. |
97 | */ | 97 | */ |
98 | static void outReg (u8 data, u8 reg) | 98 | static void outReg(u8 data, u8 reg) |
99 | { | 99 | { |
100 | outb_p(reg, regPort); | 100 | outb_p(reg, regPort); |
101 | outb_p(data, dataPort); | 101 | outb_p(data, dataPort); |
@@ -143,7 +143,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
143 | /* | 143 | /* |
144 | * Auto-detect the IDE controller port. | 144 | * Auto-detect the IDE controller port. |
145 | */ | 145 | */ |
146 | static int __init findPort (void) | 146 | static int __init findPort(void) |
147 | { | 147 | { |
148 | int i; | 148 | int i; |
149 | u8 t; | 149 | u8 t; |
@@ -175,7 +175,8 @@ static int __init findPort (void) | |||
175 | /* | 175 | /* |
176 | * Initialize controller registers with default values. | 176 | * Initialize controller registers with default values. |
177 | */ | 177 | */ |
178 | static int __init initRegisters (void) { | 178 | static int __init initRegisters(void) |
179 | { | ||
179 | const RegInitializer *p; | 180 | const RegInitializer *p; |
180 | u8 t; | 181 | u8 t; |
181 | unsigned long flags; | 182 | unsigned long flags; |
@@ -199,7 +200,8 @@ static const struct ide_port_info ali14xx_port_info = { | |||
199 | 200 | ||
200 | static int __init ali14xx_probe(void) | 201 | static int __init ali14xx_probe(void) |
201 | { | 202 | { |
202 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 203 | ide_hwif_t *hwif, *mate; |
204 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
203 | hw_regs_t hw[2]; | 205 | hw_regs_t hw[2]; |
204 | 206 | ||
205 | printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n", | 207 | printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n", |
@@ -219,18 +221,26 @@ static int __init ali14xx_probe(void) | |||
219 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 221 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
220 | hw[1].irq = 15; | 222 | hw[1].irq = 15; |
221 | 223 | ||
222 | ide_init_port_hw(&ide_hwifs[0], &hw[0]); | 224 | hwif = ide_find_port(); |
223 | ide_init_port_hw(&ide_hwifs[1], &hw[1]); | 225 | if (hwif) { |
226 | ide_init_port_hw(hwif, &hw[0]); | ||
227 | hwif->set_pio_mode = &ali14xx_set_pio_mode; | ||
228 | idx[0] = hwif->index; | ||
229 | } | ||
224 | 230 | ||
225 | ide_hwifs[0].set_pio_mode = &ali14xx_set_pio_mode; | 231 | mate = ide_find_port(); |
226 | ide_hwifs[1].set_pio_mode = &ali14xx_set_pio_mode; | 232 | if (mate) { |
233 | ide_init_port_hw(mate, &hw[1]); | ||
234 | mate->set_pio_mode = &ali14xx_set_pio_mode; | ||
235 | idx[1] = mate->index; | ||
236 | } | ||
227 | 237 | ||
228 | ide_device_add(idx, &ali14xx_port_info); | 238 | ide_device_add(idx, &ali14xx_port_info); |
229 | 239 | ||
230 | return 0; | 240 | return 0; |
231 | } | 241 | } |
232 | 242 | ||
233 | int probe_ali14xx = 0; | 243 | int probe_ali14xx; |
234 | 244 | ||
235 | module_param_named(probe, probe_ali14xx, bool, 0); | 245 | module_param_named(probe, probe_ali14xx, bool, 0); |
236 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); | 246 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); |
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index fdd3791e465f..6956eb8f2d5f 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c | |||
@@ -221,7 +221,7 @@ fail_base2: | |||
221 | 221 | ||
222 | buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); | 222 | buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); |
223 | 223 | ||
224 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 224 | hwif = ide_find_port(); |
225 | if (hwif) { | 225 | if (hwif) { |
226 | u8 index = hwif->index; | 226 | u8 index = hwif->index; |
227 | 227 | ||
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c index 5f69cd2ea6f7..9c6b3249a004 100644 --- a/drivers/ide/legacy/dtc2278.c +++ b/drivers/ide/legacy/dtc2278.c | |||
@@ -102,15 +102,9 @@ static int __init dtc2278_probe(void) | |||
102 | { | 102 | { |
103 | unsigned long flags; | 103 | unsigned long flags; |
104 | ide_hwif_t *hwif, *mate; | 104 | ide_hwif_t *hwif, *mate; |
105 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 105 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
106 | hw_regs_t hw[2]; | 106 | hw_regs_t hw[2]; |
107 | 107 | ||
108 | hwif = &ide_hwifs[0]; | ||
109 | mate = &ide_hwifs[1]; | ||
110 | |||
111 | if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown) | ||
112 | return 1; | ||
113 | |||
114 | local_irq_save(flags); | 108 | local_irq_save(flags); |
115 | /* | 109 | /* |
116 | * This enables the second interface | 110 | * This enables the second interface |
@@ -137,10 +131,18 @@ static int __init dtc2278_probe(void) | |||
137 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 131 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
138 | hw[1].irq = 15; | 132 | hw[1].irq = 15; |
139 | 133 | ||
140 | ide_init_port_hw(hwif, &hw[0]); | 134 | hwif = ide_find_port(); |
141 | ide_init_port_hw(mate, &hw[1]); | 135 | if (hwif) { |
136 | ide_init_port_hw(hwif, &hw[0]); | ||
137 | hwif->set_pio_mode = dtc2278_set_pio_mode; | ||
138 | idx[0] = hwif->index; | ||
139 | } | ||
142 | 140 | ||
143 | hwif->set_pio_mode = &dtc2278_set_pio_mode; | 141 | mate = ide_find_port(); |
142 | if (mate) { | ||
143 | ide_init_port_hw(mate, &hw[1]); | ||
144 | idx[1] = mate->index; | ||
145 | } | ||
144 | 146 | ||
145 | ide_device_add(idx, &dtc2278_port_info); | 147 | ide_device_add(idx, &dtc2278_port_info); |
146 | 148 | ||
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index e950afa5939c..8c9c9f7f54ca 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/atariints.h> | 22 | #include <asm/atariints.h> |
23 | #include <asm/atari_stdma.h> | 23 | #include <asm/atari_stdma.h> |
24 | 24 | ||
25 | #define DRV_NAME "falconide" | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Base of the IDE interface | 28 | * Base of the IDE interface |
@@ -74,15 +75,21 @@ static int __init falconide_init(void) | |||
74 | 75 | ||
75 | printk(KERN_INFO "ide: Falcon IDE controller\n"); | 76 | printk(KERN_INFO "ide: Falcon IDE controller\n"); |
76 | 77 | ||
78 | if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) { | ||
79 | printk(KERN_ERR "%s: resources busy\n", DRV_NAME); | ||
80 | return -EBUSY; | ||
81 | } | ||
82 | |||
77 | falconide_setup_ports(&hw); | 83 | falconide_setup_ports(&hw); |
78 | 84 | ||
79 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 85 | hwif = ide_find_port(); |
80 | if (hwif) { | 86 | if (hwif) { |
81 | u8 index = hwif->index; | 87 | u8 index = hwif->index; |
82 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 88 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
83 | 89 | ||
84 | ide_init_port_data(hwif, index); | 90 | ide_init_port_data(hwif, index); |
85 | ide_init_port_hw(hwif, &hw); | 91 | ide_init_port_hw(hwif, &hw); |
92 | hwif->mmio = 1; | ||
86 | 93 | ||
87 | ide_get_lock(NULL, NULL); | 94 | ide_get_lock(NULL, NULL); |
88 | ide_device_add(idx, NULL); | 95 | ide_device_add(idx, NULL); |
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index e3b4638cc883..fcc8d52bf2a1 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c | |||
@@ -175,7 +175,7 @@ found: | |||
175 | 175 | ||
176 | gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); | 176 | gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); |
177 | 177 | ||
178 | hwif = ide_find_port(base); | 178 | hwif = ide_find_port(); |
179 | if (hwif) { | 179 | if (hwif) { |
180 | u8 index = hwif->index; | 180 | u8 index = hwif->index; |
181 | 181 | ||
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index 0b0d86731927..abdedf56643e 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c | |||
@@ -122,12 +122,12 @@ static int hd_error; | |||
122 | * This struct defines the HD's and their types. | 122 | * This struct defines the HD's and their types. |
123 | */ | 123 | */ |
124 | struct hd_i_struct { | 124 | struct hd_i_struct { |
125 | unsigned int head,sect,cyl,wpcom,lzone,ctl; | 125 | unsigned int head, sect, cyl, wpcom, lzone, ctl; |
126 | int unit; | 126 | int unit; |
127 | int recalibrate; | 127 | int recalibrate; |
128 | int special_op; | 128 | int special_op; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | #ifdef HD_TYPE | 131 | #ifdef HD_TYPE |
132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; | 132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; |
133 | static int NR_HD = ARRAY_SIZE(hd_info); | 133 | static int NR_HD = ARRAY_SIZE(hd_info); |
@@ -168,7 +168,7 @@ unsigned long read_timer(void) | |||
168 | 168 | ||
169 | spin_lock_irqsave(&i8253_lock, flags); | 169 | spin_lock_irqsave(&i8253_lock, flags); |
170 | t = jiffies * 11932; | 170 | t = jiffies * 11932; |
171 | outb_p(0, 0x43); | 171 | outb_p(0, 0x43); |
172 | i = inb_p(0x40); | 172 | i = inb_p(0x40); |
173 | i |= inb(0x40) << 8; | 173 | i |= inb(0x40) << 8; |
174 | spin_unlock_irqrestore(&i8253_lock, flags); | 174 | spin_unlock_irqrestore(&i8253_lock, flags); |
@@ -183,7 +183,7 @@ static void __init hd_setup(char *str, int *ints) | |||
183 | if (ints[0] != 3) | 183 | if (ints[0] != 3) |
184 | return; | 184 | return; |
185 | if (hd_info[0].head != 0) | 185 | if (hd_info[0].head != 0) |
186 | hdind=1; | 186 | hdind = 1; |
187 | hd_info[hdind].head = ints[2]; | 187 | hd_info[hdind].head = ints[2]; |
188 | hd_info[hdind].sect = ints[3]; | 188 | hd_info[hdind].sect = ints[3]; |
189 | hd_info[hdind].cyl = ints[1]; | 189 | hd_info[hdind].cyl = ints[1]; |
@@ -193,7 +193,7 @@ static void __init hd_setup(char *str, int *ints) | |||
193 | NR_HD = hdind+1; | 193 | NR_HD = hdind+1; |
194 | } | 194 | } |
195 | 195 | ||
196 | static void dump_status (const char *msg, unsigned int stat) | 196 | static void dump_status(const char *msg, unsigned int stat) |
197 | { | 197 | { |
198 | char *name = "hd?"; | 198 | char *name = "hd?"; |
199 | if (CURRENT) | 199 | if (CURRENT) |
@@ -291,7 +291,6 @@ static int controller_ready(unsigned int drive, unsigned int head) | |||
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | |||
295 | static void hd_out(struct hd_i_struct *disk, | 294 | static void hd_out(struct hd_i_struct *disk, |
296 | unsigned int nsect, | 295 | unsigned int nsect, |
297 | unsigned int sect, | 296 | unsigned int sect, |
@@ -313,15 +312,15 @@ static void hd_out(struct hd_i_struct *disk, | |||
313 | return; | 312 | return; |
314 | } | 313 | } |
315 | SET_HANDLER(intr_addr); | 314 | SET_HANDLER(intr_addr); |
316 | outb_p(disk->ctl,HD_CMD); | 315 | outb_p(disk->ctl, HD_CMD); |
317 | port=HD_DATA; | 316 | port = HD_DATA; |
318 | outb_p(disk->wpcom>>2,++port); | 317 | outb_p(disk->wpcom >> 2, ++port); |
319 | outb_p(nsect,++port); | 318 | outb_p(nsect, ++port); |
320 | outb_p(sect,++port); | 319 | outb_p(sect, ++port); |
321 | outb_p(cyl,++port); | 320 | outb_p(cyl, ++port); |
322 | outb_p(cyl>>8,++port); | 321 | outb_p(cyl >> 8, ++port); |
323 | outb_p(0xA0|(disk->unit<<4)|head,++port); | 322 | outb_p(0xA0 | (disk->unit << 4) | head, ++port); |
324 | outb_p(cmd,++port); | 323 | outb_p(cmd, ++port); |
325 | } | 324 | } |
326 | 325 | ||
327 | static void hd_request (void); | 326 | static void hd_request (void); |
@@ -344,14 +343,14 @@ static void reset_controller(void) | |||
344 | { | 343 | { |
345 | int i; | 344 | int i; |
346 | 345 | ||
347 | outb_p(4,HD_CMD); | 346 | outb_p(4, HD_CMD); |
348 | for(i = 0; i < 1000; i++) barrier(); | 347 | for (i = 0; i < 1000; i++) barrier(); |
349 | outb_p(hd_info[0].ctl & 0x0f,HD_CMD); | 348 | outb_p(hd_info[0].ctl & 0x0f, HD_CMD); |
350 | for(i = 0; i < 1000; i++) barrier(); | 349 | for (i = 0; i < 1000; i++) barrier(); |
351 | if (drive_busy()) | 350 | if (drive_busy()) |
352 | printk("hd: controller still busy\n"); | 351 | printk("hd: controller still busy\n"); |
353 | else if ((hd_error = inb(HD_ERROR)) != 1) | 352 | else if ((hd_error = inb(HD_ERROR)) != 1) |
354 | printk("hd: controller reset failed: %02x\n",hd_error); | 353 | printk("hd: controller reset failed: %02x\n", hd_error); |
355 | } | 354 | } |
356 | 355 | ||
357 | static void reset_hd(void) | 356 | static void reset_hd(void) |
@@ -371,8 +370,8 @@ repeat: | |||
371 | if (++i < NR_HD) { | 370 | if (++i < NR_HD) { |
372 | struct hd_i_struct *disk = &hd_info[i]; | 371 | struct hd_i_struct *disk = &hd_info[i]; |
373 | disk->special_op = disk->recalibrate = 1; | 372 | disk->special_op = disk->recalibrate = 1; |
374 | hd_out(disk,disk->sect,disk->sect,disk->head-1, | 373 | hd_out(disk, disk->sect, disk->sect, disk->head-1, |
375 | disk->cyl,WIN_SPECIFY,&reset_hd); | 374 | disk->cyl, WIN_SPECIFY, &reset_hd); |
376 | if (reset) | 375 | if (reset) |
377 | goto repeat; | 376 | goto repeat; |
378 | } else | 377 | } else |
@@ -393,7 +392,7 @@ static void unexpected_hd_interrupt(void) | |||
393 | unsigned int stat = inb_p(HD_STATUS); | 392 | unsigned int stat = inb_p(HD_STATUS); |
394 | 393 | ||
395 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { | 394 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { |
396 | dump_status ("unexpected interrupt", stat); | 395 | dump_status("unexpected interrupt", stat); |
397 | SET_TIMER; | 396 | SET_TIMER; |
398 | } | 397 | } |
399 | } | 398 | } |
@@ -453,7 +452,7 @@ static void read_intr(void) | |||
453 | return; | 452 | return; |
454 | ok_to_read: | 453 | ok_to_read: |
455 | req = CURRENT; | 454 | req = CURRENT; |
456 | insw(HD_DATA,req->buffer,256); | 455 | insw(HD_DATA, req->buffer, 256); |
457 | req->sector++; | 456 | req->sector++; |
458 | req->buffer += 512; | 457 | req->buffer += 512; |
459 | req->errors = 0; | 458 | req->errors = 0; |
@@ -507,7 +506,7 @@ ok_to_write: | |||
507 | end_request(req, 1); | 506 | end_request(req, 1); |
508 | if (i > 0) { | 507 | if (i > 0) { |
509 | SET_HANDLER(&write_intr); | 508 | SET_HANDLER(&write_intr); |
510 | outsw(HD_DATA,req->buffer,256); | 509 | outsw(HD_DATA, req->buffer, 256); |
511 | local_irq_enable(); | 510 | local_irq_enable(); |
512 | } else { | 511 | } else { |
513 | #if (HD_DELAY > 0) | 512 | #if (HD_DELAY > 0) |
@@ -560,11 +559,11 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req) | |||
560 | { | 559 | { |
561 | if (disk->recalibrate) { | 560 | if (disk->recalibrate) { |
562 | disk->recalibrate = 0; | 561 | disk->recalibrate = 0; |
563 | hd_out(disk,disk->sect,0,0,0,WIN_RESTORE,&recal_intr); | 562 | hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr); |
564 | return reset; | 563 | return reset; |
565 | } | 564 | } |
566 | if (disk->head > 16) { | 565 | if (disk->head > 16) { |
567 | printk ("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); | 566 | printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); |
568 | end_request(req, 0); | 567 | end_request(req, 0); |
569 | } | 568 | } |
570 | disk->special_op = 0; | 569 | disk->special_op = 0; |
@@ -633,19 +632,21 @@ repeat: | |||
633 | if (blk_fs_request(req)) { | 632 | if (blk_fs_request(req)) { |
634 | switch (rq_data_dir(req)) { | 633 | switch (rq_data_dir(req)) { |
635 | case READ: | 634 | case READ: |
636 | hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr); | 635 | hd_out(disk, nsect, sec, head, cyl, WIN_READ, |
636 | &read_intr); | ||
637 | if (reset) | 637 | if (reset) |
638 | goto repeat; | 638 | goto repeat; |
639 | break; | 639 | break; |
640 | case WRITE: | 640 | case WRITE: |
641 | hd_out(disk,nsect,sec,head,cyl,WIN_WRITE,&write_intr); | 641 | hd_out(disk, nsect, sec, head, cyl, WIN_WRITE, |
642 | &write_intr); | ||
642 | if (reset) | 643 | if (reset) |
643 | goto repeat; | 644 | goto repeat; |
644 | if (wait_DRQ()) { | 645 | if (wait_DRQ()) { |
645 | bad_rw_intr(); | 646 | bad_rw_intr(); |
646 | goto repeat; | 647 | goto repeat; |
647 | } | 648 | } |
648 | outsw(HD_DATA,req->buffer,256); | 649 | outsw(HD_DATA, req->buffer, 256); |
649 | break; | 650 | break; |
650 | default: | 651 | default: |
651 | printk("unknown hd-command\n"); | 652 | printk("unknown hd-command\n"); |
@@ -655,7 +656,7 @@ repeat: | |||
655 | } | 656 | } |
656 | } | 657 | } |
657 | 658 | ||
658 | static void do_hd_request (struct request_queue * q) | 659 | static void do_hd_request(struct request_queue *q) |
659 | { | 660 | { |
660 | disable_irq(HD_IRQ); | 661 | disable_irq(HD_IRQ); |
661 | hd_request(); | 662 | hd_request(); |
@@ -708,12 +709,12 @@ static int __init hd_init(void) | |||
708 | { | 709 | { |
709 | int drive; | 710 | int drive; |
710 | 711 | ||
711 | if (register_blkdev(MAJOR_NR,"hd")) | 712 | if (register_blkdev(MAJOR_NR, "hd")) |
712 | return -1; | 713 | return -1; |
713 | 714 | ||
714 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); | 715 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); |
715 | if (!hd_queue) { | 716 | if (!hd_queue) { |
716 | unregister_blkdev(MAJOR_NR,"hd"); | 717 | unregister_blkdev(MAJOR_NR, "hd"); |
717 | return -ENOMEM; | 718 | return -ENOMEM; |
718 | } | 719 | } |
719 | 720 | ||
@@ -742,7 +743,7 @@ static int __init hd_init(void) | |||
742 | goto out; | 743 | goto out; |
743 | } | 744 | } |
744 | 745 | ||
745 | for (drive=0 ; drive < NR_HD ; drive++) { | 746 | for (drive = 0 ; drive < NR_HD ; drive++) { |
746 | struct gendisk *disk = alloc_disk(64); | 747 | struct gendisk *disk = alloc_disk(64); |
747 | struct hd_i_struct *p = &hd_info[drive]; | 748 | struct hd_i_struct *p = &hd_info[drive]; |
748 | if (!disk) | 749 | if (!disk) |
@@ -756,7 +757,7 @@ static int __init hd_init(void) | |||
756 | disk->queue = hd_queue; | 757 | disk->queue = hd_queue; |
757 | p->unit = drive; | 758 | p->unit = drive; |
758 | hd_gendisk[drive] = disk; | 759 | hd_gendisk[drive] = disk; |
759 | printk ("%s: %luMB, CHS=%d/%d/%d\n", | 760 | printk("%s: %luMB, CHS=%d/%d/%d\n", |
760 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, | 761 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, |
761 | p->cyl, p->head, p->sect); | 762 | p->cyl, p->head, p->sect); |
762 | } | 763 | } |
@@ -776,7 +777,7 @@ static int __init hd_init(void) | |||
776 | } | 777 | } |
777 | 778 | ||
778 | /* Let them fly */ | 779 | /* Let them fly */ |
779 | for(drive=0; drive < NR_HD; drive++) | 780 | for (drive = 0; drive < NR_HD; drive++) |
780 | add_disk(hd_gendisk[drive]); | 781 | add_disk(hd_gendisk[drive]); |
781 | 782 | ||
782 | return 0; | 783 | return 0; |
@@ -791,7 +792,7 @@ out1: | |||
791 | NR_HD = 0; | 792 | NR_HD = 0; |
792 | out: | 793 | out: |
793 | del_timer(&device_timer); | 794 | del_timer(&device_timer); |
794 | unregister_blkdev(MAJOR_NR,"hd"); | 795 | unregister_blkdev(MAJOR_NR, "hd"); |
795 | blk_cleanup_queue(hd_queue); | 796 | blk_cleanup_queue(hd_queue); |
796 | return -1; | 797 | return -1; |
797 | Enomem: | 798 | Enomem: |
@@ -800,7 +801,8 @@ Enomem: | |||
800 | goto out; | 801 | goto out; |
801 | } | 802 | } |
802 | 803 | ||
803 | static int __init parse_hd_setup (char *line) { | 804 | static int __init parse_hd_setup(char *line) |
805 | { | ||
804 | int ints[6]; | 806 | int ints[6]; |
805 | 807 | ||
806 | (void) get_options(line, ARRAY_SIZE(ints), ints); | 808 | (void) get_options(line, ARRAY_SIZE(ints), ints); |
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index 88fe9070c9c3..60f52f5158c9 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c | |||
@@ -35,6 +35,7 @@ | |||
35 | * Try: http://www.maf.iki.fi/~maf/ht6560b/ | 35 | * Try: http://www.maf.iki.fi/~maf/ht6560b/ |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #define DRV_NAME "ht6560b" | ||
38 | #define HT6560B_VERSION "v0.08" | 39 | #define HT6560B_VERSION "v0.08" |
39 | 40 | ||
40 | #include <linux/module.h> | 41 | #include <linux/module.h> |
@@ -339,16 +340,13 @@ static const struct ide_port_info ht6560b_port_info __initdata = { | |||
339 | static int __init ht6560b_init(void) | 340 | static int __init ht6560b_init(void) |
340 | { | 341 | { |
341 | ide_hwif_t *hwif, *mate; | 342 | ide_hwif_t *hwif, *mate; |
342 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 343 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
343 | hw_regs_t hw[2]; | 344 | hw_regs_t hw[2]; |
344 | 345 | ||
345 | if (probe_ht6560b == 0) | 346 | if (probe_ht6560b == 0) |
346 | return -ENODEV; | 347 | return -ENODEV; |
347 | 348 | ||
348 | hwif = &ide_hwifs[0]; | 349 | if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) { |
349 | mate = &ide_hwifs[1]; | ||
350 | |||
351 | if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) { | ||
352 | printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n", | 350 | printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n", |
353 | __FUNCTION__); | 351 | __FUNCTION__); |
354 | return -ENODEV; | 352 | return -ENODEV; |
@@ -367,17 +365,23 @@ static int __init ht6560b_init(void) | |||
367 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 365 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
368 | hw[1].irq = 15; | 366 | hw[1].irq = 15; |
369 | 367 | ||
370 | ide_init_port_hw(hwif, &hw[0]); | 368 | hwif = ide_find_port(); |
371 | ide_init_port_hw(mate, &hw[1]); | 369 | if (hwif) { |
372 | 370 | ide_init_port_hw(hwif, &hw[0]); | |
373 | hwif->selectproc = &ht6560b_selectproc; | 371 | hwif->selectproc = ht6560b_selectproc; |
374 | hwif->set_pio_mode = &ht6560b_set_pio_mode; | 372 | hwif->set_pio_mode = ht6560b_set_pio_mode; |
375 | 373 | hwif->port_init_devs = ht6560b_port_init_devs; | |
376 | mate->selectproc = &ht6560b_selectproc; | 374 | idx[0] = hwif->index; |
377 | mate->set_pio_mode = &ht6560b_set_pio_mode; | 375 | } |
378 | 376 | ||
379 | hwif->port_init_devs = ht6560b_port_init_devs; | 377 | mate = ide_find_port(); |
380 | mate->port_init_devs = ht6560b_port_init_devs; | 378 | if (mate) { |
379 | ide_init_port_hw(mate, &hw[1]); | ||
380 | mate->selectproc = ht6560b_selectproc; | ||
381 | mate->set_pio_mode = ht6560b_set_pio_mode; | ||
382 | mate->port_init_devs = ht6560b_port_init_devs; | ||
383 | idx[1] = mate->index; | ||
384 | } | ||
381 | 385 | ||
382 | ide_device_add(idx, &ht6560b_port_info); | 386 | ide_device_add(idx, &ht6560b_port_info); |
383 | 387 | ||
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c index ecd7f3553554..c352f12348af 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/legacy/ide-4drives.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/ide.h> | 5 | #include <linux/ide.h> |
6 | 6 | ||
7 | int probe_4drives = 0; | 7 | int probe_4drives; |
8 | 8 | ||
9 | module_param_named(probe, probe_4drives, bool, 0); | 9 | module_param_named(probe, probe_4drives, bool, 0); |
10 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); | 10 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); |
@@ -12,31 +12,37 @@ MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); | |||
12 | static int __init ide_4drives_init(void) | 12 | static int __init ide_4drives_init(void) |
13 | { | 13 | { |
14 | ide_hwif_t *hwif, *mate; | 14 | ide_hwif_t *hwif, *mate; |
15 | u8 idx[4] = { 0, 1, 0xff, 0xff }; | 15 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
16 | hw_regs_t hw; | 16 | hw_regs_t hw; |
17 | 17 | ||
18 | if (probe_4drives == 0) | 18 | if (probe_4drives == 0) |
19 | return -ENODEV; | 19 | return -ENODEV; |
20 | 20 | ||
21 | hwif = &ide_hwifs[0]; | ||
22 | mate = &ide_hwifs[1]; | ||
23 | |||
24 | memset(&hw, 0, sizeof(hw)); | 21 | memset(&hw, 0, sizeof(hw)); |
25 | 22 | ||
26 | ide_std_init_ports(&hw, 0x1f0, 0x3f6); | 23 | ide_std_init_ports(&hw, 0x1f0, 0x3f6); |
27 | hw.irq = 14; | 24 | hw.irq = 14; |
28 | hw.chipset = ide_4drives; | 25 | hw.chipset = ide_4drives; |
29 | 26 | ||
30 | ide_init_port_hw(hwif, &hw); | 27 | hwif = ide_find_port(); |
31 | ide_init_port_hw(mate, &hw); | 28 | if (hwif) { |
32 | 29 | ide_init_port_hw(hwif, &hw); | |
33 | mate->drives[0].select.all ^= 0x20; | 30 | idx[0] = hwif->index; |
34 | mate->drives[1].select.all ^= 0x20; | 31 | } |
35 | 32 | ||
36 | hwif->mate = mate; | 33 | mate = ide_find_port(); |
37 | mate->mate = hwif; | 34 | if (mate) { |
38 | 35 | ide_init_port_hw(mate, &hw); | |
39 | hwif->serialized = mate->serialized = 1; | 36 | mate->drives[0].select.all ^= 0x20; |
37 | mate->drives[1].select.all ^= 0x20; | ||
38 | idx[1] = mate->index; | ||
39 | |||
40 | if (hwif) { | ||
41 | hwif->mate = mate; | ||
42 | mate->mate = hwif; | ||
43 | hwif->serialized = mate->serialized = 1; | ||
44 | } | ||
45 | } | ||
40 | 46 | ||
41 | ide_device_add(idx, NULL); | 47 | ide_device_add(idx, NULL); |
42 | 48 | ||
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 9a23b94f2939..b97b8d51b3eb 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -156,7 +156,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq | |||
156 | hw.chipset = ide_pci; | 156 | hw.chipset = ide_pci; |
157 | hw.dev = &handle->dev; | 157 | hw.dev = &handle->dev; |
158 | 158 | ||
159 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 159 | hwif = ide_find_port(); |
160 | if (hwif == NULL) | 160 | if (hwif == NULL) |
161 | return -1; | 161 | return -1; |
162 | 162 | ||
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index 361b1bb544bf..bf240775531e 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c | |||
@@ -89,7 +89,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
89 | res_alt->start, res_alt->end - res_alt->start + 1); | 89 | res_alt->start, res_alt->end - res_alt->start + 1); |
90 | } | 90 | } |
91 | 91 | ||
92 | hwif = ide_find_port((unsigned long)base); | 92 | hwif = ide_find_port(); |
93 | if (!hwif) { | 93 | if (!hwif) { |
94 | ret = -ENODEV; | 94 | ret = -ENODEV; |
95 | goto out; | 95 | goto out; |
@@ -100,11 +100,10 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
100 | hw.dev = &pdev->dev; | 100 | hw.dev = &pdev->dev; |
101 | 101 | ||
102 | ide_init_port_hw(hwif, &hw); | 102 | ide_init_port_hw(hwif, &hw); |
103 | hwif->mmio = 1; | ||
103 | 104 | ||
104 | if (mmio) { | 105 | if (mmio) |
105 | hwif->mmio = 1; | ||
106 | default_hwif_mmiops(hwif); | 106 | default_hwif_mmiops(hwif); |
107 | } | ||
108 | 107 | ||
109 | idx[0] = hwif->index; | 108 | idx[0] = hwif->index; |
110 | 109 | ||
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index eaf5dbe58bc2..7429b80cb089 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c | |||
@@ -120,7 +120,7 @@ static int __init macide_init(void) | |||
120 | 120 | ||
121 | macide_setup_ports(&hw, base, irq, ack_intr); | 121 | macide_setup_ports(&hw, base, irq, ack_intr); |
122 | 122 | ||
123 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 123 | hwif = ide_find_port(); |
124 | if (hwif) { | 124 | if (hwif) { |
125 | u8 index = hwif->index; | 125 | u8 index = hwif->index; |
126 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 126 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 2da28759686e..fcbff0eced1b 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -137,7 +137,7 @@ static int __init q40ide_init(void) | |||
137 | // m68kide_iops, | 137 | // m68kide_iops, |
138 | q40ide_default_irq(pcide_bases[i])); | 138 | q40ide_default_irq(pcide_bases[i])); |
139 | 139 | ||
140 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 140 | hwif = ide_find_port(); |
141 | if (hwif) { | 141 | if (hwif) { |
142 | ide_init_port_data(hwif, hwif->index); | 142 | ide_init_port_data(hwif, hwif->index); |
143 | ide_init_port_hw(hwif, &hw); | 143 | ide_init_port_hw(hwif, &hw); |
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 7016bdf4fcc1..6e820c7c5c6b 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c | |||
@@ -88,12 +88,12 @@ | |||
88 | static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ | 88 | static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * qd_select: | 91 | * qd65xx_select: |
92 | * | 92 | * |
93 | * This routine is invoked from ide.c to prepare for access to a given drive. | 93 | * This routine is invoked to prepare for access to a given drive. |
94 | */ | 94 | */ |
95 | 95 | ||
96 | static void qd_select (ide_drive_t *drive) | 96 | static void qd65xx_select(ide_drive_t *drive) |
97 | { | 97 | { |
98 | u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | | 98 | u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | |
99 | (QD_TIMREG(drive) & 0x02); | 99 | (QD_TIMREG(drive) & 0x02); |
@@ -168,36 +168,15 @@ static int qd_find_disk_type (ide_drive_t *drive, | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * qd_timing_ok: | ||
172 | * | ||
173 | * check whether timings don't conflict | ||
174 | */ | ||
175 | |||
176 | static int qd_timing_ok (ide_drive_t drives[]) | ||
177 | { | ||
178 | return (IDE_IMPLY(drives[0].present && drives[1].present, | ||
179 | IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1), | ||
180 | QD_TIMING(drives) == QD_TIMING(drives+1)))); | ||
181 | /* if same timing register, must be same timing */ | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * qd_set_timing: | 171 | * qd_set_timing: |
186 | * | 172 | * |
187 | * records the timing, and enables selectproc as needed | 173 | * records the timing |
188 | */ | 174 | */ |
189 | 175 | ||
190 | static void qd_set_timing (ide_drive_t *drive, u8 timing) | 176 | static void qd_set_timing (ide_drive_t *drive, u8 timing) |
191 | { | 177 | { |
192 | ide_hwif_t *hwif = HWIF(drive); | ||
193 | |||
194 | drive->drive_data &= 0xff00; | 178 | drive->drive_data &= 0xff00; |
195 | drive->drive_data |= timing; | 179 | drive->drive_data |= timing; |
196 | if (qd_timing_ok(hwif->drives)) { | ||
197 | qd_select(drive); /* selects once */ | ||
198 | hwif->selectproc = NULL; | ||
199 | } else | ||
200 | hwif->selectproc = &qd_select; | ||
201 | 180 | ||
202 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); | 181 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); |
203 | } | 182 | } |
@@ -225,10 +204,11 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
225 | 204 | ||
226 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | 205 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) |
227 | { | 206 | { |
228 | int base = HWIF(drive)->select_data; | 207 | ide_hwif_t *hwif = drive->hwif; |
229 | unsigned int cycle_time; | 208 | unsigned int cycle_time; |
230 | int active_time = 175; | 209 | int active_time = 175; |
231 | int recovery_time = 415; /* worst case values from the dos driver */ | 210 | int recovery_time = 415; /* worst case values from the dos driver */ |
211 | u8 base = (hwif->config_data & 0xff00) >> 8; | ||
232 | 212 | ||
233 | if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { | 213 | if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { |
234 | cycle_time = ide_pio_cycle_time(drive, pio); | 214 | cycle_time = ide_pio_cycle_time(drive, pio); |
@@ -299,21 +279,10 @@ static int __init qd_testreg(int port) | |||
299 | return (readreg != QD_TESTVAL); | 279 | return (readreg != QD_TESTVAL); |
300 | } | 280 | } |
301 | 281 | ||
302 | /* | ||
303 | * qd_setup: | ||
304 | * | ||
305 | * called to setup an ata channel : adjusts attributes & links for tuning | ||
306 | */ | ||
307 | |||
308 | static void __init qd_setup(ide_hwif_t *hwif, int base, int config) | ||
309 | { | ||
310 | hwif->select_data = base; | ||
311 | hwif->config_data = config; | ||
312 | } | ||
313 | |||
314 | static void __init qd6500_port_init_devs(ide_hwif_t *hwif) | 282 | static void __init qd6500_port_init_devs(ide_hwif_t *hwif) |
315 | { | 283 | { |
316 | u8 base = hwif->select_data, config = QD_CONFIG(hwif); | 284 | u8 base = (hwif->config_data & 0xff00) >> 8; |
285 | u8 config = QD_CONFIG(hwif); | ||
317 | 286 | ||
318 | hwif->drives[0].drive_data = QD6500_DEF_DATA; | 287 | hwif->drives[0].drive_data = QD6500_DEF_DATA; |
319 | hwif->drives[1].drive_data = QD6500_DEF_DATA; | 288 | hwif->drives[1].drive_data = QD6500_DEF_DATA; |
@@ -322,9 +291,10 @@ static void __init qd6500_port_init_devs(ide_hwif_t *hwif) | |||
322 | static void __init qd6580_port_init_devs(ide_hwif_t *hwif) | 291 | static void __init qd6580_port_init_devs(ide_hwif_t *hwif) |
323 | { | 292 | { |
324 | u16 t1, t2; | 293 | u16 t1, t2; |
325 | u8 base = hwif->select_data, config = QD_CONFIG(hwif); | 294 | u8 base = (hwif->config_data & 0xff00) >> 8; |
295 | u8 config = QD_CONFIG(hwif); | ||
326 | 296 | ||
327 | if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) { | 297 | if (hwif->host_flags & IDE_HFLAG_SINGLE) { |
328 | t1 = QD6580_DEF_DATA; | 298 | t1 = QD6580_DEF_DATA; |
329 | t2 = QD6580_DEF_DATA2; | 299 | t2 = QD6580_DEF_DATA2; |
330 | } else | 300 | } else |
@@ -355,14 +325,18 @@ static int __init qd_probe(int base) | |||
355 | u8 config, unit; | 325 | u8 config, unit; |
356 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 326 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
357 | hw_regs_t hw[2]; | 327 | hw_regs_t hw[2]; |
328 | struct ide_port_info d = qd65xx_port_info; | ||
358 | 329 | ||
359 | config = inb(QD_CONFIG_PORT); | 330 | config = inb(QD_CONFIG_PORT); |
360 | 331 | ||
361 | if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) | 332 | if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) |
362 | return 1; | 333 | return -ENODEV; |
363 | 334 | ||
364 | unit = ! (config & QD_CONFIG_IDE_BASEPORT); | 335 | unit = ! (config & QD_CONFIG_IDE_BASEPORT); |
365 | 336 | ||
337 | if (unit) | ||
338 | d.host_flags |= IDE_HFLAG_QD_2ND_PORT; | ||
339 | |||
366 | memset(&hw, 0, sizeof(hw)); | 340 | memset(&hw, 0, sizeof(hw)); |
367 | 341 | ||
368 | ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); | 342 | ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); |
@@ -373,30 +347,37 @@ static int __init qd_probe(int base) | |||
373 | 347 | ||
374 | if ((config & 0xf0) == QD_CONFIG_QD6500) { | 348 | if ((config & 0xf0) == QD_CONFIG_QD6500) { |
375 | 349 | ||
376 | if (qd_testreg(base)) return 1; /* bad register */ | 350 | if (qd_testreg(base)) |
351 | return -ENODEV; /* bad register */ | ||
377 | 352 | ||
378 | /* qd6500 found */ | 353 | /* qd6500 found */ |
379 | 354 | ||
380 | hwif = &ide_hwifs[unit]; | ||
381 | printk(KERN_NOTICE "%s: qd6500 at %#x\n", hwif->name, base); | ||
382 | printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n", | ||
383 | config, QD_ID3); | ||
384 | |||
385 | if (config & QD_CONFIG_DISABLED) { | 355 | if (config & QD_CONFIG_DISABLED) { |
386 | printk(KERN_WARNING "qd6500 is disabled !\n"); | 356 | printk(KERN_WARNING "qd6500 is disabled !\n"); |
387 | return 1; | 357 | return -ENODEV; |
388 | } | 358 | } |
389 | 359 | ||
360 | printk(KERN_NOTICE "qd6500 at %#x\n", base); | ||
361 | printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n", | ||
362 | config, QD_ID3); | ||
363 | |||
364 | d.host_flags |= IDE_HFLAG_SINGLE; | ||
365 | |||
366 | hwif = ide_find_port_slot(&d); | ||
367 | if (hwif == NULL) | ||
368 | return -ENOENT; | ||
369 | |||
390 | ide_init_port_hw(hwif, &hw[unit]); | 370 | ide_init_port_hw(hwif, &hw[unit]); |
391 | 371 | ||
392 | qd_setup(hwif, base, config); | 372 | hwif->config_data = (base << 8) | config; |
393 | 373 | ||
394 | hwif->port_init_devs = qd6500_port_init_devs; | 374 | hwif->port_init_devs = qd6500_port_init_devs; |
395 | hwif->set_pio_mode = &qd6500_set_pio_mode; | 375 | hwif->set_pio_mode = qd6500_set_pio_mode; |
376 | hwif->selectproc = qd65xx_select; | ||
396 | 377 | ||
397 | idx[unit] = unit; | 378 | idx[unit] = hwif->index; |
398 | 379 | ||
399 | ide_device_add(idx, &qd65xx_port_info); | 380 | ide_device_add(idx, &d); |
400 | 381 | ||
401 | return 1; | 382 | return 1; |
402 | } | 383 | } |
@@ -406,8 +387,8 @@ static int __init qd_probe(int base) | |||
406 | 387 | ||
407 | u8 control; | 388 | u8 control; |
408 | 389 | ||
409 | if (qd_testreg(base) || qd_testreg(base+0x02)) return 1; | 390 | if (qd_testreg(base) || qd_testreg(base + 0x02)) |
410 | /* bad registers */ | 391 | return -ENODEV; /* bad registers */ |
411 | 392 | ||
412 | /* qd6580 found */ | 393 | /* qd6580 found */ |
413 | 394 | ||
@@ -422,46 +403,52 @@ static int __init qd_probe(int base) | |||
422 | if (control & QD_CONTR_SEC_DISABLED) { | 403 | if (control & QD_CONTR_SEC_DISABLED) { |
423 | /* secondary disabled */ | 404 | /* secondary disabled */ |
424 | 405 | ||
425 | hwif = &ide_hwifs[unit]; | 406 | printk(KERN_INFO "qd6580: single IDE board\n"); |
426 | printk(KERN_INFO "%s: qd6580: single IDE board\n", | 407 | |
427 | hwif->name); | 408 | d.host_flags |= IDE_HFLAG_SINGLE; |
409 | |||
410 | hwif = ide_find_port_slot(&d); | ||
411 | if (hwif == NULL) | ||
412 | return -ENOENT; | ||
428 | 413 | ||
429 | ide_init_port_hw(hwif, &hw[unit]); | 414 | ide_init_port_hw(hwif, &hw[unit]); |
430 | 415 | ||
431 | qd_setup(hwif, base, config | (control << 8)); | 416 | hwif->config_data = (base << 8) | config; |
432 | 417 | ||
433 | hwif->port_init_devs = qd6580_port_init_devs; | 418 | hwif->port_init_devs = qd6580_port_init_devs; |
434 | hwif->set_pio_mode = &qd6580_set_pio_mode; | 419 | hwif->set_pio_mode = qd6580_set_pio_mode; |
420 | hwif->selectproc = qd65xx_select; | ||
435 | 421 | ||
436 | idx[unit] = unit; | 422 | idx[unit] = hwif->index; |
437 | 423 | ||
438 | ide_device_add(idx, &qd65xx_port_info); | 424 | ide_device_add(idx, &d); |
439 | 425 | ||
440 | return 1; | 426 | return 1; |
441 | } else { | 427 | } else { |
442 | ide_hwif_t *mate; | 428 | ide_hwif_t *mate; |
443 | 429 | ||
444 | hwif = &ide_hwifs[0]; | ||
445 | mate = &ide_hwifs[1]; | ||
446 | /* secondary enabled */ | 430 | /* secondary enabled */ |
447 | printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n", | 431 | printk(KERN_INFO "qd6580: dual IDE board\n"); |
448 | hwif->name, mate->name); | 432 | |
449 | 433 | hwif = ide_find_port(); | |
450 | ide_init_port_hw(hwif, &hw[0]); | 434 | if (hwif) { |
451 | ide_init_port_hw(mate, &hw[1]); | 435 | ide_init_port_hw(hwif, &hw[0]); |
452 | 436 | hwif->config_data = (base << 8) | config; | |
453 | qd_setup(hwif, base, config | (control << 8)); | 437 | hwif->port_init_devs = qd6580_port_init_devs; |
454 | 438 | hwif->set_pio_mode = qd6580_set_pio_mode; | |
455 | hwif->port_init_devs = qd6580_port_init_devs; | 439 | hwif->selectproc = qd65xx_select; |
456 | hwif->set_pio_mode = &qd6580_set_pio_mode; | 440 | idx[0] = hwif->index; |
457 | 441 | } | |
458 | qd_setup(mate, base, config | (control << 8)); | 442 | |
459 | 443 | mate = ide_find_port(); | |
460 | mate->port_init_devs = qd6580_port_init_devs; | 444 | if (mate) { |
461 | mate->set_pio_mode = &qd6580_set_pio_mode; | 445 | ide_init_port_hw(mate, &hw[1]); |
462 | 446 | mate->config_data = (base << 8) | config; | |
463 | idx[0] = 0; | 447 | mate->port_init_devs = qd6580_port_init_devs; |
464 | idx[1] = 1; | 448 | mate->set_pio_mode = qd6580_set_pio_mode; |
449 | mate->selectproc = qd65xx_select; | ||
450 | idx[1] = mate->index; | ||
451 | } | ||
465 | 452 | ||
466 | ide_device_add(idx, &qd65xx_port_info); | 453 | ide_device_add(idx, &qd65xx_port_info); |
467 | 454 | ||
@@ -469,7 +456,7 @@ static int __init qd_probe(int base) | |||
469 | } | 456 | } |
470 | } | 457 | } |
471 | /* no qd65xx found */ | 458 | /* no qd65xx found */ |
472 | return 1; | 459 | return -ENODEV; |
473 | } | 460 | } |
474 | 461 | ||
475 | int probe_qd65xx = 0; | 462 | int probe_qd65xx = 0; |
@@ -479,14 +466,18 @@ MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); | |||
479 | 466 | ||
480 | static int __init qd65xx_init(void) | 467 | static int __init qd65xx_init(void) |
481 | { | 468 | { |
469 | int rc1, rc2 = -ENODEV; | ||
470 | |||
482 | if (probe_qd65xx == 0) | 471 | if (probe_qd65xx == 0) |
483 | return -ENODEV; | 472 | return -ENODEV; |
484 | 473 | ||
485 | if (qd_probe(0x30)) | 474 | rc1 = qd_probe(0x30); |
486 | qd_probe(0xb0); | 475 | if (rc1) |
487 | if (ide_hwifs[0].chipset != ide_qd65xx && | 476 | rc2 = qd_probe(0xb0); |
488 | ide_hwifs[1].chipset != ide_qd65xx) | 477 | |
478 | if (rc1 < 0 && rc2 < 0) | ||
489 | return -ENODEV; | 479 | return -ENODEV; |
480 | |||
490 | return 0; | 481 | return 0; |
491 | } | 482 | } |
492 | 483 | ||
diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/legacy/qd65xx.h index 28dd50a15d55..c83dea85e621 100644 --- a/drivers/ide/legacy/qd65xx.h +++ b/drivers/ide/legacy/qd65xx.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #define QD_ID3 ((config & QD_CONFIG_ID3)!=0) | 30 | #define QD_ID3 ((config & QD_CONFIG_ID3)!=0) |
31 | 31 | ||
32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) | 32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) |
33 | #define QD_CONTROL(hwif) (((hwif)->config_data & 0xff00) >> 8) | ||
34 | 33 | ||
35 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) | 34 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) |
36 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) | 35 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) |
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c index bc1944811b99..4d90badd2bda 100644 --- a/drivers/ide/legacy/umc8672.c +++ b/drivers/ide/legacy/umc8672.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * VLB Controller Support from | 22 | * VLB Controller Support from |
23 | * Wolfram Podien | 23 | * Wolfram Podien |
24 | * Rohoefe 3 | 24 | * Rohoefe 3 |
25 | * D28832 Achim | 25 | * D28832 Achim |
@@ -32,7 +32,7 @@ | |||
32 | * #define UMC_DRIVE0 11 | 32 | * #define UMC_DRIVE0 11 |
33 | * in the beginning of the driver, which sets the speed of drive 0 to 11 (there | 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 | 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 | 35 | * the results from the DOS speed test program supplied from UMC. 11 is the |
36 | * highest speed (about PIO mode 3) | 36 | * highest speed (about PIO mode 3) |
37 | */ | 37 | */ |
38 | #define REALLY_SLOW_IO /* some systems can safely undef this */ | 38 | #define REALLY_SLOW_IO /* some systems can safely undef this */ |
@@ -60,62 +60,62 @@ | |||
60 | #define UMC_DRIVE3 1 /* In case of crash reduce speed */ | 60 | #define UMC_DRIVE3 1 /* In case of crash reduce speed */ |
61 | 61 | ||
62 | static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; | 62 | static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; |
63 | static const u8 pio_to_umc [5] = {0,3,7,10,11}; /* rough guesses */ | 63 | static const u8 pio_to_umc [5] = {0, 3, 7, 10, 11}; /* rough guesses */ |
64 | 64 | ||
65 | /* 0 1 2 3 4 5 6 7 8 9 10 11 */ | 65 | /* 0 1 2 3 4 5 6 7 8 9 10 11 */ |
66 | static const u8 speedtab [3][12] = { | 66 | static const u8 speedtab [3][12] = { |
67 | {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, | 67 | {0x0f, 0x0b, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, |
68 | {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, | 68 | {0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, |
69 | {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}}; | 69 | {0xff, 0xcb, 0xc0, 0x58, 0x36, 0x33, 0x23, 0x22, 0x21, 0x11, 0x10, 0x0} |
70 | }; | ||
70 | 71 | ||
71 | static void out_umc (char port,char wert) | 72 | static void out_umc(char port, char wert) |
72 | { | 73 | { |
73 | outb_p(port,0x108); | 74 | outb_p(port, 0x108); |
74 | outb_p(wert,0x109); | 75 | outb_p(wert, 0x109); |
75 | } | 76 | } |
76 | 77 | ||
77 | static inline u8 in_umc (char port) | 78 | static inline u8 in_umc(char port) |
78 | { | 79 | { |
79 | outb_p(port,0x108); | 80 | outb_p(port, 0x108); |
80 | return inb_p(0x109); | 81 | return inb_p(0x109); |
81 | } | 82 | } |
82 | 83 | ||
83 | static void umc_set_speeds (u8 speeds[]) | 84 | static void umc_set_speeds(u8 speeds[]) |
84 | { | 85 | { |
85 | int i, tmp; | 86 | int i, tmp; |
86 | 87 | ||
87 | outb_p(0x5A,0x108); /* enable umc */ | 88 | outb_p(0x5A, 0x108); /* enable umc */ |
88 | 89 | ||
89 | out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); | 90 | out_umc(0xd7, (speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); |
90 | out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); | 91 | out_umc(0xd6, (speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); |
91 | tmp = 0; | 92 | tmp = 0; |
92 | for (i = 3; i >= 0; i--) { | 93 | for (i = 3; i >= 0; i--) |
93 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; | 94 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; |
95 | out_umc(0xdc, tmp); | ||
96 | for (i = 0; i < 4; i++) { | ||
97 | out_umc(0xd0 + i, speedtab[2][speeds[i]]); | ||
98 | out_umc(0xd8 + i, speedtab[2][speeds[i]]); | ||
94 | } | 99 | } |
95 | out_umc (0xdc,tmp); | 100 | outb_p(0xa5, 0x108); /* disable umc */ |
96 | for (i = 0;i < 4; i++) { | ||
97 | out_umc (0xd0+i,speedtab[2][speeds[i]]); | ||
98 | out_umc (0xd8+i,speedtab[2][speeds[i]]); | ||
99 | } | ||
100 | outb_p(0xa5,0x108); /* disable umc */ | ||
101 | 101 | ||
102 | printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", | 102 | printk("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", |
103 | speeds[0], speeds[1], speeds[2], speeds[3]); | 103 | speeds[0], speeds[1], speeds[2], speeds[3]); |
104 | } | 104 | } |
105 | 105 | ||
106 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) | 106 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) |
107 | { | 107 | { |
108 | ide_hwif_t *hwif = drive->hwif; | ||
108 | unsigned long flags; | 109 | unsigned long flags; |
109 | ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup; | ||
110 | 110 | ||
111 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", | 111 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", |
112 | drive->name, pio, pio_to_umc[pio]); | 112 | drive->name, pio, pio_to_umc[pio]); |
113 | spin_lock_irqsave(&ide_lock, flags); | 113 | spin_lock_irqsave(&ide_lock, flags); |
114 | if (hwgroup && hwgroup->handler != NULL) { | 114 | if (hwif->mate && hwif->mate->hwgroup->handler) { |
115 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); | 115 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); |
116 | } else { | 116 | } else { |
117 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; | 117 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; |
118 | umc_set_speeds (current_speeds); | 118 | umc_set_speeds(current_speeds); |
119 | } | 119 | } |
120 | spin_unlock_irqrestore(&ide_lock, flags); | 120 | spin_unlock_irqrestore(&ide_lock, flags); |
121 | } | 121 | } |
@@ -128,8 +128,9 @@ static const struct ide_port_info umc8672_port_info __initdata = { | |||
128 | 128 | ||
129 | static int __init umc8672_probe(void) | 129 | static int __init umc8672_probe(void) |
130 | { | 130 | { |
131 | ide_hwif_t *hwif, *mate; | ||
131 | unsigned long flags; | 132 | unsigned long flags; |
132 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 133 | static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
133 | hw_regs_t hw[2]; | 134 | hw_regs_t hw[2]; |
134 | 135 | ||
135 | if (!request_region(0x108, 2, "umc8672")) { | 136 | if (!request_region(0x108, 2, "umc8672")) { |
@@ -137,16 +138,16 @@ static int __init umc8672_probe(void) | |||
137 | return 1; | 138 | return 1; |
138 | } | 139 | } |
139 | local_irq_save(flags); | 140 | local_irq_save(flags); |
140 | outb_p(0x5A,0x108); /* enable umc */ | 141 | outb_p(0x5A, 0x108); /* enable umc */ |
141 | if (in_umc (0xd5) != 0xa0) { | 142 | if (in_umc (0xd5) != 0xa0) { |
142 | local_irq_restore(flags); | 143 | local_irq_restore(flags); |
143 | printk(KERN_ERR "umc8672: not found\n"); | 144 | printk(KERN_ERR "umc8672: not found\n"); |
144 | release_region(0x108, 2); | 145 | release_region(0x108, 2); |
145 | return 1; | 146 | return 1; |
146 | } | 147 | } |
147 | outb_p(0xa5,0x108); /* disable umc */ | 148 | outb_p(0xa5, 0x108); /* disable umc */ |
148 | 149 | ||
149 | umc_set_speeds (current_speeds); | 150 | umc_set_speeds(current_speeds); |
150 | local_irq_restore(flags); | 151 | local_irq_restore(flags); |
151 | 152 | ||
152 | memset(&hw, 0, sizeof(hw)); | 153 | memset(&hw, 0, sizeof(hw)); |
@@ -157,18 +158,26 @@ static int __init umc8672_probe(void) | |||
157 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 158 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
158 | hw[1].irq = 15; | 159 | hw[1].irq = 15; |
159 | 160 | ||
160 | ide_init_port_hw(&ide_hwifs[0], &hw[0]); | 161 | hwif = ide_find_port(); |
161 | ide_init_port_hw(&ide_hwifs[1], &hw[1]); | 162 | if (hwif) { |
163 | ide_init_port_hw(hwif, &hw[0]); | ||
164 | hwif->set_pio_mode = umc_set_pio_mode; | ||
165 | idx[0] = hwif->index; | ||
166 | } | ||
162 | 167 | ||
163 | ide_hwifs[0].set_pio_mode = &umc_set_pio_mode; | 168 | mate = ide_find_port(); |
164 | ide_hwifs[1].set_pio_mode = &umc_set_pio_mode; | 169 | if (mate) { |
170 | ide_init_port_hw(mate, &hw[1]); | ||
171 | mate->set_pio_mode = umc_set_pio_mode; | ||
172 | idx[1] = mate->index; | ||
173 | } | ||
165 | 174 | ||
166 | ide_device_add(idx, &umc8672_port_info); | 175 | ide_device_add(idx, &umc8672_port_info); |
167 | 176 | ||
168 | return 0; | 177 | return 0; |
169 | } | 178 | } |
170 | 179 | ||
171 | int probe_umc8672 = 0; | 180 | int probe_umc8672; |
172 | 181 | ||
173 | module_param_named(probe, probe_umc8672, bool, 0); | 182 | module_param_named(probe, probe_umc8672, bool, 0); |
174 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); | 183 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); |