libata: fix length validation of ATAPI-relayed SCSI commands
[pandora-kernel.git] / drivers / ssb / main.c
index 29c7d4f..bb6317f 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_regs.h>
 #include <linux/ssb/ssb_driver_gige.h>
@@ -1260,16 +1261,34 @@ void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
 }
 EXPORT_SYMBOL(ssb_device_disable);
 
+/* Some chipsets need routing known for PCIe and 64-bit DMA */
+static bool ssb_dma_translation_special_bit(struct ssb_device *dev)
+{
+       u16 chip_id = dev->bus->chip_id;
+
+       if (dev->id.coreid == SSB_DEV_80211) {
+               return (chip_id == 0x4322 || chip_id == 43221 ||
+                       chip_id == 43231 || chip_id == 43222);
+       }
+
+       return 0;
+}
+
 u32 ssb_dma_translation(struct ssb_device *dev)
 {
        switch (dev->bus->bustype) {
        case SSB_BUSTYPE_SSB:
                return 0;
        case SSB_BUSTYPE_PCI:
-               if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)
+               if (pci_is_pcie(dev->bus->host_pci) &&
+                   ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64) {
                        return SSB_PCIE_DMA_H32;
-               else
-                       return SSB_PCI_DMA;
+               } else {
+                       if (ssb_dma_translation_special_bit(dev))
+                               return SSB_PCIE_DMA_H32;
+                       else
+                               return SSB_PCI_DMA;
+               }
        default:
                __ssb_dma_not_implemented(dev);
        }