1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * USB CDC serial (ACM) function driver
4  *
5  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
6  * Copyright (C) 2008 by David Brownell
7  * Copyright (C) 2008 by Nokia Corporation
8  * Copyright (C) 2009 by Samsung Electronics
9  * Copyright (c) 2021, Linaro Ltd <loic.poulain@linaro.org>
10  */
11 
12 #include <circbuf.h>
13 #include <common.h>
14 #include <console.h>
15 #include <errno.h>
16 #include <g_dnl.h>
17 #include <malloc.h>
18 #include <memalign.h>
19 #include <stdio_dev.h>
20 #include <version.h>
21 #include <watchdog.h>
22 
23 #include <linux/usb/ch9.h>
24 #include <linux/usb/gadget.h>
25 #include <linux/usb/composite.h>
26 #include <linux/usb/cdc.h>
27 
28 #define REQ_SIZE_MAX	512
29 
30 struct f_acm {
31 	int ctrl_id;
32 	int data_id;
33 
34 	struct usb_ep *ep_in;
35 	struct usb_ep *ep_out;
36 	struct usb_ep *ep_notify;
37 
38 	struct usb_request *req_in;
39 	struct usb_request *req_out;
40 
41 	bool connected;
42 	bool tx_on;
43 
44 	circbuf_t rx_buf;
45 	circbuf_t tx_buf;
46 
47 	struct usb_function usb_function;
48 
49 	struct usb_cdc_line_coding line_coding;
50 	u16 handshake_bits;
51 #define ACM_CTRL_RTS	BIT(1)	/* unused with full duplex */
52 #define ACM_CTRL_DTR	BIT(0)	/* host is ready for data r/w */
53 
54 	int controller_index;
55 };
56 
57 static struct f_acm *default_acm_function;
58 
func_to_acm(struct usb_function * f)59 static inline struct f_acm *func_to_acm(struct usb_function *f)
60 {
61 	return container_of(f, struct f_acm, usb_function);
62 }
63 
stdio_to_acm(struct stdio_dev * s)64 static inline struct f_acm *stdio_to_acm(struct stdio_dev *s)
65 {
66 	/* stdio dev is cloned on registration, do not use container_of */
67 	return s->priv;
68 }
69 
70 static struct usb_interface_assoc_descriptor
71 acm_iad_descriptor = {
72 	.bLength =              sizeof(acm_iad_descriptor),
73 	.bDescriptorType =      USB_DT_INTERFACE_ASSOCIATION,
74 	.bFirstInterface =      0,
75 	.bInterfaceCount =      2,	// control + data
76 	.bFunctionClass =       USB_CLASS_COMM,
77 	.bFunctionSubClass =    USB_CDC_SUBCLASS_ACM,
78 	.bFunctionProtocol =    USB_CDC_ACM_PROTO_AT_V25TER,
79 };
80 
81 static struct usb_interface_descriptor acm_control_intf_desc = {
82 	.bLength =              USB_DT_INTERFACE_SIZE,
83 	.bDescriptorType =      USB_DT_INTERFACE,
84 	.bNumEndpoints =        1,
85 	.bInterfaceClass =      USB_CLASS_COMM,
86 	.bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
87 	.bInterfaceProtocol =   USB_CDC_ACM_PROTO_AT_V25TER,
88 };
89 
90 static struct usb_interface_descriptor acm_data_intf_desc = {
91 	.bLength =              sizeof(acm_data_intf_desc),
92 	.bDescriptorType =      USB_DT_INTERFACE,
93 	.bNumEndpoints =        2,
94 	.bInterfaceClass =      USB_CLASS_CDC_DATA,
95 };
96 
97 static struct usb_cdc_header_desc acm_header_desc = {
98 	.bLength =		sizeof(acm_header_desc),
99 	.bDescriptorType =	USB_DT_CS_INTERFACE,
100 	.bDescriptorSubType =	USB_CDC_HEADER_TYPE,
101 	.bcdCDC =		__constant_cpu_to_le16(0x0110),
102 };
103 
104 static struct usb_cdc_call_mgmt_descriptor acm_call_mgmt_desc = {
105 	.bLength =              sizeof(acm_call_mgmt_desc),
106 	.bDescriptorType =      USB_DT_CS_INTERFACE,
107 	.bDescriptorSubType =   USB_CDC_CALL_MANAGEMENT_TYPE,
108 	.bmCapabilities =       0,
109 	.bDataInterface =       0x01,
110 };
111 
112 static struct usb_cdc_acm_descriptor acm_desc = {
113 	.bLength =		sizeof(acm_desc),
114 	.bDescriptorType =	USB_DT_CS_INTERFACE,
115 	.bDescriptorSubType =	USB_CDC_ACM_TYPE,
116 	.bmCapabilities =	USB_CDC_CAP_LINE,
117 };
118 
119 static struct usb_cdc_union_desc acm_union_desc = {
120 	.bLength =		sizeof(acm_union_desc),
121 	.bDescriptorType =	USB_DT_CS_INTERFACE,
122 	.bDescriptorSubType =	USB_CDC_UNION_TYPE,
123 	.bMasterInterface0 =	0x00,
124 	.bSlaveInterface0 =	0x01,
125 };
126 
127 static struct usb_endpoint_descriptor acm_fs_notify_desc = {
128 	.bLength =              USB_DT_ENDPOINT_SIZE,
129 	.bDescriptorType =      USB_DT_ENDPOINT,
130 	.bEndpointAddress =     3 | USB_DIR_IN,
131 	.bmAttributes =         USB_ENDPOINT_XFER_INT,
132 	.wMaxPacketSize =       __constant_cpu_to_le16(64),
133 	.bInterval =            32,
134 };
135 
136 static struct usb_endpoint_descriptor acm_fs_in_desc = {
137 	.bLength =              USB_DT_ENDPOINT_SIZE,
138 	.bDescriptorType =      USB_DT_ENDPOINT,
139 	.bEndpointAddress =     USB_DIR_IN,
140 	.bmAttributes =         USB_ENDPOINT_XFER_BULK,
141 };
142 
143 static struct usb_endpoint_descriptor acm_fs_out_desc = {
144 	.bLength =              USB_DT_ENDPOINT_SIZE,
145 	.bDescriptorType =      USB_DT_ENDPOINT,
146 	.bEndpointAddress =     USB_DIR_OUT,
147 	.bmAttributes =         USB_ENDPOINT_XFER_BULK,
148 };
149 
150 static struct usb_descriptor_header *acm_fs_function[] = {
151 	(struct usb_descriptor_header *)&acm_iad_descriptor,
152 	(struct usb_descriptor_header *)&acm_control_intf_desc,
153 	(struct usb_descriptor_header *)&acm_header_desc,
154 	(struct usb_descriptor_header *)&acm_call_mgmt_desc,
155 	(struct usb_descriptor_header *)&acm_desc,
156 	(struct usb_descriptor_header *)&acm_union_desc,
157 	(struct usb_descriptor_header *)&acm_fs_notify_desc,
158 	(struct usb_descriptor_header *)&acm_data_intf_desc,
159 	(struct usb_descriptor_header *)&acm_fs_in_desc,
160 	(struct usb_descriptor_header *)&acm_fs_out_desc,
161 	NULL,
162 };
163 
164 static struct usb_endpoint_descriptor acm_hs_notify_desc = {
165 	.bLength =              USB_DT_ENDPOINT_SIZE,
166 	.bDescriptorType =      USB_DT_ENDPOINT,
167 	.bmAttributes =         USB_ENDPOINT_XFER_INT,
168 	.wMaxPacketSize =       __constant_cpu_to_le16(64),
169 	.bInterval =            11,
170 };
171 
172 static struct usb_endpoint_descriptor acm_hs_in_desc = {
173 	.bLength		= USB_DT_ENDPOINT_SIZE,
174 	.bDescriptorType	= USB_DT_ENDPOINT,
175 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
176 	.wMaxPacketSize		= __constant_cpu_to_le16(512),
177 };
178 
179 static struct usb_endpoint_descriptor acm_hs_out_desc = {
180 	.bLength		= USB_DT_ENDPOINT_SIZE,
181 	.bDescriptorType	= USB_DT_ENDPOINT,
182 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
183 	.wMaxPacketSize		= __constant_cpu_to_le16(512),
184 };
185 
186 static struct usb_descriptor_header *acm_hs_function[] = {
187 	(struct usb_descriptor_header *)&acm_iad_descriptor,
188 	(struct usb_descriptor_header *)&acm_control_intf_desc,
189 	(struct usb_descriptor_header *)&acm_header_desc,
190 	(struct usb_descriptor_header *)&acm_call_mgmt_desc,
191 	(struct usb_descriptor_header *)&acm_desc,
192 	(struct usb_descriptor_header *)&acm_union_desc,
193 	(struct usb_descriptor_header *)&acm_hs_notify_desc,
194 	(struct usb_descriptor_header *)&acm_data_intf_desc,
195 	(struct usb_descriptor_header *)&acm_hs_in_desc,
196 	(struct usb_descriptor_header *)&acm_hs_out_desc,
197 	NULL,
198 };
199 
200 static inline struct usb_endpoint_descriptor *
ep_desc(struct usb_gadget * g,struct usb_endpoint_descriptor * hs,struct usb_endpoint_descriptor * fs)201 ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
202 	struct usb_endpoint_descriptor *fs)
203 {
204 	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
205 		return hs;
206 	return fs;
207 }
208 
acm_bind(struct usb_configuration * c,struct usb_function * f)209 static int acm_bind(struct usb_configuration *c, struct usb_function *f)
210 {
211 	struct usb_gadget *gadget = c->cdev->gadget;
212 	struct f_acm *f_acm = func_to_acm(f);
213 	struct usb_ep *ep;
214 	int id;
215 
216 	id = usb_interface_id(c, f);
217 	if (id < 0)
218 		return id;
219 
220 	acm_iad_descriptor.bFirstInterface = id;
221 	acm_control_intf_desc.bInterfaceNumber = id;
222 	acm_union_desc.bMasterInterface0 = id;
223 
224 	f_acm->ctrl_id = id;
225 
226 	id = usb_interface_id(c, f);
227 	if (id < 0)
228 		return id;
229 
230 	acm_data_intf_desc.bInterfaceNumber = id;
231 	acm_union_desc.bSlaveInterface0 = id;
232 	acm_call_mgmt_desc.bDataInterface = id;
233 
234 	f_acm->data_id = id;
235 
236 	/* allocate instance-specific endpoints */
237 	ep = usb_ep_autoconfig(gadget, &acm_fs_in_desc);
238 	if (!ep)
239 		return -ENODEV;
240 
241 	f_acm->ep_in = ep;
242 
243 	ep = usb_ep_autoconfig(gadget, &acm_fs_out_desc);
244 	if (!ep)
245 		return -ENODEV;
246 
247 	f_acm->ep_out = ep;
248 
249 	ep = usb_ep_autoconfig(gadget, &acm_fs_notify_desc);
250 	if (!ep)
251 		return -ENODEV;
252 
253 	f_acm->ep_notify = ep;
254 
255 	if (gadget_is_dualspeed(gadget)) {
256 		/* Assume endpoint addresses are the same for both speeds */
257 		acm_hs_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress;
258 		acm_hs_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress;
259 		acm_hs_notify_desc.bEndpointAddress = acm_fs_notify_desc.bEndpointAddress;
260 	}
261 
262 	return 0;
263 }
264 
acm_unbind(struct usb_configuration * c,struct usb_function * f)265 static void acm_unbind(struct usb_configuration *c, struct usb_function *f)
266 {
267 	struct f_acm *f_acm = func_to_acm(f);
268 
269 	if (default_acm_function == f_acm)
270 		default_acm_function = NULL;
271 
272 	buf_free(&f_acm->rx_buf);
273 	buf_free(&f_acm->tx_buf);
274 
275 	free(f_acm);
276 }
277 
acm_notify_complete(struct usb_ep * ep,struct usb_request * req)278 static void acm_notify_complete(struct usb_ep *ep, struct usb_request *req)
279 {
280 	/* nothing to do */
281 }
282 
acm_tx_complete(struct usb_ep * ep,struct usb_request * req)283 static void acm_tx_complete(struct usb_ep *ep, struct usb_request *req)
284 {
285 	struct f_acm *f_acm = req->context;
286 
287 	f_acm->tx_on = true;
288 }
289 
acm_rx_complete(struct usb_ep * ep,struct usb_request * req)290 static void acm_rx_complete(struct usb_ep *ep, struct usb_request *req)
291 {
292 	struct f_acm *f_acm = req->context;
293 
294 	buf_push(&f_acm->rx_buf, req->buf, req->actual);
295 
296 	/* Queue RX req again */
297 	req->actual = 0;
298 	usb_ep_queue(ep, req, 0);
299 }
300 
acm_start_ep(struct usb_ep * ep,void * complete_cb,void * context)301 static struct usb_request *acm_start_ep(struct usb_ep *ep, void *complete_cb,
302 					void *context)
303 {
304 	struct usb_request *req;
305 
306 	req = usb_ep_alloc_request(ep, 0);
307 	if (!req)
308 		return NULL;
309 
310 	req->length = REQ_SIZE_MAX;
311 	req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, REQ_SIZE_MAX);
312 	if (!req->buf) {
313 		usb_ep_free_request(ep, req);
314 		return NULL;
315 	}
316 
317 	memset(req->buf, 0, req->length);
318 	req->complete = complete_cb;
319 	req->context = context;
320 
321 	return req;
322 }
323 
acm_start_data(struct f_acm * f_acm,struct usb_gadget * gadget)324 static int acm_start_data(struct f_acm *f_acm, struct usb_gadget *gadget)
325 {
326 	const struct usb_endpoint_descriptor *d;
327 	int ret;
328 
329 	/* EP IN */
330 	d = ep_desc(gadget, &acm_hs_in_desc, &acm_fs_in_desc);
331 	ret = usb_ep_enable(f_acm->ep_in, d);
332 	if (ret)
333 		return ret;
334 
335 	f_acm->req_in = acm_start_ep(f_acm->ep_in, acm_tx_complete, f_acm);
336 
337 	/* EP OUT */
338 	d = ep_desc(gadget, &acm_hs_out_desc, &acm_fs_out_desc);
339 	ret = usb_ep_enable(f_acm->ep_out, d);
340 	if (ret)
341 		return ret;
342 
343 	f_acm->req_out = acm_start_ep(f_acm->ep_out, acm_rx_complete, f_acm);
344 
345 	/* Start OUT transfer (EP OUT) */
346 	ret = usb_ep_queue(f_acm->ep_out, f_acm->req_out, 0);
347 	if (ret)
348 		return ret;
349 
350 	return 0;
351 }
352 
acm_start_ctrl(struct f_acm * f_acm,struct usb_gadget * gadget)353 static int acm_start_ctrl(struct f_acm *f_acm, struct usb_gadget *gadget)
354 {
355 	const struct usb_endpoint_descriptor *d;
356 
357 	usb_ep_disable(f_acm->ep_notify);
358 
359 	d = ep_desc(gadget, &acm_hs_notify_desc, &acm_fs_notify_desc);
360 	usb_ep_enable(f_acm->ep_notify, d);
361 
362 	acm_start_ep(f_acm->ep_notify, acm_notify_complete, f_acm);
363 
364 	return 0;
365 }
366 
acm_set_alt(struct usb_function * f,unsigned int intf,unsigned int alt)367 static int acm_set_alt(struct usb_function *f, unsigned int intf, unsigned int alt)
368 {
369 	struct usb_gadget *gadget = f->config->cdev->gadget;
370 	struct f_acm *f_acm = func_to_acm(f);
371 
372 	if (intf == f_acm->ctrl_id) {
373 		return acm_start_ctrl(f_acm, gadget);
374 	} else if (intf == f_acm->data_id) {
375 		acm_start_data(f_acm, gadget);
376 		f_acm->connected = true;
377 		f_acm->tx_on = true;
378 		return 0;
379 	}
380 
381 	return -EINVAL;
382 }
383 
acm_setup(struct usb_function * f,const struct usb_ctrlrequest * ctrl)384 static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
385 {
386 	struct usb_gadget *gadget =  f->config->cdev->gadget;
387 	struct usb_request *req = f->config->cdev->req;
388 	u16 w_index = le16_to_cpu(ctrl->wIndex);
389 	u16 w_value = le16_to_cpu(ctrl->wValue);
390 	u16 w_length = le16_to_cpu(ctrl->wLength);
391 	struct f_acm *f_acm = func_to_acm(f);
392 	int value = -1;
393 
394 	switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
395 	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
396 			| USB_CDC_REQ_SET_LINE_CODING:
397 		/* SET_LINE_CODING */
398 
399 		if (w_length != sizeof(f_acm->line_coding) || w_index != f_acm->ctrl_id)
400 			goto invalid;
401 
402 		value = w_length;
403 
404 		memcpy(&f_acm->line_coding, req->buf, value);
405 
406 		break;
407 	case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
408 			| USB_CDC_REQ_GET_LINE_CODING:
409 		/* GET_LINE_CODING */
410 
411 		if (w_length != sizeof(f_acm->line_coding) || w_index != f_acm->ctrl_id)
412 			goto invalid;
413 
414 		value = w_length;
415 
416 		memcpy(req->buf, &f_acm->line_coding, value);
417 
418 		break;
419 	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
420 			| USB_CDC_REQ_SET_CONTROL_LINE_STATE:
421 		/* SET_CONTROL_LINE_STATE */
422 
423 		if (w_index != f_acm->ctrl_id)
424 			goto invalid;
425 
426 		value = 0;
427 
428 		f_acm->handshake_bits = w_value;
429 
430 		break;
431 	default:
432 invalid:
433 		printf("invalid control req%02x.%02x v%04x i%04x l%d\n",
434 		       ctrl->bRequestType, ctrl->bRequest, w_value, w_index,
435 		       w_length);
436 	}
437 
438 	/* respond with data transfer or status phase? */
439 	if (value >= 0) {
440 		req->zero = 0;
441 		req->length = value;
442 		usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
443 	}
444 
445 	return 0;
446 }
447 
acm_disable(struct usb_function * f)448 static void acm_disable(struct usb_function *f)
449 {
450 	struct f_acm *f_acm = func_to_acm(f);
451 
452 	usb_ep_disable(f_acm->ep_out);
453 	usb_ep_disable(f_acm->ep_in);
454 	usb_ep_disable(f_acm->ep_notify);
455 
456 	if (f_acm->req_out) {
457 		free(f_acm->req_out->buf);
458 		usb_ep_free_request(f_acm->ep_out, f_acm->req_out);
459 		f_acm->req_out = NULL;
460 	}
461 
462 	if (f_acm->req_in) {
463 		free(f_acm->req_in->buf);
464 		usb_ep_free_request(f_acm->ep_in, f_acm->req_in);
465 		f_acm->req_in = NULL;
466 	}
467 }
468 
469 /* static strings, in UTF-8 */
470 static struct usb_string acm_string_defs[] = {
471 	[0].s = "CDC Abstract Control Model (ACM)",
472 	[1].s = "CDC ACM Data",
473 	[2].s = "CDC Serial",
474 	{  } /* end of list */
475 };
476 
477 static struct usb_gadget_strings acm_string_table = {
478 	.language = 0x0409, /* en-us */
479 	.strings = acm_string_defs,
480 };
481 
482 static struct usb_gadget_strings *acm_strings[] = {
483 	&acm_string_table,
484 	NULL,
485 };
486 
__acm_tx(struct f_acm * f_acm)487 static void __acm_tx(struct f_acm *f_acm)
488 {
489 	int len, ret;
490 
491 	do {
492 		usb_gadget_handle_interrupts(f_acm->controller_index);
493 
494 		if (!(f_acm->handshake_bits & ACM_CTRL_DTR))
495 			break;
496 
497 		if (!f_acm->tx_on)
498 			continue;
499 
500 		len = buf_pop(&f_acm->tx_buf, f_acm->req_in->buf, REQ_SIZE_MAX);
501 		if (!len)
502 			break;
503 
504 		f_acm->req_in->length = len;
505 
506 		ret = usb_ep_queue(f_acm->ep_in, f_acm->req_in, 0);
507 		if (ret)
508 			break;
509 
510 		f_acm->tx_on = false;
511 
512 		/* Do not reset the watchdog, if TX is stuck there is probably
513 		 * a real issue.
514 		 */
515 	} while (1);
516 }
517 
acm_connected(struct stdio_dev * dev)518 static bool acm_connected(struct stdio_dev *dev)
519 {
520 	struct f_acm *f_acm = stdio_to_acm(dev);
521 
522 	/* give a chance to process udc irq */
523 	usb_gadget_handle_interrupts(f_acm->controller_index);
524 
525 	return f_acm->connected;
526 }
527 
acm_add(struct usb_configuration * c)528 static int acm_add(struct usb_configuration *c)
529 {
530 	struct f_acm *f_acm;
531 	int status;
532 
533 	f_acm = calloc(1, sizeof(*f_acm));
534 	if (!f_acm)
535 		return -ENOMEM;
536 
537 	f_acm->usb_function.name = "f_acm";
538 	f_acm->usb_function.bind = acm_bind;
539 	f_acm->usb_function.unbind = acm_unbind;
540 	f_acm->usb_function.set_alt = acm_set_alt;
541 	f_acm->usb_function.disable = acm_disable;
542 	f_acm->usb_function.strings = acm_strings;
543 	f_acm->usb_function.descriptors = acm_fs_function;
544 	f_acm->usb_function.hs_descriptors = acm_hs_function;
545 	f_acm->usb_function.setup = acm_setup;
546 	f_acm->controller_index = 0;
547 
548 	status = usb_add_function(c, &f_acm->usb_function);
549 	if (status) {
550 		free(f_acm);
551 		return status;
552 	}
553 
554 	buf_init(&f_acm->rx_buf, 2048);
555 	buf_init(&f_acm->tx_buf, 2048);
556 
557 	if (!default_acm_function)
558 		default_acm_function = f_acm;
559 
560 	return status;
561 }
562 
563 DECLARE_GADGET_BIND_CALLBACK(usb_serial_acm, acm_add);
564 
565 /* STDIO */
acm_stdio_tstc(struct stdio_dev * dev)566 static int acm_stdio_tstc(struct stdio_dev *dev)
567 {
568 	struct f_acm *f_acm = stdio_to_acm(dev);
569 
570 	usb_gadget_handle_interrupts(f_acm->controller_index);
571 
572 	return (f_acm->rx_buf.size > 0);
573 }
574 
acm_stdio_getc(struct stdio_dev * dev)575 static int acm_stdio_getc(struct stdio_dev *dev)
576 {
577 	struct f_acm *f_acm = stdio_to_acm(dev);
578 	char c;
579 
580 	/* Wait for a character to arrive. */
581 	while (!acm_stdio_tstc(dev))
582 		schedule();
583 
584 	buf_pop(&f_acm->rx_buf, &c, 1);
585 
586 	return c;
587 }
588 
acm_stdio_putc(struct stdio_dev * dev,const char c)589 static void acm_stdio_putc(struct stdio_dev *dev, const char c)
590 {
591 	struct f_acm *f_acm = stdio_to_acm(dev);
592 
593 	if (c == '\n')
594 		buf_push(&f_acm->tx_buf, "\r", 1);
595 
596 	buf_push(&f_acm->tx_buf, &c, 1);
597 
598 	if (!f_acm->connected)
599 		return;
600 
601 	__acm_tx(f_acm);
602 }
603 
acm_stdio_puts(struct stdio_dev * dev,const char * str)604 static void acm_stdio_puts(struct stdio_dev *dev, const char *str)
605 {
606 	struct f_acm *f_acm = stdio_to_acm(dev);
607 
608 	while (*str) {
609 		if (*str == '\n')
610 			buf_push(&f_acm->tx_buf, "\r", 1);
611 
612 		buf_push(&f_acm->tx_buf, str++, 1);
613 	}
614 
615 	if (!f_acm->connected)
616 		return;
617 
618 	__acm_tx(f_acm);
619 }
620 
acm_stdio_start(struct stdio_dev * dev)621 static int acm_stdio_start(struct stdio_dev *dev)
622 {
623 	int ret;
624 
625 	if (dev->priv) { /* function already exist */
626 		return 0;
627 	}
628 
629 	ret = g_dnl_register("usb_serial_acm");
630 	if (ret)
631 		return ret;
632 
633 	if (default_acm_function)
634 		dev->priv = default_acm_function;
635 	else
636 		return -ENODEV;
637 
638 	while (!acm_connected(dev)) {
639 		if (ctrlc())
640 			return -ECANCELED;
641 
642 		schedule();
643 	}
644 
645 	return 0;
646 }
647 
acm_stdio_stop(struct stdio_dev * dev)648 static int acm_stdio_stop(struct stdio_dev *dev)
649 {
650 	g_dnl_unregister();
651 	g_dnl_clear_detach();
652 
653 	return 0;
654 }
655 
drv_usbacm_init(void)656 int drv_usbacm_init(void)
657 {
658 	struct stdio_dev stdio;
659 
660 	strcpy(stdio.name, "usbacm");
661 	stdio.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT;
662 	stdio.tstc = acm_stdio_tstc;
663 	stdio.getc = acm_stdio_getc;
664 	stdio.putc = acm_stdio_putc;
665 	stdio.puts = acm_stdio_puts;
666 	stdio.start = acm_stdio_start;
667 	stdio.stop = acm_stdio_stop;
668 	stdio.priv = NULL;
669 	stdio.ext = 0;
670 
671 	return stdio_register(&stdio);
672 }
673