ricoh_mmc: Handle newer models of Ricoh controllers (resend)
PATCH 1/1 ricoh_mmc: Handle newer models of Ricoh controllers (resend)
The latest generation of laptops are shipping with a newer model of Ricoh chip where the firewire controller is the primary PCI function but a cardbus controller is also present.
The existing code assumes that if a cardbus controller is, present, then it must be the one to manipulate - but the real rule is that you manipulate PCI function 0. This patch adds an additional constraint that the target must be function 0.
---
ricoh_mmc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/mmc/host/ricoh_mmc.c +11 -6
@@ -11,9 +11,10 @@/* * This is a conceptually ridiculous driver, but it is required by the way -* the Ricoh multi-function R5C832 works. This chip implements firewire -* and four different memory card controllers. Two of those controllers are -* an SDHCI controller and a proprietary MMC controller. The linux SDHCI +* the Ricoh multi-function chips (R5CXXX) work. These chips implement +* the four main memory card controllers (SD, MMC, MS, xD) and one or both +* of cardbus or firewire. It happens that they implement SD and MMC +* support as separate controllers (and PCI functions). The linux SDHCI * driver supports MMC cards but the chip detects MMC cards in hardware * and directs them to the MMC controller - so the SDHCI driver never sees * them. To get around this, we must disable the useless MMC controller.
@@ -21,8 +22,10 @@* a detection event occurs immediately, even if the MMC card is already * in the reader. * -* The relevant registers live on the firewire function, so this is unavoidably -* ugly. Such is life. +* It seems to be the case that the relevant PCI registers to deactivate the +* MMC controller live on PCI function 0, which might be the cardbus controller +* or the firewire controller, depending on the particular chip in question. As +* such, it makes what this driver has to do unavoidably ugly. Such is life. */ #include <linux/pci.h>
@@ -143,6 +146,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {if (PCI_SLOT (pdev->devfn) ==PCI_SLOT (fw_dev->devfn) && +PCI_FUNC (fw_dev->devfn) ==0 && pdev->bus == fw_dev->bus) {if (ricoh_mmc_disable (fw_dev) !=0 )return -ENODEV ;
@@ -160,6 +164,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {if (PCI_SLOT (pdev->devfn) ==PCI_SLOT (fw_dev->devfn) && +PCI_FUNC (fw_dev->devfn) ==0 && pdev->bus == fw_dev->bus) {if (ricoh_mmc_disable (fw_dev) !=0 )return -ENODEV ;
@@ -172,7 +177,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,if (!ctrlfound) { printk(KERN_WARNING DRIVER_NAME - ": Main firewire function not found. Cannot disable controller.\n"); + ": Main Ricoh function not found. Cannot disable controller.\n");return -ENODEV ; }
Quoted 36 lines · On Sun, 30 Nov 2008 20:27:50 -0500 (EST) [email protected] wrote:
The latest generation of laptops are shipping with a newer model of Ricoh chip where the firewire controller is the primary PCI function but a cardbus controller is also present.
The existing code assumes that if a cardbus controller is, present, then it must be the one to manipulate - but the real rule is that you manipulate PCI function 0. This patch adds an additional constraint that the target must be function 0.
Signed-off-by Philip Langdale <[email protected]>---
ricoh_mmc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)drivers/mmc/host/ricoh_mmc.c +4
-3@@ -11,9 +11,10 @@/* * This is a conceptually ridiculous driver, but it is required by the way -* the Ricoh multi-function R5C832 works. This chip implements firewire -* and four different memory card controllers. Two of those controllers are -* an SDHCI controller and a proprietary MMC controller. The linux SDHCI +* the Ricoh multi-function chips (R5CXXX) work. These chips implement +* the four main memory card controllers (SD, MMC, MS, xD) and one or both +* of cardbus or firewire. It happens that they implement SD and MMC +* support as separate controllers (and PCI functions). The linux SDHCI * driver supports MMC cards but the chip detects MMC cards in hardware * and directs them to the MMC controller - so the SDHCI driver never sees * them. To get around this, we must disable the useless MMC controller. @@ -21,8 +22,10 @@* a detection event occurs immediately, even if the MMC card is already * in the reader.
drivers/mmc/host/ricoh_mmc.c line 31
Quoted 10 lines
drivers/mmc/host/ricoh_mmc.c +4
-2* -* The relevant registers live on the firewire function, so this is unavoidably -* ugly. Such is life. +* It seems to be the case that the relevant PCI registers to deactivate the +* MMC controller live on PCI function 0, which might be the cardbus controller +* or the firewire controller, depending on the particular chip in question. As +* such, it makes what this driver has to do unavoidably ugly. Such is life. */ #include <linux/pci.h>
The above two hunks already are in linux-next.
Quoted 17 lines
drivers/mmc/host/ricoh_mmc.c +2
-0@@ -143,6 +146,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {if (PCI_SLOT (pdev->devfn) ==PCI_SLOT (fw_dev->devfn) && +PCI_FUNC (fw_dev->devfn) ==0 && pdev->bus == fw_dev->bus) {if (ricoh_mmc_disable (fw_dev) !=0 )return -ENODEV ;@@ -160,6 +164,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {if (PCI_SLOT (pdev->devfn) ==PCI_SLOT (fw_dev->devfn) && +PCI_FUNC (fw_dev->devfn) ==0 && pdev->bus == fw_dev->bus) {if (ricoh_mmc_disable (fw_dev) !=0 )return -ENODEV ;
drivers/mmc/host/ricoh_mmc.c static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, · line 182
Quoted 7 lines
drivers/mmc/host/ricoh_mmc.c +1
-1@@ -172,7 +177,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,if (!ctrlfound) { printk(KERN_WARNING DRIVER_NAME - ": Main firewire function not found. Cannot disable controller.\n"); + ": Main Ricoh function not found. Cannot disable controller.\n");return -ENODEV ; }
Those three are not.
Quoted 53 lines · Andrew Morton
Quoted 22 lines
drivers/mmc/host/ricoh_mmc.c +4
-3@@ -11,9 +11,10 @@/* * This is a conceptually ridiculous driver, but it is required by the way -* the Ricoh multi-function R5C832 works. This chip implements firewire -* and four different memory card controllers. Two of those controllers are -* an SDHCI controller and a proprietary MMC controller. The linux SDHCI +* the Ricoh multi-function chips (R5CXXX) work. These chips implement +* the four main memory card controllers (SD, MMC, MS, xD) and one or both +* of cardbus or firewire. It happens that they implement SD and MMC +* support as separate controllers (and PCI functions). The linux SDHCI * driver supports MMC cards but the chip detects MMC cards in hardware * and directs them to the MMC controller - so the SDHCI driver never sees * them. To get around this, we must disable the useless MMC controller. @@ -21,8 +22,10 @@* a detection event occurs immediately, even if the MMC card is already * in the reader. drivers/mmc/host/ricoh_mmc.c line 31
Quoted 10 lines
drivers/mmc/host/ricoh_mmc.c +4
-2* -* The relevant registers live on the firewire function, so this is unavoidably -* ugly. Such is life. +* It seems to be the case that the relevant PCI registers to deactivate the +* MMC controller live on PCI function 0, which might be the cardbus controller +* or the firewire controller, depending on the particular chip in question. As +* such, it makes what this driver has to do unavoidably ugly. Such is life. */ #include <linux/pci.h> The above two hunks already are in linux-next.
Quoted 18 lines
drivers/mmc/host/ricoh_mmc.c +2
-0@@ -143,6 +146,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {if (PCI_SLOT (pdev->devfn) ==PCI_SLOT (fw_dev->devfn) && +PCI_FUNC (fw_dev->devfn) ==0 && pdev->bus == fw_dev->bus) {if (ricoh_mmc_disable (fw_dev) !=0 )return -ENODEV ;@@ -160,6 +164,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {if (PCI_SLOT (pdev->devfn) ==PCI_SLOT (fw_dev->devfn) && +PCI_FUNC (fw_dev->devfn) ==0 && pdev->bus == fw_dev->bus) {if (ricoh_mmc_disable (fw_dev) !=0 )return -ENODEV ;@@ -172,7 +177,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
Quoted 9 lines
drivers/mmc/host/ricoh_mmc.c static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, · line 182
Quoted 6 lines
drivers/mmc/host/ricoh_mmc.c +1
-1if (!ctrlfound) { printk(KERN_WARNING DRIVER_NAME - ": Main firewire function not found. Cannot disable controller.\n"); + ": Main Ricoh function not found. Cannot disable controller.\n");return -ENODEV ; }Those three are not.
Indeed. Pierre, seems like the patch didn't git-apply properly. It's this way in your tree too. Did you apply the previous garbled version?
--phil
Quoted 4 lines · On Tue, 02 Dec 2008 19:37:01 -0800 Philip Langdale <[email protected]> wrote:
Indeed. Pierre, seems like the patch didn't git-apply properly. It's this way in your tree too. Did you apply the previous garbled version?
Odd.
Anyway, I've queued up the fixed versions instead. Should be hitting next in a day or two.
Signature · 6 lines
-- Pierre Ossman WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.