aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/acm_ms.c10
-rw-r--r--drivers/usb/gadget/cdc2.c9
-rw-r--r--drivers/usb/gadget/dbgp.c10
-rw-r--r--drivers/usb/gadget/f_acm.c3
-rw-r--r--drivers/usb/gadget/f_obex.c4
-rw-r--r--drivers/usb/gadget/f_serial.c4
-rw-r--r--drivers/usb/gadget/multi.c12
-rw-r--r--drivers/usb/gadget/nokia.c37
-rw-r--r--drivers/usb/gadget/serial.c31
-rw-r--r--drivers/usb/gadget/u_serial.c310
-rw-r--r--drivers/usb/gadget/u_serial.h8
11 files changed, 229 insertions, 209 deletions
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
index 35cbe7283514..eb0fbdae5ccb 100644
--- a/drivers/usb/gadget/acm_ms.c
+++ b/drivers/usb/gadget/acm_ms.c
@@ -111,6 +111,7 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
111static struct fsg_common fsg_common; 111static struct fsg_common fsg_common;
112 112
113/*-------------------------------------------------------------------------*/ 113/*-------------------------------------------------------------------------*/
114static unsigned char tty_line;
114 115
115/* 116/*
116 * We _always_ have both ACM and mass storage functions. 117 * We _always_ have both ACM and mass storage functions.
@@ -125,7 +126,7 @@ static int __init acm_ms_do_config(struct usb_configuration *c)
125 } 126 }
126 127
127 128
128 status = acm_bind_config(c, 0); 129 status = acm_bind_config(c, tty_line);
129 if (status < 0) 130 if (status < 0)
130 return status; 131 return status;
131 132
@@ -152,7 +153,7 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
152 void *retp; 153 void *retp;
153 154
154 /* set up serial link layer */ 155 /* set up serial link layer */
155 status = gserial_setup(cdev->gadget, 1); 156 status = gserial_alloc_line(&tty_line);
156 if (status < 0) 157 if (status < 0)
157 return status; 158 return status;
158 159
@@ -188,14 +189,13 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
188fail1: 189fail1:
189 fsg_common_put(&fsg_common); 190 fsg_common_put(&fsg_common);
190fail0: 191fail0:
191 gserial_cleanup(); 192 gserial_free_line(tty_line);
192 return status; 193 return status;
193} 194}
194 195
195static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) 196static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
196{ 197{
197 gserial_cleanup(); 198 gserial_free_line(tty_line);
198
199 return 0; 199 return 0;
200} 200}
201 201
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 379df679ef30..16911a5aeb03 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -108,6 +108,7 @@ static u8 hostaddr[ETH_ALEN];
108 108
109/*-------------------------------------------------------------------------*/ 109/*-------------------------------------------------------------------------*/
110 110
111static unsigned char tty_line;
111/* 112/*
112 * We _always_ have both CDC ECM and CDC ACM functions. 113 * We _always_ have both CDC ECM and CDC ACM functions.
113 */ 114 */
@@ -124,7 +125,7 @@ static int __init cdc_do_config(struct usb_configuration *c)
124 if (status < 0) 125 if (status < 0)
125 return status; 126 return status;
126 127
127 status = acm_bind_config(c, 0); 128 status = acm_bind_config(c, tty_line);
128 if (status < 0) 129 if (status < 0)
129 return status; 130 return status;
130 131
@@ -157,7 +158,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
157 return status; 158 return status;
158 159
159 /* set up serial link layer */ 160 /* set up serial link layer */
160 status = gserial_setup(cdev->gadget, 1); 161 status = gserial_alloc_line(&tty_line);
161 if (status < 0) 162 if (status < 0)
162 goto fail0; 163 goto fail0;
163 164
@@ -183,7 +184,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
183 return 0; 184 return 0;
184 185
185fail1: 186fail1:
186 gserial_cleanup(); 187 gserial_free_line(tty_line);
187fail0: 188fail0:
188 gether_cleanup(); 189 gether_cleanup();
189 return status; 190 return status;
@@ -191,7 +192,7 @@ fail0:
191 192
192static int __exit cdc_unbind(struct usb_composite_dev *cdev) 193static int __exit cdc_unbind(struct usb_composite_dev *cdev)
193{ 194{
194 gserial_cleanup(); 195 gserial_free_line(tty_line);
195 gether_cleanup(); 196 gether_cleanup();
196 return 0; 197 return 0;
197} 198}
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c
index 41eb98df5644..986fc511a2ed 100644
--- a/drivers/usb/gadget/dbgp.c
+++ b/drivers/usb/gadget/dbgp.c
@@ -231,6 +231,10 @@ static void dbgp_unbind(struct usb_gadget *gadget)
231 gadget->ep0->driver_data = NULL; 231 gadget->ep0->driver_data = NULL;
232} 232}
233 233
234#ifdef CONFIG_USB_G_DBGP_SERIAL
235static unsigned char tty_line;
236#endif
237
234static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) 238static int __init dbgp_configure_endpoints(struct usb_gadget *gadget)
235{ 239{
236 int stp; 240 int stp;
@@ -268,7 +272,7 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget)
268 dbgp.serial->in->desc = &i_desc; 272 dbgp.serial->in->desc = &i_desc;
269 dbgp.serial->out->desc = &o_desc; 273 dbgp.serial->out->desc = &o_desc;
270 274
271 if (gserial_setup(gadget, 1) < 0) { 275 if (gserial_alloc_line(&tty_line)) {
272 stp = 3; 276 stp = 3;
273 goto fail_3; 277 goto fail_3;
274 } 278 }
@@ -377,7 +381,7 @@ static int dbgp_setup(struct usb_gadget *gadget,
377#ifdef CONFIG_USB_G_DBGP_PRINTK 381#ifdef CONFIG_USB_G_DBGP_PRINTK
378 err = dbgp_enable_ep(); 382 err = dbgp_enable_ep();
379#else 383#else
380 err = gserial_connect(dbgp.serial, 0); 384 err = gserial_connect(dbgp.serial, tty_line);
381#endif 385#endif
382 if (err < 0) 386 if (err < 0)
383 goto fail; 387 goto fail;
@@ -420,7 +424,7 @@ static void __exit dbgp_exit(void)
420{ 424{
421 usb_gadget_unregister_driver(&dbgp_driver); 425 usb_gadget_unregister_driver(&dbgp_driver);
422#ifdef CONFIG_USB_G_DBGP_SERIAL 426#ifdef CONFIG_USB_G_DBGP_SERIAL
423 gserial_cleanup(); 427 gserial_free_line(tty_line);
424#endif 428#endif
425} 429}
426 430
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index d4a7c1912105..3178fa70916e 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -719,9 +719,6 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f)
719 * 719 *
720 * Returns zero on success, else negative errno. 720 * Returns zero on success, else negative errno.
721 * 721 *
722 * Caller must have called @gserial_setup() with enough ports to
723 * handle all the ones it binds. Caller is also responsible
724 * for calling @gserial_cleanup() before module unload.
725 */ 722 */
726int acm_bind_config(struct usb_configuration *c, u8 port_num) 723int acm_bind_config(struct usb_configuration *c, u8 port_num)
727{ 724{
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index d8dd8782768c..36a004563b82 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -406,10 +406,6 @@ static inline bool can_support_obex(struct usb_configuration *c)
406 * Context: single threaded during gadget setup 406 * Context: single threaded during gadget setup
407 * 407 *
408 * Returns zero on success, else negative errno. 408 * Returns zero on success, else negative errno.
409 *
410 * Caller must have called @gserial_setup() with enough ports to
411 * handle all the ones it binds. Caller is also responsible
412 * for calling @gserial_cleanup() before module unload.
413 */ 409 */
414int __init obex_bind_config(struct usb_configuration *c, u8 port_num) 410int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
415{ 411{
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 98fa7795df5f..da33cfb3031d 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -260,10 +260,6 @@ gser_unbind(struct usb_configuration *c, struct usb_function *f)
260 * Context: single threaded during gadget setup 260 * Context: single threaded during gadget setup
261 * 261 *
262 * Returns zero on success, else negative errno. 262 * Returns zero on success, else negative errno.
263 *
264 * Caller must have called @gserial_setup() with enough ports to
265 * handle all the ones it binds. Caller is also responsible
266 * for calling @gserial_cleanup() before module unload.
267 */ 263 */
268int __init gser_bind_config(struct usb_configuration *c, u8 port_num) 264int __init gser_bind_config(struct usb_configuration *c, u8 port_num)
269{ 265{
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 00667911100d..9ca0ac0334e7 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -136,6 +136,7 @@ static struct fsg_common fsg_common;
136 136
137static u8 hostaddr[ETH_ALEN]; 137static u8 hostaddr[ETH_ALEN];
138 138
139static unsigned char tty_line;
139 140
140/********** RNDIS **********/ 141/********** RNDIS **********/
141 142
@@ -154,7 +155,7 @@ static __init int rndis_do_config(struct usb_configuration *c)
154 if (ret < 0) 155 if (ret < 0)
155 return ret; 156 return ret;
156 157
157 ret = acm_bind_config(c, 0); 158 ret = acm_bind_config(c, tty_line);
158 if (ret < 0) 159 if (ret < 0)
159 return ret; 160 return ret;
160 161
@@ -205,7 +206,7 @@ static __init int cdc_do_config(struct usb_configuration *c)
205 if (ret < 0) 206 if (ret < 0)
206 return ret; 207 return ret;
207 208
208 ret = acm_bind_config(c, 0); 209 ret = acm_bind_config(c, tty_line);
209 if (ret < 0) 210 if (ret < 0)
210 return ret; 211 return ret;
211 212
@@ -242,7 +243,6 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
242 243
243/****************************** Gadget Bind ******************************/ 244/****************************** Gadget Bind ******************************/
244 245
245
246static int __ref multi_bind(struct usb_composite_dev *cdev) 246static int __ref multi_bind(struct usb_composite_dev *cdev)
247{ 247{
248 struct usb_gadget *gadget = cdev->gadget; 248 struct usb_gadget *gadget = cdev->gadget;
@@ -260,7 +260,7 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
260 return status; 260 return status;
261 261
262 /* set up serial link layer */ 262 /* set up serial link layer */
263 status = gserial_setup(cdev->gadget, 1); 263 status = gserial_alloc_line(&tty_line);
264 if (status < 0) 264 if (status < 0)
265 goto fail0; 265 goto fail0;
266 266
@@ -300,7 +300,7 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
300fail2: 300fail2:
301 fsg_common_put(&fsg_common); 301 fsg_common_put(&fsg_common);
302fail1: 302fail1:
303 gserial_cleanup(); 303 gserial_free_line(tty_line);
304fail0: 304fail0:
305 gether_cleanup(); 305 gether_cleanup();
306 return status; 306 return status;
@@ -308,7 +308,7 @@ fail0:
308 308
309static int __exit multi_unbind(struct usb_composite_dev *cdev) 309static int __exit multi_unbind(struct usb_composite_dev *cdev)
310{ 310{
311 gserial_cleanup(); 311 gserial_free_line(tty_line);
312 gether_cleanup(); 312 gether_cleanup();
313 return 0; 313 return 0;
314} 314}
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
index 48f0d5c372a8..084d0d7cb8fa 100644
--- a/drivers/usb/gadget/nokia.c
+++ b/drivers/usb/gadget/nokia.c
@@ -100,6 +100,15 @@ MODULE_LICENSE("GPL");
100 100
101static u8 hostaddr[ETH_ALEN]; 101static u8 hostaddr[ETH_ALEN];
102 102
103enum {
104 TTY_PORT_OBEX0,
105 TTY_PORT_OBEX1,
106 TTY_PORT_ACM,
107 TTY_PORTS_MAX,
108};
109
110static unsigned char tty_lines[TTY_PORTS_MAX];
111
103static int __init nokia_bind_config(struct usb_configuration *c) 112static int __init nokia_bind_config(struct usb_configuration *c)
104{ 113{
105 int status = 0; 114 int status = 0;
@@ -108,15 +117,15 @@ static int __init nokia_bind_config(struct usb_configuration *c)
108 if (status) 117 if (status)
109 printk(KERN_DEBUG "could not bind phonet config\n"); 118 printk(KERN_DEBUG "could not bind phonet config\n");
110 119
111 status = obex_bind_config(c, 0); 120 status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX0]);
112 if (status) 121 if (status)
113 printk(KERN_DEBUG "could not bind obex config %d\n", 0); 122 printk(KERN_DEBUG "could not bind obex config %d\n", 0);
114 123
115 status = obex_bind_config(c, 1); 124 status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX1]);
116 if (status) 125 if (status)
117 printk(KERN_DEBUG "could not bind obex config %d\n", 0); 126 printk(KERN_DEBUG "could not bind obex config %d\n", 0);
118 127
119 status = acm_bind_config(c, 2); 128 status = acm_bind_config(c, tty_lines[TTY_PORT_ACM]);
120 if (status) 129 if (status)
121 printk(KERN_DEBUG "could not bind acm config\n"); 130 printk(KERN_DEBUG "could not bind acm config\n");
122 131
@@ -147,14 +156,17 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
147{ 156{
148 struct usb_gadget *gadget = cdev->gadget; 157 struct usb_gadget *gadget = cdev->gadget;
149 int status; 158 int status;
159 int cur_line;
150 160
151 status = gphonet_setup(cdev->gadget); 161 status = gphonet_setup(cdev->gadget);
152 if (status < 0) 162 if (status < 0)
153 goto err_phonet; 163 goto err_phonet;
154 164
155 status = gserial_setup(cdev->gadget, 3); 165 for (cur_line = 0; cur_line < TTY_PORTS_MAX; cur_line++) {
156 if (status < 0) 166 status = gserial_alloc_line(&tty_lines[cur_line]);
157 goto err_serial; 167 if (status)
168 goto err_ether;
169 }
158 170
159 status = gether_setup(cdev->gadget, hostaddr); 171 status = gether_setup(cdev->gadget, hostaddr);
160 if (status < 0) 172 if (status < 0)
@@ -191,8 +203,10 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
191err_usb: 203err_usb:
192 gether_cleanup(); 204 gether_cleanup();
193err_ether: 205err_ether:
194 gserial_cleanup(); 206 cur_line--;
195err_serial: 207 while (cur_line >= 0)
208 gserial_free_line(tty_lines[cur_line--]);
209
196 gphonet_cleanup(); 210 gphonet_cleanup();
197err_phonet: 211err_phonet:
198 return status; 212 return status;
@@ -200,8 +214,13 @@ err_phonet:
200 214
201static int __exit nokia_unbind(struct usb_composite_dev *cdev) 215static int __exit nokia_unbind(struct usb_composite_dev *cdev)
202{ 216{
217 int i;
218
203 gphonet_cleanup(); 219 gphonet_cleanup();
204 gserial_cleanup(); 220
221 for (i = 0; i < TTY_PORTS_MAX; i++)
222 gserial_free_line(tty_lines[i]);
223
205 gether_cleanup(); 224 gether_cleanup();
206 225
207 return 0; 226 return 0;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 4816f494fc4d..a883562f6a89 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -127,6 +127,7 @@ module_param(n_ports, uint, 0);
127MODULE_PARM_DESC(n_ports, "number of ports to create, default=1"); 127MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");
128 128
129/*-------------------------------------------------------------------------*/ 129/*-------------------------------------------------------------------------*/
130static unsigned char tty_lines[MAX_U_SERIAL_PORTS];
130 131
131static int __init serial_bind_acm_config(struct usb_configuration *c) 132static int __init serial_bind_acm_config(struct usb_configuration *c)
132{ 133{
@@ -134,7 +135,7 @@ static int __init serial_bind_acm_config(struct usb_configuration *c)
134 int status = 0; 135 int status = 0;
135 136
136 for (i = 0; i < n_ports && status == 0; i++) 137 for (i = 0; i < n_ports && status == 0; i++)
137 status = acm_bind_config(c, i); 138 status = acm_bind_config(c, tty_lines[i]);
138 return status; 139 return status;
139} 140}
140 141
@@ -144,7 +145,7 @@ static int __init serial_bind_obex_config(struct usb_configuration *c)
144 int status = 0; 145 int status = 0;
145 146
146 for (i = 0; i < n_ports && status == 0; i++) 147 for (i = 0; i < n_ports && status == 0; i++)
147 status = obex_bind_config(c, i); 148 status = obex_bind_config(c, tty_lines[i]);
148 return status; 149 return status;
149} 150}
150 151
@@ -154,7 +155,7 @@ static int __init serial_bind_gser_config(struct usb_configuration *c)
154 int status = 0; 155 int status = 0;
155 156
156 for (i = 0; i < n_ports && status == 0; i++) 157 for (i = 0; i < n_ports && status == 0; i++)
157 status = gser_bind_config(c, i); 158 status = gser_bind_config(c, tty_lines[i]);
158 return status; 159 return status;
159} 160}
160 161
@@ -165,13 +166,25 @@ static struct usb_configuration serial_config_driver = {
165 .bmAttributes = USB_CONFIG_ATT_SELFPOWER, 166 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
166}; 167};
167 168
169static int gs_unbind(struct usb_composite_dev *cdev)
170{
171 int i;
172
173 for (i = 0; i < n_ports; i++)
174 gserial_free_line(tty_lines[i]);
175 return 0;
176}
177
168static int __init gs_bind(struct usb_composite_dev *cdev) 178static int __init gs_bind(struct usb_composite_dev *cdev)
169{ 179{
170 int status; 180 int status;
181 int cur_line;
171 182
172 status = gserial_setup(cdev->gadget, n_ports); 183 for (cur_line = 0; cur_line < n_ports; cur_line++) {
173 if (status < 0) 184 status = gserial_alloc_line(&tty_lines[cur_line]);
174 return status; 185 if (status)
186 goto fail;
187 }
175 188
176 /* Allocate string descriptor numbers ... note that string 189 /* Allocate string descriptor numbers ... note that string
177 * contents can be overridden by the composite_dev glue. 190 * contents can be overridden by the composite_dev glue.
@@ -209,7 +222,9 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
209 return 0; 222 return 0;
210 223
211fail: 224fail:
212 gserial_cleanup(); 225 cur_line--;
226 while (cur_line >= 0)
227 gserial_free_line(tty_lines[cur_line--]);
213 return status; 228 return status;
214} 229}
215 230
@@ -219,6 +234,7 @@ static __refdata struct usb_composite_driver gserial_driver = {
219 .strings = dev_strings, 234 .strings = dev_strings,
220 .max_speed = USB_SPEED_SUPER, 235 .max_speed = USB_SPEED_SUPER,
221 .bind = gs_bind, 236 .bind = gs_bind,
237 .unbind = gs_unbind,
222}; 238};
223 239
224static int __init init(void) 240static int __init init(void)
@@ -254,6 +270,5 @@ module_init(init);
254static void __exit cleanup(void) 270static void __exit cleanup(void)
255{ 271{
256 usb_composite_unregister(&gserial_driver); 272 usb_composite_unregister(&gserial_driver);
257 gserial_cleanup();
258} 273}
259module_exit(cleanup); 274module_exit(cleanup);
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 1662d839a1d6..ea360fda2e14 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -36,11 +36,12 @@
36 * "serial port" functionality through the USB gadget stack. Each such 36 * "serial port" functionality through the USB gadget stack. Each such
37 * port is exposed through a /dev/ttyGS* node. 37 * port is exposed through a /dev/ttyGS* node.
38 * 38 *
39 * After initialization (gserial_setup), these TTY port devices stay 39 * After this module has been loaded, the individual TTY port can be requested
40 * available until they are removed (gserial_cleanup). Each one may be 40 * (gserial_alloc_line()) and it will stay available until they are removed
41 * connected to a USB function (gserial_connect), or disconnected (with 41 * (gserial_free_line()). Each one may be connected to a USB function
42 * gserial_disconnect) when the USB host issues a config change event. 42 * (gserial_connect), or disconnected (with gserial_disconnect) when the USB
43 * Data can only flow when the port is connected to the host. 43 * host issues a config change event. Data can only flow when the port is
44 * connected to the host.
44 * 45 *
45 * A given TTY port can be made available in multiple configurations. 46 * A given TTY port can be made available in multiple configurations.
46 * For example, each one might expose a ttyGS0 node which provides a 47 * For example, each one might expose a ttyGS0 node which provides a
@@ -120,13 +121,10 @@ struct gs_port {
120 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ 121 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */
121}; 122};
122 123
123/* increase N_PORTS if you need more */
124#define N_PORTS 4
125static struct portmaster { 124static struct portmaster {
126 struct mutex lock; /* protect open/close */ 125 struct mutex lock; /* protect open/close */
127 struct gs_port *port; 126 struct gs_port *port;
128} ports[N_PORTS]; 127} ports[MAX_U_SERIAL_PORTS];
129static unsigned n_ports;
130 128
131#define GS_CLOSE_TIMEOUT 15 /* seconds */ 129#define GS_CLOSE_TIMEOUT 15 /* seconds */
132 130
@@ -1033,10 +1031,19 @@ static int
1033gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) 1031gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
1034{ 1032{
1035 struct gs_port *port; 1033 struct gs_port *port;
1034 int ret = 0;
1035
1036 mutex_lock(&ports[port_num].lock);
1037 if (ports[port_num].port) {
1038 ret = -EBUSY;
1039 goto out;
1040 }
1036 1041
1037 port = kzalloc(sizeof(struct gs_port), GFP_KERNEL); 1042 port = kzalloc(sizeof(struct gs_port), GFP_KERNEL);
1038 if (port == NULL) 1043 if (port == NULL) {
1039 return -ENOMEM; 1044 ret = -ENOMEM;
1045 goto out;
1046 }
1040 1047
1041 tty_port_init(&port->port); 1048 tty_port_init(&port->port);
1042 spin_lock_init(&port->port_lock); 1049 spin_lock_init(&port->port_lock);
@@ -1052,114 +1059,10 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
1052 port->port_line_coding = *coding; 1059 port->port_line_coding = *coding;
1053 1060
1054 ports[port_num].port = port; 1061 ports[port_num].port = port;
1055 1062out:
1056 return 0; 1063 mutex_unlock(&ports[port_num].lock);
1057} 1064 return ret;
1058
1059/**
1060 * gserial_setup - initialize TTY driver for one or more ports
1061 * @g: gadget to associate with these ports
1062 * @count: how many ports to support
1063 * Context: may sleep
1064 *
1065 * The TTY stack needs to know in advance how many devices it should
1066 * plan to manage. Use this call to set up the ports you will be
1067 * exporting through USB. Later, connect them to functions based
1068 * on what configuration is activated by the USB host; and disconnect
1069 * them as appropriate.
1070 *
1071 * An example would be a two-configuration device in which both
1072 * configurations expose port 0, but through different functions.
1073 * One configuration could even expose port 1 while the other
1074 * one doesn't.
1075 *
1076 * Returns negative errno or zero.
1077 */
1078int gserial_setup(struct usb_gadget *g, unsigned count)
1079{
1080 unsigned i;
1081 struct usb_cdc_line_coding coding;
1082 int status;
1083
1084 if (count == 0 || count > N_PORTS)
1085 return -EINVAL;
1086
1087 if (gs_tty_driver)
1088 return -EBUSY;
1089
1090 gs_tty_driver = alloc_tty_driver(count);
1091 if (!gs_tty_driver)
1092 return -ENOMEM;
1093
1094 gs_tty_driver->driver_name = "g_serial";
1095 gs_tty_driver->name = PREFIX;
1096 /* uses dynamically assigned dev_t values */
1097
1098 gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1099 gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
1100 gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
1101 gs_tty_driver->init_termios = tty_std_termios;
1102
1103 /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
1104 * MS-Windows. Otherwise, most of these flags shouldn't affect
1105 * anything unless we were to actually hook up to a serial line.
1106 */
1107 gs_tty_driver->init_termios.c_cflag =
1108 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1109 gs_tty_driver->init_termios.c_ispeed = 9600;
1110 gs_tty_driver->init_termios.c_ospeed = 9600;
1111
1112 coding.dwDTERate = cpu_to_le32(9600);
1113 coding.bCharFormat = 8;
1114 coding.bParityType = USB_CDC_NO_PARITY;
1115 coding.bDataBits = USB_CDC_1_STOP_BITS;
1116
1117 tty_set_operations(gs_tty_driver, &gs_tty_ops);
1118
1119 /* make devices be openable */
1120 for (i = 0; i < count; i++) {
1121 mutex_init(&ports[i].lock);
1122 status = gs_port_alloc(i, &coding);
1123 if (status) {
1124 count = i;
1125 goto fail;
1126 }
1127 }
1128 n_ports = count;
1129
1130 /* export the driver ... */
1131 status = tty_register_driver(gs_tty_driver);
1132 if (status) {
1133 pr_err("%s: cannot register, err %d\n",
1134 __func__, status);
1135 goto fail;
1136 }
1137
1138 /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
1139 for (i = 0; i < count; i++) {
1140 struct device *tty_dev;
1141
1142 tty_dev = tty_port_register_device(&ports[i].port->port,
1143 gs_tty_driver, i, &g->dev);
1144 if (IS_ERR(tty_dev))
1145 pr_warning("%s: no classdev for port %d, err %ld\n",
1146 __func__, i, PTR_ERR(tty_dev));
1147 }
1148
1149 pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
1150 count, (count == 1) ? "" : "s");
1151
1152 return status;
1153fail:
1154 while (count--) {
1155 tty_port_destroy(&ports[count].port->port);
1156 kfree(ports[count].port);
1157 }
1158 put_tty_driver(gs_tty_driver);
1159 gs_tty_driver = NULL;
1160 return status;
1161} 1065}
1162EXPORT_SYMBOL_GPL(gserial_setup);
1163 1066
1164static int gs_closed(struct gs_port *port) 1067static int gs_closed(struct gs_port *port)
1165{ 1068{
@@ -1171,56 +1074,77 @@ static int gs_closed(struct gs_port *port)
1171 return cond; 1074 return cond;
1172} 1075}
1173 1076
1174/** 1077static void gserial_free_port(struct gs_port *port)
1175 * gserial_cleanup - remove TTY-over-USB driver and devices 1078{
1176 * Context: may sleep 1079 tasklet_kill(&port->push);
1177 * 1080 /* wait for old opens to finish */
1178 * This is called to free all resources allocated by @gserial_setup(). 1081 wait_event(port->port.close_wait, gs_closed(port));
1179 * Accordingly, it may need to wait until some open /dev/ files have 1082 WARN_ON(port->port_usb != NULL);
1180 * closed. 1083 tty_port_destroy(&port->port);
1181 * 1084 kfree(port);
1182 * The caller must have issued @gserial_disconnect() for any ports 1085}
1183 * that had previously been connected, so that there is never any 1086
1184 * I/O pending when it's called. 1087void gserial_free_line(unsigned char port_num)
1185 */
1186void gserial_cleanup(void)
1187{ 1088{
1188 unsigned i;
1189 struct gs_port *port; 1089 struct gs_port *port;
1190 1090
1191 if (!gs_tty_driver) 1091 mutex_lock(&ports[port_num].lock);
1092 if (WARN_ON(!ports[port_num].port)) {
1093 mutex_unlock(&ports[port_num].lock);
1192 return; 1094 return;
1095 }
1096 port = ports[port_num].port;
1097 ports[port_num].port = NULL;
1098 mutex_unlock(&ports[port_num].lock);
1193 1099
1194 /* start sysfs and /dev/ttyGS* node removal */ 1100 gserial_free_port(port);
1195 for (i = 0; i < n_ports; i++) 1101 tty_unregister_device(gs_tty_driver, port_num);
1196 tty_unregister_device(gs_tty_driver, i); 1102}
1197 1103EXPORT_SYMBOL_GPL(gserial_free_line);
1198 for (i = 0; i < n_ports; i++) {
1199 /* prevent new opens */
1200 mutex_lock(&ports[i].lock);
1201 port = ports[i].port;
1202 ports[i].port = NULL;
1203 mutex_unlock(&ports[i].lock);
1204
1205 tasklet_kill(&port->push);
1206 1104
1207 /* wait for old opens to finish */ 1105int gserial_alloc_line(unsigned char *line_num)
1208 wait_event(port->port.close_wait, gs_closed(port)); 1106{
1107 struct usb_cdc_line_coding coding;
1108 struct device *tty_dev;
1109 int ret;
1110 int port_num;
1209 1111
1210 WARN_ON(port->port_usb != NULL); 1112 coding.dwDTERate = cpu_to_le32(9600);
1113 coding.bCharFormat = 8;
1114 coding.bParityType = USB_CDC_NO_PARITY;
1115 coding.bDataBits = USB_CDC_1_STOP_BITS;
1211 1116
1212 tty_port_destroy(&port->port); 1117 for (port_num = 0; port_num < MAX_U_SERIAL_PORTS; port_num++) {
1213 kfree(port); 1118 ret = gs_port_alloc(port_num, &coding);
1119 if (ret == -EBUSY)
1120 continue;
1121 if (ret)
1122 return ret;
1123 break;
1214 } 1124 }
1215 n_ports = 0; 1125 if (ret)
1126 return ret;
1216 1127
1217 tty_unregister_driver(gs_tty_driver); 1128 /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
1218 put_tty_driver(gs_tty_driver);
1219 gs_tty_driver = NULL;
1220 1129
1221 pr_debug("%s: cleaned up ttyGS* support\n", __func__); 1130 tty_dev = tty_port_register_device(&ports[port_num].port->port,
1131 gs_tty_driver, port_num, NULL);
1132 if (IS_ERR(tty_dev)) {
1133 struct gs_port *port;
1134 pr_err("%s: failed to register tty for port %d, err %ld\n",
1135 __func__, port_num, PTR_ERR(tty_dev));
1136
1137 ret = PTR_ERR(tty_dev);
1138 port = ports[port_num].port;
1139 ports[port_num].port = NULL;
1140 gserial_free_port(port);
1141 goto err;
1142 }
1143 *line_num = port_num;
1144err:
1145 return ret;
1222} 1146}
1223EXPORT_SYMBOL_GPL(gserial_cleanup); 1147EXPORT_SYMBOL_GPL(gserial_alloc_line);
1224 1148
1225/** 1149/**
1226 * gserial_connect - notify TTY I/O glue that USB link is active 1150 * gserial_connect - notify TTY I/O glue that USB link is active
@@ -1237,8 +1161,8 @@ EXPORT_SYMBOL_GPL(gserial_cleanup);
1237 * 1161 *
1238 * Caller needs to have set up the endpoints and USB function in @dev 1162 * Caller needs to have set up the endpoints and USB function in @dev
1239 * before calling this, as well as the appropriate (speed-specific) 1163 * before calling this, as well as the appropriate (speed-specific)
1240 * endpoint descriptors, and also have set up the TTY driver by calling 1164 * endpoint descriptors, and also have allocate @port_num by calling
1241 * @gserial_setup(). 1165 * @gserial_alloc_line().
1242 * 1166 *
1243 * Returns negative errno or zero. 1167 * Returns negative errno or zero.
1244 * On success, ep->driver_data will be overwritten. 1168 * On success, ep->driver_data will be overwritten.
@@ -1249,11 +1173,18 @@ int gserial_connect(struct gserial *gser, u8 port_num)
1249 unsigned long flags; 1173 unsigned long flags;
1250 int status; 1174 int status;
1251 1175
1252 if (!gs_tty_driver || port_num >= n_ports) 1176 if (port_num >= MAX_U_SERIAL_PORTS)
1253 return -ENXIO; 1177 return -ENXIO;
1254 1178
1255 /* we "know" gserial_cleanup() hasn't been called */
1256 port = ports[port_num].port; 1179 port = ports[port_num].port;
1180 if (!port) {
1181 pr_err("serial line %d not allocated.\n", port_num);
1182 return -EINVAL;
1183 }
1184 if (port->port_usb) {
1185 pr_err("serial line %d is in use.\n", port_num);
1186 return -EBUSY;
1187 }
1257 1188
1258 /* activate the endpoints */ 1189 /* activate the endpoints */
1259 status = usb_ep_enable(gser->in); 1190 status = usb_ep_enable(gser->in);
@@ -1357,4 +1288,63 @@ void gserial_disconnect(struct gserial *gser)
1357} 1288}
1358EXPORT_SYMBOL_GPL(gserial_disconnect); 1289EXPORT_SYMBOL_GPL(gserial_disconnect);
1359 1290
1291int userial_init(void)
1292{
1293 unsigned i;
1294 int status;
1295
1296 gs_tty_driver = alloc_tty_driver(MAX_U_SERIAL_PORTS);
1297 if (!gs_tty_driver)
1298 return -ENOMEM;
1299
1300 gs_tty_driver->driver_name = "g_serial";
1301 gs_tty_driver->name = PREFIX;
1302 /* uses dynamically assigned dev_t values */
1303
1304 gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1305 gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
1306 gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
1307 gs_tty_driver->init_termios = tty_std_termios;
1308
1309 /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
1310 * MS-Windows. Otherwise, most of these flags shouldn't affect
1311 * anything unless we were to actually hook up to a serial line.
1312 */
1313 gs_tty_driver->init_termios.c_cflag =
1314 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1315 gs_tty_driver->init_termios.c_ispeed = 9600;
1316 gs_tty_driver->init_termios.c_ospeed = 9600;
1317
1318 tty_set_operations(gs_tty_driver, &gs_tty_ops);
1319 for (i = 0; i < MAX_U_SERIAL_PORTS; i++)
1320 mutex_init(&ports[i].lock);
1321
1322 /* export the driver ... */
1323 status = tty_register_driver(gs_tty_driver);
1324 if (status) {
1325 pr_err("%s: cannot register, err %d\n",
1326 __func__, status);
1327 goto fail;
1328 }
1329
1330 pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
1331 MAX_U_SERIAL_PORTS,
1332 (MAX_U_SERIAL_PORTS == 1) ? "" : "s");
1333
1334 return status;
1335fail:
1336 put_tty_driver(gs_tty_driver);
1337 gs_tty_driver = NULL;
1338 return status;
1339}
1340module_init(userial_init);
1341
1342static void userial_cleanup(void)
1343{
1344 tty_unregister_driver(gs_tty_driver);
1345 put_tty_driver(gs_tty_driver);
1346 gs_tty_driver = NULL;
1347}
1348module_exit(userial_cleanup);
1349
1360MODULE_LICENSE("GPL"); 1350MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h
index 9b0fe6450fbf..f06ee9a5db51 100644
--- a/drivers/usb/gadget/u_serial.h
+++ b/drivers/usb/gadget/u_serial.h
@@ -15,6 +15,8 @@
15#include <linux/usb/composite.h> 15#include <linux/usb/composite.h>
16#include <linux/usb/cdc.h> 16#include <linux/usb/cdc.h>
17 17
18#define MAX_U_SERIAL_PORTS 4
19
18/* 20/*
19 * One non-multiplexed "serial" I/O port ... there can be several of these 21 * One non-multiplexed "serial" I/O port ... there can be several of these
20 * on any given USB peripheral device, if it provides enough endpoints. 22 * on any given USB peripheral device, if it provides enough endpoints.
@@ -49,9 +51,9 @@ struct gserial {
49struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags); 51struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags);
50void gs_free_req(struct usb_ep *, struct usb_request *req); 52void gs_free_req(struct usb_ep *, struct usb_request *req);
51 53
52/* port setup/teardown is handled by gadget driver */ 54/* management of individual TTY ports */
53int gserial_setup(struct usb_gadget *g, unsigned n_ports); 55int gserial_alloc_line(unsigned char *port_line);
54void gserial_cleanup(void); 56void gserial_free_line(unsigned char port_line);
55 57
56/* connect/disconnect is handled by individual functions */ 58/* connect/disconnect is handled by individual functions */
57int gserial_connect(struct gserial *, u8 port_num); 59int gserial_connect(struct gserial *, u8 port_num);