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 /drivers/ide/pci/cmd64x.c | |
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>
Diffstat (limited to 'drivers/ide/pci/cmd64x.c')
-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[] = { |