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

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

Merge "usb: gadget: Add check gadget function bind or not"

parents ceff9044 2b958bac
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -15,11 +15,16 @@
#include <linux/kdev_t.h>
#include <linux/usb/ch9.h>

#ifdef CONFIG_USB_F_NCM
#include <function/u_ncm.h>
#endif

#ifdef CONFIG_USB_CONFIGFS_F_ACC
extern int acc_ctrlrequest(struct usb_composite_dev *cdev,
				const struct usb_ctrlrequest *ctrl);
void acc_disconnect(void);
#endif

static struct class *android_class;
static struct device *android_device;
static int index;
@@ -1508,6 +1513,18 @@ static int android_setup(struct usb_gadget *gadget,
		}
	}

#ifdef CONFIG_USB_F_NCM
	if (value < 0)
		value = ncm_ctrlrequest(cdev, c);

	/*
	 * for mirror link command case, if it already been handled,
	 * do not pass to composite_setup
	 */
	if (value == 0)
		return value;
#endif

#ifdef CONFIG_USB_CONFIGFS_F_ACC
	if (value < 0)
		value = acc_ctrlrequest(cdev, c);
+58 −1
Original line number Diff line number Diff line
@@ -1580,10 +1580,58 @@ static const struct config_item_type ncm_func_type = {
	.ct_owner	= THIS_MODULE,
};

#ifdef CONFIG_USB_CONFIGFS_UEVENT

struct ncm_setup_desc {
	struct work_struct work;
	struct device *device;
	uint8_t major; // Mirror Link major version
	uint8_t minor; // Mirror Link minor version
};

static struct ncm_setup_desc *_ncm_setup_desc;

#define MIRROR_LINK_STRING_LENGTH_MAX 32
static void ncm_setup_work(struct work_struct *data)
{
	char mirror_link_string[MIRROR_LINK_STRING_LENGTH_MAX];
	char *envp[2] = { mirror_link_string, NULL };

	snprintf(mirror_link_string, MIRROR_LINK_STRING_LENGTH_MAX,
		"MirrorLink=V%d.%d",
		_ncm_setup_desc->major, _ncm_setup_desc->minor);
	kobject_uevent_env(&_ncm_setup_desc->device->kobj, KOBJ_CHANGE, envp);
}

int ncm_ctrlrequest(struct usb_composite_dev *cdev,
			const struct usb_ctrlrequest *ctrl)
{
	int value = -EOPNOTSUPP;

	if (ctrl->bRequestType == 0x40 && ctrl->bRequest == 0xF0
			&& _ncm_setup_desc) {
		_ncm_setup_desc->minor = (uint8_t)(ctrl->wValue >> 8);
		_ncm_setup_desc->major = (uint8_t)(ctrl->wValue & 0xFF);
		schedule_work(&_ncm_setup_desc->work);
		value = 0;
	}

	return value;
}
#endif

static void ncm_free_inst(struct usb_function_instance *f)
{
	struct f_ncm_opts *opts;

#ifdef CONFIG_USB_CONFIGFS_UEVENT
	cancel_work_sync(&_ncm_setup_desc->work);
	/* release _ncm_setup_desc related resource */
	device_destroy(_ncm_setup_desc->device->class,
		_ncm_setup_desc->device->devt);
	kfree(_ncm_setup_desc);
#endif

	opts = container_of(f, struct f_ncm_opts, func_inst);
	if (opts->bound)
		gether_cleanup(netdev_priv(opts->net));
@@ -1602,6 +1650,14 @@ static struct usb_function_instance *ncm_alloc_inst(void)

	config_group_init_type_name(&opts->func_inst.group, "", &ncm_func_type);

#ifdef CONFIG_USB_CONFIGFS_UEVENT
	_ncm_setup_desc = kzalloc(sizeof(*_ncm_setup_desc), GFP_KERNEL);
	if (!_ncm_setup_desc)
		return ERR_PTR(-ENOMEM);
	INIT_WORK(&_ncm_setup_desc->work, ncm_setup_work);
	_ncm_setup_desc->device = create_function_device("f_ncm");
#endif

	return &opts->func_inst;
}

@@ -1626,6 +1682,8 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)

	DBG(c->cdev, "ncm unbind\n");

	opts->bound = false;

	hrtimer_cancel(&ncm->task_timer);

	ncm_string_defs[0].id = 0;
@@ -1635,7 +1693,6 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)
	usb_ep_free_request(ncm->notify, ncm->notify_req);

	gether_cleanup(netdev_priv(opts->net));
	opts->bound = false;
}

static struct usb_function *ncm_alloc(struct usb_function_instance *fi)
+35 −0
Original line number Diff line number Diff line
@@ -32,6 +32,11 @@
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		int result;						\
									\
		if (opts->bound == false) {		\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;			\
		}							\
									\
		mutex_lock(&opts->lock);				\
		result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \
		mutex_unlock(&opts->lock);				\
@@ -45,6 +50,11 @@
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		int ret;						\
									\
		if (opts->bound == false) {		\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;			\
		}							\
									\
		mutex_lock(&opts->lock);				\
		if (opts->refcnt) {					\
			mutex_unlock(&opts->lock);			\
@@ -67,6 +77,11 @@
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		int result;						\
									\
		if (opts->bound == false) {		\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;			\
		}							\
									\
		mutex_lock(&opts->lock);				\
		result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \
		mutex_unlock(&opts->lock);				\
@@ -80,6 +95,11 @@
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		int ret;						\
									\
		if (opts->bound == false) {		\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;			\
		}							\
									\
		mutex_lock(&opts->lock);				\
		if (opts->refcnt) {					\
			mutex_unlock(&opts->lock);			\
@@ -102,6 +122,11 @@
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		unsigned qmult;						\
									\
		if (opts->bound == false) {		\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;			\
		}							\
									\
		mutex_lock(&opts->lock);				\
		qmult = gether_get_qmult(opts->net);			\
		mutex_unlock(&opts->lock);				\
@@ -115,6 +140,11 @@
		u8 val;							\
		int ret;						\
									\
		if (opts->bound == false) {		\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;			\
		}							\
									\
		mutex_lock(&opts->lock);				\
		if (opts->refcnt) {					\
			ret = -EBUSY;					\
@@ -141,6 +171,11 @@ out: \
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		int ret;						\
									\
		if (opts->bound == false) {		\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;			\
		}							\
									\
		mutex_lock(&opts->lock);				\
		ret = gether_get_ifname(opts->net, page, PAGE_SIZE);	\
		mutex_unlock(&opts->lock);				\
+4 −0
Original line number Diff line number Diff line
@@ -30,4 +30,8 @@ struct f_ncm_opts {
	int				refcnt;
};

extern struct device *create_function_device(char *name);
int ncm_ctrlrequest(struct usb_composite_dev *cdev,
		const struct usb_ctrlrequest *ctrl);

#endif /* U_NCM_H */