Loading drivers/usb/gadget/configfs.c +17 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading drivers/usb/gadget/function/f_ncm.c +58 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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; } Loading @@ -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; Loading @@ -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) Loading drivers/usb/gadget/function/u_ether_configfs.h +35 −0 Original line number Diff line number Diff line Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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; \ Loading @@ -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); \ Loading drivers/usb/gadget/function/u_ncm.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
drivers/usb/gadget/configfs.c +17 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
drivers/usb/gadget/function/f_ncm.c +58 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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; } Loading @@ -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; Loading @@ -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) Loading
drivers/usb/gadget/function/u_ether_configfs.h +35 −0 Original line number Diff line number Diff line Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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); \ Loading @@ -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; \ Loading @@ -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); \ Loading
drivers/usb/gadget/function/u_ncm.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 */