Skip to content

Commit

Permalink
usb: gadget: allocate & giveback serial ports instead hard code them
Browse files Browse the repository at this point in the history
This patch removes gserial_setup() and gserial_cleanup() and adds
gserial_alloc_line() and gserial_free_line() to replace them.

The initial setup of u_serial happens now on module load time. A
maximum of four TTY ports can be requested which is the current limit.
In theory we could extend this limit, the hard limit is the number of
available endpoints.
alloc_tty_driver() is now called at module init time with the max
available ports. The per-line footprint here is on 32bit is 3 * size of
pointer + 60 bytes (for cdevs).
The remaining memory (struct gs_port) is allocated once a port is
requested.

With this change it is possible to load g_multi and g_serial at the same
time. GS0 receives the module that is loaded first, GS1 is received by
the next module and so on. With the configfs interface the port number
can be exported and the device node is more predictable. Nothing changes
for g_serial and friends as long as one module is used.

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 Jan 21, 2013
1 parent b473577 commit 19b10a8
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 209 deletions.
10 changes: 5 additions & 5 deletions drivers/usb/gadget/acm_ms.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
static struct fsg_common fsg_common;

/*-------------------------------------------------------------------------*/
static unsigned char tty_line;

/*
* We _always_ have both ACM and mass storage functions.
Expand All @@ -125,7 +126,7 @@ static int __init acm_ms_do_config(struct usb_configuration *c)
}


status = acm_bind_config(c, 0);
status = acm_bind_config(c, tty_line);
if (status < 0)
return status;

Expand All @@ -152,7 +153,7 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
void *retp;

/* set up serial link layer */
status = gserial_setup(cdev->gadget, 1);
status = gserial_alloc_line(&tty_line);
if (status < 0)
return status;

Expand Down Expand Up @@ -188,14 +189,13 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
fail1:
fsg_common_put(&fsg_common);
fail0:
gserial_cleanup();
gserial_free_line(tty_line);
return status;
}

static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
{
gserial_cleanup();

gserial_free_line(tty_line);
return 0;
}

Expand Down
9 changes: 5 additions & 4 deletions drivers/usb/gadget/cdc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static u8 hostaddr[ETH_ALEN];

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

static unsigned char tty_line;
/*
* We _always_ have both CDC ECM and CDC ACM functions.
*/
Expand All @@ -124,7 +125,7 @@ static int __init cdc_do_config(struct usb_configuration *c)
if (status < 0)
return status;

status = acm_bind_config(c, 0);
status = acm_bind_config(c, tty_line);
if (status < 0)
return status;

Expand Down Expand Up @@ -157,7 +158,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
return status;

/* set up serial link layer */
status = gserial_setup(cdev->gadget, 1);
status = gserial_alloc_line(&tty_line);
if (status < 0)
goto fail0;

Expand All @@ -183,15 +184,15 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
return 0;

fail1:
gserial_cleanup();
gserial_free_line(tty_line);
fail0:
gether_cleanup();
return status;
}

static int __exit cdc_unbind(struct usb_composite_dev *cdev)
{
gserial_cleanup();
gserial_free_line(tty_line);
gether_cleanup();
return 0;
}
Expand Down
10 changes: 7 additions & 3 deletions drivers/usb/gadget/dbgp.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ static void dbgp_unbind(struct usb_gadget *gadget)
gadget->ep0->driver_data = NULL;
}

#ifdef CONFIG_USB_G_DBGP_SERIAL
static unsigned char tty_line;
#endif

static int __init dbgp_configure_endpoints(struct usb_gadget *gadget)
{
int stp;
Expand Down Expand Up @@ -268,7 +272,7 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget)
dbgp.serial->in->desc = &i_desc;
dbgp.serial->out->desc = &o_desc;

