Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1946462AbdDYK3h (ORCPT ); Tue, 25 Apr 2017 06:29:37 -0400 Received: from mga06.intel.com ([134.134.136.31]:21206 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1429535AbdDYK2y (ORCPT ); Tue, 25 Apr 2017 06:28:54 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.37,249,1488873600"; d="scan'208";a="960809735" Date: Tue, 25 Apr 2017 13:28:42 +0300 From: Heikki Krogerus To: Guenter Roeck Cc: Felipe Balbi , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Mats Karrman , Badhri Jagan Sridharan , Oliver Neukum , Guenter Roeck Subject: Re: [RFC PATCH v5 1/2] usb: typec: USB Type-C Port Manager (tcpm) Message-ID: <20170425102842.GD14268@kuha.fi.intel.com> References: <1492812953-30434-1-git-send-email-linux@roeck-us.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1492812953-30434-1-git-send-email-linux@roeck-us.net> User-Agent: Mutt/1.8.0 (2017-02-23) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3991 Lines: 154 Hi Guenter, On Fri, Apr 21, 2017 at 03:15:52PM -0700, Guenter Roeck wrote: > +/* > + * Logging > + */ > + > +#ifdef CONFIG_DEBUG_FS > + > +static bool tcpm_log_full(struct tcpm_port *port) > +{ > + return port->logbuffer_tail == > + (port->logbuffer_head + 1) % LOG_BUFFER_ENTRIES; > +} > + > +static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args) > +{ > + char tmpbuffer[LOG_BUFFER_ENTRY_SIZE]; > + u64 ts_nsec = local_clock(); > + unsigned long rem_nsec; > + > + if (!port->logbuffer[port->logbuffer_head]) { > + port->logbuffer[port->logbuffer_head] = > + kzalloc(LOG_BUFFER_ENTRY_SIZE, GFP_KERNEL); > + if (!port->logbuffer[port->logbuffer_head]) > + return; > + } > + > + vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args); > + > + mutex_lock(&port->logbuffer_lock); > + > + if (tcpm_log_full(port)) { > + port->logbuffer_head = max(port->logbuffer_head - 1, 0); > + strcpy(tmpbuffer, "overflow"); > + } > + > + if (port->logbuffer_head < 0 || > + port->logbuffer_head >= LOG_BUFFER_ENTRIES) { > + dev_warn(port->dev, > + "Bad log buffer index %d\n", port->logbuffer_head); > + goto abort; > + } > + > + if (!port->logbuffer[port->logbuffer_head]) { > + dev_warn(port->dev, > + "Log buffer index %d is NULL\n", port->logbuffer_head); > + goto abort; > + } > + > + rem_nsec = do_div(ts_nsec, 1000000000); > + scnprintf(port->logbuffer[port->logbuffer_head], > + LOG_BUFFER_ENTRY_SIZE, "[%5lu.%06lu] %s", > + (unsigned long)ts_nsec, rem_nsec / 1000, > + tmpbuffer); > + port->logbuffer_head = (port->logbuffer_head + 1) % LOG_BUFFER_ENTRIES; > + > +abort: > + mutex_unlock(&port->logbuffer_lock); > +} > + > +static void tcpm_log(struct tcpm_port *port, const char *fmt, ...) > +{ > + va_list args; > + > + /* Do not log while disconnected and unattached */ > + if (tcpm_port_is_disconnected(port) && > + (port->state == SRC_UNATTACHED || port->state == SNK_UNATTACHED || > + port->state == DRP_TOGGLING)) > + return; > + > + va_start(args, fmt); > + _tcpm_log(port, fmt, args); > + va_end(args); > +} > + > +static void tcpm_log_force(struct tcpm_port *port, const char *fmt, ...) > +{ > + va_list args; > + > + va_start(args, fmt); > + _tcpm_log(port, fmt, args); > + va_end(args); > +} > + > +static int tcpm_seq_show(struct seq_file *s, void *v) > +{ > + struct tcpm_port *port = (struct tcpm_port *)s->private; > + int tail; > + > + mutex_lock(&port->logbuffer_lock); > + tail = port->logbuffer_tail; > + while (tail != port->logbuffer_head) { > + seq_printf(s, "%s\n", port->logbuffer[tail]); > + tail = (tail + 1) % LOG_BUFFER_ENTRIES; > + } > + if (!seq_has_overflowed(s)) > + port->logbuffer_tail = tail; > + mutex_unlock(&port->logbuffer_lock); > + > + return 0; > +} > + > +static int tcpm_debug_open(struct inode *inode, struct file *file) > +{ > + return single_open(file, tcpm_seq_show, inode->i_private); > +} > + > +static const struct file_operations tcpm_debug_operations = { > + .open = tcpm_debug_open, > + .llseek = seq_lseek, > + .read = seq_read, > + .release = single_release, > +}; > + > +static struct dentry *rootdir; > + > +static int tcpm_debugfs_init(struct tcpm_port *port) > +{ > + mutex_init(&port->logbuffer_lock); > + /* /sys/kernel/debug/tcpm/usbcX */ > + if (!rootdir) { > + rootdir = debugfs_create_dir("tcpm", NULL); > + if (!rootdir) > + return -ENOMEM; > + } > + > + port->dentry = debugfs_create_file(dev_name(port->dev), > + S_IFREG | 0444, rootdir, > + port, &tcpm_debug_operations); > + > + return 0; > +} > + > +static void tcpm_debugfs_exit(struct tcpm_port *port) > +{ > + debugfs_remove(port->dentry); > +} > + > +#else > > +static void tcpm_log(const struct tcpm_port *port, const char *fmt, ...) { } > +static int tcpm_debugfs_init(const struct tcpm_port *port) { return 0; } > +static void tcpm_debugfs_exit(const struct tcpm_port *port) { } > + > +#endif I think those should be converted into tracepoints at one point. Thanks, -- heikki