Skip to content

Commit

Permalink
usb: gadget: nokia: use function framework for ACM
Browse files Browse the repository at this point in the history
This patch converts the acm_ms gadget to make use of the function
framework to request the ACM function.

The "old" include interface for acm is now removed since nokia was the
last user of it (for ACM).

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Sebastian Andrzej Siewior authored and Felipe Balbi committed Apr 3, 2013
1 parent 5882337 commit 1576182
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 95 deletions.
1 change: 1 addition & 0 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ config USB_G_NOKIA
depends on PHONET
select USB_LIBCOMPOSITE
select USB_U_SERIAL
select USB_F_ACM
help
The Nokia composite gadget provides support for acm, obex
and phonet in only one composite gadget driver.
Expand Down
83 changes: 15 additions & 68 deletions drivers/usb/gadget/f_acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,72 +715,6 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
return status;
}

static struct f_acm *acm_alloc_basic_func(void)
{
struct f_acm *acm;

acm = kzalloc(sizeof(*acm), GFP_KERNEL);
if (!acm)
return NULL;

spin_lock_init(&acm->lock);

acm->port.connect = acm_connect;
acm->port.disconnect = acm_disconnect;
acm->port.send_break = acm_send_break;

acm->port.func.name = "acm";
/* descriptors are per-instance copies */
acm->port.func.bind = acm_bind;
acm->port.func.set_alt = acm_set_alt;
acm->port.func.setup = acm_setup;
acm->port.func.disable = acm_disable;

return acm;
}

#ifdef USB_FACM_INCLUDED
static void
acm_old_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_acm *acm = func_to_acm(f);

usb_free_all_descriptors(f);
if (acm->notify_req)
gs_free_req(acm->notify, acm->notify_req);
kfree(acm);
}

/**
* acm_bind_config - add a CDC ACM function to a configuration
* @c: the configuration to support the CDC ACM instance
* @port_num: /dev/ttyGS* port this interface will use
* Context: single threaded during gadget setup
*
* Returns zero on success, else negative errno.
*
*/
int acm_bind_config(struct usb_configuration *c, u8 port_num)
{
struct f_acm *acm;
int status;

/* allocate and initialize one new instance */
acm = acm_alloc_basic_func();
if (!acm)
return -ENOMEM;

acm->port_num = port_num;
acm->port.func.unbind = acm_old_unbind;

status = usb_add_function(c, &acm->port.func);
if (status)
kfree(acm);
return status;
}

#else

static void acm_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_acm *acm = func_to_acm(f);
Expand All @@ -803,10 +737,24 @@ static struct usb_function *acm_alloc_func(struct usb_function_instance *fi)
struct f_serial_opts *opts;
struct f_acm *acm;

acm = acm_alloc_basic_func();
acm = kzalloc(sizeof(*acm), GFP_KERNEL);
if (!acm)
return ERR_PTR(-ENOMEM);

spin_lock_init(&acm->lock);

acm->port.connect = acm_connect;
acm->port.disconnect = acm_disconnect;
acm->port.send_break = acm_send_break;

acm->port.func.name = "acm";
acm->port.func.strings = acm_strings;
/* descriptors are per-instance copies */
acm->port.func.bind = acm_bind;
acm->port.func.set_alt = acm_set_alt;
acm->port.func.setup = acm_setup;
acm->port.func.disable = acm_disable;

opts = container_of(fi, struct f_serial_opts, func_inst);
acm->port_num = opts->port_num;
acm->port.func.unbind = acm_unbind;
Expand Down Expand Up @@ -835,4 +783,3 @@ static struct usb_function_instance *acm_alloc_instance(void)
}
DECLARE_USB_FUNCTION_INIT(acm, acm_alloc_instance, acm_alloc_func);
MODULE_LICENSE("GPL");
#endif
82 changes: 56 additions & 26 deletions drivers/usb/gadget/nokia.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
* the runtime footprint, and giving us at least some parts of what
* a "gcc --combine ... part1.c part2.c part3.c ... " build would.
*/
#define USB_FACM_INCLUDED
#include "f_acm.c"
#include "f_ecm.c"
#include "f_obex.c"
#include "f_serial.c"
Expand Down Expand Up @@ -98,7 +96,8 @@ MODULE_AUTHOR("Felipe Balbi");
MODULE_LICENSE("GPL");