if (gserial_setup(gadget, 1) < 0) {
if (gserial_alloc_line(&tty_line)) {
stp = 3;
goto fail_3;
}
Expand Down Expand Up @@ -377,7 +381,7 @@ static int dbgp_setup(struct usb_gadget *gadget,
#ifdef CONFIG_USB_G_DBGP_PRINTK
err = dbgp_enable_ep();
#else
err = gserial_connect(dbgp.serial, 0);
err = gserial_connect(dbgp.serial, tty_line);
#endif
if (err < 0)
goto fail;
Expand Down Expand Up @@ -420,7 +424,7 @@ static void __exit dbgp_exit(void)
{
usb_gadget_unregister_driver(&dbgp_driver);
#ifdef CONFIG_USB_G_DBGP_SERIAL
gserial_cleanup();
gserial_free_line(tty_line);
#endif
}

Expand Down
3 changes: 0 additions & 3 deletions drivers/usb/gadget/f_acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,6 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f)
*
* Returns zero on success, else negative errno.
*
* Caller must have called @gserial_setup() with enough ports to
* handle all the ones it binds. Caller is also responsible
* for calling @gserial_cleanup() before module unload.
*/
int acm_bind_config(struct usb_configuration *c, u8 port_num)
{
Expand Down
4 changes: 0 additions & 4 deletions drivers/usb/gadget/f_obex.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,6 @@ static inline bool can_support_obex(struct usb_configuration *c)
* Context: single threaded during gadget setup
*
* Returns zero on success, else negative errno.
*
* Caller must have called @gserial_setup() with enough ports to
* handle all the ones it binds. Caller is also responsible
* for calling @gserial_cleanup() before module unload.
*/
int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
{
Expand Down
4 changes: 0 additions & 4 deletions drivers/usb/gadget/f_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,6 @@ gser_unbind(struct usb_configuration *c, struct usb_function *f)
* Context: single threaded during gadget setup
*
* Returns zero on success, else negative errno.
*
* Caller must have called @gserial_setup() with enough ports to
* handle all the ones it binds. Caller is also responsible
* for calling @gserial_cleanup() before module unload.
*/
int __init gser_bind_config(struct usb_configuration *c, u8 port_num)
{
Expand Down
12 changes: 6 additions & 6 deletions drivers/usb/gadget/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ static struct fsg_common fsg_common;

static u8 hostaddr[ETH_ALEN];

static unsigned char tty_line;

/********** RNDIS **********/

Expand All @@ -154,7 +155,7 @@ static __init int rndis_do_config(struct usb_configuration *c)
if (ret < 0)
return ret;

ret = acm_bind_config(c, 0);
ret = acm_bind_config(c, tty_line);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -205,7 +206,7 @@ static __init int cdc_do_config(struct usb_configuration *c)
if (ret < 0)
return ret;

ret = acm_bind_config(c, 0);
ret = acm_bind_config(c, tty_line);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -242,7 +243,6 @@ static int cdc_config_register(struct usb_composite_dev *cdev)

/****************************** Gadget Bind ******************************/


static int __ref multi_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
Expand All @@ -260,7 +260,7 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
return status;

/* set up serial link layer */
status = gserial_setup(cdev->gadget, 1);
status = gserial_alloc_line(&tty_line);
if (status < 0)
goto fail0;

Expand Down Expand Up @@ -300,15 +300,15 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
fail2:
fsg_common_put(&fsg_common);
fail1:
gserial_cleanup();
gserial_free_line(tty_line);
fail0:
gether_cleanup();
return status;
}

static int __exit multi_unbind(struct usb_composite_dev *cdev)
{
gserial_cleanup();
gserial_free_line(tty_line);
gether_cleanup();
return 0;
}
Expand Down
37 changes: 28 additions & 9 deletions drivers/usb/gadget/nokia.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ MODULE_LICENSE("GPL");

static u8 hostaddr[ETH_ALEN];

enum {
TTY_PORT_OBEX0,
TTY_PORT_OBEX1,
TTY_PORT_ACM,
TTY_PORTS_MAX,
};

static unsigned char tty_lines[TTY_PORTS_MAX];

static int __init nokia_bind_config(struct usb_configuration *c)
{
int status = 0;
Expand All @@ -108,15 +117,15 @@ static int __init nokia_bind_config(struct usb_configuration *c)
if (status)
printk(KERN_DEBUG "could not bind phonet config\n");

status = obex_bind_config(c, 0);
status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX0]);
if (status)
printk(KERN_DEBUG "could not bind obex config %d\n", 0);

status = obex_bind_config(c, 1);
status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX1]);
if (status)
printk(KERN_DEBUG "could not bind obex config %d\n", 0);

