diff options
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r-- | drivers/ide/pci/hpt366.c | 179 |
1 files changed, 85 insertions, 94 deletions
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index b486442dd5d7..49ae9f6d2183 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 | 2 | * linux/drivers/ide/pci/hpt366.c Version 0.43 May 17, 2006 |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
@@ -62,8 +62,8 @@ | |||
62 | * be done on 66 MHz PCI bus | 62 | * be done on 66 MHz PCI bus |
63 | * - avoid calibrating PLL twice as the second time results in a wrong PCI | 63 | * - avoid calibrating PLL twice as the second time results in a wrong PCI |
64 | * frequency and thus in the wrong timings for the secondary channel | 64 | * frequency and thus in the wrong timings for the secondary channel |
65 | * - disable UltraATA/133 for HPT372 by default (50 MHz DPLL clock do not | 65 | * - disable UltraATA/133 for HPT372 and UltraATA/100 for HPT370 by default |
66 | * allow for this speed anyway) | 66 | * as the ATA clock being used does not allow for this speed anyway |
67 | * - add support for HPT302N and HPT371N clocking (the same as for HPT372N) | 67 | * - add support for HPT302N and HPT371N clocking (the same as for HPT372N) |
68 | * - HPT371/N are single channel chips, so avoid touching the primary channel | 68 | * - HPT371/N are single channel chips, so avoid touching the primary channel |
69 | * which exists only virtually (there's no pins for it) | 69 | * which exists only virtually (there's no pins for it) |
@@ -76,6 +76,7 @@ | |||
76 | * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead | 76 | * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead |
77 | * - pass to init_chipset() handlers a copy of the IDE PCI device structure as | 77 | * - pass to init_chipset() handlers a copy of the IDE PCI device structure as |
78 | * they tamper with its fields | 78 | * they tamper with its fields |
79 | * - optimize the rate masking/filtering and the drive list lookup code | ||
79 | * <source@mvista.com> | 80 | * <source@mvista.com> |
80 | * | 81 | * |
81 | */ | 82 | */ |
@@ -336,7 +337,7 @@ static u32 sixty_six_base_hpt37x[] = { | |||
336 | #define HPT371_ALLOW_ATA133_6 0 | 337 | #define HPT371_ALLOW_ATA133_6 0 |
337 | #define HPT302_ALLOW_ATA133_6 0 | 338 | #define HPT302_ALLOW_ATA133_6 0 |
338 | #define HPT372_ALLOW_ATA133_6 0 | 339 | #define HPT372_ALLOW_ATA133_6 0 |
339 | #define HPT370_ALLOW_ATA100_5 1 | 340 | #define HPT370_ALLOW_ATA100_5 0 |
340 | #define HPT366_ALLOW_ATA66_4 1 | 341 | #define HPT366_ALLOW_ATA66_4 1 |
341 | #define HPT366_ALLOW_ATA66_3 1 | 342 | #define HPT366_ALLOW_ATA66_3 1 |
342 | #define HPT366_MAX_DEVS 8 | 343 | #define HPT366_MAX_DEVS 8 |
@@ -354,8 +355,8 @@ static u32 sixty_six_base_hpt37x[] = { | |||
354 | struct hpt_info | 355 | struct hpt_info |
355 | { | 356 | { |
356 | u8 max_mode; /* Speeds allowed */ | 357 | u8 max_mode; /* Speeds allowed */ |
357 | int revision; /* Chipset revision */ | 358 | u8 revision; /* Chipset revision */ |
358 | int flags; /* Chipset properties */ | 359 | u8 flags; /* Chipset properties */ |
359 | #define PLL_MODE 1 | 360 | #define PLL_MODE 1 |
360 | #define IS_3xxN 2 | 361 | #define IS_3xxN 2 |
361 | #define PCI_66MHZ 4 | 362 | #define PCI_66MHZ 4 |
@@ -364,61 +365,50 @@ struct hpt_info | |||
364 | }; | 365 | }; |
365 | 366 | ||
366 | /* | 367 | /* |
367 | * This wants fixing so that we do everything not by classrev | 368 | * This wants fixing so that we do everything not by revision |
368 | * (which breaks on the newest chips) but by creating an | 369 | * (which breaks on the newest chips) but by creating an |
369 | * enumeration of chip variants and using that | 370 | * enumeration of chip variants and using that |
370 | */ | 371 | */ |
371 | 372 | ||
372 | static __devinit u32 hpt_revision (struct pci_dev *dev) | 373 | static __devinit u8 hpt_revision(struct pci_dev *dev) |
373 | { | 374 | { |
374 | u32 class_rev; | 375 | u8 rev = 0; |
375 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | 376 | |
376 | class_rev &= 0xff; | 377 | pci_read_config_byte(dev, PCI_REVISION_ID, &rev); |
377 | 378 | ||
378 | switch(dev->device) { | 379 | switch(dev->device) { |
379 | /* Remap new 372N onto 372 */ | 380 | /* Remap new 372N onto 372 */ |
380 | case PCI_DEVICE_ID_TTI_HPT372N: | 381 | case PCI_DEVICE_ID_TTI_HPT372N: |
381 | class_rev = PCI_DEVICE_ID_TTI_HPT372; break; | 382 | rev = PCI_DEVICE_ID_TTI_HPT372; break; |
382 | case PCI_DEVICE_ID_TTI_HPT374: | 383 | case PCI_DEVICE_ID_TTI_HPT374: |
383 | class_rev = PCI_DEVICE_ID_TTI_HPT374; break; | 384 | rev = PCI_DEVICE_ID_TTI_HPT374; break; |
384 | case PCI_DEVICE_ID_TTI_HPT371: | 385 | case PCI_DEVICE_ID_TTI_HPT371: |
385 | class_rev = PCI_DEVICE_ID_TTI_HPT371; break; | 386 | rev = PCI_DEVICE_ID_TTI_HPT371; break; |
386 | case PCI_DEVICE_ID_TTI_HPT302: | 387 | case PCI_DEVICE_ID_TTI_HPT302: |
387 | class_rev = PCI_DEVICE_ID_TTI_HPT302; break; | 388 | rev = PCI_DEVICE_ID_TTI_HPT302; break; |
388 | case PCI_DEVICE_ID_TTI_HPT372: | 389 | case PCI_DEVICE_ID_TTI_HPT372: |
389 | class_rev = PCI_DEVICE_ID_TTI_HPT372; break; | 390 | rev = PCI_DEVICE_ID_TTI_HPT372; break; |
390 | default: | 391 | default: |
391 | break; | 392 | break; |
392 | } | 393 | } |
393 | return class_rev; | 394 | return rev; |
394 | } | 395 | } |
395 | 396 | ||
396 | static int check_in_drive_lists(ide_drive_t *drive, const char **list); | 397 | static int check_in_drive_list(ide_drive_t *drive, const char **list) |
398 | { | ||
399 | struct hd_driveid *id = drive->id; | ||
400 | |||
401 | while (*list) | ||
402 | if (!strcmp(*list++,id->model)) | ||
403 | return 1; | ||
404 | return 0; | ||
405 | } | ||
397 | 406 | ||
398 | static u8 hpt3xx_ratemask (ide_drive_t *drive) | 407 | static u8 hpt3xx_ratemask(ide_drive_t *drive) |
399 | { | 408 | { |
400 | ide_hwif_t *hwif = drive->hwif; | 409 | struct hpt_info *info = ide_get_hwifdata(HWIF(drive)); |
401 | struct hpt_info *info = ide_get_hwifdata(hwif); | 410 | u8 mode = info->max_mode; |
402 | u8 mode = 0; | 411 | |
403 | |||
404 | /* FIXME: TODO - move this to set info->mode once at boot */ | ||
405 | |||
406 | if (info->revision >= 8) { /* HPT374 */ | ||
407 | mode = (HPT374_ALLOW_ATA133_6) ? 4 : 3; | ||
408 | } else if (info->revision >= 7) { /* HPT371 */ | ||
409 | mode = (HPT371_ALLOW_ATA133_6) ? 4 : 3; | ||
410 | } else if (info->revision >= 6) { /* HPT302 */ | ||
411 | mode = (HPT302_ALLOW_ATA133_6) ? 4 : 3; | ||
412 | } else if (info->revision >= 5) { /* HPT372 */ | ||
413 | mode = (HPT372_ALLOW_ATA133_6) ? 4 : 3; | ||
414 | } else if (info->revision >= 4) { /* HPT370A */ | ||
415 | mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2; | ||
416 | } else if (info->revision >= 3) { /* HPT370 */ | ||
417 | mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2; | ||
418 | mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : mode; | ||
419 | } else { /* HPT366 and HPT368 */ | ||
420 | mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : 2; | ||
421 | } | ||
422 | if (!eighty_ninty_three(drive) && mode) | 412 | if (!eighty_ninty_three(drive) && mode) |
423 | mode = min(mode, (u8)1); | 413 | mode = min(mode, (u8)1); |
424 | return mode; | 414 | return mode; |
@@ -429,16 +419,15 @@ static u8 hpt3xx_ratemask (ide_drive_t *drive) | |||
429 | * either PIO or UDMA modes 0,4,5 | 419 | * either PIO or UDMA modes 0,4,5 |
430 | */ | 420 | */ |
431 | 421 | ||
432 | static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed) | 422 | static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed) |
433 | { | 423 | { |
434 | ide_hwif_t *hwif = drive->hwif; | 424 | struct hpt_info *info = ide_get_hwifdata(HWIF(drive)); |
435 | struct hpt_info *info = ide_get_hwifdata(hwif); | ||
436 | u8 mode = hpt3xx_ratemask(drive); | 425 | u8 mode = hpt3xx_ratemask(drive); |
437 | 426 | ||
438 | if (drive->media != ide_disk) | 427 | if (drive->media != ide_disk) |
439 | return min(speed, (u8)XFER_PIO_4); | 428 | return min(speed, (u8)XFER_PIO_4); |
440 | 429 | ||
441 | switch(mode) { | 430 | switch (mode) { |
442 | case 0x04: | 431 | case 0x04: |
443 | speed = min(speed, (u8)XFER_UDMA_6); | 432 | speed = min(speed, (u8)XFER_UDMA_6); |
444 | break; | 433 | break; |
@@ -446,33 +435,34 @@ static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed) | |||
446 | speed = min(speed, (u8)XFER_UDMA_5); | 435 | speed = min(speed, (u8)XFER_UDMA_5); |
447 | if (info->revision >= 5) | 436 | if (info->revision >= 5) |
448 | break; | 437 | break; |
449 | if (check_in_drive_lists(drive, bad_ata100_5)) | 438 | if (!check_in_drive_list(drive, bad_ata100_5)) |
450 | speed = min(speed, (u8)XFER_UDMA_4); | 439 | goto check_bad_ata33; |
451 | break; | 440 | /* fall thru */ |
452 | case 0x02: | 441 | case 0x02: |
453 | speed = min(speed, (u8)XFER_UDMA_4); | 442 | speed = min(speed, (u8)XFER_UDMA_4); |
454 | /* | 443 | /* |
455 | * CHECK ME, Does this need to be set to 5 ?? | 444 | * CHECK ME, Does this need to be set to 5 ?? |
456 | */ | 445 | */ |
457 | if (info->revision >= 3) | 446 | if (info->revision >= 3) |
458 | break; | 447 | goto check_bad_ata33; |
459 | if ((check_in_drive_lists(drive, bad_ata66_4)) || | 448 | if (HPT366_ALLOW_ATA66_4 && |
460 | (!(HPT366_ALLOW_ATA66_4))) | 449 | !check_in_drive_list(drive, bad_ata66_4)) |
461 | speed = min(speed, (u8)XFER_UDMA_3); | 450 | goto check_bad_ata33; |
462 | if ((check_in_drive_lists(drive, bad_ata66_3)) || | 451 | |
463 | (!(HPT366_ALLOW_ATA66_3))) | 452 | speed = min(speed, (u8)XFER_UDMA_3); |
464 | speed = min(speed, (u8)XFER_UDMA_2); | 453 | if (HPT366_ALLOW_ATA66_3 && |
465 | break; | 454 | !check_in_drive_list(drive, bad_ata66_3)) |
455 | goto check_bad_ata33; | ||
456 | /* fall thru */ | ||
466 | case 0x01: | 457 | case 0x01: |
467 | speed = min(speed, (u8)XFER_UDMA_2); | 458 | speed = min(speed, (u8)XFER_UDMA_2); |
468 | /* | 459 | |
469 | * CHECK ME, Does this need to be set to 5 ?? | 460 | check_bad_ata33: |
470 | */ | 461 | if (info->revision >= 4) |
471 | if (info->revision >= 3) | ||
472 | break; | 462 | break; |
473 | if (check_in_drive_lists(drive, bad_ata33)) | 463 | if (!check_in_drive_list(drive, bad_ata33)) |
474 | speed = min(speed, (u8)XFER_MW_DMA_2); | 464 | break; |
475 | break; | 465 | /* fall thru */ |
476 | case 0x00: | 466 | case 0x00: |
477 | default: | 467 | default: |
478 | speed = min(speed, (u8)XFER_MW_DMA_2); | 468 | speed = min(speed, (u8)XFER_MW_DMA_2); |
@@ -481,22 +471,6 @@ static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed) | |||
481 | return speed; | 471 | return speed; |
482 | } | 472 | } |
483 | 473 | ||
484 | static int check_in_drive_lists (ide_drive_t *drive, const char **list) | ||
485 | { | ||
486 | struct hd_driveid *id = drive->id; | ||
487 | |||
488 | if (quirk_drives == list) { | ||
489 | while (*list) | ||
490 | if (strstr(id->model, *list++)) | ||
491 | return 1; | ||
492 | } else { | ||
493 | while (*list) | ||
494 | if (!strcmp(*list++,id->model)) | ||
495 | return 1; | ||
496 | } | ||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | static u32 pci_bus_clock_list(u8 speed, u32 *chipset_table) | 474 | static u32 pci_bus_clock_list(u8 speed, u32 *chipset_table) |
501 | { | 475 | { |
502 | int i; | 476 | int i; |
@@ -671,9 +645,15 @@ static int config_chipset_for_dma (ide_drive_t *drive) | |||
671 | return ide_dma_enable(drive); | 645 | return ide_dma_enable(drive); |
672 | } | 646 | } |
673 | 647 | ||
674 | static int hpt3xx_quirkproc (ide_drive_t *drive) | 648 | static int hpt3xx_quirkproc(ide_drive_t *drive) |
675 | { | 649 | { |
676 | return ((int) check_in_drive_lists(drive, quirk_drives)); | 650 | struct hd_driveid *id = drive->id; |
651 | const char **list = quirk_drives; | ||
652 | |||
653 | while (*list) | ||
654 | if (strstr(id->model, *list++)) | ||
655 | return 1; | ||
656 | return 0; | ||
677 | } | 657 | } |
678 | 658 | ||
679 | static void hpt3xx_intrproc (ide_drive_t *drive) | 659 | static void hpt3xx_intrproc (ide_drive_t *drive) |
@@ -1381,7 +1361,7 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif) | |||
1381 | struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL); | 1361 | struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL); |
1382 | struct pci_dev *dev = hwif->pci_dev; | 1362 | struct pci_dev *dev = hwif->pci_dev; |
1383 | u16 did = dev->device; | 1363 | u16 did = dev->device; |
1384 | u8 rid = 0; | 1364 | u8 mode, rid = 0; |
1385 | 1365 | ||
1386 | if(info == NULL) { | 1366 | if(info == NULL) { |
1387 | printk(KERN_WARNING "hpt366: out of memory.\n"); | 1367 | printk(KERN_WARNING "hpt366: out of memory.\n"); |
@@ -1395,7 +1375,7 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif) | |||
1395 | return; | 1375 | return; |
1396 | } | 1376 | } |
1397 | 1377 | ||
1398 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &rid); | 1378 | pci_read_config_byte(dev, PCI_REVISION_ID, &rid); |
1399 | 1379 | ||
1400 | if (( did == PCI_DEVICE_ID_TTI_HPT366 && rid == 6) || | 1380 | if (( did == PCI_DEVICE_ID_TTI_HPT366 && rid == 6) || |
1401 | ((did == PCI_DEVICE_ID_TTI_HPT372 || | 1381 | ((did == PCI_DEVICE_ID_TTI_HPT372 || |
@@ -1404,9 +1384,22 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif) | |||
1404 | did == PCI_DEVICE_ID_TTI_HPT372N) | 1384 | did == PCI_DEVICE_ID_TTI_HPT372N) |
1405 | info->flags |= IS_3xxN; | 1385 | info->flags |= IS_3xxN; |
1406 | 1386 | ||
1407 | info->revision = hpt_revision(dev); | 1387 | rid = info->revision = hpt_revision(dev); |
1408 | 1388 | if (rid >= 8) /* HPT374 */ | |
1409 | if (info->revision >= 3) | 1389 | mode = HPT374_ALLOW_ATA133_6 ? 4 : 3; |
1390 | else if (rid >= 7) /* HPT371 and HPT371N */ | ||
1391 | mode = HPT371_ALLOW_ATA133_6 ? 4 : 3; | ||
1392 | else if (rid >= 6) /* HPT302 and HPT302N */ | ||
1393 | mode = HPT302_ALLOW_ATA133_6 ? 4 : 3; | ||
1394 | else if (rid >= 5) /* HPT372, HPT372A, and HPT372N */ | ||
1395 | mode = HPT372_ALLOW_ATA133_6 ? 4 : 3; | ||
1396 | else if (rid >= 3) /* HPT370 and HPT370A */ | ||
1397 | mode = HPT370_ALLOW_ATA100_5 ? 3 : 2; | ||
1398 | else /* HPT366 and HPT368 */ | ||
1399 | mode = (HPT366_ALLOW_ATA66_4 || HPT366_ALLOW_ATA66_3) ? 2 : 1; | ||
1400 | info->max_mode = mode; | ||
1401 | |||
1402 | if (rid >= 3) | ||
1410 | hpt37x_clocking(hwif); | 1403 | hpt37x_clocking(hwif); |
1411 | else | 1404 | else |
1412 | hpt366_clocking(hwif); | 1405 | hpt366_clocking(hwif); |
@@ -1461,8 +1454,7 @@ static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d) | |||
1461 | static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) | 1454 | static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) |
1462 | { | 1455 | { |
1463 | struct pci_dev *findev = NULL; | 1456 | struct pci_dev *findev = NULL; |
1464 | u8 pin1 = 0, pin2 = 0; | 1457 | u8 rev = 0, pin1 = 0, pin2 = 0; |
1465 | unsigned int class_rev; | ||
1466 | char *chipset_names[] = {"HPT366", "HPT366", "HPT368", | 1458 | char *chipset_names[] = {"HPT366", "HPT366", "HPT368", |
1467 | "HPT370", "HPT370A", "HPT372", | 1459 | "HPT370", "HPT370A", "HPT372", |
1468 | "HPT372N" }; | 1460 | "HPT372N" }; |
@@ -1470,16 +1462,15 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) | |||
1470 | if (PCI_FUNC(dev->devfn) & 1) | 1462 | if (PCI_FUNC(dev->devfn) & 1) |
1471 | return -ENODEV; | 1463 | return -ENODEV; |
1472 | 1464 | ||
1473 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | 1465 | pci_read_config_byte(dev, PCI_REVISION_ID, &rev); |
1474 | class_rev &= 0xff; | ||
1475 | 1466 | ||
1476 | if(dev->device == PCI_DEVICE_ID_TTI_HPT372N) | 1467 | if(dev->device == PCI_DEVICE_ID_TTI_HPT372N) |
1477 | class_rev = 6; | 1468 | rev = 6; |
1478 | 1469 | ||
1479 | if(class_rev <= 6) | 1470 | if(rev <= 6) |
1480 | d->name = chipset_names[class_rev]; | 1471 | d->name = chipset_names[rev]; |
1481 | 1472 | ||
1482 | switch(class_rev) { | 1473 | switch(rev) { |
1483 | case 6: | 1474 | case 6: |
1484 | case 5: | 1475 | case 5: |
1485 | case 4: | 1476 | case 4: |