diff options
| author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2007-05-05 16:03:49 -0400 |
|---|---|---|
| committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-05-05 16:03:49 -0400 |
| commit | 7accbffdb8163a59c7bdd3e4eb9a391198979522 (patch) | |
| tree | f5752ca425f25a2be87bb84fec13488879a74cc6 | |
| parent | e51e2528d589c13f0e51dfa671c310021d003e21 (diff) | |
cmd64x: add/fix enablebits (take 2)
The IDE core looks at the wrong bit when checking if the secondary channel is
enabled on PCI0646 -- CNTRL register bit 7 is read-ahead disable, bit 3 is the
correct one.
Starting with PCI0646U chip, the primary channel can also be enabled/disabled --
so, add 'enablebits' initializers to each 'ide_pci_device_t' structure, handling
the original PCI0646 via adding the init_setup() method and clearing the 'reg'
field there if necessary...
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
| -rw-r--r-- | drivers/ide/pci/cmd64x.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index f165bf1c06dc..63fd9294c7c4 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/ide/pci/cmd64x.c Version 1.44 Mar 12, 2007 | 2 | * linux/drivers/ide/pci/cmd64x.c Version 1.45 Mar 14, 2007 |
| 3 | * | 3 | * |
| 4 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. | 4 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. |
| 5 | * Due to massive hardware bugs, UltraDMA is only supported | 5 | * Due to massive hardware bugs, UltraDMA is only supported |
| @@ -684,42 +684,75 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) | |||
| 684 | hwif->drives[1].autodma = hwif->autodma; | 684 | hwif->drives[1].autodma = hwif->autodma; |
| 685 | } | 685 | } |
| 686 | 686 | ||
| 687 | static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d) | ||
| 688 | { | ||
| 689 | return ide_setup_pci_device(dev, d); | ||
| 690 | } | ||
| 691 | |||
| 692 | static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d) | ||
| 693 | { | ||
| 694 | u8 rev = 0; | ||
| 695 | |||
| 696 | /* | ||
| 697 | * The original PCI0646 didn't have the primary channel enable bit, | ||
| 698 | * it appeared starting with PCI0646U (i.e. revision ID 3). | ||
| 699 | */ | ||
| 700 | pci_read_config_byte(dev, PCI_REVISION_ID, &rev); | ||
| 701 | if (rev < 3) | ||
| 702 | d->enablebits[0].reg = 0; | ||
| 703 | |||
| 704 | return ide_setup_pci_device(dev, d); | ||
| 705 | } | ||
| 706 | |||
| 687 | static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { | 707 | static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { |
| 688 | { /* 0 */ | 708 | { /* 0 */ |
| 689 | .name = "CMD643", | 709 | .name = "CMD643", |
| 710 | .init_setup = init_setup_cmd64x, | ||
| 690 | .init_chipset = init_chipset_cmd64x, | 711 | .init_chipset = init_chipset_cmd64x, |
| 691 | .init_hwif = init_hwif_cmd64x, | 712 | .init_hwif = init_hwif_cmd64x, |
| 692 | .channels = 2, | 713 | .channels = 2, |
| 693 | .autodma = AUTODMA, | 714 | .autodma = AUTODMA, |
| 715 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, | ||
| 694 | .bootable = ON_BOARD, | 716 | .bootable = ON_BOARD, |
| 695 | },{ /* 1 */ | 717 | },{ /* 1 */ |
| 696 | .name = "CMD646", | 718 | .name = "CMD646", |
| 719 | .init_setup = init_setup_cmd646, | ||
| 697 | .init_chipset = init_chipset_cmd64x, | 720 | .init_chipset = init_chipset_cmd64x, |
| 698 | .init_hwif = init_hwif_cmd64x, | 721 | .init_hwif = init_hwif_cmd64x, |
| 699 | .channels = 2, | 722 | .channels = 2, |
| 700 | .autodma = AUTODMA, | 723 | .autodma = AUTODMA, |
| 701 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, | 724 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
| 702 | .bootable = ON_BOARD, | 725 | .bootable = ON_BOARD, |
| 703 | },{ /* 2 */ | 726 | },{ /* 2 */ |
| 704 | .name = "CMD648", | 727 | .name = "CMD648", |
| 728 | .init_setup = init_setup_cmd64x, | ||
| 705 | .init_chipset = init_chipset_cmd64x, | 729 | .init_chipset = init_chipset_cmd64x, |
| 706 | .init_hwif = init_hwif_cmd64x, | 730 | .init_hwif = init_hwif_cmd64x, |
| 707 | .channels = 2, | 731 | .channels = 2, |
| 708 | .autodma = AUTODMA, | 732 | .autodma = AUTODMA, |
| 733 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | ||
| 709 | .bootable = ON_BOARD, | 734 | .bootable = ON_BOARD, |
| 710 | },{ /* 3 */ | 735 | },{ /* 3 */ |
| 711 | .name = "CMD649", | 736 | .name = "CMD649", |
| 737 | .init_setup = init_setup_cmd64x, | ||
| 712 | .init_chipset = init_chipset_cmd64x, | 738 | .init_chipset = init_chipset_cmd64x, |
| 713 | .init_hwif = init_hwif_cmd64x, | 739 | .init_hwif = init_hwif_cmd64x, |
| 714 | .channels = 2, | 740 | .channels = 2, |
| 715 | .autodma = AUTODMA, | 741 | .autodma = AUTODMA, |
| 742 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | ||
| 716 | .bootable = ON_BOARD, | 743 | .bootable = ON_BOARD, |
| 717 | } | 744 | } |
| 718 | }; | 745 | }; |
| 719 | 746 | ||
| 747 | /* | ||
| 748 | * We may have to modify enablebits for PCI0646, so we'd better pass | ||
| 749 | * a local copy of the ide_pci_device_t structure down the call chain... | ||
| 750 | */ | ||
| 720 | static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 751 | static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
| 721 | { | 752 | { |
| 722 | return ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]); | 753 | ide_pci_device_t d = cmd64x_chipsets[id->driver_data]; |
| 754 | |||
| 755 | return d.init_setup(dev, &d); | ||
| 723 | } | 756 | } |
| 724 | 757 | ||
| 725 | static struct pci_device_id cmd64x_pci_tbl[] = { | 758 | static struct pci_device_id cmd64x_pci_tbl[] = { |