status = acm_bind_config(c, 2);
status = acm_bind_config(c, tty_lines[TTY_PORT_ACM]);
if (status)
printk(KERN_DEBUG "could not bind acm config\n");

Expand Down Expand Up @@ -147,14 +156,17 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
int status;
int cur_line;

status = gphonet_setup(cdev->gadget);
if (status < 0)
goto err_phonet;

status = gserial_setup(cdev->gadget, 3);
if (status < 0)
goto err_serial;
for (cur_line = 0; cur_line < TTY_PORTS_MAX; cur_line++) {
status = gserial_alloc_line(&tty_lines[cur_line]);
if (status)
goto err_ether;
}

status = gether_setup(cdev->gadget, hostaddr);
if (status < 0)
Expand Down Expand Up @@ -191,17 +203,24 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
err_usb:
gether_cleanup();
err_ether:
gserial_cleanup();
err_serial:
cur_line--;
while (cur_line >= 0)
gserial_free_line(tty_lines[cur_line--]);

gphonet_cleanup();
err_phonet:
return status;
}

static int __exit nokia_unbind(struct usb_composite_dev *cdev)
{
int i;

gphonet_cleanup();
gserial_cleanup();

for (i = 0; i < TTY_PORTS_MAX; i++)
gserial_free_line(tty_lines[i]);

gether_cleanup();

return 0;
Expand Down
31 changes: 23 additions & 8 deletions drivers/usb/gadget/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,15 @@ module_param(n_ports, uint, 0);
MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");

/*-------------------------------------------------------------------------*/
static unsigned char tty_lines[MAX_U_SERIAL_PORTS];

static int __init serial_bind_acm_config(struct usb_configuration *c)
{
unsigned i;
int status = 0;

for (i = 0; i < n_ports && status == 0; i++)
status = acm_bind_config(c, i);
status = acm_bind_config(c, tty_lines[i]);
return status;
}

Expand All @@ -144,7 +145,7 @@ static int __init serial_bind_obex_config(struct usb_configuration *c)
int status = 0;

for (i = 0; i < n_ports && status == 0; i++)
status = obex_bind_config(c, i);
status = obex_bind_config(c, tty_lines[i]);
return status;
}

Expand All @@ -154,7 +155,7 @@ static int __init serial_bind_gser_config(struct usb_configuration *c)
int status = 0;

for (i = 0; i < n_ports && status == 0; i++)
status = gser_bind_config(c, i);
status = gser_bind_config(c, tty_lines[i]);
return status;
}

Expand All @@ -165,13 +166,25 @@ static struct usb_configuration serial_config_driver = {
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
};

static int gs_unbind(struct usb_composite_dev *cdev)
{
int i;

for (i = 0; i < n_ports; i++)
gserial_free_line(tty_lines[i]);
return 0;
}

static int __init gs_bind(struct usb_composite_dev *cdev)
{
int status;
int cur_line;

status = gserial_setup(cdev->gadget, n_ports);
if (status < 0)
return status;
for (cur_line = 0; cur_line < n_ports; cur_line++) {
status = gserial_alloc_line(&tty_lines[cur_line]);
if (status)
goto fail;
}

/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
Expand Down Expand Up @@ -209,7 +222,9 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
return 0;

fail:
gserial_cleanup();
cur_line--;
while (cur_line >= 0)
gserial_free_line(tty_lines[cur_line--]);
return status;
}

Expand All @@ -219,6 +234,7 @@ static __refdata struct usb_composite_driver gserial_driver = {
.strings = dev_strings,
.max_speed = USB_SPEED_SUPER,
.bind = gs_bind,
.unbind = gs_unbind,
};

static int __init init(void)
Expand Down Expand Up @@ -254,6 +270,5 @@ module_init(init);
static void __exit cleanup(void)
{
usb_composite_unregister(&gserial_driver);
gserial_cleanup();
}
module_exit(cleanup);
Loading

0 comments on commit 19b10a8

Please sign in to comment.