Re: [PATCH v2] mmc: extend ricoh_mmc to support Ricoh RL5c476

2008-02-04 Thread Philip Langdale

On Mon, 4 Feb 2008 19:25:42 +0100, Frank Seidel <[EMAIL PROTECTED]> wrote:
> From: Frank Seidel <[EMAIL PROTECTED]>
> 
> This patch (base on current linus git tree plus Philip Langdales
> suspend/resume patch) adds support for the Ricoh RL5c476 chip:
> with this the mmc adapter that needs this disabler (R5C843) can
> also be handled correctly when it sits on a RL5c476.
> (+ minor style changes (removed spaces between function names
> and open parenthesis .. checkpatch warned from previos patch))
> 
> Signed-off-by: Frank Seidel <[EMAIL PROTECTED]>
> ---
>  drivers/mmc/host/ricoh_mmc.c |  101
> ++-
>  1 file changed, 80 insertions(+), 21 deletions(-)
> 
> --- a/drivers/mmc/host/ricoh_mmc.c
> +++ b/drivers/mmc/host/ricoh_mmc.c
> @@ -44,19 +44,43 @@ MODULE_DEVICE_TABLE(pci, pci_ids);
>  static int ricoh_mmc_disable(struct pci_dev *fw_dev)
>  {
>   u8 write_enable;
> + u8 write_target;
>   u8 disable;
> 
> - pci_read_config_byte(fw_dev, 0xCB, &disable);
> - if (disable & 0x02) {
> - printk(KERN_INFO DRIVER_NAME
> -": Controller already disabled. Nothing to do.\n");
> - return -ENODEV;
> - }
> + if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
> + /* via RL5C476 */
> +
> + pci_read_config_byte(fw_dev, 0xB7, &disable);
> + if (disable & 0x02) {
> + printk(KERN_INFO DRIVER_NAME
> + ": Controller already disabled. " \
> + "Nothing to do.\n");
> + return -ENODEV;
> + }
> +
> + pci_read_config_byte(fw_dev, 0x8E, &write_enable);
> + pci_write_config_byte(fw_dev, 0x8E, 0xAA);
> + pci_read_config_byte(fw_dev, 0x8D, &write_target);
> + pci_write_config_byte(fw_dev, 0x8D, 0xB7);
> + pci_write_config_byte(fw_dev, 0xB7, disable | 0x02);
> + pci_write_config_byte(fw_dev, 0x8E, write_enable);
> + pci_write_config_byte(fw_dev, 0x8D, write_target);
> + } else {
> + /* via R5C832 */
> +
> + pci_read_config_byte(fw_dev, 0xCB, &disable);
> + if (disable & 0x02) {
> + printk(KERN_INFO DRIVER_NAME
> +": Controller already disabled. " \
> + "Nothing to do.\n");
> + return -ENODEV;
> + }
> 
> - pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> - pci_write_config_byte(fw_dev, 0xCA, 0x57);
> - pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
> - pci_write_config_byte(fw_dev, 0xCA, write_enable);
> + pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> + pci_write_config_byte(fw_dev, 0xCA, 0x57);
> + pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
> + pci_write_config_byte(fw_dev, 0xCA, write_enable);
> + }
> 
>   printk(KERN_INFO DRIVER_NAME
>  ": Controller is now disabled.\n");
> @@ -67,13 +91,29 @@ static int ricoh_mmc_disable(struct pci_
>  static int ricoh_mmc_enable(struct pci_dev *fw_dev)
>  {
>   u8 write_enable;
> + u8 write_target;
>   u8 disable;
> 
> - pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> - pci_read_config_byte(fw_dev, 0xCB, &disable);
> - pci_write_config_byte(fw_dev, 0xCA, 0x57);
> - pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
> - pci_write_config_byte(fw_dev, 0xCA, write_enable);
> + if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
> + /* via RL5C476 */
> +
> + pci_read_config_byte(fw_dev, 0x8E, &write_enable);
> + pci_write_config_byte(fw_dev, 0x8E, 0xAA);
> + pci_read_config_byte(fw_dev, 0x8D, &write_target);
> + pci_write_config_byte(fw_dev, 0x8D, 0xB7);
> + pci_read_config_byte(fw_dev, 0xB7, &disable);
> + pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02);
> + pci_write_config_byte(fw_dev, 0x8E, write_enable);
> + pci_write_config_byte(fw_dev, 0x8D, write_target);
> + } else {
> + /* via R5C832 */
> +
> + pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> + pci_read_config_byte(fw_dev, 0xCB, &disable);
> + pci_write_config_byte(fw_dev, 0xCA, 0x57);
> + pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
> + pci_write_config_byte(fw_dev, 0xCA, write_enable);
> + }
> 
>   printk(KERN_INFO DRIVER_NAME
>  ": Controller is now re-enabled.\n");
> @@ -85,6 +125,7 @@ static int __devinit ricoh_mmc_probe(str
>const struct pci_device_id *ent)
>  {
>   u8 rev;
> + u8 ctrlfound = 0;
> 
>   struct pci_dev *fw_dev = NULL;
> 
> @@ -98,20 +139,38 @@ static int __devinit ricoh_mmc_probe(str
>   pci_name(pdev), (int)pdev->vend

Re: [PATCH] mmc: Handle suspend/resume in Ricoh MMC disabler (resent refreshed)

2008-02-04 Thread Philip Langdale

On Mon, 4 Feb 2008 19:25:38 +0100, Frank Seidel <[EMAIL PROTECTED]> wrote:
> From: Philip Langdale <[EMAIL PROTECTED]>
> 
> As pci config space is reinitialised on suspend/resume cycle, the
> disabler needs to work its magic at resume time. For symmetry this
> change also explicitly enables the controller at suspend time but
> it's not strictly necessary.
> 
> Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>
> Signed-off-by: Frank Seidel <[EMAIL PROTECTED]>
> ---
>  drivers/mmc/host/ricoh_mmc.c |   97
> +++
>  1 file changed, 72 insertions(+), 25 deletions(-)
> 
> --- a/drivers/mmc/host/ricoh_mmc.c
> +++ b/drivers/mmc/host/ricoh_mmc.c
> @@ -41,6 +41,46 @@ static const struct pci_device_id pci_id
> 
>  MODULE_DEVICE_TABLE(pci, pci_ids);
> 
> +static int ricoh_mmc_disable(struct pci_dev *fw_dev)
> +{
> + u8 write_enable;
> + u8 disable;
> +
> + pci_read_config_byte(fw_dev, 0xCB, &disable);
> + if (disable & 0x02) {
> + printk(KERN_INFO DRIVER_NAME
> +": Controller already disabled. Nothing to do.\n");
> + return -ENODEV;
> + }
> +
> + pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> + pci_write_config_byte(fw_dev, 0xCA, 0x57);
> + pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
> + pci_write_config_byte(fw_dev, 0xCA, write_enable);
> +
> + printk(KERN_INFO DRIVER_NAME
> +": Controller is now disabled.\n");
> +
> + return 0;
> +}
> +
> +static int ricoh_mmc_enable(struct pci_dev *fw_dev)
> +{
> + u8 write_enable;
> + u8 disable;
> +
> + pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> + pci_read_config_byte(fw_dev, 0xCB, &disable);
> + pci_write_config_byte(fw_dev, 0xCA, 0x57);
> + pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
> + pci_write_config_byte(fw_dev, 0xCA, write_enable);
> +
> + printk(KERN_INFO DRIVER_NAME
> +": Controller is now re-enabled.\n");
> +
> + return 0;
> +}
> +
>  static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
>const struct pci_device_id *ent)
>  {
> @@ -61,26 +101,12 @@ static int __devinit ricoh_mmc_probe(str
>   while ((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) &&
>   pdev->bus == fw_dev->bus) {
> - u8 write_enable;
> - u8 disable;
> -
> - pci_read_config_byte(fw_dev, 0xCB, &disable);
> - if (disable & 0x02) {
> - printk(KERN_INFO DRIVER_NAME
> -": Controller already disabled. Nothing 
> to do.\n");
> + if (ricoh_mmc_disable(fw_dev) != 0) {
>   return -ENODEV;
>   }
> 
> - pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> - pci_write_config_byte(fw_dev, 0xCA, 0x57);
> - pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
> - pci_write_config_byte(fw_dev, 0xCA, write_enable);
> -
>   pci_set_drvdata(pdev, fw_dev);
> 
> - printk(KERN_INFO DRIVER_NAME
> -": Controller is now disabled.\n");
> -
>   break;
>   }
>   }
> @@ -96,30 +122,51 @@ static int __devinit ricoh_mmc_probe(str
> 
>  static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
>  {
> - u8 write_enable;
> - u8 disable;
>   struct pci_dev *fw_dev = NULL;
> 
>   fw_dev = pci_get_drvdata(pdev);
>   BUG_ON(fw_dev == NULL);
> 
> - pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> - pci_read_config_byte(fw_dev, 0xCB, &disable);
> - pci_write_config_byte(fw_dev, 0xCA, 0x57);
> - pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
> - pci_write_config_byte(fw_dev, 0xCA, write_enable);
> -
> - printk(KERN_INFO DRIVER_NAME
> -": Controller is now re-enabled.\n");
> + ricoh_mmc_enable(fw_dev);
> 
>   pci_set_drvdata(pdev, NULL);
>  }
> 
> +static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state)
> +{
> + struct pci_dev *fw_dev = NULL;
> +
> + fw_dev = pci_get_drvdata(pdev);
> + BUG_ON(fw_dev == NULL);
> +
> + printk(KERN_INFO DRIVE

Re: [PATCH] mmc: extend ricoh_mmc to support Ricoh RL5c476

2008-02-01 Thread Philip Langdale
Frank Seidel wrote:
> From: Frank Seidel <[EMAIL PROTECTED]>
> 
> This patch (based on current linus git tree) adds support for
> the Ricoh RL5c476 chip: with this the mmc adapter that needs this
> disabler (R5C843) can also be handled correctly when it sits
> on a RL5c476.

Again, thanks a lot for investigating and finding the appropriate magic
incantations. My main comment is to please base this on top of my suspend/resume
patch which Pierre said he accepted but which isn't in his tree yet - I guess
he's busy offline right now - haven't heard from him in a while.

> Signed-off-by: Frank Seidel <[EMAIL PROTECTED]>
> ---
>  drivers/mmc/host/ricoh_mmc.c |   91 
> +++
>  1 file changed, 75 insertions(+), 16 deletions(-)
> 
> --- a/drivers/mmc/host/ricoh_mmc.c
> +++ b/drivers/mmc/host/ricoh_mmc.c
> @@ -45,8 +45,10 @@ static int __devinit ricoh_mmc_probe(str
>const struct pci_device_id *ent)
>  {
>   u8 rev;
> + u8 ctrlfound = 0;
>  
>   struct pci_dev *fw_dev = NULL;
> + struct pci_dev *main_dev = NULL; /* for Ricoh RL5c476 II */

There's no need to have two pointers. One will do fine.

>   BUG_ON(pdev == NULL);
>   BUG_ON(ent == NULL);
> @@ -58,7 +60,47 @@ static int __devinit ricoh_mmc_probe(str
>   pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
>   (int)rev);
>  
> - while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, 
> PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
> + /* disable mmc controller via main function (RL5C476) */
> + while ((main_dev =
> + pci_get_device(PCI_VENDOR_ID_RICOH,
> + PCI_DEVICE_ID_RICOH_RL5C476, main_dev))) {
> + if (PCI_SLOT(pdev->devfn) == PCI_SLOT(main_dev->devfn) &&
> + pdev->bus == main_dev->bus) {
> + u8 write_enable;
> + u8 write_target;
> + u8 disable;
> +
> + pci_read_config_byte(main_dev, 0xB7, &disable);
> + if (disable & 0x02) {
> + printk(KERN_INFO DRIVER_NAME
> + ": Controller already disabled. " \
> + "Nothing to do.\n");
> + return -ENODEV;
> + }
> +
> + pci_read_config_byte(main_dev, 0x8E, &write_enable);
> + pci_write_config_byte(main_dev, 0x8E, 0xAA);
> + pci_read_config_byte(main_dev, 0x8D, &write_target);
> + pci_write_config_byte(main_dev, 0x8D, 0xB7);
> + pci_write_config_byte(main_dev, 0xB7, disable | 0x02);
> + pci_write_config_byte(main_dev, 0x8E, write_enable);
> + pci_write_config_byte(main_dev, 0x8D, write_target);
> +
> + pci_set_drvdata(pdev, main_dev);
> +
> + printk(KERN_INFO DRIVER_NAME
> + ": Controller is now disabled " \
> + "(via R5L5C476).\n");
> +
> + ctrlfound = 1;
> + break;
> + }
> + }
> +
> + /* disable mmc controller via firewire function (R5C832) */
> + while (!ctrlfound &&
> + (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) &&
>   pdev->bus == fw_dev->bus) {
>   u8 write_enable;

It feels like there's a bit too much code duplication going on here, but I think
that after you rebase the patch it'll look a lot tidier and I won't feel bad 
about
it :-)

> @@ -67,7 +109,8 @@ static int __devinit ricoh_mmc_probe(str
>   pci_read_config_byte(fw_dev, 0xCB, &disable);
>   if (disable & 0x02) {
>   printk(KERN_INFO DRIVER_NAME
> -": Controller already disabled. Nothing 
> to do.\n");
> + ": Controller already disabled. " \
> + "Nothing to do.\n");
>   return -ENODEV;
>   }
>  
> @@ -79,15 +122,16 @@ static int __devinit ricoh_mmc_probe(str
>   pci_set_drvdata(pdev, fw_dev);
>  
>   printk(KERN_INFO DRIVER_NAME
> -": Controller is now disabled.\n");
> +": Controller is now disabled (via R5C832).\n");
>  
> - break;
> + ctrlfound = 1;
>   }
>   }
>  
> - if (pci_get_drvdata(pdev) == NULL) {
> + if (!ctrlfound) {
>   printk(KERN_WARNING DRIVER_NAME
> -": Main firewire function not found. Cannot disable 
> controll

Re: eMMC and MMC plus card supports

2007-12-29 Thread Philip Langdale

Sandeep K wrote:

Hi all,

Can anybody please let me know, does the current linux
tree supports MMC plus and eMMC cards.


It certainly supports MMCplus. My understanding is that eMMC
is just a form-factor and is not visibly different to the host
controller, so it should just work. I know that the nokia n810
has an internal eMMC and it, obviously, works. They had some
odd issues with the Samsung part they're using and SET_BLOCK_COUNT
but I have no idea if that's an eMMC thing or specific to the part
they're using.

You also asked about "28bit lba" support in another email. I assume
you are asking about support for block addressed SDHC and MMCplus-HC cards.
The kernel supports both (although good luck trying to get a hold of an MMC
one).

Hope that helps,

--phil
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mmc: Handle suspend/resume in Ricoh MMC disabler

2007-12-29 Thread Philip Langdale

As pci config space is reinitialised on a suspend/resume cycle, the
disabler needs to work its magic at resume time. For symmetry this
change also explicitly enables the controller at suspend time but
it's not strictly necessary.

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>

--- linux-2.6.24/drivers/mmc/host/ricoh_mmc.c   2007-12-28 17:18:18.0 
-0800
+++ linux-2.6.24-phil/drivers/mmc/host/ricoh_mmc.c  2007-12-29 
00:05:30.0 -0800
@@ -41,6 +41,46 @@

 MODULE_DEVICE_TABLE(pci, pci_ids);

+static int ricoh_mmc_disable(struct pci_dev *fw_dev)
+{
+   u8 write_enable;
+   u8 disable;
+
+   pci_read_config_byte(fw_dev, 0xCB, &disable);
+   if (disable & 0x02) {
+   printk(KERN_INFO DRIVER_NAME
+  ": Controller already disabled. Nothing to do.\n");
+   return -ENODEV;
+   }
+
+   pci_read_config_byte(fw_dev, 0xCA, &write_enable);
+   pci_write_config_byte(fw_dev, 0xCA, 0x57);
+   pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
+   pci_write_config_byte(fw_dev, 0xCA, write_enable);
+
+   printk(KERN_INFO DRIVER_NAME
+  ": Controller is now disabled.\n");
+
+   return 0;
+}
+
+static int ricoh_mmc_enable(struct pci_dev *fw_dev)
+{
+   u8 write_enable;
+   u8 disable;
+
+   pci_read_config_byte(fw_dev, 0xCA, &write_enable);
+   pci_read_config_byte(fw_dev, 0xCB, &disable);
+   pci_write_config_byte(fw_dev, 0xCA, 0x57);
+   pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
+   pci_write_config_byte(fw_dev, 0xCA, write_enable);
+
+   printk(KERN_INFO DRIVER_NAME
+  ": Controller is now re-enabled.\n");
+
+   return 0;
+}
+
 static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
 const struct pci_device_id *ent)
 {
@@ -61,26 +101,12 @@
while ((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) &&
pdev->bus == fw_dev->bus) {
-   u8 write_enable;
-   u8 disable;
-
-   pci_read_config_byte(fw_dev, 0xCB, &disable);
-   if (disable & 0x02) {
-   printk(KERN_INFO DRIVER_NAME
-  ": Controller already disabled. Nothing to 
do.\n");
+   if (ricoh_mmc_disable(fw_dev) != 0) {
return -ENODEV;
}

-   pci_read_config_byte(fw_dev, 0xCA, &write_enable);
-   pci_write_config_byte(fw_dev, 0xCA, 0x57);
-   pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
-   pci_write_config_byte(fw_dev, 0xCA, write_enable);
-
pci_set_drvdata(pdev, fw_dev);

-   printk(KERN_INFO DRIVER_NAME
-  ": Controller is now disabled.\n");
-
break;
}
}
@@ -96,30 +122,51 @@

 static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
 {
-   u8 write_enable;
-   u8 disable;
struct pci_dev *fw_dev = NULL;

fw_dev = pci_get_drvdata(pdev);
BUG_ON(fw_dev == NULL);

-   pci_read_config_byte(fw_dev, 0xCA, &write_enable);
-   pci_read_config_byte(fw_dev, 0xCB, &disable);
-   pci_write_config_byte(fw_dev, 0xCA, 0x57);
-   pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
-   pci_write_config_byte(fw_dev, 0xCA, write_enable);
-
-   printk(KERN_INFO DRIVER_NAME
-  ": Controller is now re-enabled.\n");
+   ricoh_mmc_enable(fw_dev);

pci_set_drvdata(pdev, NULL);
 }

+static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state)
+{
+   struct pci_dev *fw_dev = NULL;
+
+   fw_dev = pci_get_drvdata(pdev);
+   BUG_ON(fw_dev == NULL);
+
+   printk(KERN_INFO DRIVER_NAME ": Suspending.\n");
+
+   ricoh_mmc_enable(fw_dev);
+
+   return 0;
+}
+
+static int ricoh_mmc_resume (struct pci_dev *pdev)
+{
+   struct pci_dev *fw_dev = NULL;
+
+   fw_dev = pci_get_drvdata(pdev);
+   BUG_ON(fw_dev == NULL);
+
+   printk(KERN_INFO DRIVER_NAME ": Resuming.\n");
+
+   ricoh_mmc_disable(fw_dev);
+
+   return 0;
+}
+
 static struct pci_driver ricoh_mmc_driver = {
.name = DRIVER_NAME,
.id_table = pci_ids,
.probe =ricoh_mmc_probe,
.remove =   __devexit_p(ricoh_mmc_remove),
+   .suspend =  ricoh_mmc_suspend,
+   .resume =   ricoh_mmc_resume,
 };

 /*\
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the F

Re: powernow-k8 and non-standard multipliers

2007-11-14 Thread Philip Langdale
Langsdorf, Mark wrote:
> 
> The standard PowerNow! driver, by design, will stop 
> working in this situation.  I'm not going to support
> a driver that allows non-standard multipliers because
> it could cause a lot of hard to debug maintenance
> issues.

Just a follow-up to get this into the public record. I
discussed this with Mark privately and then did more
digging and established that in my particular case, the
problem was that the BIOS was hiding the p-state table
when a non-standard multiplier was used. So, I built
a custom DSDT that included the p-state table along
with an extra entry for my higher speed and now I've
happily got powernow support again.

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


powernow-k8 and non-standard multipliers

2007-11-12 Thread Philip Langdale
Hi Mark,

I've just upgraded to an X2 5000+ black edition. This model
doesn't have a multiple lock and I tried bumping the multiplier
up, which is perfectly stable, but which causes powernow-k8 to
fail to load. I also tried with the updated patch you posted
at the beginning of october (http://lkml.org/lkml/2007/10/9/224)
which didn't make a difference.

Is it possible to make the driver work in this situation or does
a non-standard multipler inherently mean that powernow stops
working?

Thanks,

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Input: Refactor evdev 32bit compat to be shareable with uinput

2007-10-13 Thread Philip Langdale
Currently, evdev has working 32bit compatibility and uinput does not. uinput
needs the input_event code that evdev uses, so let's refactor it so it can
be shared.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>
---

drivers/input/Makefile   |2
drivers/input/evdev.c|  118 ++-
drivers/input/input_compat.c |   89 
drivers/input/misc/uinput.c  |   23 ++--
include/linux/input_compat.h |   61 ++
5 files changed, 175 insertions(+), 118 deletions(-)

diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 15eb752..92f34da 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -5,7 +5,7 @@
 # Each configuration option enables a list of files.

 obj-$(CONFIG_INPUT)+= input-core.o
-input-core-objs := input.o ff-core.o
+input-core-objs := input.o input_compat.o ff-core.o

 obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
 obj-$(CONFIG_INPUT_POLLDEV)+= input-polldev.o
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 27026f7..91b086c 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -17,9 +17,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
-#include 

 struct evdev {
int exist;
@@ -294,110 +294,6 @@ static int evdev_open(struct inode *inode, struct file 
*file)
return error;
 }

-#ifdef CONFIG_COMPAT
-
-struct input_event_compat {
-   struct compat_timeval time;
-   __u16 type;
-   __u16 code;
-   __s32 value;
-};
-
-/* Note to the author of this code: did it ever occur to
-   you why the ifdefs are needed? Think about it again. -AK */
-#ifdef CONFIG_X86_64
-#  define COMPAT_TEST is_compat_task()
-#elif defined(CONFIG_IA64)
-#  define COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
-#elif defined(CONFIG_S390)
-#  define COMPAT_TEST test_thread_flag(TIF_31BIT)
-#elif defined(CONFIG_MIPS)
-#  define COMPAT_TEST test_thread_flag(TIF_32BIT_ADDR)
-#else
-#  define COMPAT_TEST test_thread_flag(TIF_32BIT)
-#endif
-
-static inline size_t evdev_event_size(void)
-{
-   return COMPAT_TEST ?
-   sizeof(struct input_event_compat) : sizeof(struct input_event);
-}
-
-static int evdev_event_from_user(const char __user *buffer,
-struct input_event *event)
-{
-   if (COMPAT_TEST) {
-   struct input_event_compat compat_event;
-
-   if (copy_from_user(&compat_event, buffer,
-  sizeof(struct input_event_compat)))
-   return -EFAULT;
-
-   event->time.tv_sec = compat_event.time.tv_sec;
-   event->time.tv_usec = compat_event.time.tv_usec;
-   event->type = compat_event.type;
-   event->code = compat_event.code;
-   event->value = compat_event.value;
-
-   } else {
-   if (copy_from_user(event, buffer, sizeof(struct input_event)))
-   return -EFAULT;
-   }
-
-   return 0;
-}
-
-static int evdev_event_to_user(char __user *buffer,
-   const struct input_event *event)
-{
-   if (COMPAT_TEST) {
-   struct input_event_compat compat_event;
-
-   compat_event.time.tv_sec = event->time.tv_sec;
-   compat_event.time.tv_usec = event->time.tv_usec;
-   compat_event.type = event->type;
-   compat_event.code = event->code;
-   compat_event.value = event->value;
-
-   if (copy_to_user(buffer, &compat_event,
-sizeof(struct input_event_compat)))
-   return -EFAULT;
-
-   } else {
-   if (copy_to_user(buffer, event, sizeof(struct input_event)))
-   return -EFAULT;
-   }
-
-   return 0;
-}
-
-#else
-
-static inline size_t evdev_event_size(void)
-{
-   return sizeof(struct input_event);
-}
-
-static int evdev_event_from_user(const char __user *buffer,
-struct input_event *event)
-{
-   if (copy_from_user(event, buffer, sizeof(struct input_event)))
-   return -EFAULT;
-
-   return 0;
-}
-
-static int evdev_event_to_user(char __user *buffer,
-   const struct input_event *event)
-{
-   if (copy_to_user(buffer, event, sizeof(struct input_event)))
-   return -EFAULT;
-
-   return 0;
-}
-
-#endif /* CONFIG_COMPAT */
-
 static ssize_t evdev_write(struct file *file, const char __user *buffer,
   size_t count, loff_t *ppos)
 {
@@ -417,14 +313,14 @@ static ssize_t evdev_write(struct file *file, const char 
__user *buffer,

while (retval < count) {

-   if (evdev_event_from_user(buffer + retval, &event)) {
+   if (input_event_from_user(buffer + retval, &event)) {
  

Re: [PATCH] hiddev: Add 32bit ioctl compatibilty

2007-10-13 Thread Philip Langdale
Al Viro wrote:
>>
>> +static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, 
>> unsigned long arg)
>> +{
>> +struct inode *inode = file->f_path.dentry->d_inode;
>> +return hiddev_ioctl(inode, file, cmd, compat_ptr(arg));
>> +}
> 
> Just how many instances of that sucker do we need?  It's nothing but
> 
>  struct inode *inode = file->f_path.dentry->d_inode;
>  return file->f_op->ioctl(inode, file, cmd, compat_ptr(arg));
> 

So, I don't actually know what you're looking for, but of the 140 occasions
that .compat_ioctl is implemented in Linus' tree, I can't find another one
that actually uses this form. So, writing a shared implementation doesn't pick
off any low hanging fruit. Now, it's possible that some of the other 
implementations
could be reduced to this form - but for now, it seems the answer to your 
question
is 'one' in either case. :-)

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] hiddev: Add 32bit ioctl compatibilty

2007-10-12 Thread Philip Langdale
The hiddev driver currently lacks 32bit ioctl compatibility, so
if you're running with a 64bit kernel and 32bit userspace, it won't
work.

I'm pretty sure that the only thing missing is a compat_ioctl
implementation as all structs have fixed size fields.

With this change I can use revoco to configure my MX Revolution mouse.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>

--- linux-2.6.23/drivers/hid/usbhid/hiddev.c2007-10-09 13:31:38.0 
-0700
+++ linux-phil/drivers/hid/usbhid/hiddev.c  2007-10-12 15:02:15.0 
-0700
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "usbhid.h"

 #ifdef CONFIG_USB_DYNAMIC_MINORS
@@ -738,6 +738,14 @@
return -EINVAL;
 }

+#ifdef CONFIG_COMPAT
+static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned 
long arg)
+{
+   struct inode *inode = file->f_path.dentry->d_inode;
+   return hiddev_ioctl(inode, file, cmd, compat_ptr(arg));
+}
+#endif
+
 static const struct file_operations hiddev_fops = {
.owner =THIS_MODULE,
.read = hiddev_read,
@@ -747,6 +754,9 @@
.release =  hiddev_release,
.ioctl =hiddev_ioctl,
.fasync =   hiddev_fasync,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = hiddev_compat_ioctl,
+#endif
 };

 static struct usb_class_driver hiddev_class = {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mmc: Disabler for Ricoh MMC controller

2007-10-01 Thread Philip Langdale
Benjamin Herrenschmidt wrote:
> On Tue, 2007-10-02 at 14:44 +1000, Benjamin Herrenschmidt wrote:
>> On Mon, 2007-10-01 at 20:23 -0700, Philip Langdale wrote:
>>> Thanks to Matt Domsch and Rezwanul Kabir at Dell, we know how to disable the
>>> MMC controller on the multi-function Ricoh R5C832. The MMC controller needs
>>> to be disabled or it will steal MMC cards from the SD controller where they
>>> would otherwise be supported by the Linux SDHCI driver.
>> Why can't that be a quirk instead ?
> 
> That is, a global quirk or a quirk in the SDHCI driver...

Pierre doesn't want a quirk.

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mmc: Disabler for Ricoh MMC controller

2007-10-01 Thread Philip Langdale
Thanks to Matt Domsch and Rezwanul Kabir at Dell, we know how to disable the
MMC controller on the multi-function Ricoh R5C832. The MMC controller needs
to be disabled or it will steal MMC cards from the SD controller where they
would otherwise be supported by the Linux SDHCI driver.

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>

--- linux-2.6.22/drivers/mmc/host/Kconfig   2007-07-08 16:32:17.0 
-0700
+++ linux-ricoh/drivers/mmc/host/Kconfig2007-09-15 12:32:10.0 
-0700
@@ -35,6 +35,23 @@

  If unsure, say N.

+config MMC_RICOH_MMC
+   tristate "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
+   depends on PCI && EXPERIMENTAL && MMC_SDHCI
+   help
+ This selects the disabler for the Ricoh MMC Controller. This
+ proprietary controller is unnecessary because the SDHCI driver
+ supports MMC cards on the SD controller, but if it is not
+ disabled, it will steal the MMC cards away - rendering them
+ useless. It is safe to select this driver even if you don't
+ have a Ricoh based card reader.
+
+
+ To compile this driver as a module, choose M here:
+ the module will be called ricoh_mmc.
+
+ If unsure, say Y.
+
 config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
depends on ARCH_OMAP
--- linux-2.6.22/drivers/mmc/host/Makefile  2007-07-08 16:32:17.0 
-0700
+++ linux-ricoh/drivers/mmc/host/Makefile   2007-09-15 12:28:49.0 
-0700
@@ -15,4 +15,5 @@
 obj-$(CONFIG_MMC_OMAP) += omap.o
 obj-$(CONFIG_MMC_AT91) += at91_mci.o
 obj-$(CONFIG_MMC_TIFM_SD)  += tifm_sd.o
+obj-$(CONFIG_MMC_RICOH_MMC)+= ricoh_mmc.o

--- linux-2.6.22/drivers/mmc/host/ricoh_mmc.c   1969-12-31 16:00:00.0 
-0800
+++ linux-ricoh/drivers/mmc/host/ricoh_mmc.c2007-09-15 12:29:05.0 
-0700
@@ -0,0 +1,156 @@
+/*
+ *  ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller.
+ *
+ *  Copyright (C) 2007 Philip Langdale, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+/*
+ * 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
+ * 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.
+ * At that point, the SDHCI controller will start seeing them. As a bonus,
+ * 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.
+ */
+
+#include 
+
+#define DRIVER_NAME "ricoh-mmc"
+
+#define DBG(f, x...) \
+   pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
+
+static const struct pci_device_id pci_ids[] __devinitdata = {
+   {
+   .vendor = PCI_VENDOR_ID_RICOH,
+   .device = PCI_DEVICE_ID_RICOH_R5C843,
+   .subvendor  = PCI_ANY_ID,
+   .subdevice  = PCI_ANY_ID,
+   },
+   { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(pci, pci_ids);
+
+static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
+const struct pci_device_id *ent)
+{
+   u8 rev;
+
+   struct pci_dev *fw_dev = NULL;
+
+   BUG_ON(pdev == NULL);
+   BUG_ON(ent == NULL);
+
+   pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
+
+   printk(KERN_INFO DRIVER_NAME
+   ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n",
+   pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
+   (int)rev);
+
+   while ((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) &&
+   pdev->bus == fw_dev->bus) {
+   u8 write_enable;
+   u8 disable;
+
+   pci_read_config_byte(fw_dev, 0xCB, &disable);
+   if (disable & 0x02) {
+   printk(KERN_INFO DRIVER_NAME
+  ": Controller already disabled. Nothing 
to do.\n");
+   return -ENODEV;
+   }
+
+   pci_read_config_byte(fw_dev, 0xCA, &am

Re: [PATCH] mmc: Disabler for Ricoh MMC controller

2007-10-01 Thread Philip Langdale
Pierre Ossman wrote:
> 
> Preferably. But if you can't figure it out until it is time to merge
> things upstream, then I'll go with what we have right now.

I have not been contacted by anyone with one of those laptops so I
haven't been able to find out what's going on.

I'm updating the diff, because I forgot to terminate the pci table,
so it didn't add the alias correctly.

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mmc: Disabler for Ricoh MMC controller

2007-09-21 Thread Philip Langdale
Pierre Ossman wrote:
>>
> 
> Patch looks ok. Please try to sort out that completely disabled
> controller that was reported first though.

This remains confusing. I went and investigated and the SD disable
bit is 0x20. The one lspci dump from the IFL90 shows that 0x80 is
set by default, but setting this on my laptop did not disable the
SD controller. I will need to collect more information from owners
to find out what's really going on.

Do you want to wait on this before taking this patch?

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mmc: Disabler for Ricoh MMC controller

2007-09-15 Thread Philip Langdale
Thanks to Matt Domsch and Rezwanul Kabir at Dell, we know how to disable the
MMC controller on the multi-function Ricoh R5C832. The MMC controller needs
to be disabled or it will steal MMC cards from the SD controller where they
would otherwise be supported by the Linux SDHCI driver.

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>

--- linux-2.6.22/drivers/mmc/host/Kconfig   2007-07-08 16:32:17.0 
-0700
+++ linux-ricoh/drivers/mmc/host/Kconfig2007-09-15 12:32:10.0 
-0700
@@ -35,6 +35,23 @@

  If unsure, say N.

+config MMC_RICOH_MMC
+   tristate "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
+   depends on PCI && EXPERIMENTAL && MMC_SDHCI
+   help
+ This selects the disabler for the Ricoh MMC Controller. This
+ proprietary controller is unnecessary because the SDHCI driver
+ supports MMC cards on the SD controller, but if it is not
+ disabled, it will steal the MMC cards away - rendering them
+ useless. It is safe to select this driver even if you don't
+ have a Ricoh based card reader.
+
+
+ To compile this driver as a module, choose M here:
+ the module will be called ricoh_mmc.
+
+ If unsure, say Y.
+
 config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
depends on ARCH_OMAP
--- linux-2.6.22/drivers/mmc/host/Makefile  2007-07-08 16:32:17.0 
-0700
+++ linux-ricoh/drivers/mmc/host/Makefile   2007-09-15 12:28:49.0 
-0700
@@ -15,4 +15,5 @@
 obj-$(CONFIG_MMC_OMAP) += omap.o
 obj-$(CONFIG_MMC_AT91) += at91_mci.o
 obj-$(CONFIG_MMC_TIFM_SD)  += tifm_sd.o
+obj-$(CONFIG_MMC_RICOH_MMC)+= ricoh_mmc.o

--- linux-2.6.22/drivers/mmc/host/ricoh_mmc.c   1969-12-31 16:00:00.0 
-0800
+++ linux-ricoh/drivers/mmc/host/ricoh_mmc.c2007-09-15 12:29:05.0 
-0700
@@ -0,0 +1,152 @@
+/*
+ *  ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller.
+ *
+ *  Copyright (C) 2007 Philip Langdale, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+/*
+ * 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
+ * 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.
+ * At that point, the SDHCI controller will start seeing them. As a bonus,
+ * 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.
+ */
+
+#include 
+
+#define DRIVER_NAME "ricoh-mmc"
+
+static const struct pci_device_id pci_ids[] __devinitdata = {
+   {
+   .vendor = PCI_VENDOR_ID_RICOH,
+   .device = PCI_DEVICE_ID_RICOH_R5C843,
+   .subvendor  = PCI_ANY_ID,
+   .subdevice  = PCI_ANY_ID,
+   },
+};
+
+MODULE_DEVICE_TABLE(pci, pci_ids);
+
+static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
+const struct pci_device_id *ent)
+{
+   u8 rev;
+
+   struct pci_dev *fw_dev = NULL;
+
+   BUG_ON(pdev == NULL);
+   BUG_ON(ent == NULL);
+
+   pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
+
+   printk(KERN_INFO DRIVER_NAME
+   ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n",
+   pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
+   (int)rev);
+
+   while ((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) &&
+   pdev->bus == fw_dev->bus) {
+   u8 write_enable;
+   u8 disable;
+
+   pci_read_config_byte(fw_dev, 0xCB, &disable);
+   if (disable & 0x02) {
+   printk(KERN_INFO DRIVER_NAME
+  ": Controller already disabled. Nothing 
to do.\n");
+   return -ENODEV;
+   }
+
+   pci_read_config_byte(fw_dev, 0xCA, &write_enable);
+   pci_write_config_byte(fw_dev, 0xCA, 0x57);
+   pci_wr

Re: [PATCH] sdhci: Add quirk to support polling for card presence

2007-05-14 Thread Philip Langdale
There is apparently at least one instance of the Ricoh SDHCI
implementation out there where card insertion and removal
interrupts do not work - so the only way to detect a change
in the presence of a card is to poll.

This changes adds a polling quirk for the particular model
reported. Others may be affected, but we can add them as they
arise.

As part of this change, caching of the present state is introduced
to reduce the amount of work done when nothing has changed. This
cached state is referred to in the standard interrupt path but as
it is interrupt driven - the cached and new state should never be
the same so it will cause no change in behaviour.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ff5bf73..2d5ec61 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -34,6 +34,7 @@ static unsigned int debug_quirks = 0;
 /* Controller doesn't like some resets when there is no card inserted. */
 #define SDHCI_QUIRK_NO_CARD_NO_RESET   (1<<2)
 #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
+#define SDHCI_QUIRK_NO_CARD_DETECT_INT (1<<4)

 static const struct pci_device_id pci_ids[] __devinitdata = {
{
@@ -48,6 +49,16 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_RICOH,
.device = PCI_DEVICE_ID_RICOH_R5C822,
+   .subvendor  = PCI_SUBVENDOR_ID_FUJITSU_SIEMENS,
+   .subdevice  = PCI_SUBDEVICE_ID_FUJITSU_SIEMENS_SI1520,
+   .driver_data= SDHCI_QUIRK_FORCE_DMA |
+ SDHCI_QUIRK_NO_CARD_NO_RESET |
+ SDHCI_QUIRK_NO_CARD_DETECT_INT,
+   },
+
+   {
+   .vendor = PCI_VENDOR_ID_RICOH,
+   .device = PCI_DEVICE_ID_RICOH_R5C822,
.subvendor  = PCI_ANY_ID,
.subdevice  = PCI_ANY_ID,
.driver_data= SDHCI_QUIRK_FORCE_DMA |
@@ -788,13 +799,18 @@ static void sdhci_tasklet_card(unsigned long param)
 {
struct sdhci_host *host;
unsigned long flags;
+   int present;
+   int polling;

host = (struct sdhci_host*)param;

+   polling = host->chip->quirks & SDHCI_QUIRK_NO_CARD_DETECT_INT;
+
spin_lock_irqsave(&host->lock, flags);

-   if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
-   if (host->mrq) {
+   present = readl(host->ioaddr + SDHCI_PRESENT_STATE) & 
SDHCI_CARD_PRESENT;
+   if (present != host->present) {
+   if (!present && host->mrq) {
printk(KERN_ERR "%s: Card removed during transfer!\n",
mmc_hostname(host->mmc));
printk(KERN_ERR "%s: Resetting controller.\n",
@@ -806,11 +822,21 @@ static void sdhci_tasklet_card(unsigned long param)
host->mrq->cmd->error = MMC_ERR_FAILED;
tasklet_schedule(&host->finish_tasklet);
}
-   }

-   spin_unlock_irqrestore(&host->lock, flags);
+   host->present = present;
+
+   spin_unlock_irqrestore(&host->lock, flags);
+
+   mmc_detect_change(host->mmc,
+ polling ? 0 : msecs_to_jiffies(500));
+   } else {
+   spin_unlock_irqrestore(&host->lock, flags);
+   }

-   mmc_detect_change(host->mmc, msecs_to_jiffies(500));
+   if (polling) {
+   host->detect_timer.expires = jiffies + HZ;
+   add_timer(&host->detect_timer);
+   }
 }

 static void sdhci_tasklet_finish(unsigned long param)
@@ -865,6 +891,15 @@ static void sdhci_tasklet_finish(unsigned long param)
mmc_request_done(host->mmc, mrq);
 }

+static void sdhci_detect_timer(unsigned long data)
+{
+   struct sdhci_host *host;
+
+   host = (struct sdhci_host*)data;
+
+   tasklet_schedule(&host->card_tasklet);
+}
+
 static void sdhci_timeout_timer(unsigned long data)
 {
struct sdhci_host *host;
@@ -1329,6 +1364,8 @@ static int __devinit sdhci_probe_slot(struct pci_dev 
*pdev, int slot)
 */
mmc->max_blk_count = 65535;

+   host->present = readl(host->ioaddr + SDHCI_PRESENT_STATE) & 
SDHCI_CARD_PRESENT;;
+
/*
 * Init tasklets.
 */
@@ -1344,6 +1381,12 @@ static int __devinit sdhci_probe_slot(struct pci_dev 
*pdev, int slot)
if (ret)
goto untasklet;

+   if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_DETECT_INT) {
+   setup_timer(&host->detect_timer, sdhci_detect_timer, (unsigned 
long)host);
+   host->detect_ti

[PATCH] sdhci: Add quirk to support polling for card presence

2007-05-13 Thread Philip Langdale
There is apparently at least one instance of the Ricoh SDHCI
implementation out there where card insertion (and possibly
removal) interrupts do not work - so the only way to detect
a change in the presence of a card is to poll.

This changes adds a polling quirk for the particular model
reported by Tobias. The change is tentative as it assumes
that removal interrupts do not work, but if they do work,
then we can optimise things by not polling when there is
a card present. So, it should not be committed until Tobias
has confirmed the removal behaviour one way or the other and
the change is accordingly updated.

The polling frequency is 3 seconds because I've been running
powertop and am paranoid about wakeups now. :-) I did some
testing locally by masking out the interrupt events and 3
seconds seems usable enough to me.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index ff5bf73..8c5b2f5 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -34,6 +34,7 @@ static unsigned int debug_quirks = 0;
 /* Controller doesn't like some resets when there is no card inserted. */
 #define SDHCI_QUIRK_NO_CARD_NO_RESET   (1<<2)
 #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
+#define SDHCI_QUIRK_NO_CARD_DETECT_INT (1<<4)

 static const struct pci_device_id pci_ids[] __devinitdata = {
{
@@ -48,6 +49,16 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_RICOH,
.device = PCI_DEVICE_ID_RICOH_R5C822,
+   .subvendor  = PCI_SUBVENDOR_ID_FUJITSU_SIEMENS,
+   .subdevice  = PCI_SUBDEVICE_ID_FUJITSU_SIEMENS_SI1520,
+   .driver_data= SDHCI_QUIRK_FORCE_DMA |
+ SDHCI_QUIRK_NO_CARD_NO_RESET |
+ SDHCI_QUIRK_NO_CARD_DETECT_INT,
+   },
+
+   {
+   .vendor = PCI_VENDOR_ID_RICOH,
+   .device = PCI_DEVICE_ID_RICOH_R5C822,
.subvendor  = PCI_ANY_ID,
.subdevice  = PCI_ANY_ID,
.driver_data= SDHCI_QUIRK_FORCE_DMA |
@@ -788,13 +799,15 @@ static void sdhci_tasklet_card(unsigned long param)
 {
struct sdhci_host *host;
unsigned long flags;
+   int present;

host = (struct sdhci_host*)param;

spin_lock_irqsave(&host->lock, flags);

-   if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
-   if (host->mrq) {
+   present = readl(host->ioaddr + SDHCI_PRESENT_STATE) & 
SDHCI_CARD_PRESENT;
+   if (present != host->present) {
+   if (!present && host->mrq) {
printk(KERN_ERR "%s: Card removed during transfer!\n",
mmc_hostname(host->mmc));
printk(KERN_ERR "%s: Resetting controller.\n",
@@ -806,11 +819,18 @@ static void sdhci_tasklet_card(unsigned long param)
host->mrq->cmd->error = MMC_ERR_FAILED;
tasklet_schedule(&host->finish_tasklet);
}
-   }

-   spin_unlock_irqrestore(&host->lock, flags);
+   spin_unlock_irqrestore(&host->lock, flags);
+
+   host->present = present;
+
+   mmc_detect_change(host->mmc, msecs_to_jiffies(500));
+   }

-   mmc_detect_change(host->mmc, msecs_to_jiffies(500));
+   if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_DETECT_INT) {
+   host->detect_timer.expires = jiffies + 3 * HZ;
+   add_timer(&host->detect_timer);
+   }
 }

 static void sdhci_tasklet_finish(unsigned long param)
@@ -865,6 +885,15 @@ static void sdhci_tasklet_finish(unsigned long param)
mmc_request_done(host->mmc, mrq);
 }

+static void sdhci_detect_timer(unsigned long data)
+{
+   struct sdhci_host *host;
+
+   host = (struct sdhci_host*)data;
+
+   tasklet_schedule(&host->card_tasklet);
+}
+
 static void sdhci_timeout_timer(unsigned long data)
 {
struct sdhci_host *host;
@@ -1329,6 +1358,8 @@ static int __devinit sdhci_probe_slot(struct pci_dev 
*pdev, int slot)
 */
mmc->max_blk_count = 65535;

+   host->present = readl(host->ioaddr + SDHCI_PRESENT_STATE) & 
SDHCI_CARD_PRESENT;;
+
/*
 * Init tasklets.
 */
@@ -1344,6 +1375,12 @@ static int __devinit sdhci_probe_slot(struct pci_dev 
*pdev, int slot)
if (ret)
goto untasklet;

+   if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_DETECT_INT) {
+   setup_timer(&host->detect_timer, sdhci_detect_timer, (unsigned 
long)host);
+   host->detect_timer.expires = jiffies + 3

Re: SDHCI issues on Ricoh in 2.6.20, 21 and 21-rc7-mm2

2007-05-13 Thread Philip Langdale
Pierre Ossman wrote:
> 
> We could do some silly polling hack. It isn't clean, but it might get things
> somewhat working at least.

Tobias,

Pierre has asked me to take a look implementing this. My first question is 
whether
all card events are getting dropped on the floor, or just insertion ones. That 
is
to say, if you have the card inserted when you load the module (which you say
makes the card usable), does it correctly detect that the card is ejected when
you eject it?

If ejects are notified correctly, then we can make the polling less hacky by
disabling it while the card is inserted.

Thanks,

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: MMCv4 support (8-bit support missing)

2007-04-20 Thread Philip Langdale
Madhusudhan c wrote:
> 
> Suppose a host controller is capable of suporting 8-bit and it tells
> the core that it can support 8-bit. Now the card that is plugged in
> might or might not support 8-bit based on the type of the card. There
> is no field in the ext_csd which will tell you what bus width the card
> can support.

My understanding is that 8-bit support on the card is not optional. ie:
the card is not mmc 4 compliant if it doesn't support 8-bit and this
is why there's no ext_csd field. The only case I could think of where
bus testing would be needed would be if a controller was placed into
a configuration where some pins were deliberately left unconnected
(perhaps because space constraints prevented the extra 4 pins from being
placed on a pcb) and there was no way to change the capabilities reported
by the controller.

But in any case - this is all hypothetical right now - one can't find
a controller in the wild for love or money (well - Arasan will sell you
a validation controller for $5000 but still...). As neither Pierre or
myself is in a position to do any sort of tests on an 8-bit controller,
we can't investigate or verify any of this.

It certainly seems that you have access to an 8-bit controller. If you
can help one or both of us get access to one, I'm sure we could work out
the right thing to do.

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: MMCv4 support (8-bit support missing)

2007-04-17 Thread Philip Langdale
Madhusudhan c wrote:
> Hi Pierre/philip,
> 
> This is regarding the MMCv4 support that came in as part of the MMC
> core of 2.6.20 linux kernel version.
> 
> The high speed MMC cards can support 4-bit/8-bit transfers. The 8-bit
> support seems to be missing from the MMCv4 support implemented by
> Philip Langdale .
> To support 8-bit transfers the core needs to implement "bus testing
> procedure". This requires support for CMD19 and CMD14.
> 
> Why is the support for bus testing procedure msiing from the MMCv4 support?

Because we have not seen any 8-bit hardware - let alone any 8-bit hardware
which we know how to drive. It is unclear how necessary the bus testing sequence
is, but the main reason why it's not there is that I could never get it to work
on the sdhci controller I use for testing. Due to how the CRC is handled for 
these
commands, the controller gets confused, reports failure, and doesn't provide the
returned data - making the test impossible.

If you have found an 8-bit controller that we can support, we'd love to know 
about
it!

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MMC: Fix handling of low-voltage cards (take 2)

2007-03-16 Thread Philip Langdale
Fix handling of low voltage MMC cards.

The latest MMC and SD specs both agree that support for
low-voltage operations is indicated by bit 7 in the OCR.
The MMC spec states that the low voltage range is
1.65-1.95V while the SD spec leaves the actual voltage
range undefined - meaning that there is still no such
thing as a low voltage SD card.

However, an old Sandisk spec implied that bits 7.0
represented voltages below 2.0V in 1V or 0.5V increments,
and the code was accordingly written with that expectation.

This confusion meant that host drivers attempting to support
the typical low voltage (1.8V) would set the wrong bits in
the host OCR mask (usually bits 5 and/or 6) resulting in the
the low voltage mode never being used.

This change corrects the low voltage range and adds sanity
checks on the reserved bits (0-6) and for SD cards that
claim to support low-voltage operations.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 21c0517..310b242 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -319,6 +319,17 @@ int mmc_attach_mmc(struct mmc_host *host

mmc_attach_bus(host, &mmc_ops);

+   /*
+* Sanity check the voltages that the card claims to
+* support.
+*/
+   if (ocr & 0x7F) {
+   printk(KERN_WARNING "%s: card claims to support voltages "
+  "below the defined range. These will be ignored.\n",
+  mmc_hostname(host));
+   ocr &= ~0x7F;
+   }
+
host->ocr = mmc_select_voltage(host, ocr);

/*
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6289ae6..e27845e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -297,6 +297,24 @@ int mmc_attach_sd(struct mmc_host *host,

mmc_attach_bus(host, &mmc_sd_ops);

+   /*
+* Sanity check the voltages that the card claims to
+* support.
+*/
+   if (ocr & 0x7F) {
+   printk(KERN_WARNING "%s: card claims to support voltages "
+  "below the defined range. These will be ignored.\n",
+  mmc_hostname(host));
+   ocr &= ~0x7F;
+   }
+
+   if (ocr & MMC_VDD_165_195) {
+   printk(KERN_WARNING "%s: SD card claims to support the "
+  "incompletely defined 'low voltage range'. This "
+  "will be ignored.\n", mmc_hostname(host));
+   ocr &= ~MMC_VDD_165_195;
+   }
+
host->ocr = mmc_select_voltage(host, ocr);

/*
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2f34ae3..a80c043 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -669,8 +669,7 @@ static void sdhci_set_power(struct sdhci
pwr = SDHCI_POWER_ON;

switch (1 << power) {
-   case MMC_VDD_17_18:
-   case MMC_VDD_18_19:
+   case MMC_VDD_165_195:
pwr |= SDHCI_POWER_180;
break;
case MMC_VDD_29_30:
@@ -1290,7 +1289,7 @@ static int __devinit sdhci_probe_slot(st
if (caps & SDHCI_CAN_VDD_300)
mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
if (caps & SDHCI_CAN_VDD_180)
-   mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;
+   mmc->ocr_avail |= MMC_VDD_165_195;

if (mmc->ocr_avail == 0) {
printk(KERN_ERR "%s: Hardware doesn't report any "
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 5a66d8a..b1350df 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -65,14 +65,7 @@ struct mmc_host {
unsigned intf_max;
u32 ocr_avail;

-#define MMC_VDD_145_1500x0001  /* VDD voltage 1.45 - 
1.50 */
-#define MMC_VDD_150_1550x0002  /* VDD voltage 1.50 - 
1.55 */
-#define MMC_VDD_155_1600x0004  /* VDD voltage 1.55 - 
1.60 */
-#define MMC_VDD_160_1650x0008  /* VDD voltage 1.60 - 
1.65 */
-#define MMC_VDD_165_1700x0010  /* VDD voltage 1.65 - 
1.70 */
-#define MMC_VDD_17_18  0x0020  /* VDD voltage 1.7 - 1.8 */
-#define MMC_VDD_18_19  0x0040  /* VDD voltage 1.8 - 1.9 */
-#define MMC_VDD_19_20  0x0080  /* VDD voltage 1.9 - 2.0 */
+#define MMC_VDD_165_1950x0080  /* VDD voltage 1.65 - 
1.95 */
 #define MMC_VDD_20_21  0x0100  /* VDD voltage 2.0 ~ 2.1 */
 #define MMC_VDD_21_22  0x0200  /* VDD voltage 2.1 ~ 2.2 */
 #define MMC_VDD_22_23  0x0400  /* VDD voltage 2.2 ~ 2.3 */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MMC: Fix handling of low-voltage cards

2007-03-11 Thread Philip Langdale
Fix handling of low voltage MMC cards.

The latest MMC and SD specs both agree that support for
low-voltage operations is indicated by bit 7 in the OCR.
The MMC spec states that the low voltage range is
1.65-1.95V while the SD spec leaves the actual voltage
range undefined - meaning that there is still no such
thing as a low voltage SD card.

However, an old Sandisk spec implied that bits 7.0
represented voltages below 2.0V in 1V or 0.5V increments,
and the code was accordingly written with that expectation.

This confusion meant that host drivers attempting to support
the typical low voltage (1.8V) would set the wrong bits in
the host OCR mask (usually bits 5 and/or 6) resulting in the
the low voltage mode never being used.

This change corrects the low voltage range and adds sanity
checks on the reserved bits (0-6) and for SD cards that
claim to support low-voltage operations.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index c87ce56..74ebd97 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -317,6 +317,24 @@ static u32 mmc_select_voltage(struct mmc
 {
int bit;

+   /*
+* Sanity check the voltages that the card claims to
+* support.
+*/
+   if (ocr & 0x7F) {
+   printk("%s: card claims to support voltages below "
+  "the defined range. These will be ignored.\n",
+  mmc_hostname(host));
+   ocr &= ~0x7F;
+   }
+
+   if (host->mode == MMC_MODE_SD && (ocr & MMC_VDD_165_195)) {
+   printk("%s: SD card claims to support the incompletely "
+  "defined 'low voltage range'. This will be ignored.\n",
+  mmc_hostname(host));
+   ocr &= ~MMC_VDD_165_195;
+   }
+
ocr &= host->ocr_avail;

bit = ffs(ocr);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2f34ae3..a80c043 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -669,8 +669,7 @@ static void sdhci_set_power(struct sdhci
pwr = SDHCI_POWER_ON;

switch (1 << power) {
-   case MMC_VDD_17_18:
-   case MMC_VDD_18_19:
+   case MMC_VDD_165_195:
pwr |= SDHCI_POWER_180;
break;
case MMC_VDD_29_30:
@@ -1290,7 +1289,7 @@ static int __devinit sdhci_probe_slot(st
if (caps & SDHCI_CAN_VDD_300)
mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
if (caps & SDHCI_CAN_VDD_180)
-   mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;
+   mmc->ocr_avail |= MMC_VDD_165_195;

if (mmc->ocr_avail == 0) {
printk(KERN_ERR "%s: Hardware doesn't report any "
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 496f540..2aac62a 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -65,14 +65,7 @@ struct mmc_host {
unsigned intf_max;
u32 ocr_avail;

-#define MMC_VDD_145_1500x0001  /* VDD voltage 1.45 - 
1.50 */
-#define MMC_VDD_150_1550x0002  /* VDD voltage 1.50 - 
1.55 */
-#define MMC_VDD_155_1600x0004  /* VDD voltage 1.55 - 
1.60 */
-#define MMC_VDD_160_1650x0008  /* VDD voltage 1.60 - 
1.65 */
-#define MMC_VDD_165_1700x0010  /* VDD voltage 1.65 - 
1.70 */
-#define MMC_VDD_17_18  0x0020  /* VDD voltage 1.7 - 1.8 */
-#define MMC_VDD_18_19  0x0040  /* VDD voltage 1.8 - 1.9 */
-#define MMC_VDD_19_20  0x0080  /* VDD voltage 1.9 - 2.0 */
+#define MMC_VDD_165_1950x0080  /* VDD voltage 1.65 - 
1.95 */
 #define MMC_VDD_20_21  0x0100  /* VDD voltage 2.0 ~ 2.1 */
 #define MMC_VDD_21_22  0x0200  /* VDD voltage 2.1 ~ 2.2 */
 #define MMC_VDD_22_23  0x0400  /* VDD voltage 2.2 ~ 2.3 */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MMC: Consolidate voltage definitions

2007-03-11 Thread Philip Langdale
Consolidate the list of available voltages.

Up until now, a separate set of defines has been
used for host->vdd than that used for the OCR
voltage mask values. Having two sets of defines
allows them to get out of sync and the current
sets are already inconsistent with one claiming
to describe ranges and the other specific voltages.

Only the SDHCI driver uses the host->vdd defines and
it is easily fixed to use the OCR defines.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 86d0957..2f34ae3 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -668,20 +668,17 @@ static void sdhci_set_power(struct sdhci

pwr = SDHCI_POWER_ON;

-   switch (power) {
-   case MMC_VDD_170:
-   case MMC_VDD_180:
-   case MMC_VDD_190:
+   switch (1 << power) {
+   case MMC_VDD_17_18:
+   case MMC_VDD_18_19:
pwr |= SDHCI_POWER_180;
break;
-   case MMC_VDD_290:
-   case MMC_VDD_300:
-   case MMC_VDD_310:
+   case MMC_VDD_29_30:
+   case MMC_VDD_30_31:
pwr |= SDHCI_POWER_300;
break;
-   case MMC_VDD_320:
-   case MMC_VDD_330:
-   case MMC_VDD_340:
+   case MMC_VDD_32_33:
+   case MMC_VDD_33_34:
pwr |= SDHCI_POWER_330;
break;
default:
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 43bf6a5..496f540 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -16,30 +16,7 @@ struct mmc_ios {
unsigned intclock;  /* clock rate */
unsigned short  vdd;

-#defineMMC_VDD_150 0
-#defineMMC_VDD_155 1
-#defineMMC_VDD_160 2
-#defineMMC_VDD_165 3
-#defineMMC_VDD_170 4
-#defineMMC_VDD_180 5
-#defineMMC_VDD_190 6
-#defineMMC_VDD_200 7
-#defineMMC_VDD_210 8
-#defineMMC_VDD_220 9
-#defineMMC_VDD_230 10
-#defineMMC_VDD_240 11
-#defineMMC_VDD_250 12
-#defineMMC_VDD_260 13
-#defineMMC_VDD_270 14
-#defineMMC_VDD_280 15
-#defineMMC_VDD_290 16
-#defineMMC_VDD_300 17
-#defineMMC_VDD_310 18
-#defineMMC_VDD_320 19
-#defineMMC_VDD_330 20
-#defineMMC_VDD_340 21
-#defineMMC_VDD_350 22
-#defineMMC_VDD_360 23
+/* vdd stores the bit number of the selected voltage range from below. */

unsigned char   bus_mode;   /* command output mode */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] MMC: Clean up low voltage range handling

2007-03-11 Thread Philip Langdale
Pierre Ossman wrote:
> 
> We must not have the same specs. My simplified SD 2.0 physical spec
> defines everything below bit 15 as reserved.

I was a little unclear. Both specs define bit 7 as the low-voltage
range but only the MMC spec defines the actual voltage. As such, there
is no complete definition of a low voltage SD card. That's why I added
the sanity check in the actual code.

> Although this is a nice change, it confuses things to have two changes
> in one commit. Could you split them up and base it on my "for-andrew"
> branch?

Yeah, I thought you'd think that :-) I'll post the two diffs shortly.

Thanks,

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MMC: Clean up low voltage range handling

2007-03-10 Thread Philip Langdale
Clean up the handling of low voltage MMC cards.

The latest MMC and SD specs both agree that the low
voltage range is defined as 1.65-1.95V and is signified
by bit 7 in the OCR. An old Sandisk spec implied that
bits 7-0 represented voltages below 2.0V in 1V increments,
and the code was accordingly written with that expectation.

This confusion meant that host drivers attempting to support
the typical low voltage (1.8V) would set the wrong bits in
the host OCR mask (usually bits 5 and 6) resulting in the
the low voltage mode never being used.

This change switches the code to conform to the specs and
fixes the SDHCI driver. It also removes the explicit
defines for the host vdd and updates the SDHCI driver
to convert the bit number back to the mask value
for comparisons. Having only a single set of defines
ensures there's nothing to get out of sync.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index c87ce56..74ebd97 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -317,6 +317,24 @@ static u32 mmc_select_voltage(struct mmc
 {
int bit;

+   /*
+* Sanity check the voltages that the card claims to
+* support.
+*/
+   if (ocr & 0x7F) {
+   printk("%s: card claims to support voltages below "
+  "the defined range. These will be ignored.\n",
+  mmc_hostname(host));
+   ocr &= ~0x7F;
+   }
+
+   if (host->mode == MMC_MODE_SD && (ocr & MMC_VDD_165_195)) {
+   printk("%s: SD card claims to support the incompletely "
+  "defined 'low voltage range'. This will be ignored.\n",
+  mmc_hostname(host));
+   ocr &= ~MMC_VDD_165_195;
+   }
+
ocr &= host->ocr_avail;

bit = ffs(ocr);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 86d0957..a80c043 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -668,20 +668,16 @@ static void sdhci_set_power(struct sdhci

pwr = SDHCI_POWER_ON;

-   switch (power) {
-   case MMC_VDD_170:
-   case MMC_VDD_180:
-   case MMC_VDD_190:
+   switch (1 << power) {
+   case MMC_VDD_165_195:
pwr |= SDHCI_POWER_180;
break;
-   case MMC_VDD_290:
-   case MMC_VDD_300:
-   case MMC_VDD_310:
+   case MMC_VDD_29_30:
+   case MMC_VDD_30_31:
pwr |= SDHCI_POWER_300;
break;
-   case MMC_VDD_320:
-   case MMC_VDD_330:
-   case MMC_VDD_340:
+   case MMC_VDD_32_33:
+   case MMC_VDD_33_34:
pwr |= SDHCI_POWER_330;
break;
default:
@@ -1293,7 +1289,7 @@ static int __devinit sdhci_probe_slot(st
if (caps & SDHCI_CAN_VDD_300)
mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
if (caps & SDHCI_CAN_VDD_180)
-   mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;
+   mmc->ocr_avail |= MMC_VDD_165_195;

if (mmc->ocr_avail == 0) {
printk(KERN_ERR "%s: Hardware doesn't report any "
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 43bf6a5..89dbb91 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -16,30 +16,7 @@ struct mmc_ios {
unsigned intclock;  /* clock rate */
unsigned short  vdd;

-#defineMMC_VDD_150 0
-#defineMMC_VDD_155 1
-#defineMMC_VDD_160 2
-#defineMMC_VDD_165 3
-#defineMMC_VDD_170 4
-#defineMMC_VDD_180 5
-#defineMMC_VDD_190 6
-#defineMMC_VDD_200 7
-#defineMMC_VDD_210 8
-#defineMMC_VDD_220 9
-#defineMMC_VDD_230 10
-#defineMMC_VDD_240 11
-#defineMMC_VDD_250 12
-#defineMMC_VDD_260 13
-#defineMMC_VDD_270 14
-#defineMMC_VDD_280 15
-#defineMMC_VDD_290 16
-#defineMMC_VDD_300 17
-#defineMMC_VDD_310 18
-#defineMMC_VDD_320 19
-#defineMMC_VDD_330 20
-#defineMMC_VDD_340 21
-#defineMMC_VDD_350 22
-#defineMMC_VDD_360 23
+/* vdd stores the bit number of the selected voltage range from protocol.h */

unsigned char   bus_mode;   /* command output mode */

@@ -88,14 +65,7 @@ struct mmc_host {
unsigned intf_max;
u32 ocr_avail;

-#define MMC_VDD_145_1500x0001  /* VDD voltage 1.45 - 
1.50 */
-#define MMC_VDD_150_1550x0002  /* VDD voltage 1.50 - 
1.55 */
-#define MMC_VDD_155_1600x0004  /* VDD voltage 1.55 - 
1.60 */
-#define MMC_VDD_160_

Re: [RFC][PATCH] MMC: Major restructuring and cleanup

2007-01-14 Thread Philip Langdale
Pierre Ossman wrote:
 >
> Eeeeww... This is a problem as the SD spec. clearly states the order of
> init commands. So I wouldn't be surprised if we find SD cards that choke
> on the MMC init sequence.
> 
> I guess what we lose by not supporting these is 8 bit data bus, but as
> we do not currently have a controller for that I think the point is moot.

Hrm. Even the MMC 4.1 App Note describes a unified init sequence where SD is
checked first.

So, these cards are essentially useless then. The number of hosts that support
MMC 4 but not SD can probably be counted on no hands. :-)

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC][PATCH] MMC: Major restructuring and cleanup

2007-01-13 Thread Philip Langdale
Pierre Ossman wrote:
> Hi everyone,
> 
> As I've mentioned to some of you, I've been working on restructuring the MMC
> layer in order to make it more easily maintained and to allow extensions
> like SDIO support. A first draft of this is now ready for public review.
> I've cc:d those who have been waiting for this patch set (and Russell since
> he always gives blunt, but valuable feedback ;)).

So, I think I'm a bit too much of a kernel newbie to be able to provide a
definitive review, but I've looked over the changes and they look good to me.

I fully agree with the rearchitecturing - it makes it a lot easier to see
what's going on and it'll scale for SDIO (as you mention) and CE-ATA as well,
if we ever get a hold of any of those :-)

One concrete observation I'd make is that we should probably try and detect
MMC first instead of SD. Up until today, I'd have said it didn't really
matter, but I've been doing some reading and discovered that Protec make
some very strange cards they call "SuperSD" which can talk mmc4 and sd 1.1.
These will happily go along with either initialisation sequence - and as mmc4
is either the same or better than sd 1.1 from a performance point of view,
we should prefer it. This is independent of your restructuring, but as you're
fiddling with this code... :-)

http://www.hjreggel.net/cardspeed/special-sd.html#supersd

http://www.jactron.co.uk/pretec/ssd/consumer/super-sd.htm

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2.6.19] mmc: Fix handling of response types in imxmmc and tifm drivers

2007-01-04 Thread Philip Langdale
This change depends on my SDHC patch and fixes a bug that was revealed during 
the
development of that patch. The R6 response type should be identical to R1 (and 
R7)
but was incorrectly defined differently. Fixing the R6 definition breaks 
assumptions
in these two drivers that response type flags are unique. Pierre and Alex both
believe that treating R6 and R7 as R1 will be sufficient. ie: The controllers do
not care about the differences between them. Due to lack of hardware, I have 
done
no testing.

Signed-off-by: Philip Langdale <[EMAIL PROTECTED]>
Cc: Alex Dubov <[EMAIL PROTECTED]>
Cc: Pavel Pisa <[EMAIL PROTECTED]>
---
 drivers/mmc/imxmmc.c|3 ---
 drivers/mmc/omap.c  |2 +-
 drivers/mmc/pxamci.c|2 +-
 drivers/mmc/tifm_sd.c   |3 ---
 include/linux/mmc/mmc.h |2 +-
 5 files changed, 3 insertions(+), 9 deletions(-)

diff -ur linux-2.6.19-sdhc/drivers/mmc/imxmmc.c 
linux-2.6.19-rspfix/drivers/mmc/imxmmc.c
--- linux-2.6.19-sdhc/drivers/mmc/imxmmc.c  2007-01-04 06:52:12.0 
-0800
+++ linux-2.6.19-rspfix/drivers/mmc/imxmmc.c2007-01-04 06:53:16.0 
-0800
@@ -351,9 +351,6 @@
case MMC_RSP_R3: /* short */
cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3;
break;
-   case MMC_RSP_R6: /* short CRC */
-   cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6;
-   break;
default:
break;
}
diff -ur linux-2.6.19-sdhc/drivers/mmc/omap.c 
linux-2.6.19-rspfix/drivers/mmc/omap.c
--- linux-2.6.19-sdhc/drivers/mmc/omap.c2007-01-04 06:52:12.0 
-0800
+++ linux-2.6.19-rspfix/drivers/mmc/omap.c  2007-01-04 05:46:24.0 
-0800
@@ -206,7 +206,7 @@
/* Our hardware needs to know exact type */
switch (RSP_TYPE(mmc_resp_type(cmd))) {
case RSP_TYPE(MMC_RSP_R1):
-   /* resp 1, resp 1b */
+   /* resp 1, 1b, 6, 7 */
resptype = 1;
break;
case RSP_TYPE(MMC_RSP_R2):
diff -ur linux-2.6.19-sdhc/drivers/mmc/pxamci.c 
linux-2.6.19-rspfix/drivers/mmc/pxamci.c
--- linux-2.6.19-sdhc/drivers/mmc/pxamci.c  2007-01-04 06:52:12.0 
-0800
+++ linux-2.6.19-rspfix/drivers/mmc/pxamci.c2007-01-04 05:46:36.0 
-0800
@@ -171,7 +171,7 @@

 #define RSP_TYPE(x)((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
switch (RSP_TYPE(mmc_resp_type(cmd))) {
-   case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */
+   case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6, r7 */
cmdat |= CMDAT_RESP_SHORT;
break;
case RSP_TYPE(MMC_RSP_R3):
diff -ur linux-2.6.19-sdhc/drivers/mmc/tifm_sd.c 
linux-2.6.19-rspfix/drivers/mmc/tifm_sd.c
--- linux-2.6.19-sdhc/drivers/mmc/tifm_sd.c 2007-01-04 06:52:12.0 
-0800
+++ linux-2.6.19-rspfix/drivers/mmc/tifm_sd.c   2007-01-04 06:53:38.0 
-0800
@@ -173,9 +173,6 @@
case MMC_RSP_R3:
rc |= TIFM_MMCSD_RSP_R3;
break;
-   case MMC_RSP_R6:
-   rc |= TIFM_MMCSD_RSP_R6;
-   break;
default:
BUG();
}
diff -ur linux-2.6.19-sdhc/include/linux/mmc/mmc.h 
linux-2.6.19-rspfix/include/linux/mmc/mmc.h
--- linux-2.6.19-sdhc/include/linux/mmc/mmc.h   2007-01-04 06:51:09.0 
-0800
+++ linux-2.6.19-rspfix/include/linux/mmc/mmc.h 2007-01-04 05:41:49.0 
-0800
@@ -42,7 +42,7 @@
 #define MMC_RSP_R1B
(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
 #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
 #define MMC_RSP_R3 (MMC_RSP_PRESENT)
-#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC)
+#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)

 #define mmc_resp_type(cmd) ((cmd)->flags & 
(MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2.6.19] mmc: Add support for SDHC cards (Take 5)

2007-01-04 Thread Philip Langdale
Thanks to the generous donation of an SDHC card by John Gilmore, and the
surprisingly enlightened decision by the SD Card Association to publish
useful specs, I've been able to bash out support for SDHC. The changes
are not too profound:

i) Add a card flag indicating the card uses block level addressing and check
it in the block driver. As we never took advantage of byte-level addressing,
this simply involves skipping the block -> byte translation when sending 
commands.

ii) The layout of the CSD is changed - a set of fields are discarded to make 
space
for a larger C_SIZE. We did not reference any of the discarded fields except 
those
related to the C_SIZE.

iii) Read and write timeouts are fixed values and not calculated from CSD 
values.

iv) Before invoking SEND_APP_OP_COND, we must invoke the new SEND_IF_COND to 
inform
the card we support SDHC.

I've done some basic read and write tests and everything seems to work fine but 
one
should obviously use caution in case it eats your data.

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>
---
 drivers/mmc/mmc.c|  138 ++-
 drivers/mmc/mmc_block.c  |8 ++
 include/linux/mmc/card.h |3
 include/linux/mmc/mmc.h  |1
 include/linux/mmc/protocol.h |   13 +++-
 5 files changed, 134 insertions(+), 29 deletions(-)

--- /usr/src/linux/drivers/mmc/mmc.c2007-01-04 06:51:58.0 -0800
+++ linux-2.6.19-sdhc/drivers/mmc/mmc.c 2007-01-03 22:16:24.0 -0800
@@ -289,7 +289,10 @@
else
limit_us = 10;

-   if (timeout_us > limit_us) {
+   /*
+* SDHC cards always use these fixed values.
+*/
+   if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
data->timeout_ns = limit_us * 1000;
data->timeout_clks = 0;
}
@@ -588,34 +591,65 @@

if (mmc_card_sd(card)) {
csd_struct = UNSTUFF_BITS(resp, 126, 2);
-   if (csd_struct != 0) {
+
+   switch (csd_struct) {
+   case 0:
+   m = UNSTUFF_BITS(resp, 115, 4);
+   e = UNSTUFF_BITS(resp, 112, 3);
+   csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 
10;
+   csd->tacc_clks   = UNSTUFF_BITS(resp, 104, 8) * 100;
+   
+   m = UNSTUFF_BITS(resp, 99, 4);
+   e = UNSTUFF_BITS(resp, 96, 3);
+   csd->max_dtr  = tran_exp[e] * tran_mant[m];
+   csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+   
+   e = UNSTUFF_BITS(resp, 47, 3);
+   m = UNSTUFF_BITS(resp, 62, 12);
+   csd->capacity = (1 + m) << (e + 2);
+   
+   csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
+   csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
+   csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
+   csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+   csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
+   csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
+   csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
+   break;
+   case 1:
+   /*
+* This is a block-addressed SDHC card. Most
+* interesting fields are unused and have fixed
+* values. To avoid getting tripped by buggy cards,
+* we assume those fixed values ourselves.
+*/
+   mmc_card_set_blockaddr(card);
+
+   csd->tacc_ns = 0; /* Unused */
+   csd->tacc_clks   = 0; /* Unused */
+   
+   m = UNSTUFF_BITS(resp, 99, 4);
+   e = UNSTUFF_BITS(resp, 96, 3);
+   csd->max_dtr  = tran_exp[e] * tran_mant[m];
+   csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+   
+   m = UNSTUFF_BITS(resp, 48, 22);
+   csd->capacity = (1 + m) << 10;
+   
+   csd->read_blkbits = 9;
+   csd->read_partial = 0;
+   csd->write_misalign = 0;
+   csd->read_misalign = 0;
+   csd->r2w_factor = 4; /* Unused */
+   csd->write_blkbits = 9;
+   csd->write_partial = 0;
+   break;
+   default:
printk("%s: unrecognised CSD structure version %d\n",
mmc_hostname(card->host), csd_struct);
mmc_card_set_bad(card);
return;
}
-
-   

[PATCH 2.6.19] mmc: Add support for SDHC cards (Take 4)

2007-01-04 Thread Philip Langdale
Thanks to the generous donation of an SDHC card by John Gilmore, and the
surprisingly enlightened decision by the SD Card Association to publish
useful specs, I've been able to bash out support for SDHC. The changes
are not too profound:

i) Add a card flag indicating the card uses block level addressing and check
it in the block driver. As we never took advantage of byte-level addressing,
this simply involves skipping the block -> byte translation when sending 
commands.

ii) The layout of the CSD is changed - a set of fields are discarded to make 
space
for a larger C_SIZE. We did not reference any of the discarded fields except 
those
related to the C_SIZE.

iii) Read and write timeouts are fixed values and not calculated from CSD 
values.

iv) Before invoking SEND_APP_OP_COND, we must invoke the new SEND_IF_COND to 
inform
the card we support SDHC.

I've done some basic read and write tests and everything seems to work fine but 
one
should obviously use caution in case it eats your data.

In the process of developing this patch, we realised that the R6 response 
definition
was incorrect and that it should have been identical to R1 (and so should R7).
Correcting this mistake revealed problems in a couple of host controller 
drivers that
relied on the response definitions to be unique. As we need a story for R7, I've
also fixed up the R6 handling in the affected drivers but I have no idea if it 
will
work in practice as I lack the hardware.

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>
---

 drivers/mmc/imxmmc.c |   14 +++-
 drivers/mmc/mmc.c|  138 ++-
 drivers/mmc/mmc_block.c  |8 ++
 drivers/mmc/omap.c   |2
 drivers/mmc/pxamci.c |2
 drivers/mmc/tifm_sd.c|   14 +++-
 include/linux/mmc/card.h |3
 include/linux/mmc/mmc.h  |3
 include/linux/mmc/protocol.h |   13 +++-
 9 files changed, 157 insertions(+), 40 deletions(-)

--- /usr/src/linux/drivers/mmc/imxmmc.c 2007-01-01 07:12:02.0 -0800
+++ linux-2.6.19-sdhc/drivers/mmc/imxmmc.c  2007-01-04 05:50:41.0 
-0800
@@ -343,7 +343,16 @@
switch (mmc_resp_type(cmd)) {
case MMC_RSP_R1: /* short CRC, OPCODE */
case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
-   cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R1;
+   switch (cmd->opcode) {
+   case SD_SEND_RELATIVE_ADDR:
+   cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6;
+   break;
+   case SD_SEND_IF_COND:
+   /* Assuming R7 should be mapped to R1. */
+   default:
+   cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R1;
+   break;
+   }
break;
case MMC_RSP_R2: /* long 136 bit + CRC */
cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R2;
@@ -351,9 +360,6 @@
case MMC_RSP_R3: /* short */
cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3;
break;
-   case MMC_RSP_R6: /* short CRC */
-   cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6;
-   break;
default:
break;
}
--- /usr/src/linux/drivers/mmc/mmc.c2007-01-04 05:40:31.0 -0800
+++ linux-2.6.19-sdhc/drivers/mmc/mmc.c 2007-01-03 22:16:24.0 -0800
@@ -289,7 +289,10 @@
else
limit_us = 10;

-   if (timeout_us > limit_us) {
+   /*
+* SDHC cards always use these fixed values.
+*/
+   if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
data->timeout_ns = limit_us * 1000;
data->timeout_clks = 0;
}
@@ -588,34 +591,65 @@

if (mmc_card_sd(card)) {
csd_struct = UNSTUFF_BITS(resp, 126, 2);
-   if (csd_struct != 0) {
+
+   switch (csd_struct) {
+   case 0:
+   m = UNSTUFF_BITS(resp, 115, 4);
+   e = UNSTUFF_BITS(resp, 112, 3);
+   csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 
10;
+   csd->tacc_clks   = UNSTUFF_BITS(resp, 104, 8) * 100;
+   
+   m = UNSTUFF_BITS(resp, 99, 4);
+   e = UNSTUFF_BITS(resp, 96, 3);
+   csd->max_dtr  = tran_exp[e] * tran_mant[m];
+   csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+   
+   e = UNSTUFF_BITS(resp, 47, 3);
+   m = UNSTUFF_BITS(resp, 62, 12);
+   csd->capacity = (1 + m) << (e + 2);
+   
+   csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
+   csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
+   csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
+   csd->read_mis

Re: [PATCH 2.6.19] mmc: Add support for SDHC cards (Take 2)

2007-01-03 Thread Philip Langdale
Pierre Ossman wrote:
> 
> Amen to that. All hw vendors that implement this particular form of
> brain damage should be dragged out and shot.
> 
> I'll fix a patch for this later on.

See my updated Take 3 patch. I've implemented a uniqueness fix by
adding additional RSP flags do make R6 and R7 unique. I don't know
if this is what you wanted, but it works without being too ugly.

However, also note my caveat that it's not clear if tifm or imxmmc
can ever be made to work with SD 2.0 cards. *sigh*

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2.6.19] mmc: Add support for SDHC cards (Take 3)

2007-01-03 Thread Philip Langdale
Thanks to the generous donation of an SDHC card by John Gilmore, and the
surprisingly enlightened decision by the SD Card Association to publish
useful specs, I've been able to bash out support for SDHC. The changes
are not too profound:

i) Add a card flag indicating the card uses block level addressing and check
it in the block driver. As we never took advantage of byte-level addressing,
this simply involves skipping the block -> byte translation when sending 
commands.

ii) The layout of the CSD is changed - a set of fields are discarded to make 
space
for a larger C_SIZE. We did not reference any of the discarded fields except 
those
related to the C_SIZE.

iii) Read and write timeouts are fixed values and not calculated from CSD 
values.

iv) Before invoking SEND_APP_OP_COND, we must invoke the new SEND_IF_COND to 
inform
the card we support SDHC.

I've done some basic read and write tests and everything seems to work fine but 
one
should obviously use caution in case it eats your data.

Caveat:

Due to braindead hardware design, some drivers have to tell the host controller
what response code an issued command uses. This leads to two problems:

1) Before this change, R1 and R6 were actually identical except R6 was 
incorrectly
defined and appeared different. Fixing this means the tifm_sd driver is unhappy 
as
it can't distinguish them. I have fixed it by adding new flags that describe the
response a bit more so that R6 and R7 are unique and correct.

2) What happens if the hardware doesn't grok R7? Is there anything we can
do or have they managed to build hardware that will never work with SD 2.0 
cards?
Right now, if you stick an SDHC card in, the tifm_sd driver will BUG() due to
the unknown response type while the imxmmc driver will probably fail to dispatch
the command correctly. All other supported controllers except SDHCI do some work
based on response type but appear to be able to cope with the new R7.

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>
---
 drivers/mmc/mmc.c|  138 ++-
 drivers/mmc/mmc_block.c  |8 ++
 include/linux/mmc/card.h |3
 include/linux/mmc/mmc.h  |   23 ---
 include/linux/mmc/protocol.h |   13 +++-
 5 files changed, 149 insertions(+), 36 deletions(-)

--- /usr/src/linux/drivers/mmc/mmc.c2007-01-03 22:17:11.0 -0800
+++ linux-2.6.19-sdhc/drivers/mmc/mmc.c 2007-01-03 22:16:24.0 -0800
@@ -289,7 +289,10 @@
else
limit_us = 10;

-   if (timeout_us > limit_us) {
+   /*
+* SDHC cards always use these fixed values.
+*/
+   if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
data->timeout_ns = limit_us * 1000;
data->timeout_clks = 0;
}
@@ -588,34 +591,65 @@

if (mmc_card_sd(card)) {
csd_struct = UNSTUFF_BITS(resp, 126, 2);
-   if (csd_struct != 0) {
+
+   switch (csd_struct) {
+   case 0:
+   m = UNSTUFF_BITS(resp, 115, 4);
+   e = UNSTUFF_BITS(resp, 112, 3);
+   csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 
10;
+   csd->tacc_clks   = UNSTUFF_BITS(resp, 104, 8) * 100;
+   
+   m = UNSTUFF_BITS(resp, 99, 4);
+   e = UNSTUFF_BITS(resp, 96, 3);
+   csd->max_dtr  = tran_exp[e] * tran_mant[m];
+   csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+   
+   e = UNSTUFF_BITS(resp, 47, 3);
+   m = UNSTUFF_BITS(resp, 62, 12);
+   csd->capacity = (1 + m) << (e + 2);
+   
+   csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
+   csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
+   csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
+   csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+   csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
+   csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
+   csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
+   break;
+   case 1:
+   /*
+* This is a block-addressed SDHC card. Most
+* interesting fields are unused and have fixed
+* values. To avoid getting tripped by buggy cards,
+* we assume those fixed values ourselves.
+*/
+   mmc_card_set_blockaddr(card);
+
+   csd->tacc_ns = 0; /* Unused */
+   csd->tacc_clks   = 0; /* Unused */
+   
+   m = UNSTUFF_BITS(resp, 99, 4);
+   e = UNSTUFF_B

Re: [PATCH 2.6.19] mmc: Add support for SDHC cards (Take 2)

2007-01-03 Thread Philip Langdale
Andrew Morton wrote:
> On Mon, 01 Jan 2007 07:29:55 -0800
> Philip Langdale <[EMAIL PROTECTED]> wrote:
> 
>>  #define MMC_RSP_R1B 
>> (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
>>  #define MMC_RSP_R2  (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
>>  #define MMC_RSP_R3  (MMC_RSP_PRESENT)
>> -#define MMC_RSP_R6  (MMC_RSP_PRESENT|MMC_RSP_CRC)
>> +#define MMC_RSP_R6  (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
>> +#define MMC_RSP_R7  (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
> 
> This gives MMC_RSP_R1 and MMC_RSP_R6 the same value, so
> 
> drivers/mmc/tifm_sd.c: In function 'tifm_sd_op_flags':
> drivers/mmc/tifm_sd.c:190: error: duplicate case value
> drivers/mmc/tifm_sd.c:181: error: previously used here

This is a bug. The MMC_RSP_R? #defines do not fully characterise the
responses (specically, the way that the response is parsed is not
characterised) and consequently there is no guarantee of uniqueness.
Given this reality - the way that the tifm_sd driver works is unsafe.

If R6 had not been incorrectly defined (the missing RSP_OPCODE should
always have been there), then this code would not have worked. As things
currently stand, it is necessary to also check the command number to
decide on the correct response type - that's suboptimal and it's probably
good to uniquely identify the response in the mmc_command in some other
fashion.

I'm going to remove the R6 fix from my next diff to keep these things
distinct but this needs to be resolved.

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2.6.19] mmc: Add support for SDHC cards (Take 2)

2007-01-01 Thread Philip Langdale
Thanks to the generous donation of an SDHC card by John Gilmore, and the
surprisingly enlightened decision by the SD Card Association to publish
useful specs, I've been able to bash out support for SDHC. The changes
are not too profound:

i) Add a card flag indicating the card uses block level addressing and check
it in the block driver. As we never took advantage of byte-level addressing,
this simply involves skipping the block -> byte translation when sending 
commands.

ii) The layout of the CSD is changed - a set of fields are discarded to make 
space
for a larger C_SIZE. We did not reference any of the discarded fields except 
those
related to the C_SIZE.

iii) Read and write timeouts are fixed values and not calculated from CSD 
values.

iv) Before invoking SEND_APP_OP_COND, we must invoke the new SEND_IF_COND to 
inform
the card we support SDHC.

I've done some basic read and write tests and everything seems to work fine but 
one
should obviously use caution in case it eats your data.

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>
---
 drivers/mmc/mmc.c|  115 ---
 drivers/mmc/mmc_block.c  |8 ++
 include/linux/mmc/card.h |3 +
 include/linux/mmc/mmc.h  |3 -
 include/linux/mmc/protocol.h |   13 
 5 files changed, 112 insertions(+), 30 deletions(-)

--- /usr/src/linux/drivers/mmc/mmc.c2007-01-01 07:12:02.0 -0800
+++ linux-2.6.19-sdhc/drivers/mmc/mmc.c 2007-01-01 06:41:01.0 -0800
@@ -289,7 +289,10 @@
else
limit_us = 10;

-   if (timeout_us > limit_us) {
+   /*
+* SDHC cards always use these fixed values.
+*/
+   if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
data->timeout_ns = limit_us * 1000;
data->timeout_clks = 0;
}
@@ -588,34 +591,65 @@

if (mmc_card_sd(card)) {
csd_struct = UNSTUFF_BITS(resp, 126, 2);
-   if (csd_struct != 0) {
+
+   switch (csd_struct) {
+   case 0:
+   m = UNSTUFF_BITS(resp, 115, 4);
+   e = UNSTUFF_BITS(resp, 112, 3);
+   csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 
10;
+   csd->tacc_clks   = UNSTUFF_BITS(resp, 104, 8) * 100;
+   
+   m = UNSTUFF_BITS(resp, 99, 4);
+   e = UNSTUFF_BITS(resp, 96, 3);
+   csd->max_dtr  = tran_exp[e] * tran_mant[m];
+   csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+   
+   e = UNSTUFF_BITS(resp, 47, 3);
+   m = UNSTUFF_BITS(resp, 62, 12);
+   csd->capacity = (1 + m) << (e + 2);
+   
+   csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
+   csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
+   csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
+   csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+   csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
+   csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
+   csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
+   break;
+   case 1:
+   /*
+* This is a block-addressed SDHC card. Most
+* interesting fields are unused and have fixed
+* values. To avoid getting tripped by buggy cards,
+* we assume those fixed values ourselves.
+*/
+   mmc_card_set_blockaddr(card);
+
+   csd->tacc_ns = 0; /* Unused */
+   csd->tacc_clks   = 0; /* Unused */
+   
+   m = UNSTUFF_BITS(resp, 99, 4);
+   e = UNSTUFF_BITS(resp, 96, 3);
+   csd->max_dtr  = tran_exp[e] * tran_mant[m];
+   csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+   
+   m = UNSTUFF_BITS(resp, 48, 22);
+   csd->capacity = (1 + m) << 10;
+   
+   csd->read_blkbits = 9;
+   csd->read_partial = 0;
+   csd->write_misalign = 0;
+   csd->read_misalign = 0;
+   csd->r2w_factor = 4; /* Unused */
+   csd->write_blkbits = 9;
+   csd->write_partial = 0;
+   break;
+   default:
printk("%s: unrecognised CSD structure version %d\n",
mmc_hostname(card->host), csd_struct);
mmc_card_set_bad(card);
return;
}
-

Re: [PATCH 2.6.19] mmc: Add support for SDHC cards

2007-01-01 Thread Philip Langdale
I will post the updated diff as a separate follow up.

Pierre Ossman wrote:
> 
> When you have a commit message larger than the patch, you know there is
> something wrong. ;)
> 
> Please skip the part about MMC at least.

Heh. I forget that you don't want to manually alter the email. Will do.

> 
> Actually, the way the spec describes version 2.0 of the CSD leaves my
> stomach a bit upset. I think we will find cards that put bogus values in
> the fields, expecting most hosts to use the well defined values. So I'd
> prefer a switch statement here, where csd_struct == 1 results in hard
> coded values for many fields.

I'm less pessimistic than you about this, but I have no problems with
hard-coding.

>> +cmd.opcode = SD_SEND_IF_COND;
>>   
> 
> Put this in mmc_setup() with the rest of the initialisation. Hiding in
> here just confuses things.

Done. I thought we needed it before both SD_APP_SEND_OP_COND calls but
it's only needed before the second one so I've moved it inline into
mmc_setup.

> Also, please add a comment about why you manipulate the ocr.

Done.

> 
> Wrong. R7 is defined as MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE.
> 
> (So is R6 btw, wonder why that is...)

Ah - I knew they were both the same so I made R7 match R6. :-)

I've added OPCODE to both.

Thanks,

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2.6.19] mmc: Add support for SDHC cards

2006-12-22 Thread Philip Langdale
Philip Langdale wrote:
> Hi all,
> 
> Thanks to the generous donation of an SDHC card by John Gilmore, and the
> surprisingly enlightened decision by the SD Card Association to publish
> useful specs, I've been able to bash out support for SDHC. The changes
> are not too profound:

So I sent that with the wrong From: address (damn you thunderbird!). Please
reply to my personal address (this one) and not my work one. :-)

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2.6.19] mmc: Add support for SDHC cards

2006-12-22 Thread Philip Langdale
Hi all,

Thanks to the generous donation of an SDHC card by John Gilmore, and the
surprisingly enlightened decision by the SD Card Association to publish
useful specs, I've been able to bash out support for SDHC. The changes
are not too profound:

i) Add a card flag indicating the card uses block level addressing and check
it in the block driver. As we never took advantage of byte-level addressing,
this simply involves skipping the block -> byte translation when sending 
commands.

ii) The layout of the CSD is changed - a set of fields are discarded to make 
space
for a larger C_SIZE. We did not reference any of the discarded fields except 
those
related to the C_SIZE.

iii) Read and write timeouts are fixed values and not calculated from CSD 
values.

iv) Before invoking SEND_APP_OP_COND, we must invoke the new SEND_IF_COND to 
inform
the card we support SDHC.

I've done some basic read and write tests and everything seems to work fine but 
one
should obviously use caution in case it eats your data.

Addendum: Similar spec changes were introduced by the MMC Association in 
version 4.2
to switch to block addressing. We do not have access to the 4.2 spec or even a 
change
summary as we did for 3 -> 4. My guess as to what's changed looks something 
like the
following:

i) A new field is added to the ext_csd to store the capacity that cannot be 
described
using existing csd fields.

ii) A new field is added to the ext_csd to indicate the need for block 
addressing.

iii) A new write-only field is added to the ext_csd which has to be toggled to 
tell the
card that the host supports block-addressing. But perhaps compatibility 
requires that
a new command be used like for SDHC...

If someone has access to the spec and can shed some light on the subject in a 
legal way,
please let us know. Of course, I don't think there are any MMC HC cards on the 
market
yet, but one was announced last month.

--phil

Signed-off-by: Philipl Langdale <[EMAIL PROTECTED]>
---

 drivers/mmc/mmc.c|   40 +++-
 drivers/mmc/mmc_block.c  |4 +++-
 include/linux/mmc/card.h |3 +++
 include/linux/mmc/mmc.h  |1 +
 include/linux/mmc/protocol.h |   13 -
 5 files changed, 54 insertions(+), 7 deletions(-)

diff -urN linux-2.6.19/drivers/mmc/mmc_block.c 
linux-2.6.19-sdhc/drivers/mmc/mmc_block.c
--- linux-2.6.19/drivers/mmc/mmc_block.c2006-12-21 20:29:49.0 
-0800
+++ linux-2.6.19-sdhc/drivers/mmc/mmc_block.c   2006-12-22 08:42:56.0 
-0800
@@ -237,7 +237,9 @@
brq.mrq.cmd = &brq.cmd;
brq.mrq.data = &brq.data;

-   brq.cmd.arg = req->sector << 9;
+   brq.cmd.arg = req->sector;
+   if (!mmc_card_blockaddr(card))
+   brq.cmd.arg <<= 9;
brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
brq.data.blksz = 1 << md->block_bits;
brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
diff -urN linux-2.6.19/drivers/mmc/mmc.c linux-2.6.19-sdhc/drivers/mmc/mmc.c
--- linux-2.6.19/drivers/mmc/mmc.c  2006-12-21 20:29:49.0 -0800
+++ linux-2.6.19-sdhc/drivers/mmc/mmc.c 2006-12-22 09:57:41.0 -0800
@@ -289,7 +289,10 @@
else
limit_us = 10;

-   if (timeout_us > limit_us) {
+   /*
+* SDHC cards always use these fixed values.
+*/
+   if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
data->timeout_ns = limit_us * 1000;
data->timeout_clks = 0;
}
@@ -588,12 +591,15 @@

if (mmc_card_sd(card)) {
csd_struct = UNSTUFF_BITS(resp, 126, 2);
-   if (csd_struct != 0) {
+   if (csd_struct != 0 && csd_struct != 1) {
printk("%s: unrecognised CSD structure version %d\n",
mmc_hostname(card->host), csd_struct);
mmc_card_set_bad(card);
return;
}
+   if (csd_struct == 1) {
+   mmc_card_set_blockaddr(card);
+   }

m = UNSTUFF_BITS(resp, 115, 4);
e = UNSTUFF_BITS(resp, 112, 3);
@@ -605,9 +611,14 @@
csd->max_dtr  = tran_exp[e] * tran_mant[m];
csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);

-   e = UNSTUFF_BITS(resp, 47, 3);
-   m = UNSTUFF_BITS(resp, 62, 12);
-   csd->capacity = (1 + m) << (e + 2);
+   if (csd_struct == 0) {
+   e = UNSTUFF_BITS(resp, 47, 3);
+   m = UNSTUFF_BITS(resp, 62, 12);
+   csd->capacity = (1 + m) << (e + 2);
+   } else if (csd_struct == 1) {
+   m = UNSTUFF_BITS(resp, 48, 22);
+   csd->capacity

re: [preview] VIA IDE 4.0 and AMD IDE 2.0 with automatic PCI clock detection

2001-02-09 Thread Philip Langdale


Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Vojtech,

I've tried out your new via driver and it
appears to have solved the problem with
the mis-detected ls-120 drive, but the ata66
drives are still being run at 33. 

More interestingly, the pci-clk calculations
seem to be returning badly off values.

My motherboard is a kt133a+686b btk7a from abit.

When I set the FSB to 133 with PCI=133/4=33 the
timing code returns 43mhz.

when I set the FSB to 100 with PCI=100/3=33 then
it returns 42mhz.

These are scarely different from the nominal values.
I didn't observe anything bad in the few minutes
I was running like this, but right now I've hacked
the driver back to a hardcoded 33.

What should I do next?

--phil
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Comparatively minor problem with via ide.

2001-02-09 Thread Philip Langdale

Hi,

I've just upgraded to an Athlon+KT133 from a P3+pro133 setup.

For the old motherboard which had a 596b southbridge I got
perfect udma66 support form my hard drives. After I switched
over, and without changing anything except switching from
p3 to athlon optimisations, the driver reports my drives running
at udma33. This is despite detecting an 80w cable, using ide0=ata66
and turning word93 checking off. The new southbridge is a 686b.

Also, possibly semi-related; it insists on detecting my ls-120 drive
as udma22 even though mwdma11 is the best it can actually do.

I'm not experiencing any corruption, fingers crossed ( I understand
that that was traced to an acpi conflict? ) but this is nevertheless
incorrect behaviour.

/proc/ide/via:

--VIA BusMastering IDE Configuration
Driver Version: 3.20
South Bridge:   VIA vt82c686b
Revision:   ISA 0x40 IDE 0x6
BM-DMA base:0xd000
PCI clock:  33MHz
Master Read  Cycle IRDY:0ws
Master Write Cycle IRDY:0ws
BM IDE Status Register Read Retry:  yes
Max DRDY Pulse Width:   No limit
---Primary IDE---Secondary IDE--
Read DMA FIFO flush:  yes yes
End Sector FIFO flush: no  no
Prefetch Buffer:   no  no
Post Write Buffer: no  no
Enabled:  yes yes
Simplex only:  no  no
Cable Type:   80w 80w
---drive0drive1drive2drive3-
Transfer Mode:   UDMA  UDMA  UDMA  UDMA
Address Setup:   30ns  30ns  30ns  60ns
Cmd Active:  90ns  90ns  90ns  90ns
Cmd Recovery:30ns  30ns  90ns  90ns
Data Active: 90ns  90ns  90ns  90ns
Data Recovery:   30ns  30ns  30ns  90ns
Cycle Time:  60ns  60ns  60ns  90ns
Transfer Rate:   33.3MB/s  33.3MB/s  33.3MB/s  22.2MB/s

and relevant dmesg:

Uniform Multi-Platform E-IDE driver Revision: 6.31
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
VP_IDE: IDE controller on PCI bus 00 dev 39
VP_IDE: chipset revision 6
VP_IDE: not 100% native mode: will probe irqs later
VP_IDE: VIA vt82c686b (rev 40) IDE UDMA100 controller on pci00:07.1
VP_IDE: ATA-66/100 forced bit set (WARNING)!!
ide0: BM-DMA at 0xd000-0xd007, BIOS settings: hda:DMA, hdb:DMA
ide1: BM-DMA at 0xd008-0xd00f, BIOS settings: hdc:DMA, hdd:DMA
hda: IBM-DPTA-372730, ATA DISK drive
hdb: QUANTUM FIREBALL CX6.4A, ATA DISK drive
hdc: TOSHIBA DVD-ROM SD-M1212, ATAPI CD/DVD-ROM drive
hdd: LS-120 VER5 00 UHD Floppy, ATAPI FLOPPY drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
hda: 53464320 sectors (27374 MB) w/1961KiB Cache, CHS=3328/255/63, UDMA(33)
hdb: 12594960 sectors (6449 MB) w/418KiB Cache, CHS=784/255/63, UDMA(33)
hdc: ATAPI 32X DVD-ROM drive, 256kB Cache, UDMA(33)
Uniform CD-ROM driver Revision: 3.12
hdd: 123264kB, 963/8/32 CHS, 533 kBps, 512 sector size, 720 rpm
ide-floppy: hdd: I/O error, pc = 5a, key =  5, asc = 24, ascq =  0

hdparm reports that the drives are udma66 capable which is correct, but how
do I convince the driver to use it?

thanks,

--phil



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/