public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* mmc_spi stopped working
@ 2007-10-17 19:19 Pierre Ossman
  2007-10-17 19:37 ` David Brownell
  0 siblings, 1 reply; 8+ messages in thread
From: Pierre Ossman @ 2007-10-17 19:19 UTC (permalink / raw)
  To: David Brownell, LKML

Hi David,

I just tried out mmc_spi on Linux HEAD and it no longer works. :/

It seems to be caused by changes in the SPI core on how to handled bus
sharing. All I'm getting in dmesg is this:

[17179577.832000] mmc_spi spi1.0: can't share SPI bus
[17179577.836000] mmc_spi: probe of spi1.0 failed with error -31

Ideas? This platform worked fine with 2.6.23-rc*

Rgds

-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  PulseAudio, core developer          http://pulseaudio.org
  rdesktop, core developer          http://www.rdesktop.org

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: mmc_spi stopped working
  2007-10-17 19:19 mmc_spi stopped working Pierre Ossman
@ 2007-10-17 19:37 ` David Brownell
  2007-10-17 19:52   ` Pierre Ossman
  2007-10-22 18:03   ` Pierre Ossman
  0 siblings, 2 replies; 8+ messages in thread
From: David Brownell @ 2007-10-17 19:37 UTC (permalink / raw)
  To: linux-kernel, drzeus-list

> I just tried out mmc_spi on Linux HEAD and it no longer works. :/

I noticed that too.  I've got a patch for one bug (appended), and
will be looking at a fix for the second.


> It seems to be caused by changes in the SPI core on how to handled bus
> sharing. All I'm getting in dmesg is this:
>
> [17179577.832000] mmc_spi spi1.0: can't share SPI bus
> [17179577.836000] mmc_spi: probe of spi1.0 failed with error -31

That issue is 49dce689ad4ef0fd1f970ef762168e4bd46f69a3, the
classdev-elimination patch from Tony Jones.  It broke the
"does this bus have more than one device" test by relocating
the relevant sysfs nodes.

Quick workaround for that one is to disable the fault return
after that test.

- Dave

==========	CUT HERE
When enumerating MMC cards using SPI, don't support the "just probe"
mechanism since it doesn't always work.  Instead, always wait for the
reset to complete before issuing the next request.

This is a regression ... this SanDisk MMC card used to enumerate with
no trouble, despite this particular spec violation.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>

