From 3c37bb685d8d668f00102502e753cccc426cc954 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Sat, 30 Mar 2013 02:46:17 +0200 Subject: usb: chipidea: drop redundant includes debug.c is carrying a lot of includes that aren't needed there, although they implicitly include the ones that are actually needed. Replace the former with the latter. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/debug.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/usb/chipidea/debug.c') diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index a62c4a47d52c..e6cc45ebb33d 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -1,20 +1,9 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include +#include +#include #include #include -#include -#include #include "ci.h" #include "udc.h" -- cgit v1.2.3 From 69b7e8d34f12a5770d57ccd38926d373e4599561 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Sat, 30 Mar 2013 12:53:50 +0200 Subject: usb: chipidea: remove home-grown tracing facility As part of the legacy from the original driver design, we retain home-grown tracing infrastructure, complete with own ring buffer and timestamps, which among other things has a performance penalty. This patch removes it. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/debug.c | 360 +------------------------------------------ 1 file changed, 1 insertion(+), 359 deletions(-) (limited to 'drivers/usb/chipidea/debug.c') diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index e6cc45ebb33d..898aca591915 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -10,46 +10,6 @@ #include "bits.h" #include "debug.h" -/* Interrupt statistics */ -#define ISR_MASK 0x1F -static struct isr_statistics { - u32 test; - u32 ui; - u32 uei; - u32 pci; - u32 uri; - u32 sli; - u32 none; - struct { - u32 cnt; - u32 buf[ISR_MASK+1]; - u32 idx; - } hndl; -} isr_statistics; - -void dbg_interrupt(u32 intmask) -{ - if (!intmask) { - isr_statistics.none++; - return; - } - - isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intmask; - isr_statistics.hndl.idx &= ISR_MASK; - isr_statistics.hndl.cnt++; - - if (USBi_URI & intmask) - isr_statistics.uri++; - if (USBi_PCI & intmask) - isr_statistics.pci++; - if (USBi_UEI & intmask) - isr_statistics.uei++; - if (USBi_UI & intmask) - isr_statistics.ui++; - if (USBi_SLI & intmask) - isr_statistics.sli++; -} - /** * hw_register_read: reads all device registers (execute without interruption) * @buf: destination buffer @@ -196,312 +156,6 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); -/* Maximum event message length */ -#define DBG_DATA_MSG 64UL - -/* Maximum event messages */ -#define DBG_DATA_MAX 128UL - -/* Event buffer descriptor */ -static struct { - char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */ - unsigned idx; /* index */ - unsigned tty; /* print to console? */ - rwlock_t lck; /* lock */ -} dbg_data = { - .idx = 0, - .tty = 0, - .lck = __RW_LOCK_UNLOCKED(dbg_data.lck) -}; - -/** - * dbg_dec: decrements debug event index - * @idx: buffer index - */ -static void dbg_dec(unsigned *idx) -{ - *idx = (*idx - 1) & (DBG_DATA_MAX-1); -} - -/** - * dbg_inc: increments debug event index - * @idx: buffer index - */ -static void dbg_inc(unsigned *idx) -{ - *idx = (*idx + 1) & (DBG_DATA_MAX-1); -} - -/** - * dbg_print: prints the common part of the event - * @addr: endpoint address - * @name: event name - * @status: status - * @extra: extra information - */ -static void dbg_print(u8 addr, const char *name, int status, const char *extra) -{ - struct timeval tval; - unsigned int stamp; - unsigned long flags; - - write_lock_irqsave(&dbg_data.lck, flags); - - do_gettimeofday(&tval); - stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */ - stamp = stamp * 1000000 + tval.tv_usec; - - scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG, - "%04X\t? %02X %-7.7s %4i ?\t%s\n", - stamp, addr, name, status, extra); - - dbg_inc(&dbg_data.idx); - - write_unlock_irqrestore(&dbg_data.lck, flags); - - if (dbg_data.tty != 0) - pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n", - stamp, addr, name, status, extra); -} - -/** - * dbg_done: prints a DONE event - * @addr: endpoint address - * @td: transfer descriptor - * @status: status - */ -void dbg_done(u8 addr, const u32 token, int status) -{ - char msg[DBG_DATA_MSG]; - - scnprintf(msg, sizeof(msg), "%d %02X", - (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES), - (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS)); - dbg_print(addr, "DONE", status, msg); -} - -/** - * dbg_event: prints a generic event - * @addr: endpoint address - * @name: event name - * @status: status - */ -void dbg_event(u8 addr, const char *name, int status) -{ - if (name != NULL) - dbg_print(addr, name, status, ""); -} - -/* - * dbg_queue: prints a QUEUE event - * @addr: endpoint address - * @req: USB request - * @status: status - */ -void dbg_queue(u8 addr, const struct usb_request *req, int status) -{ - char msg[DBG_DATA_MSG]; - - if (req != NULL) { - scnprintf(msg, sizeof(msg), - "%d %d", !req->no_interrupt, req->length); - dbg_print(addr, "QUEUE", status, msg); - } -} - -/** - * dbg_setup: prints a SETUP event - * @addr: endpoint address - * @req: setup request - */ -void dbg_setup(u8 addr, const struct usb_ctrlrequest *req) -{ - char msg[DBG_DATA_MSG]; - - if (req != NULL) { - scnprintf(msg, sizeof(msg), - "%02X %02X %04X %04X %d", req->bRequestType, - req->bRequest, le16_to_cpu(req->wValue), - le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength)); - dbg_print(addr, "SETUP", 0, msg); - } -} - -/** - * show_events: displays the event buffer - * - * Check "device.h" for details - */ -static ssize_t show_events(struct device *dev, struct device_attribute *attr, - char *buf) -{ - unsigned long flags; - unsigned i, j, n = 0; - - if (attr == NULL || buf == NULL) { - dev_err(dev->parent, "[%s] EINVAL\n", __func__); - return 0; - } - - read_lock_irqsave(&dbg_data.lck, flags); - - i = dbg_data.idx; - for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) { - n += strlen(dbg_data.buf[i]); - if (n >= PAGE_SIZE) { - n -= strlen(dbg_data.buf[i]); - break; - } - } - for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i)) - j += scnprintf(buf + j, PAGE_SIZE - j, - "%s", dbg_data.buf[i]); - - read_unlock_irqrestore(&dbg_data.lck, flags); - - return n; -} - -/** - * store_events: configure if events are going to be also printed to console - * - * Check "device.h" for details - */ -static ssize_t store_events(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned tty; - - if (attr == NULL || buf == NULL) { - dev_err(dev, "[%s] EINVAL\n", __func__); - goto done; - } - - if (sscanf(buf, "%u", &tty) != 1 || tty > 1) { - dev_err(dev, "<1|0>: enable|disable console log\n"); - goto done; - } - - dbg_data.tty = tty; - dev_info(dev, "tty = %u", dbg_data.tty); - - done: - return count; -} -static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events); - -/** - * show_inters: interrupt status, enable status and historic - * - * Check "device.h" for details - */ -static ssize_t show_inters(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - unsigned long flags; - u32 intr; - unsigned i, j, n = 0; - - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); - return 0; - } - - spin_lock_irqsave(&ci->lock, flags); - - /*n += scnprintf(buf + n, PAGE_SIZE - n, - "status = %08x\n", hw_read_intr_status(ci)); - n += scnprintf(buf + n, PAGE_SIZE - n, - "enable = %08x\n", hw_read_intr_enable(ci));*/ - - n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n", - isr_statistics.test); - n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n", - isr_statistics.ui); - n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n", - isr_statistics.uei); - n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n", - isr_statistics.pci); - n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n", - isr_statistics.uri); - n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n", - isr_statistics.sli); - n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n", - isr_statistics.none); - n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n", - isr_statistics.hndl.cnt); - - for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) { - i &= ISR_MASK; - intr = isr_statistics.hndl.buf[i]; - - if (USBi_UI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "ui "); - intr &= ~USBi_UI; - if (USBi_UEI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "uei "); - intr &= ~USBi_UEI; - if (USBi_PCI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "pci "); - intr &= ~USBi_PCI; - if (USBi_URI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "uri "); - intr &= ~USBi_URI; - if (USBi_SLI & intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "sli "); - intr &= ~USBi_SLI; - if (intr) - n += scnprintf(buf + n, PAGE_SIZE - n, "??? "); - if (isr_statistics.hndl.buf[i]) - n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); - } - - spin_unlock_irqrestore(&ci->lock, flags); - - return n; -} - -/** - * store_inters: enable & force or disable an individual interrutps - * (to be used for test purposes only) - * - * Check "device.h" for details - */ -static ssize_t store_inters(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - unsigned long flags; - unsigned en, bit; - - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "EINVAL\n"); - goto done; - } - - if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) { - dev_err(ci->dev, "<1|0> : enable|disable interrupt\n"); - goto done; - } - - spin_lock_irqsave(&ci->lock, flags); - if (en) { - if (hw_intr_force(ci, bit)) - dev_err(dev, "invalid bit number\n"); - else - isr_statistics.test++; - } else { - if (hw_intr_clear(ci, bit)) - dev_err(dev, "invalid bit number\n"); - } - spin_unlock_irqrestore(&ci->lock, flags); - - done: - return count; -} -static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters); - /** * show_port_test: reads port test mode * @@ -730,15 +384,9 @@ int dbg_create_files(struct device *dev) retval = device_create_file(dev, &dev_attr_driver); if (retval) goto rm_device; - retval = device_create_file(dev, &dev_attr_events); - if (retval) - goto rm_driver; - retval = device_create_file(dev, &dev_attr_inters); - if (retval) - goto rm_events; retval = device_create_file(dev, &dev_attr_port_test); if (retval) - goto rm_inters; + goto rm_driver; retval = device_create_file(dev, &dev_attr_qheads); if (retval) goto rm_port_test; @@ -756,10 +404,6 @@ int dbg_create_files(struct device *dev) device_remove_file(dev, &dev_attr_qheads); rm_port_test: device_remove_file(dev, &dev_attr_port_test); - rm_inters: - device_remove_file(dev, &dev_attr_inters); - rm_events: - device_remove_file(dev, &dev_attr_events); rm_driver: device_remove_file(dev, &dev_attr_driver); rm_device: @@ -782,8 +426,6 @@ int dbg_remove_files(struct device *dev) device_remove_file(dev, &dev_attr_registers); device_remove_file(dev, &dev_attr_qheads); device_remove_file(dev, &dev_attr_port_test); - device_remove_file(dev, &dev_attr_inters); - device_remove_file(dev, &dev_attr_events); device_remove_file(dev, &dev_attr_driver); device_remove_file(dev, &dev_attr_device); return 0; -- cgit v1.2.3 From 2d6512892c106556f07e502939005e73cdc6e2cc Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Sat, 30 Mar 2013 12:53:51 +0200 Subject: usb: chipidea: convert debug entries in sysfs to debugfs Currently, we have a bunch of files in sysfs that display all sorts of debugging information for the device controller, so they have to move to debugfs where they belong. The "registers" interface have been removed, since it doesn't fit into the current driver design as is and it's hardly a good idea to touch the registers from userspace anyway. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/debug.c | 469 +++++++++++++------------------------------ 1 file changed, 142 insertions(+), 327 deletions(-) (limited to 'drivers/usb/chipidea/debug.c') diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 898aca591915..057ae09025bf 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -2,6 +2,9 @@ #include #include #include +#include +#include +#include #include #include @@ -11,223 +14,113 @@ #include "debug.h" /** - * hw_register_read: reads all device registers (execute without interruption) - * @buf: destination buffer - * @size: buffer size - * - * This function returns number of registers read + * ci_device_show: prints information about device capabilities and status */ -static size_t hw_register_read(struct ci13xxx *ci, u32 *buf, size_t size) +static int ci_device_show(struct seq_file *s, void *data) { - unsigned i; - - if (size > ci->hw_bank.size) - size = ci->hw_bank.size; - - for (i = 0; i < size; i++) - buf[i] = hw_read(ci, i * sizeof(u32), ~0); - - return size; -} - -/** - * hw_register_write: writes to register - * @addr: register address - * @data: register value - * - * This function returns an error code - */ -static int hw_register_write(struct ci13xxx *ci, u16 addr, u32 data) -{ - /* align */ - addr /= sizeof(u32); + struct ci13xxx *ci = s->private; + struct usb_gadget *gadget = &ci->gadget; - if (addr >= ci->hw_bank.size) - return -EINVAL; + seq_printf(s, "speed = %d\n", gadget->speed); + seq_printf(s, "max_speed = %d\n", gadget->max_speed); + seq_printf(s, "is_otg = %d\n", gadget->is_otg); + seq_printf(s, "is_a_peripheral = %d\n", gadget->is_a_peripheral); + seq_printf(s, "b_hnp_enable = %d\n", gadget->b_hnp_enable); + seq_printf(s, "a_hnp_support = %d\n", gadget->a_hnp_support); + seq_printf(s, "a_alt_hnp_support = %d\n", gadget->a_alt_hnp_support); + seq_printf(s, "name = %s\n", + (gadget->name ? gadget->name : "")); + + if (!ci->driver) + return 0; - /* align */ - addr *= sizeof(u32); + seq_printf(s, "gadget function = %s\n", + (ci->driver->function ? ci->driver->function : "")); + seq_printf(s, "gadget max speed = %d\n", ci->driver->max_speed); - hw_write(ci, addr, ~0, data); return 0; } -/** - * hw_intr_clear: disables interrupt & clears interrupt status (execute without - * interruption) - * @n: interrupt bit - * - * This function returns an error code - */ -static int hw_intr_clear(struct ci13xxx *ci, int n) +static int ci_device_open(struct inode *inode, struct file *file) { - if (n >= REG_BITS) - return -EINVAL; - - hw_write(ci, OP_USBINTR, BIT(n), 0); - hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); - return 0; + return single_open(file, ci_device_show, inode->i_private); } -/** - * hw_intr_force: enables interrupt & forces interrupt status (execute without - * interruption) - * @n: interrupt bit - * - * This function returns an error code - */ -static int hw_intr_force(struct ci13xxx *ci, int n) -{ - if (n >= REG_BITS) - return -EINVAL; - - hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE); - hw_write(ci, OP_USBINTR, BIT(n), BIT(n)); - hw_write(ci, OP_USBSTS, BIT(n), BIT(n)); - hw_write(ci, CAP_TESTMODE, TESTMODE_FORCE, 0); - return 0; -} - -/** - * show_device: prints information about device capabilities and status - * - * Check "device.h" for details - */ -static ssize_t show_device(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - struct usb_gadget *gadget = &ci->gadget; - int n = 0; - - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); - return 0; - } - - n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", - gadget->speed); - n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n", - gadget->max_speed); - n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", - gadget->is_otg); - n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", - gadget->is_a_peripheral); - n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n", - gadget->b_hnp_enable); - n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n", - gadget->a_hnp_support); - n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n", - gadget->a_alt_hnp_support); - n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n", - (gadget->name ? gadget->name : "")); - - return n; -} -static DEVICE_ATTR(device, S_IRUSR, show_device, NULL); - -/** - * show_driver: prints information about attached gadget (if any) - * - * Check "device.h" for details - */ -static ssize_t show_driver(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - struct usb_gadget_driver *driver = ci->driver; - int n = 0; - - if (attr == NULL || buf == NULL) { - dev_err(dev, "[%s] EINVAL\n", __func__); - return 0; - } - - if (driver == NULL) - return scnprintf(buf, PAGE_SIZE, - "There is no gadget attached!\n"); - - n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", - (driver->function ? driver->function : "")); - n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", - driver->max_speed); - - return n; -} -static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); +static const struct file_operations ci_device_fops = { + .open = ci_device_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; /** - * show_port_test: reads port test mode - * - * Check "device.h" for details + * ci_port_test_show: reads port test mode */ -static ssize_t show_port_test(struct device *dev, - struct device_attribute *attr, char *buf) +static int ci_port_test_show(struct seq_file *s, void *data) { - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); + struct ci13xxx *ci = s->private; unsigned long flags; unsigned mode; - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "EINVAL\n"); - return 0; - } - spin_lock_irqsave(&ci->lock, flags); mode = hw_port_test_get(ci); spin_unlock_irqrestore(&ci->lock, flags); - return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode); + seq_printf(s, "mode = %u\n", mode); + + return 0; } /** - * store_port_test: writes port test mode - * - * Check "device.h" for details + * ci_port_test_write: writes port test mode */ -static ssize_t store_port_test(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) { - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); + struct seq_file *s = file->private_data; + struct ci13xxx *ci = s->private; unsigned long flags; unsigned mode; + char buf[32]; + int ret; - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); - goto done; - } + if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; - if (sscanf(buf, "%u", &mode) != 1) { - dev_err(ci->dev, ": set port test mode"); - goto done; - } + if (sscanf(buf, "%u", &mode) != 1) + return -EINVAL; spin_lock_irqsave(&ci->lock, flags); - if (hw_port_test_set(ci, mode)) - dev_err(ci->dev, "invalid mode\n"); + ret = hw_port_test_set(ci, mode); spin_unlock_irqrestore(&ci->lock, flags); - done: - return count; + return ret ? ret : count; } -static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR, - show_port_test, store_port_test); + +static int ci_port_test_open(struct inode *inode, struct file *file) +{ + return single_open(file, ci_port_test_show, inode->i_private); +} + +static const struct file_operations ci_port_test_fops = { + .open = ci_port_test_open, + .write = ci_port_test_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; /** - * show_qheads: DMA contents of all queue heads - * - * Check "device.h" for details + * ci_qheads_show: DMA contents of all queue heads */ -static ssize_t show_qheads(struct device *dev, struct device_attribute *attr, - char *buf) +static int ci_qheads_show(struct seq_file *s, void *data) { - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); + struct ci13xxx *ci = s->private; unsigned long flags; - unsigned i, j, n = 0; + unsigned i, j; - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); + if (ci->role != CI_ROLE_GADGET) { + seq_printf(s, "not in gadget mode\n"); return 0; } @@ -236,197 +129,119 @@ static ssize_t show_qheads(struct device *dev, struct device_attribute *attr, struct ci13xxx_ep *mEpRx = &ci->ci13xxx_ep[i]; struct ci13xxx_ep *mEpTx = &ci->ci13xxx_ep[i + ci->hw_ep_max/2]; - n += scnprintf(buf + n, PAGE_SIZE - n, - "EP=%02i: RX=%08X TX=%08X\n", - i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma); - for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) { - n += scnprintf(buf + n, PAGE_SIZE - n, - " %04X: %08X %08X\n", j, - *((u32 *)mEpRx->qh.ptr + j), - *((u32 *)mEpTx->qh.ptr + j)); - } + seq_printf(s, "EP=%02i: RX=%08X TX=%08X\n", + i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma); + for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) + seq_printf(s, " %04X: %08X %08X\n", j, + *((u32 *)mEpRx->qh.ptr + j), + *((u32 *)mEpTx->qh.ptr + j)); } spin_unlock_irqrestore(&ci->lock, flags); - return n; + return 0; } -static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL); -/** - * show_registers: dumps all registers - * - * Check "device.h" for details - */ -#define DUMP_ENTRIES 512 -static ssize_t show_registers(struct device *dev, - struct device_attribute *attr, char *buf) +static int ci_qheads_open(struct inode *inode, struct file *file) { - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - unsigned long flags; - u32 *dump; - unsigned i, k, n = 0; - - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); - return 0; - } - - dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL); - if (!dump) { - dev_err(ci->dev, "%s: out of memory\n", __func__); - return 0; - } - - spin_lock_irqsave(&ci->lock, flags); - k = hw_register_read(ci, dump, DUMP_ENTRIES); - spin_unlock_irqrestore(&ci->lock, flags); - - for (i = 0; i < k; i++) { - n += scnprintf(buf + n, PAGE_SIZE - n, - "reg[0x%04X] = 0x%08X\n", - i * (unsigned)sizeof(u32), dump[i]); - } - kfree(dump); - - return n; + return single_open(file, ci_qheads_show, inode->i_private); } -/** - * store_registers: writes value to register address - * - * Check "device.h" for details - */ -static ssize_t store_registers(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); - unsigned long addr, data, flags; - - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); - goto done; - } - - if (sscanf(buf, "%li %li", &addr, &data) != 2) { - dev_err(ci->dev, - " : write data to register address\n"); - goto done; - } - - spin_lock_irqsave(&ci->lock, flags); - if (hw_register_write(ci, addr, data)) - dev_err(ci->dev, "invalid address range\n"); - spin_unlock_irqrestore(&ci->lock, flags); - - done: - return count; -} -static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR, - show_registers, store_registers); +static const struct file_operations ci_qheads_fops = { + .open = ci_qheads_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; /** - * show_requests: DMA contents of all requests currently queued (all endpts) - * - * Check "device.h" for details + * ci_requests_show: DMA contents of all requests currently queued (all endpts) */ -static ssize_t show_requests(struct device *dev, struct device_attribute *attr, - char *buf) +static int ci_requests_show(struct seq_file *s, void *data) { - struct ci13xxx *ci = container_of(dev, struct ci13xxx, gadget.dev); + struct ci13xxx *ci = s->private; unsigned long flags; struct list_head *ptr = NULL; struct ci13xxx_req *req = NULL; - unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32); + unsigned i, j, qsize = sizeof(struct ci13xxx_td)/sizeof(u32); - if (attr == NULL || buf == NULL) { - dev_err(ci->dev, "[%s] EINVAL\n", __func__); + if (ci->role != CI_ROLE_GADGET) { + seq_printf(s, "not in gadget mode\n"); return 0; } spin_lock_irqsave(&ci->lock, flags); for (i = 0; i < ci->hw_ep_max; i++) - list_for_each(ptr, &ci->ci13xxx_ep[i].qh.queue) - { + list_for_each(ptr, &ci->ci13xxx_ep[i].qh.queue) { req = list_entry(ptr, struct ci13xxx_req, queue); - n += scnprintf(buf + n, PAGE_SIZE - n, - "EP=%02i: TD=%08X %s\n", - i % ci->hw_ep_max/2, (u32)req->dma, - ((i < ci->hw_ep_max/2) ? "RX" : "TX")); + seq_printf(s, "EP=%02i: TD=%08X %s\n", + i % ci->hw_ep_max/2, (u32)req->dma, + ((i < ci->hw_ep_max/2) ? "RX" : "TX")); - for (j = 0; j < qSize; j++) - n += scnprintf(buf + n, PAGE_SIZE - n, - " %04X: %08X\n", j, - *((u32 *)req->ptr + j)); + for (j = 0; j < qsize; j++) + seq_printf(s, " %04X: %08X\n", j, + *((u32 *)req->ptr + j)); } spin_unlock_irqrestore(&ci->lock, flags); - return n; + return 0; +} + +static int ci_requests_open(struct inode *inode, struct file *file) +{ + return single_open(file, ci_requests_show, inode->i_private); } -static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL); + +static const struct file_operations ci_requests_fops = { + .open = ci_requests_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; /** * dbg_create_files: initializes the attribute interface - * @dev: device + * @ci: device * * This function returns an error code */ -int dbg_create_files(struct device *dev) +int dbg_create_files(struct ci13xxx *ci) { - int retval = 0; - - if (dev == NULL) - return -EINVAL; - retval = device_create_file(dev, &dev_attr_device); - if (retval) - goto done; - retval = device_create_file(dev, &dev_attr_driver); - if (retval) - goto rm_device; - retval = device_create_file(dev, &dev_attr_port_test); - if (retval) - goto rm_driver; - retval = device_create_file(dev, &dev_attr_qheads); - if (retval) - goto rm_port_test; - retval = device_create_file(dev, &dev_attr_registers); - if (retval) - goto rm_qheads; - retval = device_create_file(dev, &dev_attr_requests); - if (retval) - goto rm_registers; - return 0; - - rm_registers: - device_remove_file(dev, &dev_attr_registers); - rm_qheads: - device_remove_file(dev, &dev_attr_qheads); - rm_port_test: - device_remove_file(dev, &dev_attr_port_test); - rm_driver: - device_remove_file(dev, &dev_attr_driver); - rm_device: - device_remove_file(dev, &dev_attr_device); - done: - return retval; + struct dentry *dent; + + ci->debugfs = debugfs_create_dir(dev_name(ci->dev), NULL); + if (!ci->debugfs) + return -ENOMEM; + + dent = debugfs_create_file("device", S_IRUGO, ci->debugfs, ci, + &ci_device_fops); + if (!dent) + goto err; + + dent = debugfs_create_file("port_test", S_IRUGO | S_IWUSR, ci->debugfs, + ci, &ci_port_test_fops); + if (!dent) + goto err; + + dent = debugfs_create_file("qheads", S_IRUGO, ci->debugfs, ci, + &ci_qheads_fops); + if (!dent) + goto err; + + dent = debugfs_create_file("requests", S_IRUGO, ci->debugfs, ci, + &ci_requests_fops); + if (dent) + return 0; +err: + debugfs_remove_recursive(ci->debugfs); + return -ENOMEM; } /** * dbg_remove_files: destroys the attribute interface - * @dev: device - * - * This function returns an error code + * @ci: device */ -int dbg_remove_files(struct device *dev) +void dbg_remove_files(struct ci13xxx *ci) { - if (dev == NULL) - return -EINVAL; - device_remove_file(dev, &dev_attr_requests); - device_remove_file(dev, &dev_attr_registers); - device_remove_file(dev, &dev_attr_qheads); - device_remove_file(dev, &dev_attr_port_test); - device_remove_file(dev, &dev_attr_driver); - device_remove_file(dev, &dev_attr_device); - return 0; + debugfs_remove_recursive(ci->debugfs); } -- cgit v1.2.3 From c8e333a3b17050800a5aa536feb628f18d2a01a2 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Sat, 30 Mar 2013 12:53:52 +0200 Subject: usb: chipidea: move role to debugfs Manual role switching function is there for debugging purposes, so has to move to debugfs. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/debug.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'drivers/usb/chipidea/debug.c') diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 057ae09025bf..5738079734e3 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -199,6 +199,55 @@ static const struct file_operations ci_requests_fops = { .release = single_release, }; +static int ci_role_show(struct seq_file *s, void *data) +{ + struct ci13xxx *ci = s->private; + + seq_printf(s, "%s\n", ci_role(ci)->name); + + return 0; +} + +static ssize_t ci_role_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct ci13xxx *ci = s->private; + enum ci_role role; + char buf[8]; + int ret; + + if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + for (role = CI_ROLE_HOST; role < CI_ROLE_END; role++) + if (ci->roles[role] && + !strncmp(buf, ci->roles[role]->name, + strlen(ci->roles[role]->name))) + break; + + if (role == CI_ROLE_END || role == ci->role) + return -EINVAL; + + ci_role_stop(ci); + ret = ci_role_start(ci, role); + + return ret ? ret : count; +} + +static int ci_role_open(struct inode *inode, struct file *file) +{ + return single_open(file, ci_role_show, inode->i_private); +} + +static const struct file_operations ci_role_fops = { + .open = ci_role_open, + .write = ci_role_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /** * dbg_create_files: initializes the attribute interface * @ci: device @@ -230,6 +279,11 @@ int dbg_create_files(struct ci13xxx *ci) dent = debugfs_create_file("requests", S_IRUGO, ci->debugfs, ci, &ci_requests_fops); + if (!dent) + goto err; + + dent = debugfs_create_file("role", S_IRUGO | S_IWUSR, ci->debugfs, ci, + &ci_role_fops); if (dent) return 0; err: -- cgit v1.2.3 From ba8618e067907407ec84001adc11bc1f184d19a6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 30 Mar 2013 12:53:54 +0200 Subject: usb: chipidea: fix precedence bug in ci_requests_show() The intent here was to have parenthesis around the (ci->hw_ep_max / 2) so that it counts like "0 1 2 0 1 2". In the current code, the mod operation happens first so it counts like "0 0 1 1 2 2". Signed-off-by: Dan Carpenter [rebased on top of debug.c changes] Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/chipidea/debug.c') diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 5738079734e3..36a7063a6cba 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -175,7 +175,7 @@ static int ci_requests_show(struct seq_file *s, void *data) req = list_entry(ptr, struct ci13xxx_req, queue); seq_printf(s, "EP=%02i: TD=%08X %s\n", - i % ci->hw_ep_max/2, (u32)req->dma, + i % (ci->hw_ep_max / 2), (u32)req->dma, ((i < ci->hw_ep_max/2) ? "RX" : "TX")); for (j = 0; j < qsize; j++) -- cgit v1.2.3