Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d402e1a authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

[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: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 0ed8fee1
Loading
Loading
Loading
Loading
+29 −7
Original line number Diff line number Diff line
@@ -17,10 +17,13 @@

#include "uhci-hcd.h"

static struct dentry *uhci_debugfs_root = NULL;
#define uhci_debug_operations (* (struct file_operations *) NULL)
static struct dentry *uhci_debugfs_root;

#ifdef DEBUG

/* Handle REALLY large printks so we don't overflow buffers */
static inline void lprintk(char *buf)
static void lprintk(char *buf)
{
	char *p;

@@ -196,7 +199,6 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
	return out - buf;
}

#ifdef CONFIG_PROC_FS
static const char * const qh_names[] = {
  "skel_unlink_qh", "skel_iso_qh",
  "skel_int128_qh", "skel_int64_qh",
@@ -393,12 +395,13 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
	return out - buf;
}

#ifdef CONFIG_DEBUG_FS

#define MAX_OUTPUT	(64 * 1024)

struct uhci_debug {
	int size;
	char *data;
	struct uhci_hcd *uhci;
};

static int uhci_debug_open(struct inode *inode, struct file *file)
@@ -419,7 +422,9 @@ static int uhci_debug_open(struct inode *inode, struct file *file)
		goto out;
	}

	up->size = 0;
	spin_lock_irqsave(&uhci->lock, flags);
	if (uhci->is_initialized)
		up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT);
	spin_unlock_irqrestore(&uhci->lock, flags);

@@ -472,15 +477,32 @@ static int uhci_debug_release(struct inode *inode, struct file *file)
	return 0;
}

#undef uhci_debug_operations
static struct file_operations uhci_debug_operations = {
	.owner =	THIS_MODULE,
	.open =		uhci_debug_open,
	.llseek =	uhci_debug_lseek,
	.read =		uhci_debug_read,
	.release =	uhci_debug_release,
};

#else	/* CONFIG_DEBUG_FS */
#endif	/* CONFIG_DEBUG_FS */

#define uhci_debug_operations (* (struct file_operations *) NULL)
#else	/* DEBUG */

static inline void lprintk(char *buf)
{}

static inline int uhci_show_qh(struct uhci_qh *qh, char *buf,
		int len, int space)
{
	return 0;
}

static inline int uhci_sprint_schedule(struct uhci_hcd *uhci,
		char *buf, int len)
{
	return 0;
}

#endif
+39 −21
Original line number Diff line number Diff line
@@ -68,12 +68,16 @@ Alan Stern"
 * debug = 3, show all TDs in URBs when dumping
 */
#ifdef DEBUG
#define DEBUG_CONFIGURED	1
static int debug = 1;
#else
static int debug = 0;
#endif
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level");

#else
#define DEBUG_CONFIGURED	0
#define debug			0
#endif

static char *errbuf;
#define ERRBUF_LEN    (32 * 1024)

@@ -338,6 +342,12 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
				dev_err(uhci_dev(uhci),
					"host controller halted, "
					"very bad!\n");
				if (debug > 1 && errbuf) {
					/* Print the schedule for debugging */
					uhci_sprint_schedule(uhci,
							errbuf, ERRBUF_LEN);
					lprintk(errbuf);
				}
				hc_died(uhci);

				/* Force a callback in case there are
@@ -376,6 +386,14 @@ static void release_uhci(struct uhci_hcd *uhci)
{
	int i;

	if (DEBUG_CONFIGURED) {
		spin_lock_irq(&uhci->lock);
		uhci->is_initialized = 0;
		spin_unlock_irq(&uhci->lock);

		debugfs_remove(uhci->dentry);
	}

	for (i = 0; i < UHCI_NUM_SKELQH; i++)
		uhci_free_qh(uhci, uhci->skelqh[i]);

@@ -390,8 +408,6 @@ static void release_uhci(struct uhci_hcd *uhci)
	dma_free_coherent(uhci_dev(uhci),
			UHCI_NUMFRAMES * sizeof(*uhci->frame),
			uhci->frame, uhci->frame_dma_handle);

	debugfs_remove(uhci->dentry);
}

static int uhci_reset(struct usb_hcd *hcd)
@@ -474,17 +490,6 @@ static int uhci_start(struct usb_hcd *hcd)

	hcd->uses_new_polling = 1;

	dentry = debugfs_create_file(hcd->self.bus_name,
			S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci,
			&uhci_debug_operations);
	if (!dentry) {
		dev_err(uhci_dev(uhci),
				"couldn't create uhci debugfs entry\n");
		retval = -ENOMEM;
		goto err_create_debug_entry;
	}
	uhci->dentry = dentry;

	uhci->fsbr = 0;
	uhci->fsbrtimeout = 0;

@@ -495,6 +500,19 @@ static int uhci_start(struct usb_hcd *hcd)

	init_waitqueue_head(&uhci->waitqh);

	if (DEBUG_CONFIGURED) {
		dentry = debugfs_create_file(hcd->self.bus_name,
				S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root,
				uhci, &uhci_debug_operations);
		if (!dentry) {
			dev_err(uhci_dev(uhci), "couldn't create uhci "
					"debugfs entry\n");
			retval = -ENOMEM;
			goto err_create_debug_entry;
		}
		uhci->dentry = dentry;
	}

	uhci->frame = dma_alloc_coherent(uhci_dev(uhci),
			UHCI_NUMFRAMES * sizeof(*uhci->frame),
			&uhci->frame_dma_handle, 0);
@@ -609,6 +627,7 @@ static int uhci_start(struct usb_hcd *hcd)
	mb();

	configure_hc(uhci);
	uhci->is_initialized = 1;
	start_rh(uhci);
	return 0;

@@ -872,15 +891,14 @@ static int __init uhci_hcd_init(void)
	if (usb_disabled())
		return -ENODEV;

	if (debug) {
	if (DEBUG_CONFIGURED) {
		errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
		if (!errbuf)
			goto errbuf_failed;
	}

		uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
		if (!uhci_debugfs_root)
			goto debug_failed;
	}

	uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
		sizeof(struct urb_priv), 0, 0, NULL, NULL);
+1 −0
Original line number Diff line number Diff line
@@ -411,6 +411,7 @@ struct uhci_hcd {
	unsigned int hc_inaccessible:1;		/* HC is suspended or dead */
	unsigned int working_RD:1;		/* Suspended root hub doesn't
						   need to be polled */
	unsigned int is_initialized:1;		/* Data structure is usable */

	/* Support for port suspend/resume/reset */
	unsigned long port_c_suspend;		/* Bit-arrays of ports */
+1 −11
Original line number Diff line number Diff line
@@ -736,7 +736,6 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb)
		if (errbuf) {
			/* Print the chain for debugging purposes */
			uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);

			lprintk(errbuf);
		}
	}
@@ -924,26 +923,17 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
	ret = uhci_map_status(status, uhci_packetout(td_token(td)));

err:
	/* 
	 * Enable this chunk of code if you want to see some more debugging.
	 * But be careful, it has the tendancy to starve out khubd and prevent
	 * disconnects from happening successfully if you have a slow debug
	 * log interface (like a serial console.
	 */
#if 0
	if ((debug == 1 && ret != -EPIPE) || debug > 1) {
		/* Some debugging code */
		dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
				__FUNCTION__, status);

		if (errbuf) {
		if (debug > 1 && errbuf) {
			/* Print the chain for debugging purposes */
			uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);

			lprintk(errbuf);
		}
	}
#endif

	/* Note that the queue has stopped and save the next toggle value */
	urbp->qh->element = UHCI_PTR_TERM;