--- a/drivers/mmc/core/mmc_ops.c	2007-10-13 17:44:43.000000000 -0700
+++ b/drivers/mmc/core/mmc_ops.c	2007-10-16 18:54:38.000000000 -0700
@@ -115,8 +115,11 @@ int mmc_send_op_cond(struct mmc_host *ho
 		if (err)
 			break;
 
-		/* if we're just probing, do a single pass */
-		if (ocr == 0)
+		/* if we're just probing, do a single pass ... except,
+		 * accomodate cards which don't behave right until a
+		 * SPI reset completes.
+		 */
+		if (ocr == 0 && !mmc_host_is_spi(host))
 			break;
 
 		/* otherwise wait until reset completes */

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: mmc_spi stopped working
  2007-10-17 19:37 ` David Brownell
@ 2007-10-17 19:52   ` Pierre Ossman
  2007-10-24 22:27     ` David Brownell
  2007-10-22 18:03   ` Pierre Ossman
  1 sibling, 1 reply; 8+ messages in thread
From: Pierre Ossman @ 2007-10-17 19:52 UTC (permalink / raw)
  To: David Brownell; +Cc: linux-kernel

On Wed, 17 Oct 2007 12:37:13 -0700
David Brownell <david-b@pacbell.net> wrote:

> 
> That issue is 49dce689ad4ef0fd1f970ef762168e4bd46f69a3, the
> classdev-elimination patch from Tony Jones.  It broke the
> "does this bus have more than one device" test by relocating
> the relevant sysfs nodes.
> 
> Quick workaround for that one is to disable the fault return
> after that test.
> 

Annoying. Feel free to ping me when you've pushed fixes to Linus.

> When enumerating MMC cards using SPI, don't support the "just probe"
> mechanism since it doesn't always work.  Instead, always wait for the
> reset to complete before issuing the next request.
> 
> This is a regression ... this SanDisk MMC card used to enumerate with
> no trouble, despite this particular spec violation.
> 
> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
> 

I think I'll have to NAK this as I believe it breaks MMC 4.2. I'll check
and get back to you.

Rgds
-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  PulseAudio, core developer          http://pulseaudio.org
  rdesktop, core developer          http://www.rdesktop.org

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: mmc_spi stopped working
  2007-10-17 19:37 ` David Brownell
  2007-10-17 19:52   ` Pierre Ossman
@ 2007-10-22 18:03   ` Pierre Ossman
  2007-10-24 22:37     ` David Brownell
  1 sibling, 1 reply; 8+ messages in thread
From: Pierre Ossman @ 2007-10-22 18:03 UTC (permalink / raw)
  To: David Brownell; +Cc: linux-kernel

On Wed, 17 Oct 2007 12:37:13 -0700
David Brownell <david-b@pacbell.net> wrote:

> When enumerating MMC cards using SPI, don't support the "just probe"
> mechanism since it doesn't always work.  Instead, always wait for the
> reset to complete before issuing the next request.
> 
> This is a regression ... this SanDisk MMC card used to enumerate with
> no trouble, despite this particular spec violation.
> 

I've been testing a bit more here, and I can't get this particular bug. I have others though:

Out of my five MMC cards, only two work properly. One doesn't respond to SPI commands at all, and two hang on a second CMD0 and return ILLEGAL_COMMAND on a second run of CMD1. All of this is of course wildly out of spec. SPI seems to be a bonus, not a given. :/

As for your card, could you send me a dump as I'm unable to produce the issue here?

Rgds
-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  PulseAudio, core developer          http://pulseaudio.org
  rdesktop, core developer          http://www.rdesktop.org

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: mmc_spi stopped working
  2007-10-17 19:52   ` Pierre Ossman
@ 2007-10-24 22:27     ` David Brownell
  2007-10-27 13:00       ` Pierre Ossman
  0 siblings, 1 reply; 8+ messages in thread
From: David Brownell @ 2007-10-24 22:27 UTC (permalink / raw)
  To: Pierre Ossman; +Cc: linux-kernel, tonyj, spi-devel-general

On Wednesday 17 October 2007, Pierre Ossman wrote:
> 
> On Wed, 17 Oct 2007 12:37:13 -0700
> David Brownell <david-b@pacbell.net> wrote:
> > That issue is 49dce689ad4ef0fd1f970ef762168e4bd46f69a3, the
> > classdev-elimination patch from Tony Jones.  It broke the
> > "does this bus have more than one device" test by relocating
> > the relevant sysfs nodes.
> > 
> > Quick workaround for that one is to disable the fault return
> > after that test.
> > 
> 
> Annoying. Feel free to ping me when you've pushed fixes to Linus.

This is another case where whacking around in sysfs seems
unavoidable, even when it breaks things.  The patch below
works around that that change.  It seems like something that
should go through you, not directly through Linus...

- Dave

================	CUT HERE
Fix mmc-over-spi regression

Patch 49dce689ad4ef0fd1f970ef762168e4bd46f69a3 changed the sysfs data
structures for SPI in a way which broke the MMC-over-SPI host driver.

This patch fixes that regression by changing the scheme used to keep
from knowingly trying to use a shared bus segment, and updates the
adjacent comments slightly to better explain the issue.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>

--- a/drivers/mmc/host/mmc_spi.c	2007-10-23 21:24:41.000000000 -0700
+++ b/drivers/mmc/host/mmc_spi.c	2007-10-24 14:46:59.000000000 -0700
@@ -1165,6 +1165,23 @@ mmc_spi_detect_irq(int irq, void *mmc)
 	return IRQ_HANDLED;
 }
 
+struct count_children {
+	unsigned	n;
+	struct bus_type	*bus;
+};
+
+static int maybe_count_child(struct device *dev, void *c)
+{
+	struct count_children *ccp = c;
+
+	if (dev->bus == ccp->bus) {
+		if (ccp->n)
+			return -EBUSY;
+		ccp->n++;
+	}
+	return 0;
+}
+
 static int mmc_spi_probe(struct spi_device *spi)
 {
 	void			*ones;
@@ -1188,33 +1205,30 @@ static int mmc_spi_probe(struct spi_devi
 		return status;
 	}
 
-	/* We can use the bus safely iff nobody else will interfere with
-	 * us.  That is, either we have the experimental exclusive access
-	 * primitives ... or else there's nobody to share it with.
+	/* We can use the bus safely iff nobody else will interfere with us.
+	 * Most commands consist of one SPI message to issue a command, then
+	 * several more to collect its response, then possibly more for data
+	 * transfer.  Clocking access to other devices during that period will
+	 * corrupt the command execution.
+	 *
+	 * Until we have software primitives which guarantee non-interference,
+	 * we'll aim for a hardware-level guarantee.
+	 *
+	 * REVISIT we can't guarantee another device won't be added later...
 	 */
 	if (spi->master->num_chipselect > 1) {
-		struct device	*parent = spi->dev.parent;
+		struct count_children cc;
 
-		/* If there are multiple devices on this bus, we
-		 * can't proceed.
-		 */
-		spin_lock(&parent->klist_children.k_lock);
-		if (parent->klist_children.k_list.next
-				!= parent->klist_children.k_list.prev)
-			status = -EMLINK;
-		else
-			status = 0;
-		spin_unlock(&parent->klist_children.k_lock);
+		cc.n = 0;
+		cc.bus = spi->dev.bus;
+		status = device_for_each_child(spi->dev.parent, &cc,
+				maybe_count_child);
 		if (status < 0) {
 			dev_err(&spi->dev, "can't share SPI bus\n");
 			return status;
 		}
 
-		/* REVISIT we can't guarantee another device won't
-		 * be added later.  It's uncommon though ... for now,
-		 * work as if this is safe.
-		 */
-		dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n");
+		dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");
 	}
 
 	/* We need a supply of ones to transmit.  This is the only time

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: mmc_spi stopped working
  2007-10-22 18:03   ` Pierre Ossman
@ 2007-10-24 22:37     ` David Brownell
  2007-10-27 12:52       ` Pierre Ossman
  0 siblings, 1 reply; 8+ messages in thread
From: David Brownell @ 2007-10-24 22:37 UTC (permalink / raw)
  To: Pierre Ossman; +Cc: linux-kernel

On Monday 22 October 2007, Pierre Ossman wrote:
> On Wed, 17 Oct 2007 12:37:13 -0700
> David Brownell <david-b@pacbell.net> wrote:
> 
> > When enumerating MMC cards using SPI, don't support the "just probe"
> > mechanism since it doesn't always work.  Instead, always wait for the
> > reset to complete before issuing the next request.
> > 
> > This is a regression ... this SanDisk MMC card used to enumerate with
> > no trouble, despite this particular spec violation.
> > 
> 
> I've been testing a bit more here, and I can't get this particular bug.

It's not just a bug, it's a regression ... a new bug which
was introduced by some patch.  ;)


> I have others though: 
> 
> Out of my five MMC cards, only two work properly. One doesn't respond
> to SPI commands at all, and two hang on a second CMD0 and return
> ILLEGAL_COMMAND on a second run of CMD1. All of this is of course wildly
> out of spec. SPI seems to be a bonus, not a given. :/   

SPI works fine on all the MMC and SD cards I've got here,
other than the minor glitch fixed by the "don't just probe"
patch I sent.

As you know, to be spec-conformant they *must* support SPI.
Agreed, there are too many vendors who don't appear to value
following specs.  If those cards which are using the MMC or
SD trade marks, you might notify the relevant consortium and
asking them to fix those vendors.  ;)


> As for your card, could you send me a dump as I'm unable to produce
> the issue here? 

I'm not sure what you mean by "dump", but appended the sysfs attributes
produced after I disabled that new "just probe" mechanism.

- Dave



This is a dump of the /sys/class/mmc_host/mmc0/mmc0:0001 file attributes
(except the card serial number) for a SanDisk MMC card which doesn't like
SPI requests (like reading OCR) before the reset finishes.

This card _used_ to enumerate with the MMC-over-SPI stack, but
a recent change in the MMC core now prevents it from doing that...

=== cid
00000000  30 30 30 30 30 32 35 33  34 34 34 64 34 32 32 64  |00000253444d422d|
00000010  33 31 33 36 33 32 61 39  31 66 31 30 38 34 33 31  |313632a91f108431|
00000020  0a                                                |.|
00000021

=== csd
00000000  34 34 32 36 30 30 32 61  31 66 66 39 38 33 64 33  |4426002a1ff983d3|
00000010  65 34 62 34 38 33 66 66  31 32 34 30 34 30 38 31  |e4b483ff12404081|
00000020  0a                                                |.|
00000021

=== date
00000000  30 38 2f 32 30 30 31 0a                           |08/2001.|
00000008

=== fwrev
00000000  30 78 32 0a                                       |0x2.|
00000004

=== hwrev
00000000  30 78 33 0a                                       |0x3.|
00000004

=== manfid
00000000  30 78 30 30 30 30 30 32  0a                       |0x000002.|
00000009

=== name
00000000  53 44 4d 42 2d 31 36 0a                           |SDMB-16.|
00000008

=== oemid
00000000  30 78 30 30 30 30 0a                              |0x0000.|
00000007

=== type
00000000  4d 4d 43 0a                                       |MMC.|
00000004


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: mmc_spi stopped working
  2007-10-24 22:37     ` David Brownell
@ 2007-10-27 12:52       ` Pierre Ossman
  0 siblings, 0 replies; 8+ messages in thread
From: Pierre Ossman @ 2007-10-27 12:52 UTC (permalink / raw)
  To: David Brownell; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1639 bytes --]

On Wed, 24 Oct 2007 15:37:10 -0700
David Brownell <david-b@pacbell.net> wrote:

> On Monday 22 October 2007, Pierre Ossman wrote:
> > 
> > I've been testing a bit more here, and I can't get this particular bug.
> 
> It's not just a bug, it's a regression ... a new bug which
> was introduced by some patch.  ;)
> 

It's a bug in the card, which is what I was referring to. ;)

> 
> SPI works fine on all the MMC and SD cards I've got here,
> other than the minor glitch fixed by the "don't just probe"
> patch I sent.
> 

Lucky you. :)

> As you know, to be spec-conformant they *must* support SPI.

I never recall which of the different specs require SPI (not all do).

> Agreed, there are too many vendors who don't appear to value
> following specs.  If those cards which are using the MMC or
> SD trade marks, you might notify the relevant consortium and
> asking them to fix those vendors.  ;)
> 

Hah! The SD and MMC boys seem to have no interest in people following the specs, considering all the shite that is out there.

> 
> > As for your card, could you send me a dump as I'm unable to produce
> > the issue here? 
> 
> I'm not sure what you mean by "dump", but appended the sysfs attributes
> produced after I disabled that new "just probe" mechanism.
> 

A dmesg with MMC_DEBUG so that I can see just how the card misbehaves.

Also, I see you're dying for my decodecid and decodecsd progs. ;)
I've included both.

Rgds
-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  PulseAudio, core developer          http://pulseaudio.org
  rdesktop, core developer          http://www.rdesktop.org

