[PATCH 2.6.31-rc5 3/3] mmc: Add SD_STATUS register dump to debugfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a file to debugfs to read back the SD_STATUS register from an SD
card.  SD_STATUS contains performance-related information.

Signed-off-by: don.mullis@xxxxxxxxx
---
 drivers/mmc/core/debugfs.c |   56 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/core/sd_ops.c  |   51 ++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/core/sd_ops.h  |    1
 include/linux/mmc/sd.h     |    1
 4 files changed, 109 insertions(+)

Index: linux-2.6/drivers/mmc/core/sd_ops.c
===================================================================
--- linux-2.6.orig/drivers/mmc/core/sd_ops.c	2009-11-02 15:10:28.000000000 -0800
+++ linux-2.6/drivers/mmc/core/sd_ops.c	2009-11-02 15:19:01.000000000 -0800
@@ -299,6 +299,57 @@ int mmc_app_send_scr(struct mmc_card *ca
 	return 0;
 }

+int mmc_send_sd_status(struct mmc_card *card, u32 *sd_status)
+{
+	int err;
+	struct mmc_request mrq;
+	struct mmc_command cmd;
+	struct mmc_data data;
+	struct scatterlist sg;
+	int i;
+
+	BUG_ON(!card);
+	BUG_ON(!card->host);
+	BUG_ON(!sd_status);
+
+	err = mmc_app_cmd(card->host, card);
+	if (err)
+		return err;
+
+	memset(&mrq, 0, sizeof(struct mmc_request));
+	memset(&cmd, 0, sizeof(struct mmc_command));
+	memset(&data, 0, sizeof(struct mmc_data));
+
+	mrq.cmd = &cmd;
+	mrq.data = &data;
+
+	cmd.opcode = SD_APP_SEND_SD_STATUS;
+	cmd.arg = 0;  /* not used */
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+
+	data.blksz = 16*sizeof(u32);
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+	data.sg = &sg;
+	data.sg_len = 1;
+
+	sg_init_one(&sg, sd_status, 16*sizeof(u32));
+
+	mmc_set_data_timeout(&data, card);
+
+	mmc_wait_for_req(card->host, &mrq);
+
+	if (cmd.error)
+		return cmd.error;
+	if (data.error)
+		return data.error;
+
+	for (i = 0; i < 16; i++)
+		sd_status[i] = be32_to_cpu(sd_status[i]);
+
+	return 0;
+}
+
 int mmc_sd_switch(struct mmc_card *card, int mode, int group,
 	u8 value, u8 *resp)
 {
Index: linux-2.6/drivers/mmc/core/sd_ops.h
===================================================================
--- linux-2.6.orig/drivers/mmc/core/sd_ops.h	2009-11-02 15:10:28.000000000 -0800
+++ linux-2.6/drivers/mmc/core/sd_ops.h	2009-11-02 15:19:01.000000000 -0800
@@ -13,6 +13,7 @@
 #define _MMC_SD_OPS_H

 int mmc_app_set_bus_width(struct mmc_card *card, int width);
+int mmc_send_sd_status(struct mmc_card *card, u32 *sd_status);
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr);
 int mmc_send_if_cond(struct mmc_host *host, u32 ocr);
 int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca);
Index: linux-2.6/include/linux/mmc/sd.h
===================================================================
--- linux-2.6.orig/include/linux/mmc/sd.h	2009-11-02 15:10:28.000000000 -0800
+++ linux-2.6/include/linux/mmc/sd.h	2009-11-02 15:19:01.000000000 -0800
@@ -26,6 +26,7 @@
 #define SD_APP_SEND_NUM_WR_BLKS  22   /* adtc                    R1  */
 #define SD_APP_OP_COND           41   /* bcr  [31:0] OCR         R3  */
 #define SD_APP_SEND_SCR          51   /* adtc                    R1  */
+#define SD_APP_SEND_SD_STATUS    13   /* adtc                    R1  */

 /*
  * SD_SWITCH argument format:
Index: linux-2.6/drivers/mmc/core/debugfs.c
===================================================================
--- linux-2.6.orig/drivers/mmc/core/debugfs.c	2009-11-02 15:10:28.000000000 -0800
+++ linux-2.6/drivers/mmc/core/debugfs.c	2009-11-03 12:29:23.000000000 -0800
@@ -17,6 +17,7 @@

 #include "core.h"
 #include "mmc_ops.h"
+#include "sd_ops.h"

 /* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */
 static int mmc_ios_show(struct seq_file *s, void *data)
@@ -246,6 +247,56 @@ static struct file_operations mmc_dbg_ex
 	.release	= mmc_ext_csd_release,
 };

+static int mmc_card_sd_status_show(struct seq_file *s, void *data)
+{
+	struct mmc_card	*card = s->private;
+	u32		sd_status[16];
+	int		ret;
+
+	mmc_claim_host(card->host);
+
+	/*
+	 * Fields as defined in the Simplified SD Spec, available from
+	 * http://www.sdcard.org/developers/tech/sdcard/pls/
+	 */
+	ret = mmc_send_sd_status(card, sd_status);
+	if (!ret) {
+		int i;
+		const int WIDTH = 24;
+
+		for (i = 0; i < 16; i++)
+			seq_printf(s, "%3d: %8x\n", 511-i*32, sd_status[i]);
+		seq_printf(s, "\n");
+
+		seq_printf(s, "%-*s %d\n", WIDTH, "SPEED_CLASS:",
+			UNSTUFF_BITS_ARRAY(sd_status, 440, 8)*2);
+		seq_printf(s, "%-*s %01x\n", WIDTH, "PERFORMANCE_MOVE (MB/s):",
+			UNSTUFF_BITS_ARRAY(sd_status, 432, 8));
+		seq_printf(s, "%-*s %01x\n", WIDTH, "AU_SIZE (kB):",
+			(1<<(UNSTUFF_BITS_ARRAY(sd_status, 428, 4)-1))*16);
+		seq_printf(s, "%-*s %d\n", WIDTH, "ERASE_SIZE (AU):",
+			UNSTUFF_BITS_ARRAY(sd_status, 408, 16));
+		seq_printf(s, "%-*s %d\n", WIDTH, "ERASE_TIMEOUT (sec):",
+			UNSTUFF_BITS_ARRAY(sd_status, 402, 6));
+	}
+
+	mmc_release_host(card->host);
+
+	return ret;
+}
+
+static int mmc_card_sd_status_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mmc_card_sd_status_show, inode->i_private);
+}
+
+static const struct file_operations mmc_dbg_card_sd_status_fops = {
+	.open		= mmc_card_sd_status_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 void mmc_add_card_debugfs(struct mmc_card *card)
 {
 	struct mmc_host	*host = card->host;
@@ -278,6 +329,11 @@ void mmc_add_card_debugfs(struct mmc_car
 					&mmc_dbg_ext_csd_fops))
 			goto err;

+	if (mmc_card_sd(card))
+		if (!debugfs_create_file("sd_status", S_IRUSR, root, card,
+					&mmc_dbg_card_sd_status_fops))
+			goto err;
+
 	return;

 err:





--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux