diff options
author | Asai Thambi S P <asamymuthupa@micron.com> | 2012-06-04 15:44:02 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-06-05 03:13:49 -0400 |
commit | 7b421d24eac79800ee68905f732300a291f72f00 (patch) | |
tree | 69e8477147e8f4013f1ea71ea23c9d76cc70d8aa /drivers/block/mtip32xx/mtip32xx.c | |
parent | 7412ff139d73f5561492478e89a22aede7252b7b (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/mtip32xx/mtip32xx.c')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 162 |
1 files changed, 161 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 | */ |
87 | static int mtip_major; | 88 | static int mtip_major; |
89 | static struct dentry *dfs_parent; | ||
88 | 90 | ||
89 | static DEFINE_SPINLOCK(rssd_index_lock); | 91 | static DEFINE_SPINLOCK(rssd_index_lock); |
90 | static DEFINE_IDA(rssd_index_ida); | 92 | static DEFINE_IDA(rssd_index_ida); |
@@ -2574,6 +2576,120 @@ static ssize_t mtip_hw_show_status(struct device *dev, | |||
2574 | 2576 | ||
2575 | static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); | 2577 | static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); |
2576 | 2578 | ||
2579 | static 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 | |||
2653 | static 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 | |||
2679 | static 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 | |||
2686 | static 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 | ||
2734 | static 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 | |||
2756 | static 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 | ||
3667 | kthread_run_error: | 3812 | kthread_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 | */ |
4083 | static void __exit mtip_exit(void) | 4241 | static 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 | ||