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?
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With