7

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?

fred basset
  • 9,774
  • 28
  • 88
  • 138
  • 1
    Fred, what is the driver, responsible for the working with SD card controller (check `dmesg` output)? – osgx Apr 26 '14 at 15:32
  • I don't have access to the system right now (it's in the office), but I'd assume its the standard SD card driver. – fred basset Apr 26 '14 at 16:28
  • There is no "standard driver". There is standard core MMC/SD subsystem in linux kernel, and tens of controller drivers. Can you add some information to your question: exact ARM chip/SoC/board name (sd controller is built in SoC usually), the command which you want to send to SD card? Is it SDIO or SD card? Which version of SD standard is used by the card? – osgx Apr 26 '14 at 16:53
  • 1
    OK I'll refine my question when I get access to the board on Monday. – fred basset Apr 26 '14 at 21:59
  • thank you, additional information (exact command CMD56 aka vendor-specific GEN_CMD and TI docs) helped me to make right *web* search and to find `mmc-tools` and `MMC_IOC_CMD` generic MMC/SD ioctl to send short custom commands in linux. In windows there is similar `DeviceIoControl(drv_hdl, IOCTL_SFFDISK_DEVICE_COMMAND,` with `SDCMD_DESCRIPTOR sdCmdDescriptor` struct. – osgx Apr 28 '14 at 01:24

3 Answers3

10

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...
osgx
  • 90,338
  • 53
  • 357
  • 513
  • Thank you the detailed and expert response. I'll hopefully try this out this week. I'll sign this of as answered once I've tested it. – fred basset Apr 29 '14 at 03:30
  • 1
    I was finally able to get time to work on this and the CMD56 via mmc-utils approach worked. – fred basset May 17 '14 at 15:26
  • Fred, any chance you could put your mmc-utils fork up on github? – Brad Mar 31 '15 at 22:05
  • @fredbasset I saw you have tried above changes by osgx and it worked for you. Can you please help me to executed extcsd command and get ext-csd information for SD-card? Is it possible to do? Thanks – Dixit Jan 20 '21 at 06:27
-1

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

Ezio
  • 1,116
  • 4
  • 13
  • 25
  • Ezio, are you sure that is it possible to mmap IO memory of SD controller (which one, system MMC/SD port controller, or controller built into the SD card itself) to user-space in Linux? Are there any example of such mmap? Which command should we write to controller to send CMD56 to the SD card? – osgx Apr 28 '14 at 10:59
  • @osgx I am sure. though there is no example existing,but it's easy to do it yourself. – Ezio Apr 28 '14 at 12:37
  • Ezio, you already did this? Which file I should mmap? What offset? What write and where? – osgx Apr 28 '14 at 12:59
  • @osgx You may misunderstand my idea.In my opinion you mmap sd controller's address space to memory address(refer to man mmap) not a file.The offset and place to write is based on sd controller's data sheet (you can refer to sd card's driver) – Ezio Apr 28 '14 at 17:18
  • Ezio, How can I find the controller address space from user program? I know `man mmap`. But which file should I mmap and what offset? I think that your post is not real answer, and the post may be downvoted. – osgx Apr 29 '14 at 00:11
  • @osgx These can be got from the sd controller manufacturer's data sheet or their drivers. – Ezio Apr 29 '14 at 07:46
  • @Ezio - I'm still not seeing where this is going or how your answer is helpful. The microcontroller in the e.MMC part isn't externally accessible in the sense that its memory can just be mapped into the address space of a Linux process. – Julie in Austin Nov 30 '18 at 19:02
-1

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.