diff options
-rw-r--r-- | drivers/ata/ahci.c | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c720c2c5cefe..530f0c1f1793 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -842,6 +842,8 @@ static ssize_t ahci_show_port_cmd(struct device *dev, | |||
842 | * ahci_save_initial_config - Save and fixup initial config values | 842 | * ahci_save_initial_config - Save and fixup initial config values |
843 | * @pdev: target PCI device | 843 | * @pdev: target PCI device |
844 | * @hpriv: host private area to store config values | 844 | * @hpriv: host private area to store config values |
845 | * @force_port_map: force port map to a specified value | ||
846 | * @mask_port_map: mask out particular bits from port map | ||
845 | * | 847 | * |
846 | * Some registers containing configuration info might be setup by | 848 | * Some registers containing configuration info might be setup by |
847 | * BIOS and might be cleared on reset. This function saves the | 849 | * BIOS and might be cleared on reset. This function saves the |
@@ -854,12 +856,13 @@ static ssize_t ahci_show_port_cmd(struct device *dev, | |||
854 | * None. | 856 | * None. |
855 | */ | 857 | */ |
856 | static void ahci_save_initial_config(struct pci_dev *pdev, | 858 | static void ahci_save_initial_config(struct pci_dev *pdev, |
857 | struct ahci_host_priv *hpriv) | 859 | struct ahci_host_priv *hpriv, |
860 | unsigned int force_port_map, | ||
861 | unsigned int mask_port_map) | ||
858 | { | 862 | { |
859 | void __iomem *mmio = hpriv->mmio; | 863 | void __iomem *mmio = hpriv->mmio; |
860 | u32 cap, cap2, vers, port_map; | 864 | u32 cap, cap2, vers, port_map; |
861 | int i; | 865 | int i; |
862 | int mv; | ||
863 | 866 | ||
864 | /* make sure AHCI mode is enabled before accessing CAP */ | 867 | /* make sure AHCI mode is enabled before accessing CAP */ |
865 | ahci_enable_ahci(mmio); | 868 | ahci_enable_ahci(mmio); |
@@ -909,32 +912,19 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
909 | cap &= ~HOST_CAP_SNTF; | 912 | cap &= ~HOST_CAP_SNTF; |
910 | } | 913 | } |
911 | 914 | ||
912 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 && | 915 | if (force_port_map && port_map != force_port_map) { |
913 | port_map != 1) { | ||
914 | dev_printk(KERN_INFO, &pdev->dev, | 916 | dev_printk(KERN_INFO, &pdev->dev, |
915 | "JMB361 has only one port, port_map 0x%x -> 0x%x\n", | 917 | "forcing port_map 0x%x -> 0x%x\n", |
916 | port_map, 1); | 918 | port_map, force_port_map); |
917 | port_map = 1; | 919 | port_map = force_port_map; |
918 | } | 920 | } |
919 | 921 | ||
920 | /* | 922 | if (mask_port_map) { |
921 | * Temporary Marvell 6145 hack: PATA port presence | ||
922 | * is asserted through the standard AHCI port | ||
923 | * presence register, as bit 4 (counting from 0) | ||
924 | */ | ||
925 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { | ||
926 | if (pdev->device == 0x6121) | ||
927 | mv = 0x3; | ||
928 | else | ||
929 | mv = 0xf; | ||
930 | dev_printk(KERN_ERR, &pdev->dev, | 923 | dev_printk(KERN_ERR, &pdev->dev, |
931 | "MV_AHCI HACK: port_map %x -> %x\n", | 924 | "masking port_map 0x%x -> 0x%x\n", |
932 | port_map, | 925 | port_map, |
933 | port_map & mv); | 926 | port_map & mask_port_map); |
934 | dev_printk(KERN_ERR, &pdev->dev, | 927 | port_map &= mask_port_map; |
935 | "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n"); | ||
936 | |||
937 | port_map &= mv; | ||
938 | } | 928 | } |
939 | 929 | ||
940 | /* cross check port_map and cap.n_ports */ | 930 | /* cross check port_map and cap.n_ports */ |
@@ -973,6 +963,34 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
973 | hpriv->port_map = port_map; | 963 | hpriv->port_map = port_map; |
974 | } | 964 | } |
975 | 965 | ||
966 | static void ahci_pci_save_initial_config(struct pci_dev *pdev, | ||
967 | struct ahci_host_priv *hpriv) | ||
968 | { | ||
969 | unsigned int force_port_map = 0; | ||
970 | unsigned int mask_port_map = 0; | ||
971 | |||
972 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { | ||
973 | dev_info(&pdev->dev, "JMB361 has only one port\n"); | ||
974 | force_port_map = 1; | ||
975 | } | ||
976 | |||
977 | /* | ||
978 | * Temporary Marvell 6145 hack: PATA port presence | ||
979 | * is asserted through the standard AHCI port | ||
980 | * presence register, as bit 4 (counting from 0) | ||
981 | */ | ||
982 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { | ||
983 | if (pdev->device == 0x6121) | ||
984 | mask_port_map = 0x3; | ||
985 | else | ||
986 | mask_port_map = 0xf; | ||
987 | dev_info(&pdev->dev, | ||
988 | "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n"); | ||
989 | } | ||
990 | |||
991 | ahci_save_initial_config(pdev, hpriv, force_port_map, mask_port_map); | ||
992 | } | ||
993 | |||
976 | /** | 994 | /** |
977 | * ahci_restore_initial_config - Restore initial config | 995 | * ahci_restore_initial_config - Restore initial config |
978 | * @host: target ATA host | 996 | * @host: target ATA host |
@@ -3316,7 +3334,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3316 | hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; | 3334 | hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; |
3317 | 3335 | ||
3318 | /* save initial config */ | 3336 | /* save initial config */ |
3319 | ahci_save_initial_config(pdev, hpriv); | 3337 | ahci_pci_save_initial_config(pdev, hpriv); |
3320 | 3338 | ||
3321 | /* prepare host */ | 3339 | /* prepare host */ |
3322 | if (hpriv->cap & HOST_CAP_NCQ) { | 3340 | if (hpriv->cap & HOST_CAP_NCQ) { |