aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>2007-01-05 19:36:21 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:21 -0500
commitcd36beec0b83d28dceb85696a23542bf1b97cc8c (patch)
treef1e58d5e9f12334349020b07e7c7a01fd77d9b41 /drivers/ide
parent6ae4adf50380d0fc5176a76d98d324f8fa491a8f (diff)
[PATCH] via82cxxx: fix cable detection
This patch fixes 2.6.15 regression, is straightforward and tested. Cable detection got broken probably while converting the driver to support multiple controllers. Cable detection is done by examining how BIOS configured the attached devices. The current code is broken in that it examines the status *after* modifying Clk66 configuration ending up detecting 40c cables as 80c. This patch fixes it. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/pci/via82cxxx.c138
1 files changed, 65 insertions, 73 deletions
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 61f1a9665a7f..381cc6f101ce 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -123,7 +123,7 @@ struct via82cxxx_dev
123static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) 123static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
124{ 124{
125 struct pci_dev *dev = hwif->pci_dev; 125 struct pci_dev *dev = hwif->pci_dev;
126 struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); 126 struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
127 u8 t; 127 u8 t;
128 128
129 if (~vdev->via_config->flags & VIA_BAD_AST) { 129 if (~vdev->via_config->flags & VIA_BAD_AST) {
@@ -162,7 +162,7 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
162static int via_set_drive(ide_drive_t *drive, u8 speed) 162static int via_set_drive(ide_drive_t *drive, u8 speed)
163{ 163{
164 ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); 164 ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
165 struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif); 165 struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev);
166 struct ide_timing t, p; 166 struct ide_timing t, p;
167 unsigned int T, UT; 167 unsigned int T, UT;
168 168
@@ -225,7 +225,7 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
225static int via82cxxx_ide_dma_check (ide_drive_t *drive) 225static int via82cxxx_ide_dma_check (ide_drive_t *drive)
226{ 226{
227 ide_hwif_t *hwif = HWIF(drive); 227 ide_hwif_t *hwif = HWIF(drive);
228 struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); 228 struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
229 u16 w80 = hwif->udma_four; 229 u16 w80 = hwif->udma_four;
230 230
231 u16 speed = ide_find_best_mode(drive, 231 u16 speed = ide_find_best_mode(drive,
@@ -262,6 +262,53 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
262 return via_config; 262 return via_config;
263} 263}
264 264
265/*
266 * Check and handle 80-wire cable presence
267 */
268static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
269{
270 int i;
271
272 switch (vdev->via_config->flags & VIA_UDMA) {
273 case VIA_UDMA_66:
274 for (i = 24; i >= 0; i -= 8)
275 if (((u >> (i & 16)) & 8) &&
276 ((u >> i) & 0x20) &&
277 (((u >> i) & 7) < 2)) {
278 /*
279 * 2x PCI clock and
280 * UDMA w/ < 3T/cycle
281 */
282 vdev->via_80w |= (1 << (1 - (i >> 4)));
283 }
284 break;
285
286 case VIA_UDMA_100:
287 for (i = 24; i >= 0; i -= 8)
288 if (((u >> i) & 0x10) ||
289 (((u >> i) & 0x20) &&
290 (((u >> i) & 7) < 4))) {
291 /* BIOS 80-wire bit or
292 * UDMA w/ < 60ns/cycle
293 */
294 vdev->via_80w |= (1 << (1 - (i >> 4)));
295 }
296 break;
297
298 case VIA_UDMA_133:
299 for (i = 24; i >= 0; i -= 8)
300 if (((u >> i) & 0x10) ||
301 (((u >> i) & 0x20) &&
302 (((u >> i) & 7) < 6))) {
303 /* BIOS 80-wire bit or
304 * UDMA w/ < 60ns/cycle
305 */
306 vdev->via_80w |= (1 << (1 - (i >> 4)));
307 }
308 break;
309 }
310}
311
265/** 312/**
266 * init_chipset_via82cxxx - initialization handler 313 * init_chipset_via82cxxx - initialization handler
267 * @dev: PCI device 314 * @dev: PCI device
@@ -274,14 +321,22 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
274static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) 321static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
275{ 322{
276 struct pci_dev *isa = NULL; 323 struct pci_dev *isa = NULL;
324 struct via82cxxx_dev *vdev;
277 struct via_isa_bridge *via_config; 325 struct via_isa_bridge *via_config;
278 u8 t, v; 326 u8 t, v;
279 unsigned int u; 327 u32 u;
328
329 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
330 if (!vdev) {
331 printk(KERN_ERR "VP_IDE: out of memory :(\n");
332 return -ENOMEM;
333 }
334 pci_set_drvdata(dev, vdev);
280 335
281 /* 336 /*
282 * Find the ISA bridge to see how good the IDE is. 337 * Find the ISA bridge to see how good the IDE is.
283 */ 338 */
284 via_config = via_config_find(&isa); 339 vdev->via_config = via_config = via_config_find(&isa);
285 340
286 /* We checked this earlier so if it fails here deeep badness 341 /* We checked this earlier so if it fails here deeep badness
287 is involved */ 342 is involved */
@@ -289,16 +344,17 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
289 BUG_ON(!via_config->id); 344 BUG_ON(!via_config->id);
290 345
291 /* 346 /*
292 * Setup or disable Clk66 if appropriate 347 * Detect cable and configure Clk66
293 */ 348 */
349 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
350
351 via_cable_detect(vdev, u);
294 352
295 if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) { 353 if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
296 /* Enable Clk66 */ 354 /* Enable Clk66 */
297 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
298 pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); 355 pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
299 } else if (via_config->flags & VIA_BAD_CLK66) { 356 } else if (via_config->flags & VIA_BAD_CLK66) {
300 /* Would cause trouble on 596a and 686 */ 357 /* Would cause trouble on 596a and 686 */
301 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
302 pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008); 358 pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
303 } 359 }
304 360
@@ -367,75 +423,11 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
367 return 0; 423 return 0;
368} 424}
369 425
370/*
371 * Check and handle 80-wire cable presence
372 */
373static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev)
374{
375 unsigned int u;
376 int i;
377 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
378
379 switch (vdev->via_config->flags & VIA_UDMA) {
380
381 case VIA_UDMA_66:
382 for (i = 24; i >= 0; i -= 8)
383 if (((u >> (i & 16)) & 8) &&
384 ((u >> i) & 0x20) &&
385 (((u >> i) & 7) < 2)) {
386 /*
387 * 2x PCI clock and
388 * UDMA w/ < 3T/cycle
389 */
390 vdev->via_80w |= (1 << (1 - (i >> 4)));
391 }
392 break;
393
394 case VIA_UDMA_100:
395 for (i = 24; i >= 0; i -= 8)
396 if (((u >> i) & 0x10) ||
397 (((u >> i) & 0x20) &&
398 (((u >> i) & 7) < 4))) {
399 /* BIOS 80-wire bit or
400 * UDMA w/ < 60ns/cycle
401 */
402 vdev->via_80w |= (1 << (1 - (i >> 4)));
403 }
404 break;
405
406 case VIA_UDMA_133:
407 for (i = 24; i >= 0; i -= 8)
408 if (((u >> i) & 0x10) ||
409 (((u >> i) & 0x20) &&
410 (((u >> i) & 7) < 6))) {
411 /* BIOS 80-wire bit or
412 * UDMA w/ < 60ns/cycle
413 */
414 vdev->via_80w |= (1 << (1 - (i >> 4)));
415 }
416 break;
417
418 }
419}
420
421static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) 426static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
422{ 427{
423 struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev), 428 struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
424 GFP_KERNEL);
425 struct pci_dev *isa = NULL;
426 int i; 429 int i;
427 430
428 if (vdev == NULL) {
429 printk(KERN_ERR "VP_IDE: out of memory :(\n");
430 return;
431 }
432
433 memset(vdev, 0, sizeof(struct via82cxxx_dev));
434 ide_set_hwifdata(hwif, vdev);
435
436 vdev->via_config = via_config_find(&isa);
437 via_cable_detect(hwif->pci_dev, vdev);
438
439 hwif->autodma = 0; 431 hwif->autodma = 0;
440 432
441 hwif->tuneproc = &via82cxxx_tune_drive; 433 hwif->tuneproc = &via82cxxx_tune_drive;