diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/pci/cmd640.c | 94 |
1 files changed, 48 insertions, 46 deletions
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index 662099a98a72..b076dbfc43a7 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | /* | 5 | /* |
6 | * Original authors: abramov@cecmow.enet.dec.com (Igor Abramov) | 6 | * Original authors: abramov@cecmow.enet.dec.com (Igor Abramov) |
7 | * mlord@pobox.com (Mark Lord) | 7 | * mlord@pobox.com (Mark Lord) |
8 | * | 8 | * |
9 | * See linux/MAINTAINERS for address of current maintainer. | 9 | * See linux/MAINTAINERS for address of current maintainer. |
10 | * | 10 | * |
@@ -98,7 +98,7 @@ | |||
98 | 98 | ||
99 | #define CMD640_PREFETCH_MASKS 1 | 99 | #define CMD640_PREFETCH_MASKS 1 |
100 | 100 | ||
101 | //#define CMD640_DUMP_REGS | 101 | /*#define CMD640_DUMP_REGS */ |
102 | 102 | ||
103 | #include <linux/types.h> | 103 | #include <linux/types.h> |
104 | #include <linux/kernel.h> | 104 | #include <linux/kernel.h> |
@@ -112,7 +112,7 @@ | |||
112 | /* | 112 | /* |
113 | * This flag is set in ide.c by the parameter: ide0=cmd640_vlb | 113 | * This flag is set in ide.c by the parameter: ide0=cmd640_vlb |
114 | */ | 114 | */ |
115 | int cmd640_vlb = 0; | 115 | int cmd640_vlb; |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * CMD640 specific registers definition. | 118 | * CMD640 specific registers definition. |
@@ -206,13 +206,13 @@ static unsigned int cmd640_chip_version; | |||
206 | 206 | ||
207 | /* PCI method 1 access */ | 207 | /* PCI method 1 access */ |
208 | 208 | ||
209 | static void put_cmd640_reg_pci1 (u16 reg, u8 val) | 209 | static void put_cmd640_reg_pci1(u16 reg, u8 val) |
210 | { | 210 | { |
211 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); | 211 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); |
212 | outb_p(val, (reg & 3) | 0xcfc); | 212 | outb_p(val, (reg & 3) | 0xcfc); |
213 | } | 213 | } |
214 | 214 | ||
215 | static u8 get_cmd640_reg_pci1 (u16 reg) | 215 | static u8 get_cmd640_reg_pci1(u16 reg) |
216 | { | 216 | { |
217 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); | 217 | outl_p((reg & 0xfc) | cmd640_key, 0xcf8); |
218 | return inb_p((reg & 3) | 0xcfc); | 218 | return inb_p((reg & 3) | 0xcfc); |
@@ -220,14 +220,14 @@ static u8 get_cmd640_reg_pci1 (u16 reg) | |||
220 | 220 | ||
221 | /* PCI method 2 access (from CMD datasheet) */ | 221 | /* PCI method 2 access (from CMD datasheet) */ |
222 | 222 | ||
223 | static void put_cmd640_reg_pci2 (u16 reg, u8 val) | 223 | static void put_cmd640_reg_pci2(u16 reg, u8 val) |
224 | { | 224 | { |
225 | outb_p(0x10, 0xcf8); | 225 | outb_p(0x10, 0xcf8); |
226 | outb_p(val, cmd640_key + reg); | 226 | outb_p(val, cmd640_key + reg); |
227 | outb_p(0, 0xcf8); | 227 | outb_p(0, 0xcf8); |
228 | } | 228 | } |
229 | 229 | ||
230 | static u8 get_cmd640_reg_pci2 (u16 reg) | 230 | static u8 get_cmd640_reg_pci2(u16 reg) |
231 | { | 231 | { |
232 | u8 b; | 232 | u8 b; |
233 | 233 | ||
@@ -239,13 +239,13 @@ static u8 get_cmd640_reg_pci2 (u16 reg) | |||
239 | 239 | ||
240 | /* VLB access */ | 240 | /* VLB access */ |
241 | 241 | ||
242 | static void put_cmd640_reg_vlb (u16 reg, u8 val) | 242 | static void put_cmd640_reg_vlb(u16 reg, u8 val) |
243 | { | 243 | { |
244 | outb_p(reg, cmd640_key); | 244 | outb_p(reg, cmd640_key); |
245 | outb_p(val, cmd640_key + 4); | 245 | outb_p(val, cmd640_key + 4); |
246 | } | 246 | } |
247 | 247 | ||
248 | static u8 get_cmd640_reg_vlb (u16 reg) | 248 | static u8 get_cmd640_reg_vlb(u16 reg) |
249 | { | 249 | { |
250 | outb_p(reg, cmd640_key); | 250 | outb_p(reg, cmd640_key); |
251 | return inb_p(cmd640_key + 4); | 251 | return inb_p(cmd640_key + 4); |
@@ -267,11 +267,11 @@ static void put_cmd640_reg(u16 reg, u8 val) | |||
267 | unsigned long flags; | 267 | unsigned long flags; |
268 | 268 | ||
269 | spin_lock_irqsave(&cmd640_lock, flags); | 269 | spin_lock_irqsave(&cmd640_lock, flags); |
270 | __put_cmd640_reg(reg,val); | 270 | __put_cmd640_reg(reg, val); |
271 | spin_unlock_irqrestore(&cmd640_lock, flags); | 271 | spin_unlock_irqrestore(&cmd640_lock, flags); |
272 | } | 272 | } |
273 | 273 | ||
274 | static int __init match_pci_cmd640_device (void) | 274 | static int __init match_pci_cmd640_device(void) |
275 | { | 275 | { |
276 | const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06}; | 276 | const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06}; |
277 | unsigned int i; | 277 | unsigned int i; |
@@ -291,7 +291,7 @@ static int __init match_pci_cmd640_device (void) | |||
291 | /* | 291 | /* |
292 | * Probe for CMD640x -- pci method 1 | 292 | * Probe for CMD640x -- pci method 1 |
293 | */ | 293 | */ |
294 | static int __init probe_for_cmd640_pci1 (void) | 294 | static int __init probe_for_cmd640_pci1(void) |
295 | { | 295 | { |
296 | __get_cmd640_reg = get_cmd640_reg_pci1; | 296 | __get_cmd640_reg = get_cmd640_reg_pci1; |
297 | __put_cmd640_reg = put_cmd640_reg_pci1; | 297 | __put_cmd640_reg = put_cmd640_reg_pci1; |
@@ -307,7 +307,7 @@ static int __init probe_for_cmd640_pci1 (void) | |||
307 | /* | 307 | /* |
308 | * Probe for CMD640x -- pci method 2 | 308 | * Probe for CMD640x -- pci method 2 |
309 | */ | 309 | */ |
310 | static int __init probe_for_cmd640_pci2 (void) | 310 | static int __init probe_for_cmd640_pci2(void) |
311 | { | 311 | { |
312 | __get_cmd640_reg = get_cmd640_reg_pci2; | 312 | __get_cmd640_reg = get_cmd640_reg_pci2; |
313 | __put_cmd640_reg = put_cmd640_reg_pci2; | 313 | __put_cmd640_reg = put_cmd640_reg_pci2; |
@@ -321,7 +321,7 @@ static int __init probe_for_cmd640_pci2 (void) | |||
321 | /* | 321 | /* |
322 | * Probe for CMD640x -- vlb | 322 | * Probe for CMD640x -- vlb |
323 | */ | 323 | */ |
324 | static int __init probe_for_cmd640_vlb (void) | 324 | static int __init probe_for_cmd640_vlb(void) |
325 | { | 325 | { |
326 | u8 b; | 326 | u8 b; |
327 | 327 | ||
@@ -342,7 +342,7 @@ static int __init probe_for_cmd640_vlb (void) | |||
342 | * Returns 1 if an IDE interface/drive exists at 0x170, | 342 | * Returns 1 if an IDE interface/drive exists at 0x170, |
343 | * Returns 0 otherwise. | 343 | * Returns 0 otherwise. |
344 | */ | 344 | */ |
345 | static int __init secondary_port_responding (void) | 345 | static int __init secondary_port_responding(void) |
346 | { | 346 | { |
347 | unsigned long flags; | 347 | unsigned long flags; |
348 | 348 | ||
@@ -366,7 +366,7 @@ static int __init secondary_port_responding (void) | |||
366 | /* | 366 | /* |
367 | * Dump out all cmd640 registers. May be called from ide.c | 367 | * Dump out all cmd640 registers. May be called from ide.c |
368 | */ | 368 | */ |
369 | static void cmd640_dump_regs (void) | 369 | static void cmd640_dump_regs(void) |
370 | { | 370 | { |
371 | unsigned int reg = cmd640_vlb ? 0x50 : 0x00; | 371 | unsigned int reg = cmd640_vlb ? 0x50 : 0x00; |
372 | 372 | ||
@@ -435,7 +435,7 @@ static void set_prefetch_mode(ide_drive_t *drive, unsigned int index, int mode) | |||
435 | /* | 435 | /* |
436 | * Dump out current drive clocks settings | 436 | * Dump out current drive clocks settings |
437 | */ | 437 | */ |
438 | static void display_clocks (unsigned int index) | 438 | static void display_clocks(unsigned int index) |
439 | { | 439 | { |
440 | u8 active_count, recovery_count; | 440 | u8 active_count, recovery_count; |
441 | 441 | ||
@@ -454,7 +454,7 @@ static void display_clocks (unsigned int index) | |||
454 | * Pack active and recovery counts into single byte representation | 454 | * Pack active and recovery counts into single byte representation |
455 | * used by controller | 455 | * used by controller |
456 | */ | 456 | */ |
457 | static inline u8 pack_nibbles (u8 upper, u8 lower) | 457 | static inline u8 pack_nibbles(u8 upper, u8 lower) |
458 | { | 458 | { |
459 | return ((upper & 0x0f) << 4) | (lower & 0x0f); | 459 | return ((upper & 0x0f) << 4) | (lower & 0x0f); |
460 | } | 460 | } |
@@ -462,7 +462,7 @@ static inline u8 pack_nibbles (u8 upper, u8 lower) | |||
462 | /* | 462 | /* |
463 | * This routine retrieves the initial drive timings from the chipset. | 463 | * This routine retrieves the initial drive timings from the chipset. |
464 | */ | 464 | */ |
465 | static void __init retrieve_drive_counts (unsigned int index) | 465 | static void __init retrieve_drive_counts(unsigned int index) |
466 | { | 466 | { |
467 | u8 b; | 467 | u8 b; |
468 | 468 | ||
@@ -471,10 +471,10 @@ static void __init retrieve_drive_counts (unsigned int index) | |||
471 | */ | 471 | */ |
472 | b = get_cmd640_reg(arttim_regs[index]) & ~0x3f; | 472 | b = get_cmd640_reg(arttim_regs[index]) & ~0x3f; |
473 | switch (b) { | 473 | switch (b) { |
474 | case 0x00: b = 4; break; | 474 | case 0x00: b = 4; break; |
475 | case 0x80: b = 3; break; | 475 | case 0x80: b = 3; break; |
476 | case 0x40: b = 2; break; | 476 | case 0x40: b = 2; break; |
477 | default: b = 5; break; | 477 | default: b = 5; break; |
478 | } | 478 | } |
479 | setup_counts[index] = b; | 479 | setup_counts[index] = b; |
480 | 480 | ||
@@ -523,11 +523,11 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index) | |||
523 | * Convert setup_count to internal chipset representation | 523 | * Convert setup_count to internal chipset representation |
524 | */ | 524 | */ |
525 | switch (setup_count) { | 525 | switch (setup_count) { |
526 | case 4: setup_count = 0x00; break; | 526 | case 4: setup_count = 0x00; break; |
527 | case 3: setup_count = 0x80; break; | 527 | case 3: setup_count = 0x80; break; |
528 | case 1: | 528 | case 1: |
529 | case 2: setup_count = 0x40; break; | 529 | case 2: setup_count = 0x40; break; |
530 | default: setup_count = 0xc0; /* case 5 */ | 530 | default: setup_count = 0xc0; /* case 5 */ |
531 | } | 531 | } |
532 | 532 | ||
533 | /* | 533 | /* |
@@ -607,20 +607,21 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
607 | u8 b; | 607 | u8 b; |
608 | 608 | ||
609 | switch (pio) { | 609 | switch (pio) { |
610 | case 6: /* set fast-devsel off */ | 610 | case 6: /* set fast-devsel off */ |
611 | case 7: /* set fast-devsel on */ | 611 | case 7: /* set fast-devsel on */ |
612 | b = get_cmd640_reg(CNTRL) & ~0x27; | 612 | b = get_cmd640_reg(CNTRL) & ~0x27; |
613 | if (pio & 1) | 613 | if (pio & 1) |
614 | b |= 0x27; | 614 | b |= 0x27; |
615 | put_cmd640_reg(CNTRL, b); | 615 | put_cmd640_reg(CNTRL, b); |
616 | printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis"); | 616 | printk("%s: %sabled cmd640 fast host timing (devsel)\n", |
617 | return; | 617 | drive->name, (pio & 1) ? "en" : "dis"); |
618 | 618 | return; | |
619 | case 8: /* set prefetch off */ | 619 | case 8: /* set prefetch off */ |
620 | case 9: /* set prefetch on */ | 620 | case 9: /* set prefetch on */ |
621 | set_prefetch_mode(drive, index, pio & 1); | 621 | set_prefetch_mode(drive, index, pio & 1); |
622 | printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis"); | 622 | printk("%s: %sabled cmd640 prefetch\n", |
623 | return; | 623 | drive->name, (pio & 1) ? "en" : "dis"); |
624 | return; | ||
624 | } | 625 | } |
625 | 626 | ||
626 | cycle_time = ide_pio_cycle_time(drive, pio); | 627 | cycle_time = ide_pio_cycle_time(drive, pio); |
@@ -729,7 +730,7 @@ static int __init cmd640x_init(void) | |||
729 | cfr = get_cmd640_reg(CFR); | 730 | cfr = get_cmd640_reg(CFR); |
730 | cmd640_chip_version = cfr & CFR_DEVREV; | 731 | cmd640_chip_version = cfr & CFR_DEVREV; |
731 | if (cmd640_chip_version == 0) { | 732 | if (cmd640_chip_version == 0) { |
732 | printk ("ide: bad cmd640 revision: %d\n", cmd640_chip_version); | 733 | printk("ide: bad cmd640 revision: %d\n", cmd640_chip_version); |
733 | return 0; | 734 | return 0; |
734 | } | 735 | } |
735 | 736 | ||
@@ -835,9 +836,10 @@ static int __init cmd640x_init(void) | |||
835 | 836 | ||
836 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 837 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
837 | if (drive->autotune || ((index > 1) && second_port_toggled)) { | 838 | if (drive->autotune || ((index > 1) && second_port_toggled)) { |
838 | /* | 839 | /* |
839 | * Reset timing to the slowest speed and turn off prefetch. | 840 | * Reset timing to the slowest speed and turn off |
840 | * This way, the drive identify code has a better chance. | 841 | * prefetch. This way, the drive identify code has |
842 | * a better chance. | ||
841 | */ | 843 | */ |
842 | setup_counts [index] = 4; /* max possible */ | 844 | setup_counts [index] = 4; /* max possible */ |
843 | active_counts [index] = 16; /* max possible */ | 845 | active_counts [index] = 16; /* max possible */ |