aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-dbg.c
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/usb/host/ehci-dbg.c
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/usb/host/ehci-dbg.c')
-rw-r--r--drivers/usb/host/ehci-dbg.c227
1 files changed, 187 insertions, 40 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 */