lkml.org 
[lkml]   [2007]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: mmc_spi stopped working
    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
    #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;
    }
    void gen_crc7_syndrome_table (void);
    unsigned char calc_crc7(unsigned long* resp);

    #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; \
    })
    #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;
    }
    #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;
    }
    [unhandled content-type:application/octet-stream]
    \
     
     \ /
      Last update: 2007-10-27 14:55    [W:0.050 / U:0.364 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site