aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTony Jones <tonyj@suse.de>2007-09-11 17:07:31 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 17:34:53 -0500
commit694cc2087e26f3f62b9f07c5d563564ed77ef203 (patch)
tree326a7d623aebef0f64379af1fa838adf60e9d028 /drivers
parent684c19e0d95f4640998a358a34226115a34b5eea (diff)
USB: convert ehci debug files to use debugfs instead of sysfs
We should not have multiple line files in sysfs, this moves the data to debugfs instead, like the UHCI driver. Signed-off-by: Tony Jones <tonyj@suse.de> Cc: Kay Sievers <kay.sievers@vrfy.org> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ehci-dbg.c227
-rw-r--r--drivers/usb/host/ehci-hcd.c25
-rw-r--r--drivers/usb/host/ehci.h8
3 files changed, 219 insertions, 41 deletions
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 754a146cf828..39673f8194d9 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -323,7 +323,43 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }
323 323
324#else 324#else
325 325
326/* troubleshooting help: expose state in sysfs */ 326/* troubleshooting help: expose state in debugfs */
327
328static int debug_async_open(struct inode *, struct file *);
329static int debug_periodic_open(struct inode *, struct file *);
330static int debug_registers_open(struct inode *, struct file *);
331static int debug_async_open(struct inode *, struct file *);
332static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
333static int debug_close(struct inode *, struct file *);
334
335static const struct file_operations debug_async_fops = {
336 .owner = THIS_MODULE,
337 .open = debug_async_open,
338 .read = debug_output,
339 .release = debug_close,
340};
341static const struct file_operations debug_periodic_fops = {
342 .owner = THIS_MODULE,
343 .open = debug_periodic_open,
344 .read = debug_output,
345 .release = debug_close,
346};
347static const struct file_operations debug_registers_fops = {
348 .owner = THIS_MODULE,
349 .open = debug_registers_open,
350 .read = debug_output,
351 .release = debug_close,
352};
353
354static struct dentry *ehci_debug_root;
355
356struct debug_buffer {
357 ssize_t (*fill_func)(struct debug_buffer *); /* fill method */
358 struct usb_bus *bus;
359 struct mutex mutex; /* protect filling of buffer */
360 size_t count; /* number of characters filled into buffer */
361 char *page;
362};
327 363
328#define speed_char(info1) ({ char tmp; \ 364#define speed_char(info1) ({ char tmp; \
329 switch (info1 & (3 << 12)) { \ 365 switch (info1 & (3 << 12)) { \
@@ -441,10 +477,8 @@ done:
441 *nextp = next; 477 *nextp = next;
442} 478}
443 479
444static ssize_t 480static ssize_t fill_async_buffer(struct debug_buffer *buf)
445show_async(struct device *dev, struct device_attribute *attr, char *buf)
446{ 481{
447 struct usb_bus *bus;
448 struct usb_hcd *hcd; 482 struct usb_hcd *hcd;
449 struct ehci_hcd *ehci; 483 struct ehci_hcd *ehci;
450 unsigned long flags; 484 unsigned long flags;
@@ -452,14 +486,13 @@ show_async(struct device *dev, struct device_attribute *attr, char *buf)
452 char *next; 486 char *next;
453 struct ehci_qh *qh; 487 struct ehci_qh *qh;
454 488
455 *buf = 0; 489 hcd = bus_to_hcd(buf->bus);
456
457 bus = dev_get_drvdata(dev);
458 hcd = bus_to_hcd(bus);
459 ehci = hcd_to_ehci (hcd); 490 ehci = hcd_to_ehci (hcd);
460 next = buf; 491 next = buf->page;
461 size = PAGE_SIZE; 492 size = PAGE_SIZE;
462 493
494 *next = 0;
495
463 /* dumps a snapshot of the async schedule. 496 /* dumps a snapshot of the async schedule.
464 * usually empty except for long-term bulk reads, or head. 497 * usually empty except for long-term bulk reads, or head.
465 * one QH per line, and TDs we know about 498 * one QH per line, and TDs we know about
@@ -477,16 +510,12 @@ show_async(struct device *dev, struct device_attribute *attr, char *buf)
477 } 510 }
478 spin_unlock_irqrestore (&ehci->lock, flags); 511 spin_unlock_irqrestore (&ehci->lock, flags);
479 512
480 return strlen (buf); 513 return strlen(buf->page);
481} 514}
482static DEVICE_ATTR(async, S_IRUGO, show_async, NULL);
483 515
484#define DBG_SCHED_LIMIT 64 516#define DBG_SCHED_LIMIT 64
485 517static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
486static ssize_t
487show_periodic(struct device *dev, struct device_attribute *attr, char *buf)
488{ 518{
489 struct usb_bus *bus;
490 struct usb_hcd *hcd; 519 struct usb_hcd *hcd;
491 struct ehci_hcd *ehci; 520 struct ehci_hcd *ehci;
492 unsigned long flags; 521 unsigned long flags;
@@ -500,10 +529,9 @@ show_periodic(struct device *dev, struct device_attribute *attr, char *buf)
500 return 0; 529 return 0;
501 seen_count = 0; 530 seen_count = 0;
502 531
503 bus = dev_get_drvdata(dev); 532 hcd = bus_to_hcd(buf->bus);
504 hcd = bus_to_hcd(bus);
505 ehci = hcd_to_ehci (hcd); 533 ehci = hcd_to_ehci (hcd);
506 next = buf; 534 next = buf->page;
507 size = PAGE_SIZE; 535 size = PAGE_SIZE;
508 536
509 temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size); 537 temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size);
@@ -623,14 +651,10 @@ show_periodic(struct device *dev, struct device_attribute *attr, char *buf)
623 651
624 return PAGE_SIZE - size; 652 return PAGE_SIZE - size;
625} 653}
626static DEVICE_ATTR(periodic, S_IRUGO, show_periodic, NULL);
627
628#undef DBG_SCHED_LIMIT 654#undef DBG_SCHED_LIMIT
629 655
630static ssize_t 656static ssize_t fill_registers_buffer(struct debug_buffer *buf)
631show_registers(struct device *dev, struct device_attribute *attr, char *buf)
632{ 657{
633 struct usb_bus *bus;
634 struct usb_hcd *hcd; 658 struct usb_hcd *hcd;
635 struct ehci_hcd *ehci; 659 struct ehci_hcd *ehci;
636 unsigned long flags; 660 unsigned long flags;
@@ -639,15 +663,14 @@ show_registers(struct device *dev, struct device_attribute *attr, char *buf)
639 static char fmt [] = "%*s\n"; 663 static char fmt [] = "%*s\n";
640 static char label [] = ""; 664 static char label [] = "";
641 665
642 bus = dev_get_drvdata(dev); 666 hcd = bus_to_hcd(buf->bus);
643 hcd = bus_to_hcd(bus);
644 ehci = hcd_to_ehci (hcd); 667 ehci = hcd_to_ehci (hcd);
645 next = buf; 668 next = buf->page;
646 size = PAGE_SIZE; 669 size = PAGE_SIZE;
647 670
648 spin_lock_irqsave (&ehci->lock, flags); 671 spin_lock_irqsave (&ehci->lock, flags);
649 672
650 if (bus->controller->power.power_state.event) { 673 if (buf->bus->controller->power.power_state.event) {
651 size = scnprintf (next, size, 674 size = scnprintf (next, size,
652 "bus %s, device %s (driver " DRIVER_VERSION ")\n" 675 "bus %s, device %s (driver " DRIVER_VERSION ")\n"
653 "%s\n" 676 "%s\n"
@@ -789,26 +812,150 @@ done:
789 812
790 return PAGE_SIZE - size; 813 return PAGE_SIZE - size;
791} 814}
792static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
793 815
794static inline void create_debug_files (struct ehci_hcd *ehci) 816static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
817 ssize_t (*fill_func)(struct debug_buffer *))
795{ 818{
796 struct device *dev = ehci_to_hcd(ehci)->self.dev; 819 struct debug_buffer *buf;
797 int retval; 820
821 buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
798 822
799 retval = device_create_file(dev, &dev_attr_async); 823 if (buf) {
800 retval = device_create_file(dev, &dev_attr_periodic); 824 buf->bus = bus;
801 retval = device_create_file(dev, &dev_attr_registers); 825 buf->fill_func = fill_func;
826 mutex_init(&buf->mutex);
827 }
828
829 return buf;
802} 830}
803 831
804static inline void remove_debug_files (struct ehci_hcd *ehci) 832static int fill_buffer(struct debug_buffer *buf)
805{ 833{
806 struct device *dev = ehci_to_hcd(ehci)->self.dev; 834 int ret = 0;
835
836 if (!buf->page)
837 buf->page = (char *)get_zeroed_page(GFP_KERNEL);
838
839 if (!buf->page) {
840 ret = -ENOMEM;
841 goto out;
842 }
843
844 ret = buf->fill_func(buf);
807 845
808 device_remove_file(dev, &dev_attr_async); 846 if (ret >= 0) {
809 device_remove_file(dev, &dev_attr_periodic); 847 buf->count = ret;
810 device_remove_file(dev, &dev_attr_registers); 848 ret = 0;
849 }
850
851out:
852 return ret;
811} 853}
812 854
813#endif /* STUB_DEBUG_FILES */ 855static ssize_t debug_output(struct file *file, char __user *user_buf,
856 size_t len, loff_t *offset)
857{
858 struct debug_buffer *buf = file->private_data;
859 int ret = 0;
860
861 mutex_lock(&buf->mutex);
862 if (buf->count == 0) {
863 ret = fill_buffer(buf);
864 if (ret != 0) {
865 mutex_unlock(&buf->mutex);
866 goto out;
867 }
868 }
869 mutex_unlock(&buf->mutex);
870
871 ret = simple_read_from_buffer(user_buf, len, offset,
872 buf->page, buf->count);
873
874out:
875 return ret;
876
877}
878
879static int debug_close(struct inode *inode, struct file *file)
880{
881 struct debug_buffer *buf = file->private_data;
814 882
883 if (buf) {
884 if (buf->page)
885 free_page((unsigned long)buf->page);
886 kfree(buf);
887 }
888
889 return 0;
890}
891static int debug_async_open(struct inode *inode, struct file *file)
892{
893 file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
894
895 return file->private_data ? 0 : -ENOMEM;
896}
897
898static int debug_periodic_open(struct inode *inode, struct file *file)
899{
900 file->private_data = alloc_buffer(inode->i_private,
901 fill_periodic_buffer);
902
903 return file->private_data ? 0 : -ENOMEM;
904}
905
906static int debug_registers_open(struct inode *inode, struct file *file)
907{
908 file->private_data = alloc_buffer(inode->i_private,
909 fill_registers_buffer);
910
911 return file->private_data ? 0 : -ENOMEM;
912}
913
914static inline void create_debug_files (struct ehci_hcd *ehci)
915{
916 struct usb_bus *bus = &ehci_to_hcd(ehci)->self;
917
918 ehci->debug_dir = debugfs_create_dir(bus->bus_name, ehci_debug_root);
919 if (!ehci->debug_dir)
920 goto dir_error;
921
922 ehci->debug_async = debugfs_create_file("async", S_IRUGO,
923 ehci->debug_dir, bus,
924 &debug_async_fops);
925 if (!ehci->debug_async)
926 goto async_error;
927
928 ehci->debug_periodic = debugfs_create_file("periodic", S_IRUGO,
929 ehci->debug_dir, bus,
930 &debug_periodic_fops);
931 if (!ehci->debug_periodic)
932 goto periodic_error;
933
934 ehci->debug_registers = debugfs_create_file("registers", S_IRUGO,
935 ehci->debug_dir, bus,
936 &debug_registers_fops);
937 if (!ehci->debug_registers)
938 goto registers_error;
939 return;
940
941registers_error:
942 debugfs_remove(ehci->debug_periodic);
943periodic_error:
944 debugfs_remove(ehci->debug_async);
945async_error:
946 debugfs_remove(ehci->debug_dir);
947dir_error:
948 ehci->debug_periodic = NULL;
949 ehci->debug_async = NULL;
950 ehci->debug_dir = NULL;
951}
952
953static inline void remove_debug_files (struct ehci_hcd *ehci)
954{
955 debugfs_remove(ehci->debug_registers);
956 debugfs_remove(ehci->debug_periodic);
957 debugfs_remove(ehci->debug_async);
958 debugfs_remove(ehci->debug_dir);
959}
960
961#endif /* STUB_DEBUG_FILES */
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 5f2d74ed5ad7..264182654f4c 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -33,6 +33,7 @@
33#include <linux/usb.h> 33#include <linux/usb.h>
34#include <linux/moduleparam.h> 34#include <linux/moduleparam.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/debugfs.h>
36 37
37#include "../core/hcd.h" 38#include "../core/hcd.h"
38 39
@@ -978,15 +979,30 @@ static int __init ehci_hcd_init(void)
978 sizeof(struct ehci_qh), sizeof(struct ehci_qtd), 979 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
979 sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); 980 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
980 981
982#ifdef DEBUG
983 ehci_debug_root = debugfs_create_dir("ehci", NULL);
984 if (!ehci_debug_root)
985 return -ENOENT;
986#endif
987
981#ifdef PLATFORM_DRIVER 988#ifdef PLATFORM_DRIVER
982 retval = platform_driver_register(&PLATFORM_DRIVER); 989 retval = platform_driver_register(&PLATFORM_DRIVER);
983 if (retval < 0) 990 if (retval < 0) {
991#ifdef DEBUG
992 debugfs_remove(ehci_debug_root);
993 ehci_debug_root = NULL;
994#endif
984 return retval; 995 return retval;
996 }
985#endif 997#endif
986 998
987#ifdef PCI_DRIVER 999#ifdef PCI_DRIVER
988 retval = pci_register_driver(&PCI_DRIVER); 1000 retval = pci_register_driver(&PCI_DRIVER);
989 if (retval < 0) { 1001 if (retval < 0) {
1002#ifdef DEBUG
1003 debugfs_remove(ehci_debug_root);
1004 ehci_debug_root = NULL;
1005#endif
990#ifdef PLATFORM_DRIVER 1006#ifdef PLATFORM_DRIVER
991 platform_driver_unregister(&PLATFORM_DRIVER); 1007 platform_driver_unregister(&PLATFORM_DRIVER);
992#endif 1008#endif
@@ -997,6 +1013,10 @@ static int __init ehci_hcd_init(void)
997#ifdef PS3_SYSTEM_BUS_DRIVER 1013#ifdef PS3_SYSTEM_BUS_DRIVER
998 retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER); 1014 retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
999 if (retval < 0) { 1015 if (retval < 0) {
1016#ifdef DEBUG
1017 debugfs_remove(ehci_debug_root);
1018 ehci_debug_root = NULL;
1019#endif
1000#ifdef PLATFORM_DRIVER 1020#ifdef PLATFORM_DRIVER
1001 platform_driver_unregister(&PLATFORM_DRIVER); 1021 platform_driver_unregister(&PLATFORM_DRIVER);
1002#endif 1022#endif
@@ -1022,6 +1042,9 @@ static void __exit ehci_hcd_cleanup(void)
1022#ifdef PS3_SYSTEM_BUS_DRIVER 1042#ifdef PS3_SYSTEM_BUS_DRIVER
1023 ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); 1043 ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
1024#endif 1044#endif
1045#ifdef DEBUG
1046 debugfs_remove(ehci_debug_root);
1047#endif
1025} 1048}
1026module_exit(ehci_hcd_cleanup); 1049module_exit(ehci_hcd_cleanup);
1027 1050
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 951d69fec513..10e71417c352 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -127,6 +127,14 @@ struct ehci_hcd { /* one per controller */
127#else 127#else
128# define COUNT(x) do {} while (0) 128# define COUNT(x) do {} while (0)
129#endif 129#endif
130
131 /* debug files */
132#ifdef DEBUG
133 struct dentry *debug_dir;
134 struct dentry *debug_async;
135 struct dentry *debug_periodic;
136 struct dentry *debug_registers;
137#endif
130}; 138};
131 139
132/* convert between an HCD pointer and the corresponding EHCI_HCD */ 140/* convert between an HCD pointer and the corresponding EHCI_HCD */