[-- Attachment #2: crc7.c --]
[-- Type: text/x-csrc, Size: 925 bytes --]

#include "crc7.h"

#define CRC7_POLYNOMIAL 0x89 /* x^7 + x^3 + 1 */

static unsigned char crc7_syndrome_table[256];

/*
 * Generate a table of CRC-7 syndromes for x^7 * each possible input byte
 */
void
gen_crc7_syndrome_table (void)
{
  int i, j, syndrome;
  for (i = 0;  i < 256;  ++i)
    {
      syndrome = ((i & 0x80) != 0)? i ^ CRC7_POLYNOMIAL : i;
      for (j = 0;  j < 7;  ++j)
        {
          if (((syndrome <<= 1) & 0x80) != 0)
            {
              syndrome ^= CRC7_POLYNOMIAL;
            }
        }
      crc7_syndrome_table[i] = (unsigned char) syndrome;
    }
}

unsigned char
calc_crc7(unsigned long* resp)
{
	unsigned char crc7_accum = 0;
	unsigned char byte;
	int i, j;
	
	for (i = 0;i < 4;i++)
	{
		for (j = 0;j < 4;j++)
		{
			if ((i == 3) && (j == 3))
				break;
			byte = resp[i] >> (24 - 8 * j);
			crc7_accum = crc7_syndrome_table[(crc7_accum << 1) ^ byte];
		}
	}
	
	return crc7_accum;
}

[-- Attachment #3: crc7.h --]
[-- Type: text/x-chdr, Size: 83 bytes --]

void gen_crc7_syndrome_table (void);
unsigned char calc_crc7(unsigned long* resp);

[-- Attachment #4: decode.h --]
[-- Type: text/x-chdr, Size: 383 bytes --]


#define UNSTUFF_BITS(resp,start,size)					\
	({								\
		const unsigned long __mask = (1 << (size)) - 1;			\
		const int __off = 3 - ((start) / 32);			\
		const int __shft = (start) & 31;			\
		unsigned long __res;						\
									\
		__res = resp[__off] >> __shft;				\
		if ((size) + __shft >= 32)				\
			__res |= resp[__off-1] << (32 - __shft);	\
		__res & __mask;						\
	})

[-- Attachment #5: decodecid.c --]
[-- Type: text/x-csrc, Size: 1317 bytes --]

#include <stdlib.h>
#include <stdio.h>

#include "crc7.h"
#include "decode.h"

int main(int argc, char** argv)
{
	int i, j;
	int temp, e, m;
	char ch;
	unsigned long resp[4];
	
	if (argc != 2)
		return -1;
	
	if (strlen(argv[1]) != 8 * 4)
		return -1;
	
	for (i = 0;i < 4;i++)
	{
		resp[i] = 0;
		for (j = 0;j < 8;j++)
		{
			resp[i] <<= 4;
			ch = tolower(argv[1][i * 8 + j]);
			if (isdigit(ch))
				resp[i] |= ch - '0';
			else if (isxdigit(ch))
				resp[i] |= ch - 'a' + 0xA;
			else
				return -1;
		}
	}

	printf("Manufacturer ID: %d\n", UNSTUFF_BITS(resp, 120, 8));
	printf("OEM/Application ID: %d\n", UNSTUFF_BITS(resp, 104, 16));
	
	printf("Product name: %c%c%c%c%c%c\n",
		(char)UNSTUFF_BITS(resp, 96, 8),
		(char)UNSTUFF_BITS(resp, 88, 8),
		(char)UNSTUFF_BITS(resp, 80, 8),
		(char)UNSTUFF_BITS(resp, 72, 8),
		(char)UNSTUFF_BITS(resp, 64, 8),
		(char)UNSTUFF_BITS(resp, 56, 8));

	printf("Product revision: %d:%d\n",
		UNSTUFF_BITS(resp, 52, 4),
		UNSTUFF_BITS(resp, 48, 4));

	printf("Serial: %08x\n", UNSTUFF_BITS(resp, 16, 32));

	printf("Manufacturing date: %d/%d\n",
		UNSTUFF_BITS(resp, 12, 4) + 1997,
		UNSTUFF_BITS(resp, 8, 4));
	
	gen_crc7_syndrome_table();
	printf("CRC: ");
	if (UNSTUFF_BITS(resp, 1, 7) == calc_crc7(resp))
		printf("OK");
	else
		printf("Fail");
	printf("\n");

	return 0;
}

[-- Attachment #6: decodecsd.c --]
[-- Type: text/x-csrc, Size: 5411 bytes --]

#include <stdlib.h>
#include <stdio.h>

#include "crc7.h"
#include "decode.h"

static const unsigned int tran_exp[] = {
	10000,		100000,		1000000,	10000000,
	0,		0,		0,		0
};

static const unsigned char tran_mant[] = {
	0,	10,	12,	13,	15,	20,	25,	30,
	35,	40,	45,	50,	55,	60,	70,	80,
};

static const unsigned int tacc_exp[] = {
	1,	10,	100,	1000,	10000,	100000,	1000000, 10000000,
};

static const unsigned int tacc_mant[] = {
	0,	10,	12,	13,	15,	20,	25,	30,
	35,	40,	45,	50,	55,	60,	70,	80,
};

static const unsigned int min_cur[] = {
	5,	10,	50,	100,	250,	350,	600,	1000,
};

static const unsigned int max_cur[] = {
	10,	50,	100,	250,	350,	450,	800,	2000,
};

int main(int argc, char** argv)
{
	int i, j;
	int temp, e, m;
	char ch;
	unsigned long resp[4];

	if (argc != 2)
		return -1;

	if (strlen(argv[1]) != 8 * 4)
		return -1;

	for (i = 0;i < 4;i++)
	{
		resp[i] = 0;
		for (j = 0;j < 8;j++)
		{
			resp[i] <<= 4;
			ch = tolower(argv[1][i * 8 + j]);
			if (isdigit(ch))
				resp[i] |= ch - '0';
			else if (isxdigit(ch))
				resp[i] |= ch - 'a' + 0xA;
			else
				return -1;
		}
	}

	printf("CSD Version: ");
	temp = UNSTUFF_BITS(resp, 126, 2);
	switch (temp)
	{
	case 0:
		printf("v1.0");
		break;
	case 1:
		printf("v1.1");
		break;
	case 2:
		printf("v1.2");
		break;
	default:
		printf("Unknown [%d]", temp);
	}
	printf("\n");

	printf("MMCA Version: ");
	temp = UNSTUFF_BITS(resp, 122, 4);
	switch (temp)
	{
	case 0:
		printf("v1.0 to v1.2");
		break;
	case 1:
		printf("v1.4");
		break;
	case 2:
		printf("v2.0 to v2.2");
		break;
	case 3:
		printf("v3.1 to v3.3");
		break;
	default:
		printf("Unknown [%d]", temp);
	}
	printf("\n");

	m = UNSTUFF_BITS(resp, 115, 4);
	e = UNSTUFF_BITS(resp, 112, 3);
	printf("TACC: %d ns\n", (tacc_exp[e] * tacc_mant[m] + 9) / 10);
	printf("NSAC: %d clks\n", UNSTUFF_BITS(resp, 104, 8) * 100);

	m = UNSTUFF_BITS(resp, 99, 4);
	e = UNSTUFF_BITS(resp, 96, 3);
	printf("Max rate: %d kHz\n", tran_exp[e] * tran_mant[m] / 1000);

	printf("Command classes: ");
	temp = UNSTUFF_BITS(resp, 84, 12);
	for (i = 0;i < 12;i++)
	{
		if (temp & (1 << i))
		{
			switch (i)
			{
			case 0:
				printf("basic, ");
				break;
			case 1:
				printf("stream read, ");
				break;
			case 2:
				printf("block read, ");
				break;
			case 3:
				printf("stream write, ");
				break;
			case 4:
				printf("block write, ");
				break;
			case 5:
				printf("erase, ");
				break;
			case 6:
				printf("write prot., ");
				break;
			case 7:
				printf("lock, ");
				break;
			case 8:
				printf("app. specific, ");
				break;
			case 9:
				printf("I/O mode, ");
				break;
			default:
				printf("class %d, ", i);
			}
		}
	}
	printf("\n");

	temp = 1 << UNSTUFF_BITS(resp, 80, 4);
	printf("Read block size: %d bytes\n", temp);

	temp = 1 << UNSTUFF_BITS(resp, 22, 4);
	printf("Write block size: %d bytes\n", temp);

	printf("Partial read: ");
	if (UNSTUFF_BITS(resp, 79, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("Partial write: ");
	if (UNSTUFF_BITS(resp, 21, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("Read misalign: ");
	if (UNSTUFF_BITS(resp, 77, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("Write misalign: ");
	if (UNSTUFF_BITS(resp, 78, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("DSR: ");
	if (UNSTUFF_BITS(resp, 76, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	e = UNSTUFF_BITS(resp, 47, 3);
	m = UNSTUFF_BITS(resp, 62, 12);
	printf("Capacity: %d blocks %d %d\n", ((1 + m) << (e + 2)), m, e);

	printf("Min read current: %0.1f mA\n",
		(float)min_cur[UNSTUFF_BITS(resp, 59, 3)]/10);
	printf("Max read current: %0.1f mA\n",
		(float)max_cur[UNSTUFF_BITS(resp, 56, 3)]/10);

	printf("Min write current: %0.1f mA\n",
		(float)min_cur[UNSTUFF_BITS(resp, 53, 3)]/10);
	printf("Max write current: %0.1f mA\n",
		(float)max_cur[UNSTUFF_BITS(resp, 50, 3)]/10);

	m = UNSTUFF_BITS(resp, 42, 5);
	e = UNSTUFF_BITS(resp, 37, 5);
	printf("Erase group size: %d blocks\n", (m+1) * (e+1));

	printf("WP group size: %d erase group(s)\n", UNSTUFF_BITS(resp, 32, 5));

	printf("WP enable: ");
	if (UNSTUFF_BITS(resp, 31, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("R2W factor: %d\n", UNSTUFF_BITS(resp, 26, 3));

	printf("Content protect: ");
	if (UNSTUFF_BITS(resp, 16, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("File format: ");
	if (UNSTUFF_BITS(resp, 15, 1))
		printf("Reserved");
	else
	{
		switch (UNSTUFF_BITS(resp, 10, 2))
		{
		case 0:
			printf("Hard disk");
			break;
		case 1:
			printf("Floppy");
			break;
		case 2:
			printf("Universal");
			break;
		case 3:
			printf("Unknown");
			break;
		}
	}
	printf("\n");

	printf("Copy: ");
	if (UNSTUFF_BITS(resp, 14, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("Perm write protect: ");
	if (UNSTUFF_BITS(resp, 13, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("Tmp write protect: ");
	if (UNSTUFF_BITS(resp, 12, 1))
		printf("Yes");
	else
		printf("No");
	printf("\n");

	printf("ECC: ");
	switch (UNSTUFF_BITS(resp, 8, 2))
	{
	case 0:
		printf("none");
		break;
	case 1:
		printf("BCH(512,512)");
		break;
	default:
		printf("Reserved");
	}
	printf("\n");

	gen_crc7_syndrome_table();
	printf("CRC: ");
	if (UNSTUFF_BITS(resp, 1, 7) == calc_crc7(resp))
		printf("OK");
	else
		printf("Fail");
	printf("\n");

	return 0;
}

[-- Attachment #7: Makefile --]
[-- Type: application/octet-stream, Size: 117 bytes --]

all: decodecsd decodecid

decodecsd: crc7.o crc7.h decode.h
decodecid: crc7.o crc7.h decode.h

crc7.o: crc7.c crc7.h

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: mmc_spi stopped working
  2007-10-24 22:27     ` David Brownell
@ 2007-10-27 13:00       ` Pierre Ossman
  0 siblings, 0 replies; 8+ messages in thread
From: Pierre Ossman @ 2007-10-27 13:00 UTC (permalink / raw)
  To: David Brownell; +Cc: linux-kernel, tonyj, spi-devel-general

On Wed, 24 Oct 2007 15:27:46 -0700
David Brownell <david-b@pacbell.net> wrote:

> 
> This is another case where whacking around in sysfs seems
> unavoidable, even when it breaks things.  The patch below
> works around that that change.  It seems like something that
> should go through you, not directly through Linus...
> 

Indeed. Applied.

Rgds
-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  PulseAudio, core developer          http://pulseaudio.org
  rdesktop, core developer          http://www.rdesktop.org

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-10-27 13:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-17 19:19 mmc_spi stopped working Pierre Ossman
2007-10-17 19:37 ` David Brownell
2007-10-17 19:52   ` Pierre Ossman
2007-10-24 22:27     ` David Brownell
2007-10-27 13:00       ` Pierre Ossman
2007-10-22 18:03   ` Pierre Ossman
2007-10-24 22:37     ` David Brownell
2007-10-27 12:52       ` Pierre Ossman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox