|
@@ -184,6 +184,68 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
|
|
|
DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
|
|
|
NULL, "%08llx\n");
|
|
|
|
|
|
+#define EXT_CSD_STR_LEN 1025
|
|
|
+
|
|
|
+static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
|
|
|
+{
|
|
|
+ struct mmc_card *card = inode->i_private;
|
|
|
+ char *buf;
|
|
|
+ ssize_t n = 0;
|
|
|
+ u8 *ext_csd;
|
|
|
+ int err, i;
|
|
|
+
|
|
|
+ buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
|
|
|
+ if (!buf)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ ext_csd = kmalloc(512, GFP_KERNEL);
|
|
|
+ if (!ext_csd) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto out_free;
|
|
|
+ }
|
|
|
+
|
|
|
+ mmc_claim_host(card->host);
|
|
|
+ err = mmc_send_ext_csd(card, ext_csd);
|
|
|
+ mmc_release_host(card->host);
|
|
|
+ if (err)
|
|
|
+ goto out_free;
|
|
|
+
|
|
|
+ for (i = 511; i >= 0; i--)
|
|
|
+ n += sprintf(buf + n, "%02x", ext_csd[i]);
|
|
|
+ n += sprintf(buf + n, "\n");
|
|
|
+ BUG_ON(n != EXT_CSD_STR_LEN);
|
|
|
+
|
|
|
+ filp->private_data = buf;
|
|
|
+ kfree(ext_csd);
|
|
|
+ return 0;
|
|
|
+
|
|
|
+out_free:
|
|
|
+ kfree(buf);
|
|
|
+ kfree(ext_csd);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t mmc_ext_csd_read(struct file *filp, char __user *ubuf,
|
|
|
+ size_t cnt, loff_t *ppos)
|
|
|
+{
|
|
|
+ char *buf = filp->private_data;
|
|
|
+
|
|
|
+ return simple_read_from_buffer(ubuf, cnt, ppos,
|
|
|
+ buf, EXT_CSD_STR_LEN);
|
|
|
+}
|
|
|
+
|
|
|
+static int mmc_ext_csd_release(struct inode *inode, struct file *file)
|
|
|
+{
|
|
|
+ kfree(file->private_data);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct file_operations mmc_dbg_ext_csd_fops = {
|
|
|
+ .open = mmc_ext_csd_open,
|
|
|
+ .read = mmc_ext_csd_read,
|
|
|
+ .release = mmc_ext_csd_release,
|
|
|
+};
|
|
|
+
|
|
|
void mmc_add_card_debugfs(struct mmc_card *card)
|
|
|
{
|
|
|
struct mmc_host *host = card->host;
|
|
@@ -211,6 +273,11 @@ void mmc_add_card_debugfs(struct mmc_card *card)
|
|
|
&mmc_dbg_card_status_fops))
|
|
|
goto err;
|
|
|
|
|
|
+ if (mmc_card_mmc(card))
|
|
|
+ if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
|
|
|
+ &mmc_dbg_ext_csd_fops))
|
|
|
+ goto err;
|
|
|
+
|
|
|
return;
|
|
|
|
|
|
err:
|