This source file includes following definitions.
- out_umc
- in_umc
- umc_set_speeds
- tune_umc
- init_umc8672
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 #undef REALLY_SLOW_IO
38
39 #include <linux/types.h>
40 #include <linux/kernel.h>
41 #include <linux/delay.h>
42 #include <linux/timer.h>
43 #include <linux/mm.h>
44 #include <linux/ioport.h>
45 #include <linux/blkdev.h>
46 #include <linux/hdreg.h>
47 #include <asm/io.h>
48 #include "ide.h"
49
50
51
52
53
54 #define UMC_DRIVE0 1
55 #define UMC_DRIVE1 1
56 #define UMC_DRIVE2 1
57 #define UMC_DRIVE3 1
58
59 static byte current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3};
60 static const byte pio_to_umc [5] = {0,3,6,10,11};
61
62
63 static const byte speedtab [3][12] = {
64 {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
65 {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
66 {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
67
68 static void out_umc (char port,char wert)
69 {
70 outb_p (port,0x108);
71 outb_p (wert,0x109);
72 }
73
74 static byte in_umc (char port)
75 {
76 outb_p (port,0x108);
77 return inb_p (0x109);
78 }
79
80 static void umc_set_speeds (byte speeds[])
81 {
82 int i, tmp;
83 unsigned long flags;
84
85 save_flags(flags);
86 cli ();
87 outb_p (0x5A,0x108);
88
89 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 tmp = 0;
92 for (i = 3; i >= 0; i--)
93 {
94 tmp = (tmp << 2) | speedtab[1][speeds[i]];
95 }
96 out_umc (0xdc,tmp);
97 for (i = 0;i < 4; i++)
98 {
99 out_umc (0xd0+i,speedtab[2][speeds[i]]);
100 out_umc (0xd8+i,speedtab[2][speeds[i]]);
101 }
102 outb_p (0xa5,0x108);
103 restore_flags(flags);
104
105 printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n",
106 speeds[0], speeds[1], speeds[2], speeds[4]);
107 }
108
109 static void tune_umc (ide_drive_t *drive, byte pio)
110 {
111 if (pio == 255) {
112 struct hd_driveid *id = drive->id;
113 pio = id->tPIO;
114 if (id->field_valid & 0x02) {
115 if (id->eide_pio_modes & 0x01)
116 pio = 3;
117 if (id->eide_pio_modes & 0x02)
118 pio = 4;
119 }
120 }
121 if (pio > 4)
122 pio = 4;
123 current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio];
124 umc_set_speeds (current_speeds);
125 }
126
127 void init_umc8672 (void)
128 {
129 unsigned long flags;
130
131 if (check_region(0x108, 2)) {
132 printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n");
133 return;
134 }
135 save_flags(flags);
136 cli ();
137 outb_p (0x5A,0x108);
138 if (in_umc (0xd5) != 0xa0)
139 {
140 sti ();
141 printk ("umc8672: not found\n");
142 return;
143 }
144 outb_p (0xa5,0x108);
145 restore_flags(flags);
146
147 umc_set_speeds (current_speeds);
148
149 request_region(0x108, 2, "umc8672");
150 ide_hwifs[0].chipset = ide_umc8672;
151 ide_hwifs[1].chipset = ide_umc8672;
152 ide_hwifs[0].tuneproc = &tune_umc;
153 ide_hwifs[1].tuneproc = &tune_umc;
154
155 }