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

Commit e4ed11d6 authored by Jack Pham's avatar Jack Pham
Browse files

usb: gadget: f_fs: Support multi-instance IPC logging



Currently the ffs_log() macro logs to a single IPC log buffer.
If multiple functions are instantiated (e.g. ADB and MTP) the
log would be extremely difficult to interpret. Instead, separate
each instance to its own IPC log buffer.

While at it, fix up the macro for ffs_log() to pass the exact
same string to ipc_log_string() and the printk/pr_debug(). This
is to ensure that the format string does not get duplicated with
in the compiled object.

Change-Id: Ieceea06c9b91ae8c2700e306d7ab5822e8a7a26c
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 12165278
Loading
Loading
Loading
Loading
+63 −56
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@
#include <linux/module.h>
#include <linux/sched/signal.h>
#include <linux/uio.h>
#include <linux/ipc_logging.h>
#include <asm/unaligned.h>

#include <linux/usb/composite.h>
@@ -45,12 +44,15 @@

#define NUM_PAGES	10 /* # of pages for ipc logging */

static void *ffs_ipc_log;
#ifdef CONFIG_DYNAMIC_DEBUG
#define ffs_log(fmt, ...) do { \
	ipc_log_string(ffs_ipc_log, "%s: " fmt,  __func__, \
			##__VA_ARGS__); \
	pr_debug(fmt, ##__VA_ARGS__); \
	ipc_log_string(ffs->ipc_log, "%s: " fmt,  __func__, ##__VA_ARGS__); \
	dynamic_pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
#else
#define ffs_log(fmt, ...) \
	ipc_log_string(ffs->ipc_log, "%s: " fmt,  __func__, ##__VA_ARGS__)
#endif

/* Reference counter handling */
static void ffs_data_get(struct ffs_data *ffs);
@@ -756,7 +758,6 @@ static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req)
	if (likely(req->context)) {
		struct ffs_ep *ep = _ep->driver_data;
		ep->status = req->status ? req->status : req->actual;
		ffs_log("ep status %d for req %pK", ep->status, req);
		complete(req->context);
	}
}
@@ -808,6 +809,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
{
	struct ffs_io_data *io_data = container_of(work, struct ffs_io_data,
						   work);
	struct ffs_data *ffs = io_data->ffs;
	int ret = io_data->req->status ? io_data->req->status :
					 io_data->req->actual;
	bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
@@ -938,6 +940,7 @@ static ssize_t __ffs_epfile_read_data(struct ffs_epfile *epfile,
static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
{
	struct ffs_epfile *epfile = file->private_data;
	struct ffs_data *ffs = epfile->ffs;
	struct usb_request *req;
	struct ffs_ep *ep;
	char *data = NULL;
@@ -1086,6 +1089,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
			interrupted = ep->status < 0;
		}

		ffs_log("ep status %d for req %pK", ep->status, req);

		if (interrupted)
			ret = -EINTR;
		else if (io_data->read && ep->status > 0)
@@ -1140,6 +1145,7 @@ static int
ffs_epfile_open(struct inode *inode, struct file *file)
{
	struct ffs_epfile *epfile = inode->i_private;
	struct ffs_data *ffs = epfile->ffs;

	ENTER();

@@ -1193,6 +1199,8 @@ static int ffs_aio_cancel(struct kiocb *kiocb)

static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
{
	struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
	struct ffs_data *ffs = epfile->ffs;
	struct ffs_io_data io_data, *p = &io_data;
	ssize_t res;

@@ -1234,6 +1242,8 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)

static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
{
	struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
	struct ffs_data *ffs = epfile->ffs;
	struct ffs_io_data io_data, *p = &io_data;
	ssize_t res;

@@ -1289,6 +1299,7 @@ static int
ffs_epfile_release(struct inode *inode, struct file *file)
{
	struct ffs_epfile *epfile = inode->i_private;
	struct ffs_data *ffs = epfile->ffs;

	ENTER();

@@ -1309,6 +1320,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
			     unsigned long value)
{
	struct ffs_epfile *epfile = file->private_data;
	struct ffs_data *ffs = epfile->ffs;
	struct ffs_ep *ep;
	int ret;

@@ -1416,6 +1428,7 @@ ffs_sb_make_inode(struct super_block *sb, void *data,
		  const struct inode_operations *iops,
		  struct ffs_file_perms *perms)
{
	struct ffs_data	*ffs = sb->s_fs_info;
	struct inode *inode;

	ENTER();
@@ -1527,8 +1540,6 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts)
{
	ENTER();

	ffs_log("enter");

	if (!opts || !*opts)
		return 0;

@@ -1636,8 +1647,6 @@ ffs_fs_mount(struct file_system_type *t, int flags,

	ENTER();

	ffs_log("enter");

	ret = ffs_fs_parse_opts(&data, opts);
	if (unlikely(ret < 0))
		return ERR_PTR(ret);
@@ -1676,8 +1685,6 @@ ffs_fs_kill_sb(struct super_block *sb)
{
	ENTER();

	ffs_log("enter");

	kill_litter_super(sb);
	if (sb->s_fs_info) {
		ffs_release_dev(sb->s_fs_info);
@@ -1708,10 +1715,6 @@ static int functionfs_init(void)
	else
		pr_err("failed registering file system (%d)\n", ret);

	ffs_ipc_log = ipc_log_context_create(NUM_PAGES, "f_fs", 0);
	if (IS_ERR_OR_NULL(ffs_ipc_log))
		ffs_ipc_log =  NULL;

	return ret;
}

@@ -1721,11 +1724,6 @@ static void functionfs_cleanup(void)

	pr_info("unloading\n");
	unregister_filesystem(&ffs_fs_type);

	if (ffs_ipc_log) {
		ipc_log_context_destroy(ffs_ipc_log);
		ffs_ipc_log = NULL;
	}
}


@@ -1772,6 +1770,7 @@ static void ffs_data_put(struct ffs_data *ffs)
		       waitqueue_active(&ffs->ep0req_completion.wait) ||
		       waitqueue_active(&ffs->wait));
		destroy_workqueue(ffs->io_completion_wq);
		ipc_log_context_destroy(ffs->ipc_log);
		kfree(ffs->dev_name);
		kfree(ffs);
	}
@@ -1809,14 +1808,13 @@ static void ffs_data_closed(struct ffs_data *ffs)

static struct ffs_data *ffs_data_new(const char *dev_name)
{
	char ipcname[24] = "usb_ffs_";
	struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL);
	if (unlikely(!ffs))
		return NULL;

	ENTER();

	ffs_log("enter");

	ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name);
	if (!ffs->io_completion_wq) {
		kfree(ffs);
@@ -1835,6 +1833,11 @@ static struct ffs_data *ffs_data_new(const char *dev_name)
	/* XXX REVISIT need to update it in some places, or do we? */
	ffs->ev.can_stall = 1;

	strlcat(ipcname, dev_name, sizeof(ipcname));
	ffs->ipc_log = ipc_log_context_create(NUM_PAGES, ipcname, 0);
	if (IS_ERR_OR_NULL(ffs->ipc_log))
		ffs->ipc_log =  NULL;

	return ffs;
}

@@ -1991,6 +1994,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
{
	struct ffs_epfile *epfile = epfiles;
	struct ffs_data *ffs = epfiles->ffs;

	ENTER();

@@ -2011,6 +2015,7 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
static void ffs_func_eps_disable(struct ffs_function *func)
{
	struct ffs_ep *ep         = func->eps;
	struct ffs_data *ffs      = func->ffs;
	struct ffs_epfile *epfile = func->ffs->epfiles;
	unsigned count            = func->ffs->eps_count;
	unsigned long flags;
@@ -2106,7 +2111,8 @@ typedef int (*ffs_os_desc_callback)(enum ffs_os_desc_type entity,
				    struct usb_os_desc_header *h, void *data,
				    unsigned len, void *priv);

static int __must_check ffs_do_single_desc(char *data, unsigned len,
static int __must_check ffs_do_single_desc(struct ffs_data *ffs,
					   char *data, unsigned int len,
					   ffs_entity_callback entity,
					   void *priv)
{
@@ -2239,7 +2245,8 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len,
	return length;
}

static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
static int __must_check ffs_do_descs(struct ffs_data *ffs, unsigned int count,
				     char *data, unsigned int len,
				     ffs_entity_callback entity, void *priv)
{
	const unsigned _len = len;
@@ -2266,7 +2273,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
		if (!data)
			return _len - len;

		ret = ffs_do_single_desc(data, len, entity, priv);
		ret = ffs_do_single_desc(ffs, data, len, entity, priv);
		if (unlikely(ret < 0)) {
			pr_debug("%s returns %d\n", __func__, ret);
			return ret;
@@ -2283,6 +2290,7 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
				void *priv)
{
	struct ffs_desc_helper *helper = priv;
	struct ffs_data *ffs = helper->ffs;
	struct usb_endpoint_descriptor *d;

	ENTER();
@@ -2330,7 +2338,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
	return 0;
}

static int __ffs_do_os_desc_header(enum ffs_os_desc_type *next_type,
static int __ffs_do_os_desc_header(struct ffs_data *ffs,
				   enum ffs_os_desc_type *next_type,
				   struct usb_os_desc_header *desc)
{
	u16 bcd_version = le16_to_cpu(desc->bcdVersion);
@@ -2362,7 +2371,8 @@ static int __ffs_do_os_desc_header(enum ffs_os_desc_type *next_type,
 * Process all extended compatibility/extended property descriptors
 * of a feature descriptor
 */
static int __must_check ffs_do_single_os_desc(char *data, unsigned len,
static int __must_check ffs_do_single_os_desc(struct ffs_data *ffs,
					      char *data, unsigned int len,
					      enum ffs_os_desc_type type,
					      u16 feature_count,
					      ffs_os_desc_callback entity,
@@ -2392,8 +2402,9 @@ static int __must_check ffs_do_single_os_desc(char *data, unsigned len,
}

/* Process a number of complete Feature Descriptors (Ext Compat or Ext Prop) */
static int __must_check ffs_do_os_descs(unsigned count,
					char *data, unsigned len,
static int __must_check ffs_do_os_descs(struct ffs_data *ffs,
					unsigned int count, char *data,
					unsigned int len,
					ffs_os_desc_callback entity, void *priv)
{
	const unsigned _len = len;
@@ -2422,7 +2433,7 @@ static int __must_check ffs_do_os_descs(unsigned count,
		if (le32_to_cpu(desc->dwLength) > len)
			return -EINVAL;

		ret = __ffs_do_os_desc_header(&type, desc);
		ret = __ffs_do_os_desc_header(ffs, &type, desc);
		if (unlikely(ret < 0)) {
			ffs_log("entity OS_DESCRIPTOR(%02lx); ret = %d\n",
				 num, ret);
@@ -2442,7 +2453,7 @@ static int __must_check ffs_do_os_descs(unsigned count,
		 * Process all function/property descriptors
		 * of this Feature Descriptor
		 */
		ret = ffs_do_single_os_desc(data, len, type,
		ret = ffs_do_single_os_desc(ffs, data, len, type,
					    feature_count, entity, priv, desc);
		if (unlikely(ret < 0)) {
			ffs_log("%s returns %d\n", __func__, ret);
@@ -2623,7 +2634,7 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
			continue;
		helper.interfaces_count = 0;
		helper.eps_count = 0;
		ret = ffs_do_descs(counts[i], data, len,
		ret = ffs_do_descs(ffs, counts[i], data, len,
				   __ffs_data_do_entity, &helper);
		if (ret < 0)
			goto error;
@@ -2644,7 +2655,7 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
		len  -= ret;
	}
	if (os_descs_count) {
		ret = ffs_do_os_descs(os_descs_count, data, len,
		ret = ffs_do_os_descs(ffs, os_descs_count, data, len,
				      __ffs_data_do_os_desc, ffs);
		if (ret < 0)
			goto error;
@@ -2907,6 +2918,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
{
	struct usb_endpoint_descriptor *ds = (void *)desc;
	struct ffs_function *func = priv;
	struct ffs_data *ffs = func->ffs;
	struct ffs_ep *ffs_ep;
	unsigned ep_desc_id;
	int idx;
@@ -2997,6 +3009,7 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep,
				   void *priv)
{
	struct ffs_function *func = priv;
	struct ffs_data *ffs = func->ffs;
	unsigned idx;
	u8 newValue;

@@ -3057,6 +3070,7 @@ static int __ffs_func_bind_do_os_desc(enum ffs_os_desc_type type,
				      unsigned len, void *priv)
{
	struct ffs_function *func = priv;
	struct ffs_data *ffs = func->ffs;
	u8 length = 0;

	ffs_log("enter: type %d", type);
@@ -3139,6 +3153,7 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f,
	struct ffs_function *func = ffs_func_from_usb(f);
	struct f_fs_opts *ffs_opts =
		container_of(f->fi, struct f_fs_opts, func_inst);
	struct ffs_data *ffs = ffs_opts->dev->ffs_data;
	int ret;

	ENTER();
@@ -3264,7 +3279,7 @@ static int _ffs_func_bind(struct usb_configuration *c,
	 */
	if (likely(full)) {
		func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs);
		fs_len = ffs_do_descs(ffs->fs_descs_count,
		fs_len = ffs_do_descs(ffs, ffs->fs_descs_count,
				      vla_ptr(vlabuf, d, raw_descs),
				      d_raw_descs__sz,
				      __ffs_func_bind_do_descs, func);
@@ -3278,7 +3293,7 @@ static int _ffs_func_bind(struct usb_configuration *c,

	if (likely(high)) {
		func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs);
		hs_len = ffs_do_descs(ffs->hs_descs_count,
		hs_len = ffs_do_descs(ffs, ffs->hs_descs_count,
				      vla_ptr(vlabuf, d, raw_descs) + fs_len,
				      d_raw_descs__sz - fs_len,
				      __ffs_func_bind_do_descs, func);
@@ -3292,7 +3307,7 @@ static int _ffs_func_bind(struct usb_configuration *c,

	if (likely(super)) {
		func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs);
		ss_len = ffs_do_descs(ffs->ss_descs_count,
		ss_len = ffs_do_descs(ffs, ffs->ss_descs_count,
				vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len,
				d_raw_descs__sz - fs_len - hs_len,
				__ffs_func_bind_do_descs, func);
@@ -3310,7 +3325,7 @@ static int _ffs_func_bind(struct usb_configuration *c,
	 * endpoint numbers rewriting.  We can do that in one go
	 * now.
	 */
	ret = ffs_do_descs(ffs->fs_descs_count +
	ret = ffs_do_descs(ffs, ffs->fs_descs_count +
			   (high ? ffs->hs_descs_count : 0) +
			   (super ? ffs->ss_descs_count : 0),
			   vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz,
@@ -3330,7 +3345,7 @@ static int _ffs_func_bind(struct usb_configuration *c,
				vla_ptr(vlabuf, d, ext_compat) + i * 16;
			INIT_LIST_HEAD(&desc->ext_prop);
		}
		ret = ffs_do_os_descs(ffs->ms_os_descs_count,
		ret = ffs_do_os_descs(ffs, ffs->ms_os_descs_count,
				      vla_ptr(vlabuf, d, raw_descs) +
				      fs_len + hs_len + ss_len,
				      d_raw_descs__sz - fs_len - hs_len -
@@ -3358,6 +3373,7 @@ static int ffs_func_bind(struct usb_configuration *c,
{
	struct f_fs_opts *ffs_opts = ffs_do_functionfs_bind(f, c);
	struct ffs_function *func = ffs_func_from_usb(f);
	struct ffs_data *ffs = func->ffs;
	int ret;

	ffs_log("enter");
@@ -3436,6 +3452,9 @@ static int ffs_func_set_alt(struct usb_function *f,

static void ffs_func_disable(struct usb_function *f)
{
	struct ffs_function *func = ffs_func_from_usb(f);
	struct ffs_data *ffs = func->ffs;

	ffs_log("enter");
	ffs_func_set_alt(f, 0, (unsigned)-1);
}
@@ -3510,6 +3529,7 @@ static bool ffs_func_req_match(struct usb_function *f,
			       bool config0)
{
	struct ffs_function *func = ffs_func_from_usb(f);
	struct ffs_data *ffs = func->ffs;

	if (!test_bit(FFS_FL_BOUND, &func->ffs->flags)) {
		ffs_log("ffs function do not bind yet.\n");
@@ -3534,6 +3554,8 @@ static bool ffs_func_req_match(struct usb_function *f,

static void ffs_func_suspend(struct usb_function *f)
{
	struct ffs_data *ffs = ffs_func_from_usb(f)->ffs;

	ENTER();

	ffs_log("enter");
@@ -3543,6 +3565,8 @@ static void ffs_func_suspend(struct usb_function *f)

static void ffs_func_resume(struct usb_function *f)
{
	struct ffs_data *ffs = ffs_func_from_usb(f)->ffs;

	ENTER();

	ffs_log("enter");
@@ -3581,8 +3605,6 @@ static struct ffs_dev *_ffs_do_find_dev(const char *name)
{
	struct ffs_dev *dev;

	ffs_log("enter");

	if (!name)
		return NULL;

@@ -3601,8 +3623,6 @@ static struct ffs_dev *_ffs_get_single_dev(void)
{
	struct ffs_dev *dev;

	ffs_log("enter");

	if (list_is_singular(&ffs_devices)) {
		dev = list_first_entry(&ffs_devices, struct ffs_dev, entry);
		if (dev->single)
@@ -3619,8 +3639,6 @@ static struct ffs_dev *_ffs_find_dev(const char *name)
{
	struct ffs_dev *dev;

	ffs_log("enter");

	dev = _ffs_get_single_dev();
	if (dev)
		return dev;
@@ -3815,8 +3833,6 @@ int ffs_name_dev(struct ffs_dev *dev, const char *name)
	struct ffs_dev *existing;
	int ret = 0;

	ffs_log("enter");

	ffs_dev_lock();

	existing = _ffs_do_find_dev(name);
@@ -3835,8 +3851,6 @@ int ffs_single_dev(struct ffs_dev *dev)
{
	int ret;

	ffs_log("enter");

	ret = 0;
	ffs_dev_lock();

@@ -3856,9 +3870,6 @@ EXPORT_SYMBOL_GPL(ffs_single_dev);
 */
static void _ffs_free_dev(struct ffs_dev *dev)
{

	ffs_log("enter");

	list_del(&dev->entry);

	/* Clear the private_data pointer to stop incorrect dev access */
@@ -3876,8 +3887,6 @@ static void *ffs_acquire_dev(const char *dev_name)

	ENTER();

	ffs_log("enter");

	ffs_dev_lock();

	ffs_dev = _ffs_find_dev(dev_name);
@@ -3902,8 +3911,6 @@ static void ffs_release_dev(struct ffs_data *ffs_data)

	ENTER();

	ffs_log("enter");

	ffs_dev_lock();

	ffs_dev = ffs_data->private_data;
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/refcount.h>
#include <linux/ipc_logging.h>

#ifdef VERBOSE_DEBUG
#ifndef pr_vdebug
@@ -288,6 +289,8 @@ struct ffs_data {
	 * destroyed by ffs_epfiles_destroy().
	 */
	struct ffs_epfile		*epfiles;

	void				*ipc_log;
};