Commit 67435274 authored by Pierre Ossman's avatar Pierre Ossman Committed by Russell King

[MMC] sdhci: more DMA capabilities tests

Properly test for controller interface to see if it's DMA capable.  As many
controllers are misconfigured in this regard, also add debug parameters to
force DMA support either way.
Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent d96649ed
......@@ -28,6 +28,9 @@
#define DBG(f, x...) \
pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
static unsigned int debug_nodma = 0;
static unsigned int debug_forcedma = 0;
static const struct pci_device_id pci_ids[] __devinitdata = {
/* handle any SD host controller */
{PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)},
......@@ -1105,6 +1108,16 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
return -ENODEV;
}
if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
printk(KERN_ERR DRIVER_NAME ": Vendor specific interface. Aborting.\n");
return -ENODEV;
}
if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) {
printk(KERN_ERR DRIVER_NAME ": Unknown interface. Aborting.\n");
return -ENODEV;
}
mmc = mmc_alloc_host(sizeof(struct sdhci_host), &pdev->dev);
if (!mmc)
return -ENOMEM;
......@@ -1146,7 +1159,16 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
if ((caps & SDHCI_CAN_DO_DMA) && ((pdev->class & 0x0000FF) == 0x01))
if (debug_nodma)
DBG("DMA forced off\n");
else if (debug_forcedma) {
DBG("DMA forced on\n");
host->flags |= SDHCI_USE_DMA;
} else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA)
DBG("Controller doesn't have DMA interface\n");
else if (!(caps & SDHCI_CAN_DO_DMA))
DBG("Controller doesn't have DMA capability\n");
else
host->flags |= SDHCI_USE_DMA;
if (host->flags & SDHCI_USE_DMA) {
......@@ -1429,7 +1451,13 @@ static void __exit sdhci_drv_exit(void)
module_init(sdhci_drv_init);
module_exit(sdhci_drv_exit);
module_param(debug_nodma, uint, 0444);
module_param(debug_forcedma, uint, 0444);
MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver");
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)");
MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers. (default 0)");
......@@ -12,6 +12,10 @@
* PCI registers
*/
#define PCI_SDHCI_IFPIO 0x00
#define PCI_SDHCI_IFDMA 0x01
#define PCI_SDHCI_IFVENDOR 0x02
#define PCI_SLOT_INFO 0x40 /* 8 bits */
#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7)
#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment