diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-05 10:18:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-05 10:18:21 -0700 |
commit | 0a053e8c71d666daf30da2d407147b1293923d8b (patch) | |
tree | 9ba3967845db9053cb2ca045f01a9454eb5e6230 /drivers/mmc/core/debugfs.c | |
parent | 601cc11d054ae4b5e9b5babec3d8e4667a2cb9b5 (diff) | |
parent | 32ab83a56fdf42f543b86c349143c2a86ead9707 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: (42 commits)
atmel-mci: fix sdc_reg typo
tmio_mmc: add maintainer
mmc: Add OpenFirmware bindings for SDHCI driver
sdhci: Add quirk for forcing maximum block size to 2048 bytes
sdhci: Add quirk for controllers that need IRQ re-init after reset
sdhci: Add quirk for controllers that need small delays for PIO
sdhci: Add set_clock callback and a quirk for nonstandard clocks
sdhci: Add get_{max,timeout}_clock callbacks
sdhci: Add support for hosts reporting inverted write-protect state
sdhci: Add support for card-detection polling
sdhci: Enable only relevant (DMA/PIO) interrupts during transfers
sdhci: Split card-detection IRQs management from sdhci_init()
sdhci: Add support for bus-specific IO memory accessors
mmc_spi: adjust for delayed data token response
omap_hsmmc: Wait for SDBP
omap_hsmmc: Fix MMC3 dma
omap_hsmmc: Disable SDBP at suspend
omap_hsmmc: Do not prefix slot name
omap_hsmmc: Allow cover switch to cause rescan
omap_hsmmc: Add 8-bit bus width mode support
...
Diffstat (limited to 'drivers/mmc/core/debugfs.c')
-rw-r--r-- | drivers/mmc/core/debugfs.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 1237bb4c722..610dbd1fcc8 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -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: |