aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_acm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/f_acm.c')
-rw-r--r--drivers/usb/gadget/f_acm.c194
1 files changed, 183 insertions, 11 deletions
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index f3bf5612af2d..5ee1590b8e9c 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -47,16 +47,37 @@ struct f_acm {
47 u8 ctrl_id, data_id; 47 u8 ctrl_id, data_id;
48 u8 port_num; 48 u8 port_num;
49 49
50 u8 pending;
51
52 /* lock is mostly for pending and notify_req ... they get accessed
53 * by callbacks both from tty (open/close/break) under its spinlock,
54 * and notify_req.complete() which can't use that lock.
55 */
56 spinlock_t lock;
57
50 struct acm_ep_descs fs; 58 struct acm_ep_descs fs;
51 struct acm_ep_descs hs; 59 struct acm_ep_descs hs;
52 60
53 struct usb_ep *notify; 61 struct usb_ep *notify;
54 struct usb_endpoint_descriptor *notify_desc; 62 struct usb_endpoint_descriptor *notify_desc;
63 struct usb_request *notify_req;
55 64
56 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ 65 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */
66
67 /* SetControlLineState request -- CDC 1.1 section 6.2.14 (INPUT) */
57 u16 port_handshake_bits; 68 u16 port_handshake_bits;
58#define RS232_RTS (1 << 1) /* unused with full duplex */ 69#define ACM_CTRL_RTS (1 << 1) /* unused with full duplex */
59#define RS232_DTR (1 << 0) /* host is ready for data r/w */ 70#define ACM_CTRL_DTR (1 << 0) /* host is ready for data r/w */
71
72 /* SerialState notification -- CDC 1.1 section 6.3.5 (OUTPUT) */
73 u16 serial_state;
74#define ACM_CTRL_OVERRUN (1 << 6)
75#define ACM_CTRL_PARITY (1 << 5)
76#define ACM_CTRL_FRAMING (1 << 4)
77#define ACM_CTRL_RI (1 << 3)
78#define ACM_CTRL_BRK (1 << 2)
79#define ACM_CTRL_DSR (1 << 1)
80#define ACM_CTRL_DCD (1 << 0)
60}; 81};
61 82
62static inline struct f_acm *func_to_acm(struct usb_function *f) 83static inline struct f_acm *func_to_acm(struct usb_function *f)
@@ -64,12 +85,17 @@ static inline struct f_acm *func_to_acm(struct usb_function *f)
64 return container_of(f, struct f_acm, port.func); 85 return container_of(f, struct f_acm, port.func);
65} 86}
66 87
88static inline struct f_acm *port_to_acm(struct gserial *p)
89{
90 return container_of(p, struct f_acm, port);
91}
92
67/*-------------------------------------------------------------------------*/ 93/*-------------------------------------------------------------------------*/
68 94
69/* notification endpoint uses smallish and infrequent fixed-size messages */ 95/* notification endpoint uses smallish and infrequent fixed-size messages */
70 96
71#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */ 97#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */
72#define GS_NOTIFY_MAXPACKET 8 98#define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
73 99
74/* interface and class descriptors: */ 100/* interface and class descriptors: */
75 101
@@ -115,7 +141,7 @@ static struct usb_cdc_acm_descriptor acm_descriptor __initdata = {
115 .bLength = sizeof(acm_descriptor), 141 .bLength = sizeof(acm_descriptor),
116 .bDescriptorType = USB_DT_CS_INTERFACE, 142 .bDescriptorType = USB_DT_CS_INTERFACE,
117 .bDescriptorSubType = USB_CDC_ACM_TYPE, 143 .bDescriptorSubType = USB_CDC_ACM_TYPE,
118 .bmCapabilities = (1 << 1), 144 .bmCapabilities = USB_CDC_CAP_LINE,
119}; 145};
120 146
121static struct usb_cdc_union_desc acm_union_desc __initdata = { 147static struct usb_cdc_union_desc acm_union_desc __initdata = {
@@ -275,6 +301,11 @@ static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
275 301
276 /* composite driver infrastructure handles everything except 302 /* composite driver infrastructure handles everything except
277 * CDC class messages; interface activation uses set_alt(). 303 * CDC class messages; interface activation uses set_alt().
304 *
305 * Note CDC spec table 4 lists the ACM request profile. It requires
306 * encapsulated command support ... we don't handle any, and respond
307 * to them by stalling. Options include get/set/clear comm features
308 * (not that useful) and SEND_BREAK.
278 */ 309 */
279 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { 310 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
280 311
@@ -310,7 +341,7 @@ static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
310 value = 0; 341 value = 0;
311 342
312 /* FIXME we should not allow data to flow until the 343 /* FIXME we should not allow data to flow until the
313 * host sets the RS232_DTR bit; and when it clears 344 * host sets the ACM_CTRL_DTR bit; and when it clears
314 * that bit, we should return to that no-flow state. 345 * that bit, we should return to that no-flow state.
315 */ 346 */
316 acm->port_handshake_bits = w_value; 347 acm->port_handshake_bits = w_value;
@@ -348,9 +379,6 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
348 /* we know alt == 0, so this is an activation or a reset */ 379 /* we know alt == 0, so this is an activation or a reset */
349 380
350 if (intf == acm->ctrl_id) { 381 if (intf == acm->ctrl_id) {
351 /* REVISIT this may need more work when we start to
352 * send notifications ...
353 */
354 if (acm->notify->driver_data) { 382 if (acm->notify->driver_data) {
355 VDBG(cdev, "reset acm control interface %d\n", intf); 383 VDBG(cdev, "reset acm control interface %d\n", intf);
356 usb_ep_disable(acm->notify); 384 usb_ep_disable(acm->notify);
@@ -395,6 +423,128 @@ static void acm_disable(struct usb_function *f)
395 423
396/*-------------------------------------------------------------------------*/ 424/*-------------------------------------------------------------------------*/
397 425
426/**
427 * acm_cdc_notify - issue CDC notification to host
428 * @acm: wraps host to be notified
429 * @type: notification type
430 * @value: Refer to cdc specs, wValue field.
431 * @data: data to be sent
432 * @length: size of data
433 * Context: irqs blocked, acm->lock held, acm_notify_req non-null
434 *
435 * Returns zero on sucess or a negative errno.
436 *
437 * See section 6.3.5 of the CDC 1.1 specification for information
438 * about the only notification we issue: SerialState change.
439 */
440static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
441 void *data, unsigned length)
442{
443 struct usb_ep *ep = acm->notify;
444 struct usb_request *req;
445 struct usb_cdc_notification *notify;
446 const unsigned len = sizeof(*notify) + length;
447 void *buf;
448 int status;
449
450 req = acm->notify_req;
451 acm->notify_req = NULL;
452 acm->pending = false;
453
454 req->length = len;
455 notify = req->buf;
456 buf = notify + 1;
457
458 notify->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
459 | USB_RECIP_INTERFACE;
460 notify->bNotificationType = type;
461 notify->wValue = cpu_to_le16(value);
462 notify->wIndex = cpu_to_le16(acm->ctrl_id);
463 notify->wLength = cpu_to_le16(length);
464 memcpy(buf, data, length);
465
466 status = usb_ep_queue(ep, req, GFP_ATOMIC);
467 if (status < 0) {
468 ERROR(acm->port.func.config->cdev,
469 "acm ttyGS%d can't notify serial state, %d\n",
470 acm->port_num, status);
471 acm->notify_req = req;
472 }
473
474 return status;
475}
476
477static int acm_notify_serial_state(struct f_acm *acm)
478{
479 struct usb_composite_dev *cdev = acm->port.func.config->cdev;
480 int status;
481
482 spin_lock(&acm->lock);
483 if (acm->notify_req) {
484 DBG(cdev, "acm ttyGS%d serial state %04x\n",
485 acm->port_num, acm->serial_state);
486 status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE,
487 0, &acm->serial_state, sizeof(acm->serial_state));
488 } else {
489 acm->pending = true;
490 status = 0;
491 }
492 spin_unlock(&acm->lock);
493 return status;
494}
495
496static void acm_cdc_notify_complete(struct usb_ep *ep, struct usb_request *req)
497{
498 struct f_acm *acm = req->context;
499 u8 doit = false;
500
501 /* on this call path we do NOT hold the port spinlock,
502 * which is why ACM needs its own spinlock
503 */
504 spin_lock(&acm->lock);
505 if (req->status != -ESHUTDOWN)
506 doit = acm->pending;
507 acm->notify_req = req;
508 spin_unlock(&acm->lock);
509
510 if (doit)
511 acm_notify_serial_state(acm);
512}
513
514/* connect == the TTY link is open */
515
516static void acm_connect(struct gserial *port)
517{
518 struct f_acm *acm = port_to_acm(port);
519
520 acm->serial_state |= ACM_CTRL_DSR | ACM_CTRL_DCD;
521 acm_notify_serial_state(acm);
522}
523
524static void acm_disconnect(struct gserial *port)
525{
526 struct f_acm *acm = port_to_acm(port);
527
528 acm->serial_state &= ~(ACM_CTRL_DSR | ACM_CTRL_DCD);
529 acm_notify_serial_state(acm);
530}
531
532static int acm_send_break(struct gserial *port, int duration)
533{
534 struct f_acm *acm = port_to_acm(port);
535 u16 state;
536
537 state = acm->serial_state;
538 state &= ~ACM_CTRL_BRK;
539 if (duration)
540 state |= ACM_CTRL_BRK;
541
542 acm->serial_state = state;
543 return acm_notify_serial_state(acm);
544}
545
546/*-------------------------------------------------------------------------*/
547
398/* ACM function driver setup/binding */ 548/* ACM function driver setup/binding */
399static int __init 549static int __init
400acm_bind(struct usb_configuration *c, struct usb_function *f) 550acm_bind(struct usb_configuration *c, struct usb_function *f)
@@ -443,8 +593,20 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
443 acm->notify = ep; 593 acm->notify = ep;
444 ep->driver_data = cdev; /* claim */ 594 ep->driver_data = cdev; /* claim */
445 595
596 /* allocate notification */
597 acm->notify_req = gs_alloc_req(ep,
598 sizeof(struct usb_cdc_notification) + 2,
599 GFP_KERNEL);
600 if (!acm->notify_req)
601 goto fail;
602
603 acm->notify_req->complete = acm_cdc_notify_complete;
604 acm->notify_req->context = acm;
605
446 /* copy descriptors, and track endpoint copies */ 606 /* copy descriptors, and track endpoint copies */
447 f->descriptors = usb_copy_descriptors(acm_fs_function); 607 f->descriptors = usb_copy_descriptors(acm_fs_function);
608 if (!f->descriptors)
609 goto fail;
448 610
449 acm->fs.in = usb_find_endpoint(acm_fs_function, 611 acm->fs.in = usb_find_endpoint(acm_fs_function,
450 f->descriptors, &acm_fs_in_desc); 612 f->descriptors, &acm_fs_in_desc);
@@ -476,8 +638,6 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
476 f->hs_descriptors, &acm_hs_notify_desc); 638 f->hs_descriptors, &acm_hs_notify_desc);
477 } 639 }
478 640
479 /* FIXME provide a callback for triggering notifications */
480
481 DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", 641 DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
482 acm->port_num, 642 acm->port_num,
483 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 643 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
@@ -486,6 +646,9 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
486 return 0; 646 return 0;
487 647
488fail: 648fail:
649 if (acm->notify_req)
650 gs_free_req(acm->notify, acm->notify_req);
651
489 /* we might as well release our claims on endpoints */ 652 /* we might as well release our claims on endpoints */
490 if (acm->notify) 653 if (acm->notify)
491 acm->notify->driver_data = NULL; 654 acm->notify->driver_data = NULL;
@@ -502,10 +665,13 @@ fail:
502static void 665static void
503acm_unbind(struct usb_configuration *c, struct usb_function *f) 666acm_unbind(struct usb_configuration *c, struct usb_function *f)
504{ 667{
668 struct f_acm *acm = func_to_acm(f);
669
505 if (gadget_is_dualspeed(c->cdev->gadget)) 670 if (gadget_is_dualspeed(c->cdev->gadget))
506 usb_free_descriptors(f->hs_descriptors); 671 usb_free_descriptors(f->hs_descriptors);
507 usb_free_descriptors(f->descriptors); 672 usb_free_descriptors(f->descriptors);
508 kfree(func_to_acm(f)); 673 gs_free_req(acm->notify, acm->notify_req);
674 kfree(acm);
509} 675}
510 676
511/* Some controllers can't support CDC ACM ... */ 677/* Some controllers can't support CDC ACM ... */
@@ -569,8 +735,14 @@ int __init acm_bind_config(struct usb_configuration *c, u8 port_num)
569 if (!acm) 735 if (!acm)
570 return -ENOMEM; 736 return -ENOMEM;
571 737
738 spin_lock_init(&acm->lock);
739
572 acm->port_num = port_num; 740 acm->port_num = port_num;
573 741
742 acm->port.connect = acm_connect;
743 acm->port.disconnect = acm_disconnect;
744 acm->port.send_break = acm_send_break;
745
574 acm->port.func.name = "acm"; 746 acm->port.func.name = "acm";
575 acm->port.func.strings = acm_strings; 747 acm->port.func.strings = acm_strings;
576 /* descriptors are per-instance copies */ 748 /* descriptors are per-instance copies */