Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36f988e9 authored by Philip J Kelleher's avatar Philip J Kelleher Committed by Jens Axboe
Browse files

rsxx: Adding in debugfs entries.



Adding debugfs entries to help with debugging and testing and
testing code.

pci_regs:
       	This entry will spit out all of the data stored on the BAR.

stats:
       	This entry will display all of the driver stats for each
       	DMA channel.

cram:
	This will allow read/write ability to the CRAM address space
	on our adapter's CPU.

Signed-off-by: default avatarPhilip J Kelleher <pjk1939@linux.vnet.ibm.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 62302508
Loading
Loading
Loading
Loading
+275 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>

#include <linux/genhd.h>
#include <linux/idr.h>
@@ -58,6 +60,274 @@ MODULE_PARM_DESC(sync_start, "On by Default: Driver load will not complete "
static DEFINE_IDA(rsxx_disk_ida);
static DEFINE_SPINLOCK(rsxx_ida_lock);

/* --------------------Debugfs Setup ------------------- */

struct rsxx_cram {
	u32 f_pos;
	u32 offset;
	void *i_private;
};

static int rsxx_attr_pci_regs_show(struct seq_file *m, void *p)
{
	struct rsxx_cardinfo *card = m->private;

	seq_printf(m, "HWID		0x%08x\n",
					ioread32(card->regmap + HWID));
	seq_printf(m, "SCRATCH		0x%08x\n",
					ioread32(card->regmap + SCRATCH));
	seq_printf(m, "IER		0x%08x\n",
					ioread32(card->regmap + IER));
	seq_printf(m, "IPR		0x%08x\n",
					ioread32(card->regmap + IPR));
	seq_printf(m, "CREG_CMD		0x%08x\n",
					ioread32(card->regmap + CREG_CMD));
	seq_printf(m, "CREG_ADD		0x%08x\n",
					ioread32(card->regmap + CREG_ADD));
	seq_printf(m, "CREG_CNT		0x%08x\n",
					ioread32(card->regmap + CREG_CNT));
	seq_printf(m, "CREG_STAT	0x%08x\n",
					ioread32(card->regmap + CREG_STAT));
	seq_printf(m, "CREG_DATA0	0x%08x\n",
					ioread32(card->regmap + CREG_DATA0));
	seq_printf(m, "CREG_DATA1	0x%08x\n",
					ioread32(card->regmap + CREG_DATA1));
	seq_printf(m, "CREG_DATA2	0x%08x\n",
					ioread32(card->regmap + CREG_DATA2));
	seq_printf(m, "CREG_DATA3	0x%08x\n",
					ioread32(card->regmap + CREG_DATA3));
	seq_printf(m, "CREG_DATA4	0x%08x\n",
					ioread32(card->regmap + CREG_DATA4));
	seq_printf(m, "CREG_DATA5	0x%08x\n",
					ioread32(card->regmap + CREG_DATA5));
	seq_printf(m, "CREG_DATA6	0x%08x\n",
					ioread32(card->regmap + CREG_DATA6));
	seq_printf(m, "CREG_DATA7	0x%08x\n",
					ioread32(card->regmap + CREG_DATA7));
	seq_printf(m, "INTR_COAL	0x%08x\n",
					ioread32(card->regmap + INTR_COAL));
	seq_printf(m, "HW_ERROR		0x%08x\n",
					ioread32(card->regmap + HW_ERROR));
	seq_printf(m, "DEBUG0		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG0));
	seq_printf(m, "DEBUG1		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG1));
	seq_printf(m, "DEBUG2		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG2));
	seq_printf(m, "DEBUG3		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG3));
	seq_printf(m, "DEBUG4		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG4));
	seq_printf(m, "DEBUG5		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG5));
	seq_printf(m, "DEBUG6		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG6));
	seq_printf(m, "DEBUG7		0x%08x\n",
					ioread32(card->regmap + PCI_DEBUG7));
	seq_printf(m, "RECONFIG		0x%08x\n",
					ioread32(card->regmap + PCI_RECONFIG));

	return 0;
}

static int rsxx_attr_stats_show(struct seq_file *m, void *p)
{
	struct rsxx_cardinfo *card = m->private;
	int i;

	for (i = 0; i < card->n_targets; i++) {
		seq_printf(m, "Ctrl %d CRC Errors	= %d\n",
				i, card->ctrl[i].stats.crc_errors);
		seq_printf(m, "Ctrl %d Hard Errors	= %d\n",
				i, card->ctrl[i].stats.hard_errors);
		seq_printf(m, "Ctrl %d Soft Errors	= %d\n",
				i, card->ctrl[i].stats.soft_errors);
		seq_printf(m, "Ctrl %d Writes Issued	= %d\n",
				i, card->ctrl[i].stats.writes_issued);
		seq_printf(m, "Ctrl %d Writes Failed	= %d\n",
				i, card->ctrl[i].stats.writes_failed);
		seq_printf(m, "Ctrl %d Reads Issued	= %d\n",
				i, card->ctrl[i].stats.reads_issued);
		seq_printf(m, "Ctrl %d Reads Failed	= %d\n",
				i, card->ctrl[i].stats.reads_failed);
		seq_printf(m, "Ctrl %d Reads Retried	= %d\n",
				i, card->ctrl[i].stats.reads_retried);
		seq_printf(m, "Ctrl %d Discards Issued	= %d\n",
				i, card->ctrl[i].stats.discards_issued);
		seq_printf(m, "Ctrl %d Discards Failed	= %d\n",
				i, card->ctrl[i].stats.discards_failed);
		seq_printf(m, "Ctrl %d DMA SW Errors	= %d\n",
				i, card->ctrl[i].stats.dma_sw_err);
		seq_printf(m, "Ctrl %d DMA HW Faults	= %d\n",
				i, card->ctrl[i].stats.dma_hw_fault);
		seq_printf(m, "Ctrl %d DMAs Cancelled	= %d\n",
				i, card->ctrl[i].stats.dma_cancelled);
		seq_printf(m, "Ctrl %d SW Queue Depth	= %d\n",
				i, card->ctrl[i].stats.sw_q_depth);
		seq_printf(m, "Ctrl %d HW Queue Depth	= %d\n",
			i, atomic_read(&card->ctrl[i].stats.hw_q_depth));
	}

	return 0;
}

static int rsxx_attr_stats_open(struct inode *inode, struct file *file)
{
	return single_open(file, rsxx_attr_stats_show, inode->i_private);
}

static int rsxx_attr_pci_regs_open(struct inode *inode, struct file *file)
{
	return single_open(file, rsxx_attr_pci_regs_show, inode->i_private);
}

static ssize_t rsxx_cram_read(struct file *fp, char __user *ubuf,
			      size_t cnt, loff_t *ppos)
{
	struct rsxx_cram *info = fp->private_data;
	struct rsxx_cardinfo *card = info->i_private;
	char *buf;
	int st;

	buf = kzalloc(sizeof(*buf) * cnt, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	info->f_pos = (u32)*ppos + info->offset;

	st = rsxx_creg_read(card, CREG_ADD_CRAM + info->f_pos, cnt, buf, 1);
	if (st)
		return st;

	st = copy_to_user(ubuf, buf, cnt);
	if (st)
		return st;

	info->offset += cnt;

	kfree(buf);

	return cnt;
}

static ssize_t rsxx_cram_write(struct file *fp, const char __user *ubuf,
			       size_t cnt, loff_t *ppos)
{
	struct rsxx_cram *info = fp->private_data;
	struct rsxx_cardinfo *card = info->i_private;
	char *buf;
	int st;

	buf = kzalloc(sizeof(*buf) * cnt, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	st = copy_from_user(buf, ubuf, cnt);
	if (st)
		return st;

	info->f_pos = (u32)*ppos + info->offset;

	st = rsxx_creg_write(card, CREG_ADD_CRAM + info->f_pos, cnt, buf, 1);
	if (st)
		return st;

	info->offset += cnt;

	kfree(buf);

	return cnt;
}

static int rsxx_cram_open(struct inode *inode, struct file *file)
{
	struct rsxx_cram *info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->i_private = inode->i_private;
	info->f_pos = file->f_pos;
	file->private_data = info;

	return 0;
}

static int rsxx_cram_release(struct inode *inode, struct file *file)
{
	struct rsxx_cram *info = file->private_data;

	if (!info)
		return 0;

	kfree(info);
	file->private_data = NULL;

	return 0;
}

static const struct file_operations debugfs_cram_fops = {
	.owner		= THIS_MODULE,
	.open		= rsxx_cram_open,
	.read		= rsxx_cram_read,
	.write		= rsxx_cram_write,
	.release	= rsxx_cram_release,
};

static const struct file_operations debugfs_stats_fops = {
	.owner		= THIS_MODULE,
	.open		= rsxx_attr_stats_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static const struct file_operations debugfs_pci_regs_fops = {
	.owner		= THIS_MODULE,
	.open		= rsxx_attr_pci_regs_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static void rsxx_debugfs_dev_new(struct rsxx_cardinfo *card)
{
	struct dentry *debugfs_stats;
	struct dentry *debugfs_pci_regs;
	struct dentry *debugfs_cram;

	card->debugfs_dir = debugfs_create_dir(card->gendisk->disk_name, NULL);
	if (IS_ERR_OR_NULL(card->debugfs_dir))
		goto failed_debugfs_dir;

	debugfs_stats = debugfs_create_file("stats", S_IRUGO,
					    card->debugfs_dir, card,
					    &debugfs_stats_fops);
	if (IS_ERR_OR_NULL(debugfs_stats))
		goto failed_debugfs_stats;

	debugfs_pci_regs = debugfs_create_file("pci_regs", S_IRUGO,
					       card->debugfs_dir, card,
					       &debugfs_pci_regs_fops);
	if (IS_ERR_OR_NULL(debugfs_pci_regs))
		goto failed_debugfs_pci_regs;

	debugfs_cram = debugfs_create_file("cram", S_IRUGO | S_IWUSR,
					   card->debugfs_dir, card,
					   &debugfs_cram_fops);
	if (IS_ERR_OR_NULL(debugfs_cram))
		goto failed_debugfs_cram;

	return;
failed_debugfs_cram:
	debugfs_remove(debugfs_pci_regs);
failed_debugfs_pci_regs:
	debugfs_remove(debugfs_stats);
failed_debugfs_stats:
	debugfs_remove(card->debugfs_dir);
failed_debugfs_dir:
	card->debugfs_dir = NULL;
}

/*----------------- Interrupt Control & Handling -------------------*/

static void rsxx_mask_interrupts(struct rsxx_cardinfo *card)
@@ -741,6 +1011,9 @@ static int rsxx_pci_probe(struct pci_dev *dev,

	rsxx_attach_dev(card);

	/************* Setup Debugfs *************/
	rsxx_debugfs_dev_new(card);

	return 0;

failed_create_dev:
@@ -818,6 +1091,8 @@ static void rsxx_pci_remove(struct pci_dev *dev)
	/* Prevent work_structs from re-queuing themselves. */
	card->halt = 1;

	debugfs_remove_recursive(card->debugfs_dir);

	free_irq(dev->irq, card);

	if (!force_legacy)
+3 −0
Original line number Diff line number Diff line
@@ -185,6 +185,8 @@ struct rsxx_cardinfo {

	int			n_targets;
	struct rsxx_dma_ctrl	*ctrl;

	struct dentry		*debugfs_dir;
};

enum rsxx_pci_regmap {
@@ -287,6 +289,7 @@ enum rsxx_creg_addr {
	CREG_ADD_CAPABILITIES		= 0x80001050,
	CREG_ADD_LOG			= 0x80002000,
	CREG_ADD_NUM_TARGETS		= 0x80003000,
	CREG_ADD_CRAM			= 0xA0000000,
	CREG_ADD_CONFIG			= 0xB0000000,
};