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

Commit c35ae887 authored by Ziqi Chen's avatar Ziqi Chen
Browse files

usb: gadget: Send dedicate uevent for ML client connection



According to mirror link spec, once mirror link client connected,
client will set mirror link command with bRequestType 0x40 and
bRequest 0xF0. In this scenario, USB driver send dedicate uevent
to notify userspace that USB host is a mirror link client.

Change-Id: Ic52f4f7d4e58e879877517fe5775b2f89091fe2a
Signed-off-by: default avatarZiqi Chen <ziqic@codeaurora.org>
parent 226b29b1
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -14,11 +14,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;
@@ -1503,6 +1508,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);
+55 −0
Original line number Diff line number Diff line
@@ -1605,10 +1605,57 @@ static 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->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
	/* release _ncm_setup_desc related resource */
	device_destroy(_ncm_setup_desc->device->class,
		_ncm_setup_desc->device->devt);
	cancel_work(&_ncm_setup_desc->work);
	kfree(_ncm_setup_desc);
#endif

	opts = container_of(f, struct f_ncm_opts, func_inst);
	if (opts->bound)
		gether_cleanup(netdev_priv(opts->net));
@@ -1627,6 +1674,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;
}

+4 −0
Original line number Diff line number Diff line
@@ -33,4 +33,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 */