Loading drivers/usb/dwc3/core.h +36 −0 Original line number Diff line number Diff line Loading @@ -516,6 +516,35 @@ struct dwc3_event_buffer { struct dwc3 *dwc; }; struct dwc3_gadget_events { unsigned int disconnect; unsigned int reset; unsigned int connect; unsigned int wakeup; unsigned int link_status_change; unsigned int eopf; unsigned int suspend; unsigned int sof; unsigned int erratic_error; unsigned int overflow; unsigned int vendor_dev_test_lmp; unsigned int cmdcmplt; unsigned int unknown_event; }; struct dwc3_ep_events { unsigned int xfercomplete; unsigned int xfernotready; unsigned int control_data; unsigned int control_status; unsigned int xferinprogress; unsigned int rxtxfifoevent; unsigned int streamevent; unsigned int epcmdcomplete; unsigned int unknown_event; unsigned int total; }; #define DWC3_EP_FLAG_STALLED (1 << 0) #define DWC3_EP_FLAG_WEDGED (1 << 1) Loading Loading @@ -550,6 +579,9 @@ struct dwc3_event_buffer { * @name: a human readable name e.g. ep1out-bulk * @direction: true for TX, false for RX * @stream_capable: true when streams are enabled * @dbg_ep_events: different events counter for endpoint * @dbg_ep_events_diff: differential events counter for endpoint * @dbg_ep_events_ts: timestamp for previous event counters */ struct dwc3_ep { struct usb_ep endpoint; Loading Loading @@ -601,6 +633,9 @@ struct dwc3_ep { unsigned direction:1; unsigned stream_capable:1; struct dwc3_ep_events dbg_ep_events; struct dwc3_ep_events dbg_ep_events_diff; struct timespec dbg_ep_events_ts; }; enum dwc3_phy { Loading Loading @@ -1083,6 +1118,7 @@ struct dwc3 { unsigned int irq_dbg_index; wait_queue_head_t wait_linkstate; struct dwc3_gadget_events dbg_gadget_events; }; /* -------------------------------------------------------------------------- */ Loading drivers/usb/dwc3/debugfs.c +159 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ } #define ep_event_rate(ev, c, p, dt) \ ((dt) ? ((c.ev - p.ev) * (MSEC_PER_SEC)) / (dt) : 0) static const struct debugfs_reg32 dwc3_regs[] = { dump_register(GSBUSCFG0), dump_register(GSBUSCFG1), Loading Loading @@ -843,6 +846,155 @@ static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc, } } static ssize_t dwc3_store_int_events(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { int i, ret; unsigned long flags; struct seq_file *s = file->private_data; struct dwc3 *dwc = s->private; struct dwc3_ep *dep; struct timespec ts; u8 clear_stats; if (ubuf == NULL) { pr_err("[%s] EINVAL\n", __func__); ret = -EINVAL; return ret; } ret = kstrtou8_from_user(ubuf, count, 0, &clear_stats); if (ret < 0) { pr_err("can't get enter value.\n"); return ret; } if (clear_stats != 0) { pr_err("Wrong value. To clear stats, enter value as 0.\n"); ret = -EINVAL; return ret; } pr_debug("%s(): clearing debug interrupt buffers\n", __func__); spin_lock_irqsave(&dwc->lock, flags); ts = current_kernel_time(); for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) { dep = dwc->eps[i]; memset(&dep->dbg_ep_events, 0, sizeof(dep->dbg_ep_events)); memset(&dep->dbg_ep_events_diff, 0, sizeof(dep->dbg_ep_events)); dep->dbg_ep_events_ts = ts; } memset(&dwc->dbg_gadget_events, 0, sizeof(dwc->dbg_gadget_events)); spin_unlock_irqrestore(&dwc->lock, flags); return count; } static int dwc3_gadget_int_events_show(struct seq_file *s, void *unused) { unsigned long flags; struct dwc3 *dwc = s->private; struct dwc3_gadget_events *dbg_gadget_events; struct dwc3_ep *dep; int i; struct timespec ts_delta; struct timespec ts_current; u32 ts_delta_ms; spin_lock_irqsave(&dwc->lock, flags); dbg_gadget_events = &dwc->dbg_gadget_events; for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) { dep = dwc->eps[i]; if (dep == NULL || !(dep->flags & DWC3_EP_ENABLED)) continue; ts_current = current_kernel_time(); ts_delta = timespec_sub(ts_current, dep->dbg_ep_events_ts); ts_delta_ms = ts_delta.tv_nsec / NSEC_PER_MSEC + ts_delta.tv_sec * MSEC_PER_SEC; seq_printf(s, "\n\n===== dbg_ep_events for EP(%d) %s =====\n", i, dep->name); seq_printf(s, "xfercomplete:%u @ %luHz\n", dep->dbg_ep_events.xfercomplete, ep_event_rate(xfercomplete, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "xfernotready:%u @ %luHz\n", dep->dbg_ep_events.xfernotready, ep_event_rate(xfernotready, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "control_data:%u @ %luHz\n", dep->dbg_ep_events.control_data, ep_event_rate(control_data, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "control_status:%u @ %luHz\n", dep->dbg_ep_events.control_status, ep_event_rate(control_status, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "xferinprogress:%u @ %luHz\n", dep->dbg_ep_events.xferinprogress, ep_event_rate(xferinprogress, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "rxtxfifoevent:%u @ %luHz\n", dep->dbg_ep_events.rxtxfifoevent, ep_event_rate(rxtxfifoevent, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "streamevent:%u @ %luHz\n", dep->dbg_ep_events.streamevent, ep_event_rate(streamevent, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "epcmdcomplt:%u @ %luHz\n", dep->dbg_ep_events.epcmdcomplete, ep_event_rate(epcmdcomplete, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "unknown:%u @ %luHz\n", dep->dbg_ep_events.unknown_event, ep_event_rate(unknown_event, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "total:%u @ %luHz\n", dep->dbg_ep_events.total, ep_event_rate(total, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); dep->dbg_ep_events_ts = ts_current; dep->dbg_ep_events_diff = dep->dbg_ep_events; } seq_puts(s, "\n=== dbg_gadget events ==\n"); seq_printf(s, "disconnect:%u\n reset:%u\n", dbg_gadget_events->disconnect, dbg_gadget_events->reset); seq_printf(s, "connect:%u\n wakeup:%u\n", dbg_gadget_events->connect, dbg_gadget_events->wakeup); seq_printf(s, "link_status_change:%u\n eopf:%u\n", dbg_gadget_events->link_status_change, dbg_gadget_events->eopf); seq_printf(s, "sof:%u\n suspend:%u\n", dbg_gadget_events->sof, dbg_gadget_events->suspend); seq_printf(s, "erratic_error:%u\n overflow:%u\n", dbg_gadget_events->erratic_error, dbg_gadget_events->overflow); seq_printf(s, "vendor_dev_test_lmp:%u\n cmdcmplt:%u\n", dbg_gadget_events->vendor_dev_test_lmp, dbg_gadget_events->cmdcmplt); seq_printf(s, "unknown_event:%u\n", dbg_gadget_events->unknown_event); spin_unlock_irqrestore(&dwc->lock, flags); return 0; } static int dwc3_gadget_events_open(struct inode *inode, struct file *f) { return single_open(f, dwc3_gadget_int_events_show, inode->i_private); } const struct file_operations dwc3_gadget_dbg_events_fops = { .open = dwc3_gadget_events_open, .read = seq_read, .write = dwc3_store_int_events, .llseek = seq_lseek, .release = single_release, }; int dwc3_debugfs_init(struct dwc3 *dwc) { struct dentry *root; Loading Loading @@ -892,6 +1044,13 @@ int dwc3_debugfs_init(struct dwc3 *dwc) dev_dbg(dwc->dev, "Can't create debugfs link_state\n"); dwc3_debugfs_create_endpoint_dirs(dwc, root); file = debugfs_create_file("int_events", 0644, root, dwc, &dwc3_gadget_dbg_events_fops); if (!file) { ret = -ENOMEM; goto err1; } } return 0; Loading drivers/usb/dwc3/ep0.c +21 −0 Original line number Diff line number Diff line Loading @@ -1072,9 +1072,16 @@ static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { u8 epnum; struct dwc3_ep *dep; epnum = event->endpoint_number; dep = dwc->eps[epnum]; switch (event->status) { case DEPEVT_STATUS_CONTROL_DATA: dwc3_trace(trace_dwc3_ep0, "Control Data"); dep->dbg_ep_events.control_data++; /* * We already have a DATA transfer in the controller's cache, Loading @@ -1098,6 +1105,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, break; case DEPEVT_STATUS_CONTROL_STATUS: dep->dbg_ep_events.control_status++; if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) return; Loading @@ -1118,23 +1126,36 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { struct dwc3_ep *dep; u8 epnum = event->endpoint_number; dwc3_trace(trace_dwc3_ep0, "%s: state '%s'", dwc3_ep_event_string(event), dwc3_ep0_state_string(dwc->ep0state)); dep = dwc->eps[epnum]; switch (event->endpoint_event) { case DWC3_DEPEVT_XFERCOMPLETE: dwc3_ep0_xfer_complete(dwc, event); dep->dbg_ep_events.xfercomplete++; break; case DWC3_DEPEVT_XFERNOTREADY: dwc3_ep0_xfernotready(dwc, event); dep->dbg_ep_events.xfernotready++; break; case DWC3_DEPEVT_XFERINPROGRESS: dep->dbg_ep_events.xferinprogress++; break; case DWC3_DEPEVT_RXTXFIFOEVT: dep->dbg_ep_events.rxtxfifoevent++; break; case DWC3_DEPEVT_STREAMEVT: dep->dbg_ep_events.streamevent++; break; case DWC3_DEPEVT_EPCMDCMPLT: dep->dbg_ep_events.epcmdcomplete++; break; } } drivers/usb/dwc3/gadget.c +20 −1 Original line number Diff line number Diff line Loading @@ -2613,9 +2613,12 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, return; } dep->dbg_ep_events.total++; switch (event->endpoint_event) { case DWC3_DEPEVT_XFERCOMPLETE: dep->resource_index = 0; dep->dbg_ep_events.xfercomplete++; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { dwc3_trace(trace_dwc3_gadget, Loading @@ -2627,9 +2630,11 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dwc3_endpoint_transfer_complete(dwc, dep, event); break; case DWC3_DEPEVT_XFERINPROGRESS: dep->dbg_ep_events.xferinprogress++; dwc3_endpoint_transfer_complete(dwc, dep, event); break; case DWC3_DEPEVT_XFERNOTREADY: dep->dbg_ep_events.xfernotready++; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { dwc3_gadget_start_isoc(dwc, dep, event); } else { Loading @@ -2653,6 +2658,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, break; case DWC3_DEPEVT_STREAMEVT: dep->dbg_ep_events.streamevent++; if (!usb_endpoint_xfer_bulk(dep->endpoint.desc)) { dev_err(dwc->dev, "Stream event for non-Bulk %s\n", dep->name); Loading @@ -2675,9 +2681,11 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, break; case DWC3_DEPEVT_RXTXFIFOEVT: dwc3_trace(trace_dwc3_gadget, "%s FIFO Overrun", dep->name); dep->dbg_ep_events.rxtxfifoevent++; break; case DWC3_DEPEVT_EPCMDCMPLT: dwc3_trace(trace_dwc3_gadget, "Endpoint Command Complete"); dep->dbg_ep_events.epcmdcomplete++; break; } } Loading Loading @@ -3266,15 +3274,19 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, switch (event->type) { case DWC3_DEVICE_EVENT_DISCONNECT: dwc3_gadget_disconnect_interrupt(dwc); dwc->dbg_gadget_events.disconnect++; break; case DWC3_DEVICE_EVENT_RESET: dwc3_gadget_reset_interrupt(dwc); dwc->dbg_gadget_events.reset++; break; case DWC3_DEVICE_EVENT_CONNECT_DONE: dwc3_gadget_conndone_interrupt(dwc); dwc->dbg_gadget_events.connect++; break; case DWC3_DEVICE_EVENT_WAKEUP: dwc3_gadget_wakeup_interrupt(dwc, false); dwc->dbg_gadget_events.wakeup++; break; case DWC3_DEVICE_EVENT_HIBER_REQ: if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation, Loading @@ -3285,13 +3297,15 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); dwc->dbg_gadget_events.link_status_change++; break; case DWC3_DEVICE_EVENT_SUSPEND: if (dwc->revision < DWC3_REVISION_230A) { dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame"); dwc->dbg_gadget_events.eopf++; } else { dwc3_trace(trace_dwc3_gadget, "U3/L1-L2 Suspend Event"); dwc->dbg_gadget_events.suspend++; /* * Ignore suspend event until the gadget enters into * USB_STATE_CONFIGURED state. Loading @@ -3303,18 +3317,23 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_SOF: dwc3_trace(trace_dwc3_gadget, "Start of Periodic Frame"); dwc->dbg_gadget_events.sof++; break; case DWC3_DEVICE_EVENT_ERRATIC_ERROR: dwc3_trace(trace_dwc3_gadget, "Erratic Error"); dwc->dbg_gadget_events.erratic_error++; break; case DWC3_DEVICE_EVENT_CMD_CMPL: dwc3_trace(trace_dwc3_gadget, "Command Complete"); dwc->dbg_gadget_events.cmdcmplt++; break; case DWC3_DEVICE_EVENT_OVERFLOW: dwc3_trace(trace_dwc3_gadget, "Overflow"); dwc->dbg_gadget_events.overflow++; break; default: dev_WARN(dwc->dev, "UNKNOWN IRQ %d\n", event->type); dwc->dbg_gadget_events.unknown_event++; } dwc->err_evt_seen = (event->type == DWC3_DEVICE_EVENT_ERRATIC_ERROR); Loading Loading
drivers/usb/dwc3/core.h +36 −0 Original line number Diff line number Diff line Loading @@ -516,6 +516,35 @@ struct dwc3_event_buffer { struct dwc3 *dwc; }; struct dwc3_gadget_events { unsigned int disconnect; unsigned int reset; unsigned int connect; unsigned int wakeup; unsigned int link_status_change; unsigned int eopf; unsigned int suspend; unsigned int sof; unsigned int erratic_error; unsigned int overflow; unsigned int vendor_dev_test_lmp; unsigned int cmdcmplt; unsigned int unknown_event; }; struct dwc3_ep_events { unsigned int xfercomplete; unsigned int xfernotready; unsigned int control_data; unsigned int control_status; unsigned int xferinprogress; unsigned int rxtxfifoevent; unsigned int streamevent; unsigned int epcmdcomplete; unsigned int unknown_event; unsigned int total; }; #define DWC3_EP_FLAG_STALLED (1 << 0) #define DWC3_EP_FLAG_WEDGED (1 << 1) Loading Loading @@ -550,6 +579,9 @@ struct dwc3_event_buffer { * @name: a human readable name e.g. ep1out-bulk * @direction: true for TX, false for RX * @stream_capable: true when streams are enabled * @dbg_ep_events: different events counter for endpoint * @dbg_ep_events_diff: differential events counter for endpoint * @dbg_ep_events_ts: timestamp for previous event counters */ struct dwc3_ep { struct usb_ep endpoint; Loading Loading @@ -601,6 +633,9 @@ struct dwc3_ep { unsigned direction:1; unsigned stream_capable:1; struct dwc3_ep_events dbg_ep_events; struct dwc3_ep_events dbg_ep_events_diff; struct timespec dbg_ep_events_ts; }; enum dwc3_phy { Loading Loading @@ -1083,6 +1118,7 @@ struct dwc3 { unsigned int irq_dbg_index; wait_queue_head_t wait_linkstate; struct dwc3_gadget_events dbg_gadget_events; }; /* -------------------------------------------------------------------------- */ Loading
drivers/usb/dwc3/debugfs.c +159 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ } #define ep_event_rate(ev, c, p, dt) \ ((dt) ? ((c.ev - p.ev) * (MSEC_PER_SEC)) / (dt) : 0) static const struct debugfs_reg32 dwc3_regs[] = { dump_register(GSBUSCFG0), dump_register(GSBUSCFG1), Loading Loading @@ -843,6 +846,155 @@ static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc, } } static ssize_t dwc3_store_int_events(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { int i, ret; unsigned long flags; struct seq_file *s = file->private_data; struct dwc3 *dwc = s->private; struct dwc3_ep *dep; struct timespec ts; u8 clear_stats; if (ubuf == NULL) { pr_err("[%s] EINVAL\n", __func__); ret = -EINVAL; return ret; } ret = kstrtou8_from_user(ubuf, count, 0, &clear_stats); if (ret < 0) { pr_err("can't get enter value.\n"); return ret; } if (clear_stats != 0) { pr_err("Wrong value. To clear stats, enter value as 0.\n"); ret = -EINVAL; return ret; } pr_debug("%s(): clearing debug interrupt buffers\n", __func__); spin_lock_irqsave(&dwc->lock, flags); ts = current_kernel_time(); for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) { dep = dwc->eps[i]; memset(&dep->dbg_ep_events, 0, sizeof(dep->dbg_ep_events)); memset(&dep->dbg_ep_events_diff, 0, sizeof(dep->dbg_ep_events)); dep->dbg_ep_events_ts = ts; } memset(&dwc->dbg_gadget_events, 0, sizeof(dwc->dbg_gadget_events)); spin_unlock_irqrestore(&dwc->lock, flags); return count; } static int dwc3_gadget_int_events_show(struct seq_file *s, void *unused) { unsigned long flags; struct dwc3 *dwc = s->private; struct dwc3_gadget_events *dbg_gadget_events; struct dwc3_ep *dep; int i; struct timespec ts_delta; struct timespec ts_current; u32 ts_delta_ms; spin_lock_irqsave(&dwc->lock, flags); dbg_gadget_events = &dwc->dbg_gadget_events; for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) { dep = dwc->eps[i]; if (dep == NULL || !(dep->flags & DWC3_EP_ENABLED)) continue; ts_current = current_kernel_time(); ts_delta = timespec_sub(ts_current, dep->dbg_ep_events_ts); ts_delta_ms = ts_delta.tv_nsec / NSEC_PER_MSEC + ts_delta.tv_sec * MSEC_PER_SEC; seq_printf(s, "\n\n===== dbg_ep_events for EP(%d) %s =====\n", i, dep->name); seq_printf(s, "xfercomplete:%u @ %luHz\n", dep->dbg_ep_events.xfercomplete, ep_event_rate(xfercomplete, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "xfernotready:%u @ %luHz\n", dep->dbg_ep_events.xfernotready, ep_event_rate(xfernotready, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "control_data:%u @ %luHz\n", dep->dbg_ep_events.control_data, ep_event_rate(control_data, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "control_status:%u @ %luHz\n", dep->dbg_ep_events.control_status, ep_event_rate(control_status, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "xferinprogress:%u @ %luHz\n", dep->dbg_ep_events.xferinprogress, ep_event_rate(xferinprogress, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "rxtxfifoevent:%u @ %luHz\n", dep->dbg_ep_events.rxtxfifoevent, ep_event_rate(rxtxfifoevent, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "streamevent:%u @ %luHz\n", dep->dbg_ep_events.streamevent, ep_event_rate(streamevent, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "epcmdcomplt:%u @ %luHz\n", dep->dbg_ep_events.epcmdcomplete, ep_event_rate(epcmdcomplete, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "unknown:%u @ %luHz\n", dep->dbg_ep_events.unknown_event, ep_event_rate(unknown_event, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); seq_printf(s, "total:%u @ %luHz\n", dep->dbg_ep_events.total, ep_event_rate(total, dep->dbg_ep_events, dep->dbg_ep_events_diff, ts_delta_ms)); dep->dbg_ep_events_ts = ts_current; dep->dbg_ep_events_diff = dep->dbg_ep_events; } seq_puts(s, "\n=== dbg_gadget events ==\n"); seq_printf(s, "disconnect:%u\n reset:%u\n", dbg_gadget_events->disconnect, dbg_gadget_events->reset); seq_printf(s, "connect:%u\n wakeup:%u\n", dbg_gadget_events->connect, dbg_gadget_events->wakeup); seq_printf(s, "link_status_change:%u\n eopf:%u\n", dbg_gadget_events->link_status_change, dbg_gadget_events->eopf); seq_printf(s, "sof:%u\n suspend:%u\n", dbg_gadget_events->sof, dbg_gadget_events->suspend); seq_printf(s, "erratic_error:%u\n overflow:%u\n", dbg_gadget_events->erratic_error, dbg_gadget_events->overflow); seq_printf(s, "vendor_dev_test_lmp:%u\n cmdcmplt:%u\n", dbg_gadget_events->vendor_dev_test_lmp, dbg_gadget_events->cmdcmplt); seq_printf(s, "unknown_event:%u\n", dbg_gadget_events->unknown_event); spin_unlock_irqrestore(&dwc->lock, flags); return 0; } static int dwc3_gadget_events_open(struct inode *inode, struct file *f) { return single_open(f, dwc3_gadget_int_events_show, inode->i_private); } const struct file_operations dwc3_gadget_dbg_events_fops = { .open = dwc3_gadget_events_open, .read = seq_read, .write = dwc3_store_int_events, .llseek = seq_lseek, .release = single_release, }; int dwc3_debugfs_init(struct dwc3 *dwc) { struct dentry *root; Loading Loading @@ -892,6 +1044,13 @@ int dwc3_debugfs_init(struct dwc3 *dwc) dev_dbg(dwc->dev, "Can't create debugfs link_state\n"); dwc3_debugfs_create_endpoint_dirs(dwc, root); file = debugfs_create_file("int_events", 0644, root, dwc, &dwc3_gadget_dbg_events_fops); if (!file) { ret = -ENOMEM; goto err1; } } return 0; Loading
drivers/usb/dwc3/ep0.c +21 −0 Original line number Diff line number Diff line Loading @@ -1072,9 +1072,16 @@ static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { u8 epnum; struct dwc3_ep *dep; epnum = event->endpoint_number; dep = dwc->eps[epnum]; switch (event->status) { case DEPEVT_STATUS_CONTROL_DATA: dwc3_trace(trace_dwc3_ep0, "Control Data"); dep->dbg_ep_events.control_data++; /* * We already have a DATA transfer in the controller's cache, Loading @@ -1098,6 +1105,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, break; case DEPEVT_STATUS_CONTROL_STATUS: dep->dbg_ep_events.control_status++; if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) return; Loading @@ -1118,23 +1126,36 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { struct dwc3_ep *dep; u8 epnum = event->endpoint_number; dwc3_trace(trace_dwc3_ep0, "%s: state '%s'", dwc3_ep_event_string(event), dwc3_ep0_state_string(dwc->ep0state)); dep = dwc->eps[epnum]; switch (event->endpoint_event) { case DWC3_DEPEVT_XFERCOMPLETE: dwc3_ep0_xfer_complete(dwc, event); dep->dbg_ep_events.xfercomplete++; break; case DWC3_DEPEVT_XFERNOTREADY: dwc3_ep0_xfernotready(dwc, event); dep->dbg_ep_events.xfernotready++; break; case DWC3_DEPEVT_XFERINPROGRESS: dep->dbg_ep_events.xferinprogress++; break; case DWC3_DEPEVT_RXTXFIFOEVT: dep->dbg_ep_events.rxtxfifoevent++; break; case DWC3_DEPEVT_STREAMEVT: dep->dbg_ep_events.streamevent++; break; case DWC3_DEPEVT_EPCMDCMPLT: dep->dbg_ep_events.epcmdcomplete++; break; } }
drivers/usb/dwc3/gadget.c +20 −1 Original line number Diff line number Diff line Loading @@ -2613,9 +2613,12 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, return; } dep->dbg_ep_events.total++; switch (event->endpoint_event) { case DWC3_DEPEVT_XFERCOMPLETE: dep->resource_index = 0; dep->dbg_ep_events.xfercomplete++; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { dwc3_trace(trace_dwc3_gadget, Loading @@ -2627,9 +2630,11 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dwc3_endpoint_transfer_complete(dwc, dep, event); break; case DWC3_DEPEVT_XFERINPROGRESS: dep->dbg_ep_events.xferinprogress++; dwc3_endpoint_transfer_complete(dwc, dep, event); break; case DWC3_DEPEVT_XFERNOTREADY: dep->dbg_ep_events.xfernotready++; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { dwc3_gadget_start_isoc(dwc, dep, event); } else { Loading @@ -2653,6 +2658,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, break; case DWC3_DEPEVT_STREAMEVT: dep->dbg_ep_events.streamevent++; if (!usb_endpoint_xfer_bulk(dep->endpoint.desc)) { dev_err(dwc->dev, "Stream event for non-Bulk %s\n", dep->name); Loading @@ -2675,9 +2681,11 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, break; case DWC3_DEPEVT_RXTXFIFOEVT: dwc3_trace(trace_dwc3_gadget, "%s FIFO Overrun", dep->name); dep->dbg_ep_events.rxtxfifoevent++; break; case DWC3_DEPEVT_EPCMDCMPLT: dwc3_trace(trace_dwc3_gadget, "Endpoint Command Complete"); dep->dbg_ep_events.epcmdcomplete++; break; } } Loading Loading @@ -3266,15 +3274,19 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, switch (event->type) { case DWC3_DEVICE_EVENT_DISCONNECT: dwc3_gadget_disconnect_interrupt(dwc); dwc->dbg_gadget_events.disconnect++; break; case DWC3_DEVICE_EVENT_RESET: dwc3_gadget_reset_interrupt(dwc); dwc->dbg_gadget_events.reset++; break; case DWC3_DEVICE_EVENT_CONNECT_DONE: dwc3_gadget_conndone_interrupt(dwc); dwc->dbg_gadget_events.connect++; break; case DWC3_DEVICE_EVENT_WAKEUP: dwc3_gadget_wakeup_interrupt(dwc, false); dwc->dbg_gadget_events.wakeup++; break; case DWC3_DEVICE_EVENT_HIBER_REQ: if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation, Loading @@ -3285,13 +3297,15 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); dwc->dbg_gadget_events.link_status_change++; break; case DWC3_DEVICE_EVENT_SUSPEND: if (dwc->revision < DWC3_REVISION_230A) { dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame"); dwc->dbg_gadget_events.eopf++; } else { dwc3_trace(trace_dwc3_gadget, "U3/L1-L2 Suspend Event"); dwc->dbg_gadget_events.suspend++; /* * Ignore suspend event until the gadget enters into * USB_STATE_CONFIGURED state. Loading @@ -3303,18 +3317,23 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_SOF: dwc3_trace(trace_dwc3_gadget, "Start of Periodic Frame"); dwc->dbg_gadget_events.sof++; break; case DWC3_DEVICE_EVENT_ERRATIC_ERROR: dwc3_trace(trace_dwc3_gadget, "Erratic Error"); dwc->dbg_gadget_events.erratic_error++; break; case DWC3_DEVICE_EVENT_CMD_CMPL: dwc3_trace(trace_dwc3_gadget, "Command Complete"); dwc->dbg_gadget_events.cmdcmplt++; break; case DWC3_DEVICE_EVENT_OVERFLOW: dwc3_trace(trace_dwc3_gadget, "Overflow"); dwc->dbg_gadget_events.overflow++; break; default: dev_WARN(dwc->dev, "UNKNOWN IRQ %d\n", event->type); dwc->dbg_gadget_events.unknown_event++; } dwc->err_evt_seen = (event->type == DWC3_DEVICE_EVENT_ERRATIC_ERROR); Loading