public inbox for linux-mmc@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro
@ 2009-11-06  2:49 Don Mullis
  2009-11-06  3:01 ` [PATCH 2.6.31-rc5 2/3] mmc: Clean up mmc_decode_scr() implementation Don Mullis
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Don Mullis @ 2009-11-06  2:49 UTC (permalink / raw)
  To: linux-mmc

Unify duplicated implementations of UNSTUFF_BITS() into a shared .h file.
Recode UNSTUFF_BITS() as an invocation of a new more general macro
UNSTUFF_BITS_ARRAY() that works on arrays of any multiple of 32 bits.

Signed-off-by: don.mullis@gmail.com
---
  drivers/mmc/core/core.h |   21 +++++++++++++++++++++
  drivers/mmc/core/mmc.c  |   14 --------------
  drivers/mmc/core/sd.c   |   14 --------------
  3 files changed, 21 insertions(+), 28 deletions(-)

Index: linux-2.6/drivers/mmc/core/sd.c
===================================================================
--- linux-2.6.orig/drivers/mmc/core/sd.c	2009-11-02 13:02:23.000000000 -0800
+++ linux-2.6/drivers/mmc/core/sd.c	2009-11-02 15:10:28.000000000 -0800
@@ -41,20 +41,6 @@ static const unsigned int tacc_mant[] =
  	35,	40,	45,	50,	55,	60,	70,	80,
  };

-#define UNSTUFF_BITS(resp,start,size)					\
-	({								\
-		const int __size = size;				\
-		const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;	\
-		const int __off = 3 - ((start) / 32);			\
-		const int __shft = (start) & 31;			\
-		u32 __res;						\
-									\
-		__res = resp[__off] >> __shft;				\
-		if (__size + __shft > 32)				\
-			__res |= resp[__off-1] << ((32 - __shft) % 32);	\
-		__res & __mask;						\
-	})
-
  /*
   * Given the decoded CSD structure, decode the raw CID to our CID structure.
   */
Index: linux-2.6/drivers/mmc/core/core.h
===================================================================
--- linux-2.6.orig/drivers/mmc/core/core.h	2009-11-02 13:02:23.000000000 -0800
+++ linux-2.6/drivers/mmc/core/core.h	2009-11-02 15:12:01.000000000 -0800
@@ -13,6 +13,27 @@

  #include <linux/delay.h>

+#define UNSTUFF_BITS_ARRAY(u32_array, start, size)			\
+	({								\
+		const int __size = size;				\
+		const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;	\
+		const int __off = (sizeof(u32_array)/4-1) - ((start) / 32); \
+		const int __shft = (start) & 31;			\
+		u32 __res;						\
+									\
+		__res = (u32_array)[__off] >> __shft;			\
+		if (__size + __shft > 32)				\
+			__res |= (u32_array)[__off-1]			\
+				<< ((32 - __shft) % 32); 		\
+		__res & __mask;						\
+	})
+
+/*
+ * Specific to 128-bit arrays, e.g. raw_cid[] and raw_csd[].
+ */
+#define UNSTUFF_BITS(resp, start, size)	\
+	UNSTUFF_BITS_ARRAY(*(u32(*)[4])resp, start, size)
+
  #define MMC_CMD_RETRIES        3

  struct mmc_bus_ops {
Index: linux-2.6/drivers/mmc/core/mmc.c
===================================================================
--- linux-2.6.orig/drivers/mmc/core/mmc.c	2009-11-02 13:02:23.000000000 -0800
+++ linux-2.6/drivers/mmc/core/mmc.c	2009-11-02 13:02:23.000000000 -0800
@@ -39,20 +39,6 @@ static const unsigned int tacc_mant[] =
  	35,	40,	45,	50,	55,	60,	70,	80,
  };

-#define UNSTUFF_BITS(resp,start,size)					\
-	({								\
-		const int __size = size;				\
-		const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;	\
-		const int __off = 3 - ((start) / 32);			\
-		const int __shft = (start) & 31;			\
-		u32 __res;						\
-									\
-		__res = resp[__off] >> __shft;				\
-		if (__size + __shft > 32)				\
-			__res |= resp[__off-1] << ((32 - __shft) % 32);	\
-		__res & __mask;						\
-	})
-
  /*
   * Given the decoded CSD structure, decode the raw CID to our CID structure.
   */





^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2.6.31-rc5 2/3] mmc: Clean up mmc_decode_scr() implementation
  2009-11-06  2:49 [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro Don Mullis
@ 2009-11-06  3:01 ` Don Mullis
  2009-11-06  3:03 ` [PATCH 2.6.31-rc5 3/3] mmc: Add SD_STATUS register dump to debugfs Don Mullis
  2009-11-06  3:17 ` [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro Don Mullis
  2 siblings, 0 replies; 4+ messages in thread
From: Don Mullis @ 2009-11-06  3:01 UTC (permalink / raw)
  To: linux-mmc

In mmc_decode_scr(), back out coercion of 128-bit-oriented
UNSTUFF_BITS() macro to work on 64-bit raw_scr field; invoke
UNSTUFF_BITS_ARRAY() instead.

Tested by verifying that /sys output for scr register is unchanged.

Signed-off-by: don.mullis@gmail.com
---
  drivers/mmc/core/sd.c |   10 +++-------
  1 file changed, 3 insertions(+), 7 deletions(-)

Index: linux-2.6/drivers/mmc/core/sd.c
===================================================================
--- linux-2.6.orig/drivers/mmc/core/sd.c	2009-09-29 12:50:36.000000000 -0700
+++ linux-2.6/drivers/mmc/core/sd.c	2009-11-01 22:30:37.000000000 -0800
@@ -163,20 +163,16 @@ static int mmc_decode_scr(struct mmc_car
  {
  	struct sd_scr *scr = &card->scr;
  	unsigned int scr_struct;
-	u32 resp[4];

-	resp[3] = card->raw_scr[1];
-	resp[2] = card->raw_scr[0];
-
-	scr_struct = UNSTUFF_BITS(resp, 60, 4);
+	scr_struct = UNSTUFF_BITS_ARRAY(card->raw_scr, 60, 4);
  	if (scr_struct != 0) {
  		printk(KERN_ERR "%s: unrecognised SCR structure version %d\n",
  			mmc_hostname(card->host), scr_struct);
  		return -EINVAL;
  	}

-	scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
-	scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
+	scr->sda_vsn =    UNSTUFF_BITS_ARRAY(card->raw_scr, 56, 4);
+	scr->bus_widths = UNSTUFF_BITS_ARRAY(card->raw_scr, 48, 4);

  	return 0;
  }







^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2.6.31-rc5 3/3] mmc: Add SD_STATUS register dump to debugfs
  2009-11-06  2:49 [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro Don Mullis
  2009-11-06  3:01 ` [PATCH 2.6.31-rc5 2/3] mmc: Clean up mmc_decode_scr() implementation Don Mullis
@ 2009-11-06  3:03 ` Don Mullis
  2009-11-06  3:17 ` [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro Don Mullis
  2 siblings, 0 replies; 4+ messages in thread
From: Don Mullis @ 2009-11-06  3:03 UTC (permalink / raw)
  To: linux-mmc

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@gmail.com
---
  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:






^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro
  2009-11-06  2:49 [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro Don Mullis
  2009-11-06  3:01 ` [PATCH 2.6.31-rc5 2/3] mmc: Clean up mmc_decode_scr() implementation Don Mullis
  2009-11-06  3:03 ` [PATCH 2.6.31-rc5 3/3] mmc: Add SD_STATUS register dump to debugfs Don Mullis
@ 2009-11-06  3:17 ` Don Mullis
  2 siblings, 0 replies; 4+ messages in thread
From: Don Mullis @ 2009-11-06  3:17 UTC (permalink / raw)
  To: linux-mmc

Based on a too-old kernel version.  Will rebase, test and repost the series.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-11-06  3:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-06  2:49 [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro Don Mullis
2009-11-06  3:01 ` [PATCH 2.6.31-rc5 2/3] mmc: Clean up mmc_decode_scr() implementation Don Mullis
2009-11-06  3:03 ` [PATCH 2.6.31-rc5 3/3] mmc: Add SD_STATUS register dump to debugfs Don Mullis
2009-11-06  3:17 ` [PATCH 2.6.31-rc5 1/3] mmc: Unify and generalize UNSTUFF_BITS macro Don Mullis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox