diff options
Diffstat (limited to 'drivers/ide/pci/via82cxxx.c')
-rw-r--r-- | drivers/ide/pci/via82cxxx.c | 377 |
1 files changed, 114 insertions, 263 deletions
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index a4d099c937ff..cee2c374cd2f 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c | |||
@@ -100,185 +100,14 @@ static struct via_isa_bridge { | |||
100 | { NULL } | 100 | { NULL } |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static struct via_isa_bridge *via_config; | ||
104 | static unsigned int via_80w; | ||
105 | static unsigned int via_clock; | 103 | static unsigned int via_clock; |
106 | static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; | 104 | static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; |
107 | 105 | ||
108 | /* | 106 | struct via82cxxx_dev |
109 | * VIA /proc entry. | ||
110 | */ | ||
111 | |||
112 | #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) | ||
113 | |||
114 | #include <linux/stat.h> | ||
115 | #include <linux/proc_fs.h> | ||
116 | |||
117 | static u8 via_proc = 0; | ||
118 | static unsigned long via_base; | ||
119 | static struct pci_dev *bmide_dev, *isa_dev; | ||
120 | |||
121 | static char *via_control3[] = { "No limit", "64", "128", "192" }; | ||
122 | |||
123 | #define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg) | ||
124 | #define via_print_drive(name, format, arg...)\ | ||
125 | p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n"); | ||
126 | |||
127 | |||
128 | /** | ||
129 | * via_get_info - generate via /proc file | ||
130 | * @buffer: buffer for data | ||
131 | * @addr: set to start of data to use | ||
132 | * @offset: current file offset | ||
133 | * @count: size of read | ||
134 | * | ||
135 | * Fills in buffer with the debugging/configuration information for | ||
136 | * the VIA chipset tuning and attached drives | ||
137 | */ | ||
138 | |||
139 | static int via_get_info(char *buffer, char **addr, off_t offset, int count) | ||
140 | { | 107 | { |
141 | int speed[4], cycle[4], setup[4], active[4], recover[4], den[4], | 108 | struct via_isa_bridge *via_config; |
142 | uen[4], udma[4], umul[4], active8b[4], recover8b[4]; | 109 | unsigned int via_80w; |
143 | struct pci_dev *dev = bmide_dev; | 110 | }; |
144 | unsigned int v, u, i; | ||
145 | int len; | ||
146 | u16 c, w; | ||
147 | u8 t, x; | ||
148 | char *p = buffer; | ||
149 | |||
150 | via_print("----------VIA BusMastering IDE Configuration" | ||
151 | "----------------"); | ||
152 | |||
153 | via_print("Driver Version: 3.38"); | ||
154 | via_print("South Bridge: VIA %s", | ||
155 | via_config->name); | ||
156 | |||
157 | pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t); | ||
158 | pci_read_config_byte(dev, PCI_REVISION_ID, &x); | ||
159 | via_print("Revision: ISA %#x IDE %#x", t, x); | ||
160 | via_print("Highest DMA rate: %s", | ||
161 | via_dma[via_config->flags & VIA_UDMA]); | ||
162 | |||
163 | via_print("BM-DMA base: %#lx", via_base); | ||
164 | via_print("PCI clock: %d.%dMHz", | ||
165 | via_clock / 1000, via_clock / 100 % 10); | ||
166 | |||
167 | pci_read_config_byte(dev, VIA_MISC_1, &t); | ||
168 | via_print("Master Read Cycle IRDY: %dws", | ||
169 | (t & 64) >> 6); | ||
170 | via_print("Master Write Cycle IRDY: %dws", | ||
171 | (t & 32) >> 5); | ||
172 | via_print("BM IDE Status Register Read Retry: %s", | ||
173 | (t & 8) ? "yes" : "no"); | ||
174 | |||
175 | pci_read_config_byte(dev, VIA_MISC_3, &t); | ||
176 | via_print("Max DRDY Pulse Width: %s%s", | ||
177 | via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : ""); | ||
178 | |||
179 | via_print("-----------------------Primary IDE" | ||
180 | "-------Secondary IDE------"); | ||
181 | via_print("Read DMA FIFO flush: %10s%20s", | ||
182 | (t & 0x80) ? "yes" : "no", (t & 0x40) ? "yes" : "no"); | ||
183 | via_print("End Sector FIFO flush: %10s%20s", | ||
184 | (t & 0x20) ? "yes" : "no", (t & 0x10) ? "yes" : "no"); | ||
185 | |||
186 | pci_read_config_byte(dev, VIA_IDE_CONFIG, &t); | ||
187 | via_print("Prefetch Buffer: %10s%20s", | ||
188 | (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no"); | ||
189 | via_print("Post Write Buffer: %10s%20s", | ||
190 | (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no"); | ||
191 | |||
192 | pci_read_config_byte(dev, VIA_IDE_ENABLE, &t); | ||
193 | via_print("Enabled: %10s%20s", | ||
194 | (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no"); | ||
195 | |||
196 | c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8); | ||
197 | via_print("Simplex only: %10s%20s", | ||
198 | (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no"); | ||
199 | |||
200 | via_print("Cable Type: %10s%20s", | ||
201 | (via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w"); | ||
202 | |||
203 | via_print("-------------------drive0----drive1" | ||
204 | "----drive2----drive3-----"); | ||
205 | |||
206 | pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); | ||
207 | pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v); | ||
208 | pci_read_config_word(dev, VIA_8BIT_TIMING, &w); | ||
209 | |||
210 | if (via_config->flags & VIA_UDMA) | ||
211 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | ||
212 | else u = 0; | ||
213 | |||
214 | for (i = 0; i < 4; i++) { | ||
215 | |||
216 | setup[i] = ((t >> ((3 - i) << 1)) & 0x3) + 1; | ||
217 | recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1; | ||
218 | active8b[i] = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1; | ||
219 | active[i] = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1; | ||
220 | recover[i] = ((v >> ((3 - i) << 3)) & 0xf) + 1; | ||
221 | udma[i] = ((u >> ((3 - i) << 3)) & 0x7) + 2; | ||
222 | umul[i] = ((u >> (((3 - i) & 2) << 3)) & 0x8) ? 1 : 2; | ||
223 | uen[i] = ((u >> ((3 - i) << 3)) & 0x20); | ||
224 | den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); | ||
225 | |||
226 | speed[i] = 2 * via_clock / (active[i] + recover[i]); | ||
227 | cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock; | ||
228 | |||
229 | if (!uen[i] || !den[i]) | ||
230 | continue; | ||
231 | |||
232 | switch (via_config->flags & VIA_UDMA) { | ||
233 | |||
234 | case VIA_UDMA_33: | ||
235 | speed[i] = 2 * via_clock / udma[i]; | ||
236 | cycle[i] = 1000000 * udma[i] / via_clock; | ||
237 | break; | ||
238 | |||
239 | case VIA_UDMA_66: | ||
240 | speed[i] = 4 * via_clock / (udma[i] * umul[i]); | ||
241 | cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock; | ||
242 | break; | ||
243 | |||
244 | case VIA_UDMA_100: | ||
245 | speed[i] = 6 * via_clock / udma[i]; | ||
246 | cycle[i] = 333333 * udma[i] / via_clock; | ||
247 | break; | ||
248 | |||
249 | case VIA_UDMA_133: | ||
250 | speed[i] = 8 * via_clock / udma[i]; | ||
251 | cycle[i] = 250000 * udma[i] / via_clock; | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | via_print_drive("Transfer Mode: ", "%10s", | ||
257 | den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); | ||
258 | |||
259 | via_print_drive("Address Setup: ", "%8dns", | ||
260 | 1000000 * setup[i] / via_clock); | ||
261 | via_print_drive("Cmd Active: ", "%8dns", | ||
262 | 1000000 * active8b[i] / via_clock); | ||
263 | via_print_drive("Cmd Recovery: ", "%8dns", | ||
264 | 1000000 * recover8b[i] / via_clock); | ||
265 | via_print_drive("Data Active: ", "%8dns", | ||
266 | 1000000 * active[i] / via_clock); | ||
267 | via_print_drive("Data Recovery: ", "%8dns", | ||
268 | 1000000 * recover[i] / via_clock); | ||
269 | via_print_drive("Cycle Time: ", "%8dns", | ||
270 | cycle[i]); | ||
271 | via_print_drive("Transfer Rate: ", "%4d.%dMB/s", | ||
272 | speed[i] / 1000, speed[i] / 100 % 10); | ||
273 | |||
274 | /* hoping it is less than 4K... */ | ||
275 | len = (p - buffer) - offset; | ||
276 | *addr = buffer + offset; | ||
277 | |||
278 | return len > count ? count : len; | ||
279 | } | ||
280 | |||
281 | #endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */ | ||
282 | 111 | ||
283 | /** | 112 | /** |
284 | * via_set_speed - write timing registers | 113 | * via_set_speed - write timing registers |
@@ -289,11 +118,13 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) | |||
289 | * via_set_speed writes timing values to the chipset registers | 118 | * via_set_speed writes timing values to the chipset registers |
290 | */ | 119 | */ |
291 | 120 | ||
292 | static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) | 121 | static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) |
293 | { | 122 | { |
123 | struct pci_dev *dev = hwif->pci_dev; | ||
124 | struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); | ||
294 | u8 t; | 125 | u8 t; |
295 | 126 | ||
296 | if (~via_config->flags & VIA_BAD_AST) { | 127 | if (~vdev->via_config->flags & VIA_BAD_AST) { |
297 | pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); | 128 | pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); |
298 | t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); | 129 | t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); |
299 | pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); | 130 | pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); |
@@ -305,7 +136,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) | |||
305 | pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), | 136 | pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), |
306 | ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); | 137 | ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); |
307 | 138 | ||
308 | switch (via_config->flags & VIA_UDMA) { | 139 | switch (vdev->via_config->flags & VIA_UDMA) { |
309 | case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; | 140 | case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; |
310 | case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; | 141 | case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; |
311 | case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; | 142 | case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; |
@@ -329,6 +160,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) | |||
329 | static int via_set_drive(ide_drive_t *drive, u8 speed) | 160 | static int via_set_drive(ide_drive_t *drive, u8 speed) |
330 | { | 161 | { |
331 | ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); | 162 | ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); |
163 | struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif); | ||
332 | struct ide_timing t, p; | 164 | struct ide_timing t, p; |
333 | unsigned int T, UT; | 165 | unsigned int T, UT; |
334 | 166 | ||
@@ -337,7 +169,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) | |||
337 | 169 | ||
338 | T = 1000000000 / via_clock; | 170 | T = 1000000000 / via_clock; |
339 | 171 | ||
340 | switch (via_config->flags & VIA_UDMA) { | 172 | switch (vdev->via_config->flags & VIA_UDMA) { |
341 | case VIA_UDMA_33: UT = T; break; | 173 | case VIA_UDMA_33: UT = T; break; |
342 | case VIA_UDMA_66: UT = T/2; break; | 174 | case VIA_UDMA_66: UT = T/2; break; |
343 | case VIA_UDMA_100: UT = T/3; break; | 175 | case VIA_UDMA_100: UT = T/3; break; |
@@ -352,7 +184,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) | |||
352 | ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); | 184 | ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); |
353 | } | 185 | } |
354 | 186 | ||
355 | via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); | 187 | via_set_speed(HWIF(drive), drive->dn, &t); |
356 | 188 | ||
357 | if (!drive->init_speed) | 189 | if (!drive->init_speed) |
358 | drive->init_speed = speed; | 190 | drive->init_speed = speed; |
@@ -390,20 +222,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) | |||
390 | 222 | ||
391 | static int via82cxxx_ide_dma_check (ide_drive_t *drive) | 223 | static int via82cxxx_ide_dma_check (ide_drive_t *drive) |
392 | { | 224 | { |
393 | u16 w80 = HWIF(drive)->udma_four; | 225 | ide_hwif_t *hwif = HWIF(drive); |
226 | struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); | ||
227 | u16 w80 = hwif->udma_four; | ||
394 | 228 | ||
395 | u16 speed = ide_find_best_mode(drive, | 229 | u16 speed = ide_find_best_mode(drive, |
396 | XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | | 230 | XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | |
397 | (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | | 231 | (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | |
398 | (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | | 232 | (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | |
399 | (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | | 233 | (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | |
400 | (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); | 234 | (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); |
401 | 235 | ||
402 | via_set_drive(drive, speed); | 236 | via_set_drive(drive, speed); |
403 | 237 | ||
404 | if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) | 238 | if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) |
405 | return HWIF(drive)->ide_dma_on(drive); | 239 | return hwif->ide_dma_on(drive); |
406 | return HWIF(drive)->ide_dma_off_quietly(drive); | 240 | return hwif->ide_dma_off_quietly(drive); |
241 | } | ||
242 | |||
243 | static struct via_isa_bridge *via_config_find(struct pci_dev **isa) | ||
244 | { | ||
245 | struct via_isa_bridge *via_config; | ||
246 | u8 t; | ||
247 | |||
248 | for (via_config = via_isa_bridges; via_config->id; via_config++) | ||
249 | if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA + | ||
250 | !!(via_config->flags & VIA_BAD_ID), | ||
251 | via_config->id, NULL))) { | ||
252 | |||
253 | pci_read_config_byte(*isa, PCI_REVISION_ID, &t); | ||
254 | if (t >= via_config->rev_min && | ||
255 | t <= via_config->rev_max) | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | return via_config; | ||
407 | } | 260 | } |
408 | 261 | ||
409 | /** | 262 | /** |
@@ -418,82 +271,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive) | |||
418 | static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) | 271 | static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) |
419 | { | 272 | { |
420 | struct pci_dev *isa = NULL; | 273 | struct pci_dev *isa = NULL; |
274 | struct via_isa_bridge *via_config; | ||
421 | u8 t, v; | 275 | u8 t, v; |
422 | unsigned int u; | 276 | unsigned int u; |
423 | int i; | ||
424 | 277 | ||
425 | /* | 278 | /* |
426 | * Find the ISA bridge to see how good the IDE is. | 279 | * Find the ISA bridge to see how good the IDE is. |
427 | */ | 280 | */ |
428 | 281 | via_config = via_config_find(&isa); | |
429 | for (via_config = via_isa_bridges; via_config->id; via_config++) | ||
430 | if ((isa = pci_find_device(PCI_VENDOR_ID_VIA + | ||
431 | !!(via_config->flags & VIA_BAD_ID), | ||
432 | via_config->id, NULL))) { | ||
433 | |||
434 | pci_read_config_byte(isa, PCI_REVISION_ID, &t); | ||
435 | if (t >= via_config->rev_min && | ||
436 | t <= via_config->rev_max) | ||
437 | break; | ||
438 | } | ||
439 | |||
440 | if (!via_config->id) { | 282 | if (!via_config->id) { |
441 | printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); | 283 | printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); |
442 | return -ENODEV; | 284 | return -ENODEV; |
443 | } | 285 | } |
444 | 286 | ||
445 | /* | 287 | /* |
446 | * Check 80-wire cable presence and setup Clk66. | 288 | * Setup or disable Clk66 if appropriate |
447 | */ | 289 | */ |
448 | 290 | ||
449 | switch (via_config->flags & VIA_UDMA) { | 291 | if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) { |
450 | 292 | /* Enable Clk66 */ | |
451 | case VIA_UDMA_66: | 293 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); |
452 | /* Enable Clk66 */ | 294 | pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); |
453 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | 295 | } else if (via_config->flags & VIA_BAD_CLK66) { |
454 | pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); | ||
455 | for (i = 24; i >= 0; i -= 8) | ||
456 | if (((u >> (i & 16)) & 8) && | ||
457 | ((u >> i) & 0x20) && | ||
458 | (((u >> i) & 7) < 2)) { | ||
459 | /* | ||
460 | * 2x PCI clock and | ||
461 | * UDMA w/ < 3T/cycle | ||
462 | */ | ||
463 | via_80w |= (1 << (1 - (i >> 4))); | ||
464 | } | ||
465 | break; | ||
466 | |||
467 | case VIA_UDMA_100: | ||
468 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | ||
469 | for (i = 24; i >= 0; i -= 8) | ||
470 | if (((u >> i) & 0x10) || | ||
471 | (((u >> i) & 0x20) && | ||
472 | (((u >> i) & 7) < 4))) { | ||
473 | /* BIOS 80-wire bit or | ||
474 | * UDMA w/ < 60ns/cycle | ||
475 | */ | ||
476 | via_80w |= (1 << (1 - (i >> 4))); | ||
477 | } | ||
478 | break; | ||
479 | |||
480 | case VIA_UDMA_133: | ||
481 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | ||
482 | for (i = 24; i >= 0; i -= 8) | ||
483 | if (((u >> i) & 0x10) || | ||
484 | (((u >> i) & 0x20) && | ||
485 | (((u >> i) & 7) < 6))) { | ||
486 | /* BIOS 80-wire bit or | ||
487 | * UDMA w/ < 60ns/cycle | ||
488 | */ | ||
489 | via_80w |= (1 << (1 - (i >> 4))); | ||
490 | } | ||
491 | break; | ||
492 | |||
493 | } | ||
494 | |||
495 | /* Disable Clk66 */ | ||
496 | if (via_config->flags & VIA_BAD_CLK66) { | ||
497 | /* Would cause trouble on 596a and 686 */ | 296 | /* Would cause trouble on 596a and 686 */ |
498 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | 297 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); |
499 | pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008); | 298 | pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008); |
@@ -560,26 +359,78 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const | |||
560 | via_dma[via_config->flags & VIA_UDMA], | 359 | via_dma[via_config->flags & VIA_UDMA], |
561 | pci_name(dev)); | 360 | pci_name(dev)); |
562 | 361 | ||
563 | /* | 362 | return 0; |
564 | * Setup /proc/ide/via entry. | 363 | } |
565 | */ | 364 | |
365 | /* | ||
366 | * Check and handle 80-wire cable presence | ||
367 | */ | ||
368 | static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev) | ||
369 | { | ||
370 | unsigned int u; | ||
371 | int i; | ||
372 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | ||
373 | |||
374 | switch (vdev->via_config->flags & VIA_UDMA) { | ||
375 | |||
376 | case VIA_UDMA_66: | ||
377 | for (i = 24; i >= 0; i -= 8) | ||
378 | if (((u >> (i & 16)) & 8) && | ||
379 | ((u >> i) & 0x20) && | ||
380 | (((u >> i) & 7) < 2)) { | ||
381 | /* | ||
382 | * 2x PCI clock and | ||
383 | * UDMA w/ < 3T/cycle | ||
384 | */ | ||
385 | vdev->via_80w |= (1 << (1 - (i >> 4))); | ||
386 | } | ||
387 | break; | ||
388 | |||
389 | case VIA_UDMA_100: | ||
390 | for (i = 24; i >= 0; i -= 8) | ||
391 | if (((u >> i) & 0x10) || | ||
392 | (((u >> i) & 0x20) && | ||
393 | (((u >> i) & 7) < 4))) { | ||
394 | /* BIOS 80-wire bit or | ||
395 | * UDMA w/ < 60ns/cycle | ||
396 | */ | ||
397 | vdev->via_80w |= (1 << (1 - (i >> 4))); | ||
398 | } | ||
399 | break; | ||
400 | |||
401 | case VIA_UDMA_133: | ||
402 | for (i = 24; i >= 0; i -= 8) | ||
403 | if (((u >> i) & 0x10) || | ||
404 | (((u >> i) & 0x20) && | ||
405 | (((u >> i) & 7) < 6))) { | ||
406 | /* BIOS 80-wire bit or | ||
407 | * UDMA w/ < 60ns/cycle | ||
408 | */ | ||
409 | vdev->via_80w |= (1 << (1 - (i >> 4))); | ||
410 | } | ||
411 | break; | ||
566 | 412 | ||
567 | #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) | ||
568 | if (!via_proc) { | ||
569 | via_base = pci_resource_start(dev, 4); | ||
570 | bmide_dev = dev; | ||
571 | isa_dev = isa; | ||
572 | ide_pci_create_host_proc("via", via_get_info); | ||
573 | via_proc = 1; | ||
574 | } | 413 | } |
575 | #endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */ | ||
576 | return 0; | ||
577 | } | 414 | } |
578 | 415 | ||
579 | static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) | 416 | static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) |
580 | { | 417 | { |
418 | struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev), | ||
419 | GFP_KERNEL); | ||
420 | struct pci_dev *isa = NULL; | ||
581 | int i; | 421 | int i; |
582 | 422 | ||
423 | if (vdev == NULL) { | ||
424 | printk(KERN_ERR "VP_IDE: out of memory :(\n"); | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | memset(vdev, 0, sizeof(struct via82cxxx_dev)); | ||
429 | ide_set_hwifdata(hwif, vdev); | ||
430 | |||
431 | vdev->via_config = via_config_find(&isa); | ||
432 | via_cable_detect(hwif->pci_dev, vdev); | ||
433 | |||
583 | hwif->autodma = 0; | 434 | hwif->autodma = 0; |
584 | 435 | ||
585 | hwif->tuneproc = &via82cxxx_tune_drive; | 436 | hwif->tuneproc = &via82cxxx_tune_drive; |
@@ -594,7 +445,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) | |||
594 | 445 | ||
595 | for (i = 0; i < 2; i++) { | 446 | for (i = 0; i < 2; i++) { |
596 | hwif->drives[i].io_32bit = 1; | 447 | hwif->drives[i].io_32bit = 1; |
597 | hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1; | 448 | hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1; |
598 | hwif->drives[i].autotune = 1; | 449 | hwif->drives[i].autotune = 1; |
599 | hwif->drives[i].dn = hwif->channel * 2 + i; | 450 | hwif->drives[i].dn = hwif->channel * 2 + i; |
600 | } | 451 | } |
@@ -608,7 +459,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) | |||
608 | hwif->swdma_mask = 0x07; | 459 | hwif->swdma_mask = 0x07; |
609 | 460 | ||
610 | if (!hwif->udma_four) | 461 | if (!hwif->udma_four) |
611 | hwif->udma_four = (via_80w >> hwif->channel) & 1; | 462 | hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1; |
612 | hwif->ide_dma_check = &via82cxxx_ide_dma_check; | 463 | hwif->ide_dma_check = &via82cxxx_ide_dma_check; |
613 | if (!noautodma) | 464 | if (!noautodma) |
614 | hwif->autodma = 1; | 465 | hwif->autodma = 1; |