Specify mtd:name instead of /dev/mtd# in call to open

Tag: linux Author: kang1217 Date: 2012-02-08

You can specify an MTD device by name on the kernel command line root=mtd:name and you can mount with a name mount mtd:name. I want my app to be able to do the same thing. It has to call open, but open("mtd:name", ...) fails with No such file or directory.

How do you get from 'mtd:name' to '/dev/mtd#'?

Updated

This is the code I came up with in case it's useful to someone else.

int mtd_lookup_minor(const char * mtdname)
{
    int minor;
    unsigned int size, erasesize;
    char name[65];
    char line[128];

    if (mtdname == NULL)
    {
        errno = EINVAL;
        return -1;
    }

    FILE * fp = fopen("/proc/mtd", "r");
    if (fp == NULL)
        return -1;

    while (fgets(line, sizeof(line), fp))
    {
        if (sscanf(line, "mtd%d: %x %x \"%64[^\"]\"", &minor, &size, &erasesize, name) == 4 && strcmp(name, mtdname) == 0)
        {
            fclose(fp);
            return minor;
        }
    }

    fclose(fp);
    errno = ENODEV;
    return -1;
}

/*
 * mtd_open_char allows specifying "mtd:name" instead of /dev/mtd#
 *  to refer to the MTD char device by name.
 */
int mtd_open_char(const char * mtdpath, int oflag)
{
    int minor;
    char pathbuffer[16];

    if (mtdpath == NULL)
    {
        errno = EINVAL;
        return -1;
    }

    if (strlen(mtdpath) > 4 && strncmp(mtdpath, "mtd:", 4) == 0)
    {
        minor = mtd_lookup_minor(mtdpath + 4);
        if (minor < 0 || minor > 9999999) // paranoia fit into pathbuffer
        {
            errno = ENODEV;
            return -1;
        }

        sprintf(pathbuffer, "/dev/mtd%d", minor);
        mtdpath = pathbuffer;
    }

    return open(mtdpath, oflag);
}

Best Answer

You can look up MTD names and devices in /proc/mtd.

comments:

Yea, I was hoping not to have to parse a file.
Well.... that's what you're going to have to do.