This source file includes following definitions.
- put_cmd640_reg_pci1
- get_cmd640_reg_pci1
- put_cmd640_reg_pci2
- get_cmd640_reg_pci2
- put_cmd640_reg_vlb
- get_cmd640_reg_vlb
- probe_for_cmd640_pci1
- probe_for_cmd640_pci2
- probe_for_cmd640_vlb
- cmd640_reset_controller
- ide_probe_for_cmd640x
- cmd640_off
- set_readahead_mode
- strmatch
- known_drive_readahead
- pack_arttim
- pack_counts
- max
- max4
- cmd640_set_timing
- known_drive_pio
- cmd640_timings_to_clocks
- set_pio_mode
- cmd640_set_mode
- cmd640_tune_drive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 #undef REALLY_SLOW_IO
48
49 #include <linux/types.h>
50 #include <linux/kernel.h>
51 #include <linux/delay.h>
52 #include <linux/timer.h>
53 #include <linux/mm.h>
54 #include <linux/ioport.h>
55 #include <linux/blkdev.h>
56 #include <linux/hdreg.h>
57 #include <asm/io.h>
58 #include "ide.h"
59
60 int cmd640_vlb = 0;
61
62
63
64
65
66 #define VID 0x00
67 #define DID 0x02
68 #define PCMD 0x04
69 #define PSTTS 0x06
70 #define REVID 0x08
71 #define PROGIF 0x09
72 #define SUBCL 0x0a
73 #define BASCL 0x0b
74 #define BaseA0 0x10
75 #define BaseA1 0x14
76 #define BaseA2 0x18
77 #define BaseA3 0x1c
78 #define INTLINE 0x3c
79 #define INPINE 0x3d
80
81 #define CFR 0x50
82 #define CFR_DEVREV 0x03
83 #define CFR_IDE01INTR 0x04
84 #define CFR_DEVID 0x18
85 #define CFR_AT_VESA_078h 0x20
86 #define CFR_DSA1 0x40
87 #define CFR_DSA0 0x80
88
89 #define CNTRL 0x51
90 #define CNTRL_DIS_RA0 0x40
91 #define CNTRL_DIS_RA1 0x80
92 #define CNTRL_ENA_2ND 0x08
93
94 #define CMDTIM 0x52
95 #define ARTTIM0 0x53
96 #define DRWTIM0 0x54
97 #define ARTTIM1 0x55
98 #define DRWTIM1 0x56
99 #define ARTTIM23 0x57
100 #define DIS_RA2 0x04
101 #define DIS_RA3 0x08
102 #define DRWTIM23 0x58
103 #define BRST 0x59
104
105 static ide_tuneproc_t cmd640_tune_drive;
106
107
108 static void (*put_cmd640_reg)(int reg_no, int val);
109 static byte (*get_cmd640_reg)(int reg_no);
110
111 enum { none, vlb, pci1, pci2 };
112 static int bus_type = none;
113 static int cmd640_chip_version;
114 static int cmd640_key;
115 static int bus_speed;
116
117
118
119
120
121
122
123
124 static void put_cmd640_reg_pci1(int reg_no, int val)
125 {
126 unsigned long flags;
127
128 save_flags(flags);
129 cli();
130 outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
131 outb_p(val, (reg_no & 3) + 0xcfc);
132 restore_flags(flags);
133 }
134
135 static byte get_cmd640_reg_pci1(int reg_no)
136 {
137 byte b;
138 unsigned long flags;
139
140 save_flags(flags);
141 cli();
142 outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
143 b = inb_p(0xcfc + (reg_no & 3));
144 restore_flags(flags);
145 return b;
146 }
147
148
149
150 static void put_cmd640_reg_pci2(int reg_no, int val)
151 {
152 unsigned long flags;
153
154 save_flags(flags);
155 cli();
156 outb_p(0x10, 0xcf8);
157 outb_p(val, cmd640_key + reg_no);
158 outb_p(0, 0xcf8);
159 restore_flags(flags);
160 }
161
162 static byte get_cmd640_reg_pci2(int reg_no)
163 {
164 byte b;
165 unsigned long flags;
166
167 save_flags(flags);
168 cli();
169 outb_p(0x10, 0xcf8);
170 b = inb_p(cmd640_key + reg_no);
171 outb_p(0, 0xcf8);
172 restore_flags(flags);
173 return b;
174 }
175
176
177
178 static void put_cmd640_reg_vlb(int reg_no, int val)
179 {
180 unsigned long flags;
181
182 save_flags(flags);
183 cli();
184 outb_p(reg_no, cmd640_key + 8);
185 outb_p(val, cmd640_key + 0xc);
186 restore_flags(flags);
187 }
188
189 static byte get_cmd640_reg_vlb(int reg_no)
190 {
191 byte b;
192 unsigned long flags;
193
194 save_flags(flags);
195 cli();
196 outb_p(reg_no, cmd640_key + 8);
197 b = inb_p(cmd640_key + 0xc);
198 restore_flags(flags);
199 return b;
200 }
201
202
203
204
205
206 static int probe_for_cmd640_pci1(void)
207 {
208 long id;
209 int k;
210
211 for (k = 0x80000000; k <= 0x8000f800; k += 0x800) {
212 outl(k, 0xcf8);
213 id = inl(0xcfc);
214 if (id != 0x06401095)
215 continue;
216 put_cmd640_reg = put_cmd640_reg_pci1;
217 get_cmd640_reg = get_cmd640_reg_pci1;
218 cmd640_key = k;
219 return 1;
220 }
221 return 0;
222 }
223
224
225
226
227
228 static int probe_for_cmd640_pci2(void)
229 {
230 int i;
231 int v_id;
232 int d_id;
233
234 for (i = 0xc000; i <= 0xcf00; i += 0x100) {
235 outb(0x10, 0xcf8);
236 v_id = inw(i);
237 d_id = inw(i + 2);
238 outb(0, 0xcf8);
239 if (v_id != 0x1095 || d_id != 0x640)
240 continue;
241 put_cmd640_reg = put_cmd640_reg_pci2;
242 get_cmd640_reg = get_cmd640_reg_pci2;
243 cmd640_key = i;
244 return 1;
245 }
246 return 0;
247 }
248
249
250
251
252
253 static int probe_for_cmd640_vlb(void) {
254 byte b;
255
256 outb(CFR, 0x178);
257 b = inb(0x17c);
258 if (b == 0xff || b == 0 || (b & CFR_AT_VESA_078h)) {
259 outb(CFR, 0x78);
260 b = inb(0x7c);
261 if (b == 0xff || b == 0 || !(b & CFR_AT_VESA_078h))
262 return 0;
263 cmd640_key = 0x70;
264 } else {
265 cmd640_key = 0x170;
266 }
267 put_cmd640_reg = put_cmd640_reg_vlb;
268 get_cmd640_reg = get_cmd640_reg_vlb;
269 return 1;
270 }
271
272
273
274
275
276
277
278 static void cmd640_reset_controller(int iface_no)
279 {
280 int retry_count = 600;
281 int base_port = iface_no ? 0x170 : 0x1f0;
282
283 outb_p(4, base_port + 7);
284 udelay(5);
285 outb_p(0, base_port + 7);
286
287 do {
288 udelay(5);
289 retry_count -= 1;
290 } while ((inb_p(base_port + 7) & 0x80) && retry_count);
291
292 if (retry_count == 0)
293 printk("cmd640: failed to reset controller %d\n", iface_no);
294 #if 0
295 else
296 printk("cmd640: controller %d reset [%d]\n",
297 iface_no, retry_count);
298 #endif
299 }
300
301
302
303
304
305 int ide_probe_for_cmd640x(void)
306 {
307 int second_port;
308 byte b;
309
310 if (probe_for_cmd640_pci1()) {
311 bus_type = pci1;
312 } else if (probe_for_cmd640_pci2()) {
313 bus_type = pci2;
314 } else if (cmd640_vlb && probe_for_cmd640_vlb()) {
315
316 bus_type = vlb;
317 } else {
318 return 0;
319 }
320
321 ide_hwifs[0].serialized = 1;
322
323 #if 0
324
325 for (b = 0; b != 0xff; b++) {
326 printk(" %2x%c", get_cmd640_reg(b),
327 ((b&0xf) == 0xf) ? '\n' : ',');
328 }
329
330 #endif
331
332
333
334
335
336 put_cmd640_reg(0x5b, 0xbd);
337 if (get_cmd640_reg(0x5b) != 0xbd) {
338 printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
339 return 0;
340 }
341 put_cmd640_reg(0x5b, 0);
342
343
344
345
346
347 cmd640_chip_version = get_cmd640_reg(CFR) & CFR_DEVREV;
348 if (cmd640_chip_version == 0) {
349 printk ("ide: wrong CMD640 version -- 0\n");
350 return 0;
351 }
352
353
354
355
356 put_cmd640_reg(ARTTIM0, 0xc0);
357 put_cmd640_reg(ARTTIM1, 0xc0);
358 put_cmd640_reg(ARTTIM23, 0xcc);
359
360
361
362
363 second_port = (bus_type != vlb);
364
365
366
367
368
369
370 bus_speed = (bus_type == vlb) ? 50 : 40;
371
372
373
374
375 b = get_cmd640_reg(CNTRL);
376
377 if (second_port)
378 b |= CNTRL_ENA_2ND;
379 else
380 b &= ~CNTRL_ENA_2ND;
381
382
383
384
385 b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
386
387 put_cmd640_reg(CNTRL, b);
388
389
390
391
392
393 ide_hwifs[0].chipset = ide_cmd640;
394 ide_hwifs[0].tuneproc = &cmd640_tune_drive;
395 if (ide_hwifs[0].drives[0].autotune == 0)
396 ide_hwifs[0].drives[0].autotune = 1;
397 if (ide_hwifs[0].drives[1].autotune == 0)
398 ide_hwifs[0].drives[1].autotune = 1;
399
400
401
402
403 if (second_port) {
404 ide_hwifs[1].chipset = ide_cmd640;
405 ide_hwifs[1].tuneproc = &cmd640_tune_drive;
406 if (ide_hwifs[1].drives[0].autotune == 0)
407 ide_hwifs[1].drives[0].autotune = 1;
408 if (ide_hwifs[1].drives[1].autotune == 0)
409 ide_hwifs[1].drives[1].autotune = 1;
410
411 put_cmd640_reg(ARTTIM23, (DIS_RA2 | DIS_RA3));
412 put_cmd640_reg(DRWTIM23, 0);
413
414 cmd640_reset_controller(1);
415 }
416
417 printk("ide: buggy CMD640%c interface at ",
418 'A' - 1 + cmd640_chip_version);
419 switch (bus_type) {
420 case vlb :
421 printk("local bus, port 0x%x", cmd640_key);
422 break;
423 case pci1:
424 printk("pci, (0x%x)", cmd640_key);
425 break;
426 case pci2:
427 printk("pci,(access method 2) (0x%x)", cmd640_key);
428 break;
429 }
430
431
432
433
434 put_cmd640_reg(CMDTIM, 0);
435
436 printk("\n ... serialized, secondary interface %s\n",
437 second_port ? "enabled" : "disabled");
438
439 return 1;
440 }
441
442 int cmd640_off(void) {
443 static int a = 0;
444 byte b;
445
446 if (bus_type == none || a == 1)
447 return 0;
448 a = 1;
449 b = get_cmd640_reg(CNTRL);
450 b &= ~CNTRL_ENA_2ND;
451 put_cmd640_reg(CNTRL, b);
452 return 1;
453 }
454
455
456
457
458
459
460 static void set_readahead_mode(int mode, int if_num, int dr_num)
461 {
462 static int masks[2][2] =
463 {
464 {CNTRL_DIS_RA0, CNTRL_DIS_RA1},
465 {DIS_RA2, DIS_RA3}
466 };
467
468 int port = (if_num == 0) ? CNTRL : ARTTIM23;
469 int mask = masks[if_num][dr_num];
470 byte b;
471
472 b = get_cmd640_reg(port);
473 if (mode)
474 b &= ~mask;
475 else
476 b |= mask;
477 put_cmd640_reg(port, b);
478 }
479
480 static struct readahead_black_list {
481 const char* name;
482 int mode;
483 } drives_ra[] = {
484 { "ST3655A", 0 },
485 { "SAMSUNG", 0 },
486 { NULL, 0 }
487 };
488
489 static int strmatch(const char* pattern, const char* name) {
490 char c1, c2;
491
492 while (1) {
493 c1 = *pattern++;
494 c2 = *name++;
495 if (c1 == 0) {
496 return 0;
497 }
498 if (c1 != c2)
499 return 1;
500 }
501 }
502
503 static int known_drive_readahead(char* name) {
504 int i;
505
506 for (i = 0; drives_ra[i].name != NULL; i++) {
507 if (strmatch(drives_ra[i].name, name) == 0) {
508 return drives_ra[i].mode;
509 }
510 }
511 return -1;
512 }
513
514 static int arttim[4] = {2, 2, 2, 2};
515 static int a_count[4] = {1, 1, 1, 1};
516 static int r_count[4] = {1, 1, 1, 1};
517
518
519
520
521
522
523 inline static int pack_arttim(int clocks)
524 {
525 if (clocks <= 2) return 0x40;
526 else if (clocks == 3) return 0x80;
527 else if (clocks == 4) return 0x00;
528 else return 0xc0;
529 }
530
531
532
533
534
535
536 inline static int pack_counts(int act_count, int rec_count)
537 {
538 return ((act_count & 0x0f)<<4) | (rec_count & 0x0f);
539 }
540
541 inline int max(int a, int b) { return a > b ? a : b; }
542 inline int max4(int *p) { return max(p[0], max(p[1], max(p[2], p[3]))); }
543
544
545
546
547
548 static void cmd640_set_timing(int if_num, int dr_num)
549 {
550 int b_reg;
551 int ac, rc, at;
552
553
554
555
556
557
558
559
560 if (if_num == 0) {
561 b_reg = dr_num ? ARTTIM1 : ARTTIM0;
562 at = arttim[dr_num];
563 ac = a_count[dr_num];
564 rc = r_count[dr_num];
565 } else {
566 b_reg = ARTTIM23;
567 at = max(arttim[2], arttim[3]);
568 ac = max(a_count[2], a_count[3]);
569 rc = max(r_count[2], r_count[3]);
570 }
571
572 put_cmd640_reg(b_reg, pack_arttim(at));
573 put_cmd640_reg(b_reg + 1, pack_counts(ac, rc));
574
575
576
577
578
579 ac = max4(r_count);
580 rc = max4(a_count);
581 put_cmd640_reg(CMDTIM, pack_counts(ac, rc));
582 }
583
584
585
586
587
588 static struct pio_timing {
589 int mc_time;
590 int av_time;
591 int ds_time;
592 } pio_timings[6] = {
593 { 70, 165, 600 },
594 { 50, 125, 383 },
595 { 30, 100, 240 },
596 { 30, 80, 180 },
597 { 25, 70, 125 },
598 { 20, 50, 100 }
599 };
600
601
602
603
604
605
606 static struct drive_pio_info {
607 const char *name;
608 int pio;
609 } drive_pios[] = {
610
611
612 { "WDC AC2700", 3 },
613 { "WDC AC2540", 3 },
614 { "WDC AC2420", 3 },
615 { "WDC AC2340", 3 },
616 { "WDC AC2250", 0 },
617 { "WDC AC2200", 0 },
618 { "WDC AC2120", 0 },
619 { "WDC AC2850", 3 },
620 { "WDC AC1270", 3 },
621 { "WDC AC1170", 3 },
622 { "WDC AC1210", 1 },
623 { "WDC AC280", 0 },
624
625 { "WDC AC31000", 3 },
626
627 { "WDC AC31200", 3 },
628
629
630 { "Maxtor 7131 AT", 1 },
631 { "Maxtor 7171 AT", 1 },
632 { "Maxtor 7213 AT", 1 },
633 { "Maxtor 7245 AT", 1 },
634 { "Maxtor 7345 AT", 1 },
635 { "Maxtor 7546 AT", 3 },
636 { "Maxtor 7540 AV", 3 },
637
638 { "SAMSUNG SHD-3121A", 1 },
639 { "SAMSUNG SHD-3122A", 1 },
640 { "SAMSUNG SHD-3172A", 1 },
641
642
643
644
645
646
647
648 { "ST5660A", 3 },
649 { "ST3660A", 3 },
650 { "ST3630A", 3 },
651 { "ST3655A", 3 },
652 { "ST3391A", 3 },
653 { "ST3390A", 1 },
654 { "ST3600A", 1 },
655 { "ST3290A", 0 },
656 { "ST3144A", 0 },
657
658 { "QUANTUM ELS127A", 0 },
659 { "QUANTUM ELS170A", 0 },
660 { "QUANTUM LPS240A", 0 },
661 { "QUANTUM LPS210A", 3 },
662 { "QUANTUM LPS270A", 3 },
663 { "QUANTUM LPS365A", 3 },
664 { "QUANTUM LPS540A", 3 },
665 { "QUANTUM FIREBALL", 3 },
666 { NULL, 0 }
667 };
668
669 static int known_drive_pio(char* name) {
670 struct drive_pio_info* pi;
671
672 for (pi = drive_pios; pi->name != NULL; pi++) {
673 if (strmatch(pi->name, name) == 0)
674 return pi->pio;
675 }
676 return -1;
677 }
678
679 static void cmd640_timings_to_clocks(int mc_time, int av_time, int ds_time,
680 int clock_time, int drv_idx)
681 {
682 int a, b;
683
684 arttim[drv_idx] = (mc_time + clock_time - 1)/clock_time;
685
686 a = (av_time + clock_time - 1)/clock_time;
687 if (a < 2)
688 a = 2;
689 b = (ds_time + clock_time - 1)/clock_time - a;
690 if (b < 2)
691 b = 2;
692 if (b > 0x11) {
693 a += b - 0x11;
694 b = 0x11;
695 }
696 if (a > 0x10)
697 a = 0x10;
698 if (cmd640_chip_version > 1)
699 b -= 1;
700 if (b > 0x10)
701 b = 0x10;
702
703 a_count[drv_idx] = a;
704 r_count[drv_idx] = b;
705 }
706
707 static void set_pio_mode(int if_num, int drv_num, int mode_num) {
708 int p_base;
709 int i;
710
711 p_base = if_num ? 0x170 : 0x1f0;
712 outb_p(3, p_base + 1);
713 outb_p(mode_num | 8, p_base + 2);
714 outb_p((drv_num | 0xa) << 4, p_base + 6);
715 outb_p(0xef, p_base + 7);
716 for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
717 udelay(10000);
718 }
719
720
721
722
723
724 static void cmd640_set_mode(ide_drive_t* drive, int pio_mode) {
725 int interface_number;
726 int drive_number;
727 int clock_time;
728 int mc_time, av_time, ds_time;
729
730 interface_number = HWIF(drive)->index;
731 drive_number = drive->select.b.unit;
732 clock_time = 1000/bus_speed;
733
734 mc_time = pio_timings[pio_mode].mc_time;
735 av_time = pio_timings[pio_mode].av_time;
736 ds_time = pio_timings[pio_mode].ds_time;
737
738 cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
739 interface_number*2 + drive_number);
740 set_pio_mode(interface_number, drive_number, pio_mode);
741 cmd640_set_timing(interface_number, drive_number);
742 }
743
744
745
746
747
748
749 static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) {
750 int interface_number;
751 int drive_number;
752 int clock_time;
753 int max_pio;
754 int mc_time, av_time, ds_time;
755 struct hd_driveid* id;
756 int readahead;
757
758 if (pio_mode != 255) {
759 cmd640_set_mode(drive, pio_mode);
760 return;
761 }
762
763 interface_number = HWIF(drive)->index;
764 drive_number = drive->select.b.unit;
765 clock_time = 1000/bus_speed;
766 id = drive->id;
767 if ((max_pio = known_drive_pio(id->model)) != -1) {
768 ds_time = pio_timings[max_pio].ds_time;
769 } else {
770 max_pio = id->tPIO;
771 ds_time = pio_timings[max_pio].ds_time;
772 if (id->field_valid & 2) {
773 if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
774 if (id->eide_pio_modes & 4) max_pio = 5;
775 else if (id->eide_pio_modes & 2) max_pio = 4;
776 else max_pio = 3;
777 ds_time = id->eide_pio_iordy;
778 } else {
779 ds_time = id->eide_pio;
780 }
781 if (ds_time == 0)
782 ds_time = pio_timings[max_pio].ds_time;
783 }
784
785
786
787
788 if (max_pio < 4 && max_pio != 0) {
789 max_pio -= 1;
790 ds_time = pio_timings[max_pio].ds_time;
791 }
792 }
793 mc_time = pio_timings[max_pio].mc_time;
794 av_time = pio_timings[max_pio].av_time;
795 cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
796 interface_number*2 + drive_number);
797 set_pio_mode(interface_number, drive_number, max_pio);
798 cmd640_set_timing(interface_number, drive_number);
799
800
801
802
803
804 readahead = 0;
805 if (cmd640_chip_version > 1) {
806 readahead = known_drive_readahead(id->model);
807 if (readahead == -1)
808 readahead = 1;
809 set_readahead_mode(readahead, interface_number, drive_number);
810 }
811
812 printk ("Mode and Timing set to PIO%d, Readahead is %s\n",
813 max_pio, readahead ? "enabled" : "disabled");
814 }
815