Question

I have a Debian 7.0 Linux 3.2 embedded ARM TI AM335x system. This is a custom board we've developed, but the SD card section at least is the same as the development board. There are some vendor-specific SD card commands I'd like to issue to the card, namely reading some SMART data using CMD56.

Is there any way to send commands to the SD card controller and read the response from userspace?

Was it helpful?

Solution

Your driver is omap_hsmmc according to http://processors.wiki.ti.com/index.php/AM335x_MMC/SD_Driver%27s_Guide some info also in https://www.kernel.org/doc/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt

After some web searching for SMART monitoring support in sd cards, I get the search query mmc smartctl (because smartctl is name of SMART monitoring utility for *ATA in Linux, and mmc is the kernel subsystem to implement MMC, SD, SDHC cards and controllers. I found the bug filled against some mobile PC OS, https://code.google.com/p/chromium/issues/detail?id=315380 by Gwendal Grignou

If the root device is a SATA device:

  • Add output of hdparm -I /dev/sda
  • Add output of smartctl -a /dev/sda

If the root device is a eMMC device:

  • When mmc-utils will be part of the image, add a similar command output.

It sounds like the mmc-utils it the tool of choice to implement SMART for SD cards. There is home git of mmc-utils on kernel.org: http://git.kernel.org/cgit/linux/kernel/git/cjb/mmc-utils.git/tree/

I see no "SMART" here, but the mmc-utils/mmc_cmds.c has code to send custom commands to the card by using ioctl(fd, MMC_IOC_CMD, (struct mmc_ioc_cmd*) &ioctl_data) with fd pointing to correct mmcblkX device (I hope this works with most SD controllers). Code by Johan RUDHOLM (from st-ericsson, 2012, GPLv2):

   int read_extcsd(int fd, __u8 *ext_csd)
   {
       struct mmc_ioc_cmd idata;
       memset(&idata, 0, sizeof(idata));
       memset(ext_csd, 0, sizeof(__u8) * 512);
       idata.write_flag = 0;
       idata.opcode = MMC_SEND_EXT_CSD;
       idata.arg = 0;
       idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
       idata.blksz = 512;
       idata.blocks = 1;
       mmc_ioc_cmd_set_data(idata, ext_csd);

       return  ioctl(fd, MMC_IOC_CMD, &idata);
   }

   int write_extcsd_value(int fd, __u8 index, __u8 value)
   {
       struct mmc_ioc_cmd idata;

       memset(&idata, 0, sizeof(idata));
       idata.write_flag = 1;
       idata.opcode = MMC_SWITCH;
       idata.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
            (index << 16) |
            (value << 8) |
            EXT_CSD_CMD_SET_NORMAL;
       idata.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;

       return ioctl(fd, MMC_IOC_CMD, &idata);
   }

Some documentation and examples for MMC_IOC_CMD were posted in LKML by Shashidhar Hiremath at 20 Dec 14:54 2011 "[PATCH 1/1] mmc: User Application for testing SD/MMC Commands and extra IOCTL Command for MMC card reset"

The official userAPI (uapi) for struct mmc_ioc_cmd is in linux source tree include/uapi/linux/mmc/ioctl.h:

  6 struct mmc_ioc_cmd {
...
 10         /* Application-specific command.  true = precede with CMD55 */
 11         int is_acmd;
...
 51  * Since this ioctl is only meant to enhance (and not replace) normal access
 52  * to the mmc bus device...

OTHER TIPS

The simplest way is mmap the memory space of SD controller,then write command of sd controller's data sheet to controller.

Yes, there are vendor-specific SD card commands you can read SMART data from SD card to your device using CMD56.

The Host must be able to support vendor command “CMD61” and “CMD56”. And it needs to have 5ms delay for FW busy time between issue CMD61 and CMD56.

Paul.



Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top