aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-12-17 18:03:37 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-20 17:49:57 -0500
commit8d402e1ae03656c1ad215514f8885ef4793f0948 (patch)
treeceac7800d7e07be1a7320a0b729156b12fbf26d6 /drivers/usb
parent0ed8fee1c1d38a62e981025ba40b5eba30c4ce2a (diff)
[PATCH] UHCI: improve debugging code
This patch (as626) makes some improvements to the debugging code in uhci-hcd. The main change is that now the code won't get compiled if CONFIG_USB_DEBUG isn't set. But there are other changes too, like adding a missing .owner field and printing a debugging dump if the controller dies. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/uhci-debug.c36
-rw-r--r--drivers/usb/host/uhci-hcd.c60
-rw-r--r--drivers/usb/host/uhci-hcd.h1
-rw-r--r--drivers/usb/host/uhci-q.c12
4 files changed, 70 insertions, 39 deletions
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index f2f5f8ce1715..e1239319655c 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -17,10 +17,13 @@
17 17
18#include "uhci-hcd.h" 18#include "uhci-hcd.h"
19 19
20static struct dentry *uhci_debugfs_root = NULL; 20#define uhci_debug_operations (* (struct file_operations *) NULL)
21static struct dentry *uhci_debugfs_root;
22
23#ifdef DEBUG
21 24
22/* Handle REALLY large printks so we don't overflow buffers */ 25/* Handle REALLY large printks so we don't overflow buffers */
23static inline void lprintk(char *buf) 26static void lprintk(char *buf)
24{ 27{
25 char *p; 28 char *p;
26 29
@@ -196,7 +199,6 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
196 return out - buf; 199 return out - buf;
197} 200}
198 201
199#ifdef CONFIG_PROC_FS
200static const char * const qh_names[] = { 202static const char * const qh_names[] = {
201 "skel_unlink_qh", "skel_iso_qh", 203 "skel_unlink_qh", "skel_iso_qh",
202 "skel_int128_qh", "skel_int64_qh", 204 "skel_int128_qh", "skel_int64_qh",
@@ -393,12 +395,13 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
393 return out - buf; 395 return out - buf;
394} 396}
395 397
398#ifdef CONFIG_DEBUG_FS
399
396#define MAX_OUTPUT (64 * 1024) 400#define MAX_OUTPUT (64 * 1024)
397 401
398struct uhci_debug { 402struct uhci_debug {
399 int size; 403 int size;
400 char *data; 404 char *data;
401 struct uhci_hcd *uhci;
402}; 405};
403 406
404static int uhci_debug_open(struct inode *inode, struct file *file) 407static int uhci_debug_open(struct inode *inode, struct file *file)
@@ -419,8 +422,10 @@ static int uhci_debug_open(struct inode *inode, struct file *file)
419 goto out; 422 goto out;
420 } 423 }
421 424
425 up->size = 0;
422 spin_lock_irqsave(&uhci->lock, flags); 426 spin_lock_irqsave(&uhci->lock, flags);
423 up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT); 427 if (uhci->is_initialized)
428 up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT);
424 spin_unlock_irqrestore(&uhci->lock, flags); 429 spin_unlock_irqrestore(&uhci->lock, flags);
425 430
426 file->private_data = up; 431 file->private_data = up;
@@ -472,15 +477,32 @@ static int uhci_debug_release(struct inode *inode, struct file *file)
472 return 0; 477 return 0;
473} 478}
474 479
480#undef uhci_debug_operations
475static struct file_operations uhci_debug_operations = { 481static struct file_operations uhci_debug_operations = {
482 .owner = THIS_MODULE,
476 .open = uhci_debug_open, 483 .open = uhci_debug_open,
477 .llseek = uhci_debug_lseek, 484 .llseek = uhci_debug_lseek,
478 .read = uhci_debug_read, 485 .read = uhci_debug_read,
479 .release = uhci_debug_release, 486 .release = uhci_debug_release,
480}; 487};
481 488
482#else /* CONFIG_DEBUG_FS */ 489#endif /* CONFIG_DEBUG_FS */
483 490
484#define uhci_debug_operations (* (struct file_operations *) NULL) 491#else /* DEBUG */
492
493static inline void lprintk(char *buf)
494{}
495
496static inline int uhci_show_qh(struct uhci_qh *qh, char *buf,
497 int len, int space)
498{
499 return 0;
500}
501
502static inline int uhci_sprint_schedule(struct uhci_hcd *uhci,
503 char *buf, int len)
504{
505 return 0;
506}
485 507
486#endif 508#endif
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 9865f303d3fc..4edb8330c440 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -68,12 +68,16 @@ Alan Stern"
68 * debug = 3, show all TDs in URBs when dumping 68 * debug = 3, show all TDs in URBs when dumping
69 */ 69 */
70#ifdef DEBUG 70#ifdef DEBUG
71#define DEBUG_CONFIGURED 1
71static int debug = 1; 72static int debug = 1;
72#else
73static int debug = 0;
74#endif
75module_param(debug, int, S_IRUGO | S_IWUSR); 73module_param(debug, int, S_IRUGO | S_IWUSR);
76MODULE_PARM_DESC(debug, "Debug level"); 74MODULE_PARM_DESC(debug, "Debug level");
75
76#else
77#define DEBUG_CONFIGURED 0
78#define debug 0
79#endif
80
77static char *errbuf; 81static char *errbuf;
78#define ERRBUF_LEN (32 * 1024) 82#define ERRBUF_LEN (32 * 1024)
79 83
@@ -338,6 +342,12 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
338 dev_err(uhci_dev(uhci), 342 dev_err(uhci_dev(uhci),
339 "host controller halted, " 343 "host controller halted, "
340 "very bad!\n"); 344 "very bad!\n");
345 if (debug > 1 && errbuf) {
346 /* Print the schedule for debugging */
347 uhci_sprint_schedule(uhci,
348 errbuf, ERRBUF_LEN);
349 lprintk(errbuf);
350 }
341 hc_died(uhci); 351 hc_died(uhci);
342 352
343 /* Force a callback in case there are 353 /* Force a callback in case there are
@@ -376,6 +386,14 @@ static void release_uhci(struct uhci_hcd *uhci)
376{ 386{
377 int i; 387 int i;
378 388
389 if (DEBUG_CONFIGURED) {
390 spin_lock_irq(&uhci->lock);
391 uhci->is_initialized = 0;
392 spin_unlock_irq(&uhci->lock);
393
394 debugfs_remove(uhci->dentry);
395 }
396
379 for (i = 0; i < UHCI_NUM_SKELQH; i++) 397 for (i = 0; i < UHCI_NUM_SKELQH; i++)
380 uhci_free_qh(uhci, uhci->skelqh[i]); 398 uhci_free_qh(uhci, uhci->skelqh[i]);
381 399
@@ -390,8 +408,6 @@ static void release_uhci(struct uhci_hcd *uhci)
390 dma_free_coherent(uhci_dev(uhci), 408 dma_free_coherent(uhci_dev(uhci),
391 UHCI_NUMFRAMES * sizeof(*uhci->frame), 409 UHCI_NUMFRAMES * sizeof(*uhci->frame),
392 uhci->frame, uhci->frame_dma_handle); 410 uhci->frame, uhci->frame_dma_handle);
393
394 debugfs_remove(uhci->dentry);
395} 411}
396 412
397static int uhci_reset(struct usb_hcd *hcd) 413static int uhci_reset(struct usb_hcd *hcd)
@@ -474,17 +490,6 @@ static int uhci_start(struct usb_hcd *hcd)
474 490
475 hcd->uses_new_polling = 1; 491 hcd->uses_new_polling = 1;
476 492
477 dentry = debugfs_create_file(hcd->self.bus_name,
478 S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci,
479 &uhci_debug_operations);
480 if (!dentry) {
481 dev_err(uhci_dev(uhci),
482 "couldn't create uhci debugfs entry\n");
483 retval = -ENOMEM;
484 goto err_create_debug_entry;
485 }
486 uhci->dentry = dentry;
487
488 uhci->fsbr = 0; 493 uhci->fsbr = 0;
489 uhci->fsbrtimeout = 0; 494 uhci->fsbrtimeout = 0;
490 495
@@ -495,6 +500,19 @@ static int uhci_start(struct usb_hcd *hcd)
495 500
496 init_waitqueue_head(&uhci->waitqh); 501 init_waitqueue_head(&uhci->waitqh);
497 502
503 if (DEBUG_CONFIGURED) {
504 dentry = debugfs_create_file(hcd->self.bus_name,
505 S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root,
506 uhci, &uhci_debug_operations);
507 if (!dentry) {
508 dev_err(uhci_dev(uhci), "couldn't create uhci "
509 "debugfs entry\n");
510 retval = -ENOMEM;
511 goto err_create_debug_entry;
512 }
513 uhci->dentry = dentry;
514 }
515
498 uhci->frame = dma_alloc_coherent(uhci_dev(uhci), 516 uhci->frame = dma_alloc_coherent(uhci_dev(uhci),
499 UHCI_NUMFRAMES * sizeof(*uhci->frame), 517 UHCI_NUMFRAMES * sizeof(*uhci->frame),
500 &uhci->frame_dma_handle, 0); 518 &uhci->frame_dma_handle, 0);
@@ -609,6 +627,7 @@ static int uhci_start(struct usb_hcd *hcd)
609 mb(); 627 mb();
610 628
611 configure_hc(uhci); 629 configure_hc(uhci);
630 uhci->is_initialized = 1;
612 start_rh(uhci); 631 start_rh(uhci);
613 return 0; 632 return 0;
614 633
@@ -872,16 +891,15 @@ static int __init uhci_hcd_init(void)
872 if (usb_disabled()) 891 if (usb_disabled())
873 return -ENODEV; 892 return -ENODEV;
874 893
875 if (debug) { 894 if (DEBUG_CONFIGURED) {
876 errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); 895 errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
877 if (!errbuf) 896 if (!errbuf)
878 goto errbuf_failed; 897 goto errbuf_failed;
898 uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
899 if (!uhci_debugfs_root)
900 goto debug_failed;
879 } 901 }
880 902
881 uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
882 if (!uhci_debugfs_root)
883 goto debug_failed;
884
885 uhci_up_cachep = kmem_cache_create("uhci_urb_priv", 903 uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
886 sizeof(struct urb_priv), 0, 0, NULL, NULL); 904 sizeof(struct urb_priv), 0, 0, NULL, NULL);
887 if (!uhci_up_cachep) 905 if (!uhci_up_cachep)
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 7e96bef2e88f..4a69c7eb09bd 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -411,6 +411,7 @@ struct uhci_hcd {
411 unsigned int hc_inaccessible:1; /* HC is suspended or dead */ 411 unsigned int hc_inaccessible:1; /* HC is suspended or dead */
412 unsigned int working_RD:1; /* Suspended root hub doesn't 412 unsigned int working_RD:1; /* Suspended root hub doesn't
413 need to be polled */ 413 need to be polled */
414 unsigned int is_initialized:1; /* Data structure is usable */
414 415
415 /* Support for port suspend/resume/reset */ 416 /* Support for port suspend/resume/reset */
416 unsigned long port_c_suspend; /* Bit-arrays of ports */ 417 unsigned long port_c_suspend; /* Bit-arrays of ports */
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 44bba9a6d196..5d6c4f75d0d8 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -736,7 +736,6 @@ err:
736 if (errbuf) { 736 if (errbuf) {
737 /* Print the chain for debugging purposes */ 737 /* Print the chain for debugging purposes */
738 uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); 738 uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
739
740 lprintk(errbuf); 739 lprintk(errbuf);
741 } 740 }
742 } 741 }
@@ -924,26 +923,17 @@ td_error:
924 ret = uhci_map_status(status, uhci_packetout(td_token(td))); 923 ret = uhci_map_status(status, uhci_packetout(td_token(td)));
925 924
926err: 925err:
927 /*
928 * Enable this chunk of code if you want to see some more debugging.
929 * But be careful, it has the tendancy to starve out khubd and prevent
930 * disconnects from happening successfully if you have a slow debug
931 * log interface (like a serial console.
932 */
933#if 0
934 if ((debug == 1 && ret != -EPIPE) || debug > 1) { 926 if ((debug == 1 && ret != -EPIPE) || debug > 1) {
935 /* Some debugging code */ 927 /* Some debugging code */
936 dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n", 928 dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
937 __FUNCTION__, status); 929 __FUNCTION__, status);
938 930
939 if (errbuf) { 931 if (debug > 1 && errbuf) {
940 /* Print the chain for debugging purposes */ 932 /* Print the chain for debugging purposes */
941 uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); 933 uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
942
943 lprintk(errbuf); 934 lprintk(errbuf);
944 } 935 }
945 } 936 }
946#endif
947 937
948 /* Note that the queue has stopped and save the next toggle value */ 938 /* Note that the queue has stopped and save the next toggle value */
949 urbp->qh->element = UHCI_PTR_TERM; 939 urbp->qh->element = UHCI_PTR_TERM;