usb: gadget: f_tcm: convert to new function interface with backward compatibility
Converting tcm to the new function interface requires converting USB tcm's function code and its users. This patch converts the f_tcm.c to the new function interface. The file can be now compiled into a separate module usb_f_tcm.ko. The old function interface is provided by means of preprocessor conditional directives. After all users are converted, the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
08a1cb0f65
commit
dc8c46a5ae
@ -199,6 +199,9 @@ config USB_F_HID
|
|||||||
config USB_F_PRINTER
|
config USB_F_PRINTER
|
||||||
tristate
|
tristate
|
||||||
|
|
||||||
|
config USB_F_TCM
|
||||||
|
tristate
|
||||||
|
|
||||||
choice
|
choice
|
||||||
tristate "USB Gadget Drivers"
|
tristate "USB Gadget Drivers"
|
||||||
default USB_ETH
|
default USB_ETH
|
||||||
|
@ -44,3 +44,5 @@ usb_f_hid-y := f_hid.o
|
|||||||
obj-$(CONFIG_USB_F_HID) += usb_f_hid.o
|
obj-$(CONFIG_USB_F_HID) += usb_f_hid.o
|
||||||
usb_f_printer-y := f_printer.o
|
usb_f_printer-y := f_printer.o
|
||||||
obj-$(CONFIG_USB_F_PRINTER) += usb_f_printer.o
|
obj-$(CONFIG_USB_F_PRINTER) += usb_f_printer.o
|
||||||
|
usb_f_tcm-y := f_tcm.o
|
||||||
|
obj-$(CONFIG_USB_F_TCM) += usb_f_tcm.o
|
||||||
|
@ -22,6 +22,21 @@
|
|||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#include "tcm.h"
|
#include "tcm.h"
|
||||||
|
#include "u_tcm.h"
|
||||||
|
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
|
||||||
|
#define TPG_INSTANCES 1
|
||||||
|
|
||||||
|
struct tpg_instance {
|
||||||
|
struct usb_function_instance *func_inst;
|
||||||
|
struct usbg_tpg *tpg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tpg_instance tpg_instances[TPG_INSTANCES];
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(tpg_instances_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline struct f_uas *to_f_uas(struct usb_function *f)
|
static inline struct f_uas *to_f_uas(struct usb_function *f)
|
||||||
{
|
{
|
||||||
@ -1371,6 +1386,10 @@ static struct se_portal_group *usbg_make_tpg(
|
|||||||
struct usbg_tpg *tpg;
|
struct usbg_tpg *tpg;
|
||||||
unsigned long tpgt;
|
unsigned long tpgt;
|
||||||
int ret;
|
int ret;
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
struct f_tcm_opts *opts;
|
||||||
|
unsigned i;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (strstr(name, "tpgt_") != name)
|
if (strstr(name, "tpgt_") != name)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
@ -1381,14 +1400,40 @@ static struct se_portal_group *usbg_make_tpg(
|
|||||||
pr_err("gadgets, you can't do this here.\n");
|
pr_err("gadgets, you can't do this here.\n");
|
||||||
return ERR_PTR(-EBUSY);
|
return ERR_PTR(-EBUSY);
|
||||||
}
|
}
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
ret = -ENODEV;
|
||||||
|
mutex_lock(&tpg_instances_lock);
|
||||||
|
for (i = 0; i < TPG_INSTANCES; ++i)
|
||||||
|
if (tpg_instances[i].func_inst && !tpg_instances[i].tpg)
|
||||||
|
break;
|
||||||
|
if (i == TPG_INSTANCES)
|
||||||
|
goto unlock_inst;
|
||||||
|
|
||||||
|
opts = container_of(tpg_instances[i].func_inst, struct f_tcm_opts,
|
||||||
|
func_inst);
|
||||||
|
mutex_lock(&opts->dep_lock);
|
||||||
|
if (!opts->ready)
|
||||||
|
goto unlock_dep;
|
||||||
|
|
||||||
|
if (opts->has_dep && !try_module_get(opts->dependent))
|
||||||
|
goto unlock_dep;
|
||||||
|
#endif
|
||||||
|
|
||||||
tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL);
|
tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL);
|
||||||
|
ret = -ENOMEM;
|
||||||
if (!tpg)
|
if (!tpg)
|
||||||
|
#ifdef USBF_TCM_INCLUDED
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
#else
|
||||||
|
goto unref_dep;
|
||||||
|
#endif
|
||||||
mutex_init(&tpg->tpg_mutex);
|
mutex_init(&tpg->tpg_mutex);
|
||||||
atomic_set(&tpg->tpg_port_count, 0);
|
atomic_set(&tpg->tpg_port_count, 0);
|
||||||
tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1);
|
tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1);
|
||||||
if (!tpg->workqueue) {
|
if (!tpg->workqueue) {
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
goto free_tpg;
|
||||||
|
#endif
|
||||||
kfree(tpg);
|
kfree(tpg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1402,12 +1447,35 @@ static struct se_portal_group *usbg_make_tpg(
|
|||||||
*/
|
*/
|
||||||
ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SAS);
|
ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SAS);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
goto free_workqueue;
|
||||||
|
#endif
|
||||||
destroy_workqueue(tpg->workqueue);
|
destroy_workqueue(tpg->workqueue);
|
||||||
kfree(tpg);
|
kfree(tpg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
tpg_instances[i].tpg = tpg;
|
||||||
|
tpg->fi = tpg_instances[i].func_inst;
|
||||||
|
mutex_unlock(&opts->dep_lock);
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
#endif
|
||||||
the_only_tpg_I_currently_have = tpg;
|
the_only_tpg_I_currently_have = tpg;
|
||||||
return &tpg->se_tpg;
|
return &tpg->se_tpg;
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
free_workqueue:
|
||||||
|
destroy_workqueue(tpg->workqueue);
|
||||||
|
free_tpg:
|
||||||
|
kfree(tpg);
|
||||||
|
unref_dep:
|
||||||
|
module_put(opts->dependent);
|
||||||
|
unlock_dep:
|
||||||
|
mutex_unlock(&opts->dep_lock);
|
||||||
|
unlock_inst:
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcm_usbg_drop_nexus(struct usbg_tpg *);
|
static int tcm_usbg_drop_nexus(struct usbg_tpg *);
|
||||||
@ -1416,10 +1484,29 @@ static void usbg_drop_tpg(struct se_portal_group *se_tpg)
|
|||||||
{
|
{
|
||||||
struct usbg_tpg *tpg = container_of(se_tpg,
|
struct usbg_tpg *tpg = container_of(se_tpg,
|
||||||
struct usbg_tpg, se_tpg);
|
struct usbg_tpg, se_tpg);
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
unsigned i;
|
||||||
|
struct f_tcm_opts *opts;
|
||||||
|
#endif
|
||||||
|
|
||||||
tcm_usbg_drop_nexus(tpg);
|
tcm_usbg_drop_nexus(tpg);
|
||||||
core_tpg_deregister(se_tpg);
|
core_tpg_deregister(se_tpg);
|
||||||
destroy_workqueue(tpg->workqueue);
|
destroy_workqueue(tpg->workqueue);
|
||||||
|
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
mutex_lock(&tpg_instances_lock);
|
||||||
|
for (i = 0; i < TPG_INSTANCES; ++i)
|
||||||
|
if (tpg_instances[i].tpg == tpg)
|
||||||
|
break;
|
||||||
|
if (i < TPG_INSTANCES)
|
||||||
|
tpg_instances[i].tpg = NULL;
|
||||||
|
opts = container_of(tpg_instances[i].func_inst,
|
||||||
|
struct f_tcm_opts, func_inst);
|
||||||
|
mutex_lock(&opts->dep_lock);
|
||||||
|
module_put(opts->dependent);
|
||||||
|
mutex_unlock(&opts->dep_lock);
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
#endif
|
||||||
kfree(tpg);
|
kfree(tpg);
|
||||||
the_only_tpg_I_currently_have = NULL;
|
the_only_tpg_I_currently_have = NULL;
|
||||||
}
|
}
|
||||||
@ -1440,6 +1527,7 @@ static struct se_wwn *usbg_make_tport(
|
|||||||
tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL);
|
tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL);
|
||||||
if (!(tport))
|
if (!(tport))
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
tport->tport_wwpn = wwpn;
|
tport->tport_wwpn = wwpn;
|
||||||
snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name);
|
snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name);
|
||||||
return &tport->tport_wwn;
|
return &tport->tport_wwn;
|
||||||
@ -1978,9 +2066,32 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
struct f_uas *fu = to_f_uas(f);
|
struct f_uas *fu = to_f_uas(f);
|
||||||
struct usb_gadget *gadget = c->cdev->gadget;
|
struct usb_gadget *gadget = c->cdev->gadget;
|
||||||
struct usb_ep *ep;
|
struct usb_ep *ep;
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
struct f_tcm_opts *opts;
|
||||||
|
#endif
|
||||||
int iface;
|
int iface;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifndef USBF_TCM_INCLUDED
|
||||||
|
opts = container_of(f->fi, struct f_tcm_opts, func_inst);
|
||||||
|
|
||||||
|
mutex_lock(&opts->dep_lock);
|
||||||
|
if (!opts->can_attach) {
|
||||||
|
mutex_unlock(&opts->dep_lock);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
mutex_unlock(&opts->dep_lock);
|
||||||
|
#endif
|
||||||
|
if (tcm_us_strings[0].id == 0) {
|
||||||
|
ret = usb_string_ids_tab(c->cdev, tcm_us_strings);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
bot_intf_desc.iInterface = tcm_us_strings[USB_G_STR_INT_BBB].id;
|
||||||
|
uasp_intf_desc.iInterface =
|
||||||
|
tcm_us_strings[USB_G_STR_INT_UAS].id;
|
||||||
|
}
|
||||||
|
|
||||||
iface = usb_interface_id(c, f);
|
iface = usb_interface_id(c, f);
|
||||||
if (iface < 0)
|
if (iface < 0)
|
||||||
return iface;
|
return iface;
|
||||||
@ -2038,7 +2149,9 @@ ep_fail:
|
|||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcm_unbind(struct usb_configuration *c, struct usb_function *f)
|
#ifdef USBF_TCM_INCLUDED
|
||||||
|
|
||||||
|
static void tcm_old_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||||
{
|
{
|
||||||
struct f_uas *fu = to_f_uas(f);
|
struct f_uas *fu = to_f_uas(f);
|
||||||
|
|
||||||
@ -2046,6 +2159,8 @@ static void tcm_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
kfree(fu);
|
kfree(fu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
struct guas_setup_wq {
|
struct guas_setup_wq {
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
struct f_uas *fu;
|
struct f_uas *fu;
|
||||||
@ -2114,6 +2229,8 @@ static int tcm_setup(struct usb_function *f,
|
|||||||
return usbg_bot_setup(f, ctrl);
|
return usbg_bot_setup(f, ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USBF_TCM_INCLUDED
|
||||||
|
|
||||||
static int tcm_bind_config(struct usb_configuration *c)
|
static int tcm_bind_config(struct usb_configuration *c)
|
||||||
{
|
{
|
||||||
struct f_uas *fu;
|
struct f_uas *fu;
|
||||||
@ -2124,16 +2241,13 @@ static int tcm_bind_config(struct usb_configuration *c)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
fu->function.name = "Target Function";
|
fu->function.name = "Target Function";
|
||||||
fu->function.bind = tcm_bind;
|
fu->function.bind = tcm_bind;
|
||||||
fu->function.unbind = tcm_unbind;
|
fu->function.unbind = tcm_old_unbind;
|
||||||
fu->function.set_alt = tcm_set_alt;
|
fu->function.set_alt = tcm_set_alt;
|
||||||
fu->function.setup = tcm_setup;
|
fu->function.setup = tcm_setup;
|
||||||
fu->function.disable = tcm_disable;
|
fu->function.disable = tcm_disable;
|
||||||
fu->function.strings = tcm_strings;
|
fu->function.strings = tcm_strings;
|
||||||
fu->tpg = the_only_tpg_I_currently_have;
|
fu->tpg = the_only_tpg_I_currently_have;
|
||||||
|
|
||||||
bot_intf_desc.iInterface = tcm_us_strings[USB_G_STR_INT_BBB].id;
|
|
||||||
uasp_intf_desc.iInterface = tcm_us_strings[USB_G_STR_INT_UAS].id;
|
|
||||||
|
|
||||||
ret = usb_add_function(c, &fu->function);
|
ret = usb_add_function(c, &fu->function);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
@ -2143,3 +2257,165 @@ err:
|
|||||||
kfree(fu);
|
kfree(fu);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static void tcm_free_inst(struct usb_function_instance *f)
|
||||||
|
{
|
||||||
|
struct f_tcm_opts *opts;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
opts = container_of(f, struct f_tcm_opts, func_inst);
|
||||||
|
|
||||||
|
mutex_lock(&tpg_instances_lock);
|
||||||
|
for (i = 0; i < TPG_INSTANCES; ++i)
|
||||||
|
if (tpg_instances[i].func_inst == f)
|
||||||
|
break;
|
||||||
|
if (i < TPG_INSTANCES)
|
||||||
|
tpg_instances[i].func_inst = NULL;
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
|
||||||
|
kfree(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usbg_attach(struct usbg_tpg *tpg)
|
||||||
|
{
|
||||||
|
struct usb_function_instance *f = tpg->fi;
|
||||||
|
struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
|
||||||
|
|
||||||
|
if (opts->tcm_register_callback)
|
||||||
|
return opts->tcm_register_callback(f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usbg_detach(struct usbg_tpg *tpg)
|
||||||
|
{
|
||||||
|
struct usb_function_instance *f = tpg->fi;
|
||||||
|
struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
|
||||||
|
|
||||||
|
if (opts->tcm_unregister_callback)
|
||||||
|
opts->tcm_unregister_callback(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcm_set_name(struct usb_function_instance *f, const char *name)
|
||||||
|
{
|
||||||
|
struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
|
||||||
|
|
||||||
|
pr_debug("tcm: Activating %s\n", name);
|
||||||
|
|
||||||
|
mutex_lock(&opts->dep_lock);
|
||||||
|
opts->ready = true;
|
||||||
|
mutex_unlock(&opts->dep_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct usb_function_instance *tcm_alloc_inst(void)
|
||||||
|
{
|
||||||
|
struct f_tcm_opts *opts;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
|
||||||
|
if (!opts)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
mutex_lock(&tpg_instances_lock);
|
||||||
|
for (i = 0; i < TPG_INSTANCES; ++i)
|
||||||
|
if (!tpg_instances[i].func_inst)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == TPG_INSTANCES) {
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
kfree(opts);
|
||||||
|
return ERR_PTR(-EBUSY);
|
||||||
|
}
|
||||||
|
tpg_instances[i].func_inst = &opts->func_inst;
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
|
||||||
|
mutex_init(&opts->dep_lock);
|
||||||
|
opts->func_inst.set_inst_name = tcm_set_name;
|
||||||
|
opts->func_inst.free_func_inst = tcm_free_inst;
|
||||||
|
|
||||||
|
return &opts->func_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcm_free(struct usb_function *f)
|
||||||
|
{
|
||||||
|
struct f_uas *tcm = to_f_uas(f);
|
||||||
|
|
||||||
|
kfree(tcm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcm_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||||
|
{
|
||||||
|
usb_free_all_descriptors(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct usb_function *tcm_alloc(struct usb_function_instance *fi)
|
||||||
|
{
|
||||||
|
struct f_uas *fu;
|
||||||
|
struct f_tcm_opts *opts;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
mutex_lock(&tpg_instances_lock);
|
||||||
|
for (i = 0; i < TPG_INSTANCES; ++i)
|
||||||
|
if (tpg_instances[i].func_inst == fi)
|
||||||
|
break;
|
||||||
|
if (i == TPG_INSTANCES) {
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
return ERR_PTR(-ENODEV);
|
||||||
|
}
|
||||||
|
|
||||||
|
opts = container_of(fi, struct f_tcm_opts, func_inst);
|
||||||
|
|
||||||
|
fu = kzalloc(sizeof(*fu), GFP_KERNEL);
|
||||||
|
if (!fu) {
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
fu->function.name = "Target Function";
|
||||||
|
fu->function.bind = tcm_bind;
|
||||||
|
fu->function.unbind = tcm_unbind;
|
||||||
|
fu->function.set_alt = tcm_set_alt;
|
||||||
|
fu->function.setup = tcm_setup;
|
||||||
|
fu->function.disable = tcm_disable;
|
||||||
|
fu->function.strings = tcm_strings;
|
||||||
|
fu->function.free_func = tcm_free;
|
||||||
|
fu->tpg = tpg_instances[i].tpg;
|
||||||
|
mutex_unlock(&tpg_instances_lock);
|
||||||
|
|
||||||
|
return &fu->function;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_USB_FUNCTION(tcm, tcm_alloc_inst, tcm_alloc);
|
||||||
|
|
||||||
|
static int tcm_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = usb_function_register(&tcmusb_func);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = target_register_template(&usbg_ops);
|
||||||
|
if (ret)
|
||||||
|
usb_function_unregister(&tcmusb_func);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
module_init(tcm_init);
|
||||||
|
|
||||||
|
static void tcm_exit(void)
|
||||||
|
{
|
||||||
|
target_unregister_template(&usbg_ops);
|
||||||
|
usb_function_unregister(&tcmusb_func);
|
||||||
|
}
|
||||||
|
module_exit(tcm_exit);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Sebastian Andrzej Siewior");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -39,6 +39,8 @@ struct usbg_tpg {
|
|||||||
u32 gadget_connect;
|
u32 gadget_connect;
|
||||||
struct tcm_usbg_nexus *tpg_nexus;
|
struct tcm_usbg_nexus *tpg_nexus;
|
||||||
atomic_t tpg_port_count;
|
atomic_t tpg_port_count;
|
||||||
|
|
||||||
|
struct usb_function_instance *fi;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct usbg_tport {
|
struct usbg_tport {
|
||||||
|
50
drivers/usb/gadget/function/u_tcm.h
Normal file
50
drivers/usb/gadget/function/u_tcm.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* u_tcm.h
|
||||||
|
*
|
||||||
|
* Utility definitions for the tcm function
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
|
||||||
|
* http://www.samsung.com
|
||||||
|
*
|
||||||
|
* Author: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef U_TCM_H
|
||||||
|
#define U_TCM_H
|
||||||
|
|
||||||
|
#include <linux/usb/composite.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dependent: optional dependent module. Meant for legacy gadget.
|
||||||
|
* If non-null its refcount will be increased when a tpg is created and
|
||||||
|
* decreased when tpg is dropped.
|
||||||
|
* @dep_lock: lock for dependent module operations.
|
||||||
|
* @ready: true if the dependent module information is set.
|
||||||
|
* @can_attach: true a function can be bound to gadget
|
||||||
|
* @has_dep: true if there is a dependent module
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct f_tcm_opts {
|
||||||
|
struct usb_function_instance func_inst;
|
||||||
|
struct module *dependent;
|
||||||
|
struct mutex dep_lock;
|
||||||
|
bool ready;
|
||||||
|
bool can_attach;
|
||||||
|
bool has_dep;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callbacks to be removed when legacy tcm gadget disappears.
|
||||||
|
*
|
||||||
|
* If you use the new function registration interface
|
||||||
|
* programmatically, you MUST set these callbacks to
|
||||||
|
* something sensible (e.g. probe/remove the composite).
|
||||||
|
*/
|
||||||
|
int (*tcm_register_callback)(struct usb_function_instance *);
|
||||||
|
void (*tcm_unregister_callback)(struct usb_function_instance *);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* U_TCM_H */
|
@ -24,6 +24,7 @@
|
|||||||
USB_GADGET_COMPOSITE_OPTIONS();
|
USB_GADGET_COMPOSITE_OPTIONS();
|
||||||
|
|
||||||
/* #include to be removed when new function registration interface is used */
|
/* #include to be removed when new function registration interface is used */
|
||||||
|
#define USBF_TCM_INCLUDED
|
||||||
#include "../function/f_tcm.c"
|
#include "../function/f_tcm.c"
|
||||||
|
|
||||||
#define UAS_VENDOR_ID 0x0525 /* NetChip */
|
#define UAS_VENDOR_ID 0x0525 /* NetChip */
|
||||||
|
Loading…
Reference in New Issue
Block a user