aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/legacy/umc8672.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-26 12:48:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-26 12:48:00 -0400
commit1292ebb82c00c69cf983e871faa221ce88ed3338 (patch)
tree91f624dd175c9d3e842db78789c6a0c79a78eee5 /drivers/ide/legacy/umc8672.c
parentb82287587ef9917afbea5fcbf7aa63424b6f3719 (diff)
parent784506cbddd17bcd5929f827df39b0c7014e3f1e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (61 commits) ide: sanitize handling of IDE_HFLAG_NO_SET_MODE host flag sis5513: fail early for unsupported chipsets it821x: fix kzalloc() failure handling qd65xx: use IDE_HFLAG_SINGLE host flag qd65xx: always use ->selectproc method ide-cd: put proc-related functions together under single ifdef ide-cd: Replace __FUNCTION__ with __func__ IDE: Coding Style fixes to drivers/ide/ide-cd.c IDE: Coding Style fixes to drivers/ide/pci/cy82c693.c IDE: Coding Style fixes to drivers/ide/pci/it8213.c IDE: Coding Style fixes to drivers/ide/ide-floppy.c IDE: Coding Style fixes to drivers/ide/legacy/ali14xx.c IDE: Coding Style fixes to drivers/ide/legacy/hd.c IDE: Coding Style fixes to drivers/ide/pci/cmd640.c IDE: Coding Style fixes to drivers/ide/pci/opti621.c IDE: Coding Style fixes to drivers/ide/ide-pnp.c IDE: Coding Style fixes to drivers/ide/ide-proc.c IDE: Coding Style fixes to drivers/ide/legacy/ide-4drives.c IDE: Coding Style fixes to drivers/ide/legacy/umc8672.c IDE: Coding Style fixes to drivers/ide/pci/generic.c ...
Diffstat (limited to 'drivers/ide/legacy/umc8672.c')
-rw-r--r--drivers/ide/legacy/umc8672.c81
1 files changed, 45 insertions, 36 deletions
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
62static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; 62static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3};
63static const u8 pio_to_umc [5] = {0,3,7,10,11}; /* rough guesses */ 63static 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 */
66static const u8 speedtab [3][12] = { 66static 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
71static void out_umc (char port,char wert) 72static 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
77static inline u8 in_umc (char port) 78static 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
83static void umc_set_speeds (u8 speeds[]) 84static 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
106static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) 106static 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
129static int __init umc8672_probe(void) 129static 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
171int probe_umc8672 = 0; 180int probe_umc8672;
172 181
173module_param_named(probe, probe_umc8672, bool, 0); 182module_param_named(probe, probe_umc8672, bool, 0);
174MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); 183MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");