/*-------------------------------------------------------------------------*/

static struct usb_function *f_acm_cfg1;
static struct usb_function *f_acm_cfg2;
static u8 hostaddr[ETH_ALEN];

enum {
Expand All @@ -110,8 +109,27 @@ enum {

static unsigned char tty_lines[TTY_PORTS_MAX];

static struct usb_configuration nokia_config_500ma_driver = {
.label = "Bus Powered",
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE,
.MaxPower = 500,
};

static struct usb_configuration nokia_config_100ma_driver = {
.label = "Self Powered",
.bConfigurationValue = 2,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.MaxPower = 100,
};

static struct usb_function_instance *fi_acm;

static int __init nokia_bind_config(struct usb_configuration *c)
{
struct usb_function *f_acm;
int status = 0;

status = phonet_bind_config(c);
Expand All @@ -126,36 +144,36 @@ static int __init nokia_bind_config(struct usb_configuration *c)
if (status)
printk(KERN_DEBUG "could not bind obex config %d\n", 0);

status = acm_bind_config(c, tty_lines[TTY_PORT_ACM]);
f_acm = usb_get_function(fi_acm);
if (IS_ERR(f_acm))
return PTR_ERR(f_acm);

status = usb_add_function(c, f_acm);
if (status)
printk(KERN_DEBUG "could not bind acm config\n");
goto err_conf;

status = ecm_bind_config(c, hostaddr);
if (status)
printk(KERN_DEBUG "could not bind ecm config\n");
if (status) {
pr_debug("could not bind ecm config %d\n", status);
goto err_ecm;
}
if (c == &nokia_config_500ma_driver)
f_acm_cfg1 = f_acm;
else
f_acm_cfg2 = f_acm;

return status;
err_ecm:
usb_remove_function(c, f_acm);
err_conf:
usb_put_function(f_acm);
return status;
}

static struct usb_configuration nokia_config_500ma_driver = {
.label = "Bus Powered",
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE,
.MaxPower = 500,
};

static struct usb_configuration nokia_config_100ma_driver = {
.label = "Self Powered",
.bConfigurationValue = 2,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.MaxPower = 100,
};

static int __init nokia_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
struct f_serial_opts *opts;
int status;
int cur_line;

Expand Down Expand Up @@ -185,22 +203,32 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
if (!gadget_supports_altsettings(gadget))
goto err_usb;

fi_acm = usb_get_function_instance("acm");
if (IS_ERR(fi_acm))
goto err_usb;
opts = container_of(fi_acm, struct f_serial_opts, func_inst);
opts->port_num = tty_lines[TTY_PORT_ACM];

/* finally register the configuration */
status = usb_add_config(cdev, &nokia_config_500ma_driver,
nokia_bind_config);
if (status < 0)
goto err_usb;
goto err_acm_inst;

status = usb_add_config(cdev, &nokia_config_100ma_driver,
nokia_bind_config);
if (status < 0)
goto err_usb;
goto err_put_cfg1;

usb_composite_overwrite_options(cdev, &coverwrite);
dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);

return 0;

err_put_cfg1:
usb_put_function(f_acm_cfg1);
err_acm_inst:
usb_put_function_instance(fi_acm);
err_usb:
gether_cleanup();
err_ether:
Expand All @@ -217,6 +245,9 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
{
int i;

usb_put_function(f_acm_cfg1);
usb_put_function(f_acm_cfg2);
usb_put_function_instance(fi_acm);
gphonet_cleanup();

for (i = 0; i < TTY_PORTS_MAX; i++)
Expand Down Expand Up @@ -247,4 +278,3 @@ static void __exit nokia_cleanup(void)
usb_composite_unregister(&nokia_driver);
}
module_exit(nokia_cleanup);

1 change: 0 additions & 1 deletion drivers/usb/gadget/u_serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ int gserial_connect(struct gserial *, u8 port_num);
void gserial_disconnect(struct gserial *);

/* functions are bound to configurations by a config or gadget driver */
int acm_bind_config(struct usb_configuration *c, u8 port_num);
int gser_bind_config(struct usb_configuration *c, u8 port_num);
int obex_bind_config(struct usb_configuration *c, u8 port_num);

Expand Down

0 comments on commit 1576182

Please sign in to comment.