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

Commit 444a5fa1 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 6b56e832 e4ed11d6
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;
};