aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAsai Thambi S P <asamymuthupa@micron.com>2012-06-04 15:44:02 -0400
committerJens Axboe <axboe@kernel.dk>2012-06-05 03:13:49 -0400
commit7b421d24eac79800ee68905f732300a291f72f00 (patch)
tree69e8477147e8f4013f1ea71ea23c9d76cc70d8aa /drivers/block
parent7412ff139d73f5561492478e89a22aede7252b7b (diff)
mtip32xx: Create debugfs entries for troubleshooting
On module load, creates a debugfs parent 'rssd' in debugfs root. Then for each device, create a new node with corresponding disk name. Under the new node, two entries 'registers' and 'flags' are created. NOTE: These entries were removed from sysfs in the previous patch Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c162
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h4
2 files changed, 165 insertions, 1 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index b6e95b911b8c..a8fddeb3d638 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -37,6 +37,7 @@
37#include <linux/kthread.h> 37#include <linux/kthread.h>
38#include <../drivers/ata/ahci.h> 38#include <../drivers/ata/ahci.h>
39#include <linux/export.h> 39#include <linux/export.h>
40#include <linux/debugfs.h>
40#include "mtip32xx.h" 41#include "mtip32xx.h"
41 42
42#define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) 43#define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32)
@@ -85,6 +86,7 @@ static int instance;
85 * allocated in mtip_init(). 86 * allocated in mtip_init().
86 */ 87 */
87static int mtip_major; 88static int mtip_major;
89static struct dentry *dfs_parent;
88 90
89static DEFINE_SPINLOCK(rssd_index_lock); 91static DEFINE_SPINLOCK(rssd_index_lock);
90static DEFINE_IDA(rssd_index_ida); 92static DEFINE_IDA(rssd_index_ida);
@@ -2574,6 +2576,120 @@ static ssize_t mtip_hw_show_status(struct device *dev,
2574 2576
2575static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); 2577static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
2576 2578
2579static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf,
2580 size_t len, loff_t *offset)
2581{
2582 struct driver_data *dd = (struct driver_data *)f->private_data;
2583 char buf[MTIP_DFS_MAX_BUF_SIZE];
2584 u32 group_allocated;
2585 int size = *offset;
2586 int n;
2587
2588 if (!len || size)
2589 return 0;
2590
2591 if (size < 0)
2592 return -EINVAL;
2593
2594 size += sprintf(&buf[size], "H/ S ACTive : [ 0x");
2595
2596 for (n = dd->slot_groups-1; n >= 0; n--)
2597 size += sprintf(&buf[size], "%08X ",
2598 readl(dd->port->s_active[n]));
2599
2600 size += sprintf(&buf[size], "]\n");
2601 size += sprintf(&buf[size], "H/ Command Issue : [ 0x");
2602
2603 for (n = dd->slot_groups-1; n >= 0; n--)
2604 size += sprintf(&buf[size], "%08X ",
2605 readl(dd->port->cmd_issue[n]));
2606
2607 size += sprintf(&buf[size], "]\n");
2608 size += sprintf(&buf[size], "H/ Completed : [ 0x");
2609
2610 for (n = dd->slot_groups-1; n >= 0; n--)
2611 size += sprintf(&buf[size], "%08X ",
2612 readl(dd->port->completed[n]));
2613
2614 size += sprintf(&buf[size], "]\n");
2615 size += sprintf(&buf[size], "H/ PORT IRQ STAT : [ 0x%08X ]\n",
2616 readl(dd->port->mmio + PORT_IRQ_STAT));
2617 size += sprintf(&buf[size], "H/ HOST IRQ STAT : [ 0x%08X ]\n",
2618 readl(dd->mmio + HOST_IRQ_STAT));
2619 size += sprintf(&buf[size], "\n");
2620
2621 size += sprintf(&buf[size], "L/ Allocated : [ 0x");
2622
2623 for (n = dd->slot_groups-1; n >= 0; n--) {
2624 if (sizeof(long) > sizeof(u32))
2625 group_allocated =
2626 dd->port->allocated[n/2] >> (32*(n&1));
2627 else
2628 group_allocated = dd->port->allocated[n];
2629 size += sprintf(&buf[size], "%08X ", group_allocated);
2630 }
2631 size += sprintf(&buf[size], "]\n");
2632
2633 size += sprintf(&buf[size], "L/ Commands in Q : [ 0x");
2634
2635 for (n = dd->slot_groups-1; n >= 0; n--) {
2636 if (sizeof(long) > sizeof(u32))
2637 group_allocated =
2638 dd->port->cmds_to_issue[n/2] >> (32*(n&1));
2639 else
2640 group_allocated = dd->port->cmds_to_issue[n];
2641 size += sprintf(&buf[size], "%08X ", group_allocated);
2642 }
2643 size += sprintf(&buf[size], "]\n");
2644
2645 *offset = size <= len ? size : len;
2646 size = copy_to_user(ubuf, buf, *offset);
2647 if (size)
2648 return -EFAULT;
2649
2650 return *offset;
2651}
2652
2653static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf,
2654 size_t len, loff_t *offset)
2655{
2656 struct driver_data *dd = (struct driver_data *)f->private_data;
2657 char buf[MTIP_DFS_MAX_BUF_SIZE];
2658 int size = *offset;
2659
2660 if (!len || size)
2661 return 0;
2662
2663 if (size < 0)
2664 return -EINVAL;
2665
2666 size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n",
2667 dd->port->flags);
2668 size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n",
2669 dd->dd_flag);
2670
2671 *offset = size <= len ? size : len;
2672 size = copy_to_user(ubuf, buf, *offset);
2673 if (size)
2674 return -EFAULT;
2675
2676 return *offset;
2677}
2678
2679static const struct file_operations mtip_regs_fops = {
2680 .owner = THIS_MODULE,
2681 .open = simple_open,
2682 .read = mtip_hw_read_registers,
2683 .llseek = no_llseek,
2684};
2685
2686static const struct file_operations mtip_flags_fops = {
2687 .owner = THIS_MODULE,
2688 .open = simple_open,
2689 .read = mtip_hw_read_flags,
2690 .llseek = no_llseek,
2691};
2692
2577/* 2693/*
2578 * Create the sysfs related attributes. 2694 * Create the sysfs related attributes.
2579 * 2695 *
@@ -2615,6 +2731,34 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj)
2615 return 0; 2731 return 0;
2616} 2732}
2617 2733
2734static int mtip_hw_debugfs_init(struct driver_data *dd)
2735{
2736 if (!dfs_parent)
2737 return -1;
2738
2739 dd->dfs_node = debugfs_create_dir(dd->disk->disk_name, dfs_parent);
2740 if (IS_ERR_OR_NULL(dd->dfs_node)) {
2741 dev_warn(&dd->pdev->dev,
2742 "Error creating node %s under debugfs\n",
2743 dd->disk->disk_name);
2744 dd->dfs_node = NULL;
2745 return -1;
2746 }
2747
2748 debugfs_create_file("flags", S_IRUGO, dd->dfs_node, dd,
2749 &mtip_flags_fops);
2750 debugfs_create_file("registers", S_IRUGO, dd->dfs_node, dd,
2751 &mtip_regs_fops);
2752
2753 return 0;
2754}
2755
2756static void mtip_hw_debugfs_exit(struct driver_data *dd)
2757{
2758 debugfs_remove_recursive(dd->dfs_node);
2759}
2760
2761
2618/* 2762/*
2619 * Perform any init/resume time hardware setup 2763 * Perform any init/resume time hardware setup
2620 * 2764 *
@@ -3640,6 +3784,7 @@ skip_create_disk:
3640 mtip_hw_sysfs_init(dd, kobj); 3784 mtip_hw_sysfs_init(dd, kobj);
3641 kobject_put(kobj); 3785 kobject_put(kobj);
3642 } 3786 }
3787 mtip_hw_debugfs_init(dd);
3643 3788
3644 if (dd->mtip_svc_handler) { 3789 if (dd->mtip_svc_handler) {
3645 set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); 3790 set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
@@ -3665,6 +3810,8 @@ start_service_thread:
3665 return rv; 3810 return rv;
3666 3811
3667kthread_run_error: 3812kthread_run_error:
3813 mtip_hw_debugfs_exit(dd);
3814
3668 /* Delete our gendisk. This also removes the device from /dev */ 3815 /* Delete our gendisk. This also removes the device from /dev */
3669 del_gendisk(dd->disk); 3816 del_gendisk(dd->disk);
3670 3817
@@ -3715,6 +3862,7 @@ static int mtip_block_remove(struct driver_data *dd)
3715 kobject_put(kobj); 3862 kobject_put(kobj);
3716 } 3863 }
3717 } 3864 }
3865 mtip_hw_debugfs_exit(dd);
3718 3866
3719 /* 3867 /*
3720 * Delete our gendisk structure. This also removes the device 3868 * Delete our gendisk structure. This also removes the device
@@ -4062,10 +4210,20 @@ static int __init mtip_init(void)
4062 } 4210 }
4063 mtip_major = error; 4211 mtip_major = error;
4064 4212
4213 if (!dfs_parent) {
4214 dfs_parent = debugfs_create_dir("rssd", NULL);
4215 if (IS_ERR_OR_NULL(dfs_parent)) {
4216 printk(KERN_WARNING "Error creating debugfs parent\n");
4217 dfs_parent = NULL;
4218 }
4219 }
4220
4065 /* Register our PCI operations. */ 4221 /* Register our PCI operations. */
4066 error = pci_register_driver(&mtip_pci_driver); 4222 error = pci_register_driver(&mtip_pci_driver);
4067 if (error) 4223 if (error) {
4224 debugfs_remove(dfs_parent);
4068 unregister_blkdev(mtip_major, MTIP_DRV_NAME); 4225 unregister_blkdev(mtip_major, MTIP_DRV_NAME);
4226 }
4069 4227
4070 return error; 4228 return error;
4071} 4229}
@@ -4082,6 +4240,8 @@ static int __init mtip_init(void)
4082 */ 4240 */
4083static void __exit mtip_exit(void) 4241static void __exit mtip_exit(void)
4084{ 4242{
4243 debugfs_remove_recursive(dfs_parent);
4244
4085 /* Release the allocated major block device number. */ 4245 /* Release the allocated major block device number. */
4086 unregister_blkdev(mtip_major, MTIP_DRV_NAME); 4246 unregister_blkdev(mtip_major, MTIP_DRV_NAME);
4087 4247
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index adb1aae3b752..f51fc23d17bb 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -110,6 +110,8 @@
110 #define dbg_printk(format, arg...) 110 #define dbg_printk(format, arg...)
111#endif 111#endif
112 112
113#define MTIP_DFS_MAX_BUF_SIZE 1024
114
113#define __force_bit2int (unsigned int __force) 115#define __force_bit2int (unsigned int __force)
114 116
115enum { 117enum {
@@ -446,6 +448,8 @@ struct driver_data {
446 unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ 448 unsigned long dd_flag; /* NOTE: use atomic bit operations on this */
447 449
448 struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ 450 struct task_struct *mtip_svc_handler; /* task_struct of svc thd */
451
452 struct dentry *dfs_node;
449}; 453};
450 454
451#endif 455#endif