blob: b2a013cc8ddf070a732050daafac0f5a6b6af6c7 [file] [log] [blame]
Anna Perela8c991d2012-04-09 16:44:46 +03001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/kernel.h>
17#include <linux/device.h>
18
19#include <linux/usb/cdc.h>
20
21#include <linux/usb/composite.h>
22#include <linux/usb/android_composite.h>
23#include <linux/platform_device.h>
24
25#include <linux/spinlock.h>
26
27/*
28 * This function is a "Mobile Broadband Interface Model" (MBIM) link.
29 * MBIM is intended to be used with high-speed network attachments.
30 *
31 * Note that MBIM requires the use of "alternate settings" for its data
32 * interface. This means that the set_alt() method has real work to do,
33 * and also means that a get_alt() method is required.
34 */
35
36#define MBIM_BULK_BUFFER_SIZE 4096
37
38#define MBIM_IOCTL_MAGIC 'o'
39#define MBIM_GET_NTB_SIZE _IOR(MBIM_IOCTL_MAGIC, 2, u32)
40#define MBIM_GET_DATAGRAM_COUNT _IOR(MBIM_IOCTL_MAGIC, 3, u16)
41
42#define NR_MBIM_PORTS 1
43
44struct ctrl_pkt {
45 void *buf;
46 int len;
47 struct list_head list;
48};
49
50struct mbim_ep_descs {
51 struct usb_endpoint_descriptor *in;
52 struct usb_endpoint_descriptor *out;
53 struct usb_endpoint_descriptor *notify;
54};
55
56struct mbim_notify_port {
57 struct usb_ep *notify;
58 struct usb_request *notify_req;
59 u8 notify_state;
60 atomic_t notify_count;
61};
62
63enum mbim_notify_state {
64 NCM_NOTIFY_NONE,
65 NCM_NOTIFY_CONNECT,
66 NCM_NOTIFY_SPEED,
67};
68
69struct f_mbim {
70 struct usb_function function;
71 struct usb_composite_dev *cdev;
72
73 atomic_t online;
74 bool is_open;
75
76 atomic_t open_excl;
77 atomic_t ioctl_excl;
78 atomic_t read_excl;
79 atomic_t write_excl;
80
81 wait_queue_head_t read_wq;
82 wait_queue_head_t write_wq;
83
84 u8 port_num;
85 struct data_port bam_port;
86 struct mbim_notify_port not_port;
87
88 struct mbim_ep_descs fs;
89 struct mbim_ep_descs hs;
90
91 u8 ctrl_id, data_id;
92
93 struct ndp_parser_opts *parser_opts;
94
95 spinlock_t lock;
96
97 struct list_head cpkt_req_q;
98 struct list_head cpkt_resp_q;
99
100 u32 ntb_input_size;
101 u16 ntb_max_datagrams;
102
Anna Perela8c991d2012-04-09 16:44:46 +0300103 atomic_t error;
104};
105
106struct mbim_ntb_input_size {
107 u32 ntb_input_size;
108 u16 ntb_max_datagrams;
109 u16 reserved;
110};
111
112/* temporary variable used between mbim_open() and mbim_gadget_bind() */
113static struct f_mbim *_mbim_dev;
114
115static unsigned int nr_mbim_ports;
116
117static struct mbim_ports {
118 struct f_mbim *port;
119 unsigned port_num;
120} mbim_ports[NR_MBIM_PORTS];
121
122static inline struct f_mbim *func_to_mbim(struct usb_function *f)
123{
124 return container_of(f, struct f_mbim, function);
125}
126
127/* peak (theoretical) bulk transfer rate in bits-per-second */
128static inline unsigned mbim_bitrate(struct usb_gadget *g)
129{
130 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
131 return 13 * 512 * 8 * 1000 * 8;
132 else
133 return 19 * 64 * 1 * 1000 * 8;
134}
135
136/*-------------------------------------------------------------------------*/
137
138#define NTB_DEFAULT_IN_SIZE (0x4000)
139#define NTB_OUT_SIZE (0x1000)
140#define NDP_IN_DIVISOR (0x4)
141
142#define FORMATS_SUPPORTED USB_CDC_NCM_NTB16_SUPPORTED
143
144static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
145 .wLength = sizeof ntb_parameters,
146 .bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED),
147 .dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE),
148 .wNdpInDivisor = cpu_to_le16(NDP_IN_DIVISOR),
149 .wNdpInPayloadRemainder = cpu_to_le16(0),
150 .wNdpInAlignment = cpu_to_le16(4),
151
152 .dwNtbOutMaxSize = cpu_to_le32(NTB_OUT_SIZE),
153 .wNdpOutDivisor = cpu_to_le16(4),
154 .wNdpOutPayloadRemainder = cpu_to_le16(0),
155 .wNdpOutAlignment = cpu_to_le16(4),
Anna Perelf99cd0c2012-05-03 13:30:26 +0300156 .wNtbOutMaxDatagrams = 0,
Anna Perela8c991d2012-04-09 16:44:46 +0300157};
158
159/*
160 * Use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
161 * packet, to simplify cancellation; and a big transfer interval, to
162 * waste less bandwidth.
163 */
164
165#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
166#define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
167
168static struct usb_interface_assoc_descriptor mbim_iad_desc = {
169 .bLength = sizeof mbim_iad_desc,
170 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
171
172 /* .bFirstInterface = DYNAMIC, */
173 .bInterfaceCount = 2, /* control + data */
174 .bFunctionClass = 2,
175 .bFunctionSubClass = 0x0e,
176 .bFunctionProtocol = 0,
177 /* .iFunction = DYNAMIC */
178};
179
180/* interface descriptor: */
181static struct usb_interface_descriptor mbim_control_intf = {
182 .bLength = sizeof mbim_control_intf,
183 .bDescriptorType = USB_DT_INTERFACE,
184
185 /* .bInterfaceNumber = DYNAMIC */
186 .bNumEndpoints = 1,
187 .bInterfaceClass = 0x02,
188 .bInterfaceSubClass = 0x0e,
189 .bInterfaceProtocol = 0,
190 /* .iInterface = DYNAMIC */
191};
192
193static struct usb_cdc_header_desc mbim_header_desc = {
194 .bLength = sizeof mbim_header_desc,
195 .bDescriptorType = USB_DT_CS_INTERFACE,
196 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
197
198 .bcdCDC = cpu_to_le16(0x0110),
199};
200
201static struct usb_cdc_union_desc mbim_union_desc = {
202 .bLength = sizeof(mbim_union_desc),
203 .bDescriptorType = USB_DT_CS_INTERFACE,
204 .bDescriptorSubType = USB_CDC_UNION_TYPE,
205 /* .bMasterInterface0 = DYNAMIC */
206 /* .bSlaveInterface0 = DYNAMIC */
207};
208
209static struct usb_cdc_mbb_desc mbb_desc = {
210 .bLength = sizeof mbb_desc,
211 .bDescriptorType = USB_DT_CS_INTERFACE,
212 .bDescriptorSubType = USB_CDC_MBB_TYPE,
213
214 .bcdMbbVersion = cpu_to_le16(0x0100),
215
216 .wMaxControlMessage = cpu_to_le16(0x1000),
217 .bNumberFilters = 0x10,
218 .bMaxFilterSize = 0x80,
219 .wMaxSegmentSize = cpu_to_le16(0x1000),
220 .bmNetworkCapabilities = 0x20,
221};
222
223/* the default data interface has no endpoints ... */
224static struct usb_interface_descriptor mbim_data_nop_intf = {
225 .bLength = sizeof mbim_data_nop_intf,
226 .bDescriptorType = USB_DT_INTERFACE,
227
228 /* .bInterfaceNumber = DYNAMIC */
229 .bAlternateSetting = 0,
230 .bNumEndpoints = 0,
231 .bInterfaceClass = 0x0a,
232 .bInterfaceSubClass = 0,
233 .bInterfaceProtocol = 0x02,
234 /* .iInterface = DYNAMIC */
235};
236
237/* ... but the "real" data interface has two bulk endpoints */
238static struct usb_interface_descriptor mbim_data_intf = {
239 .bLength = sizeof mbim_data_intf,
240 .bDescriptorType = USB_DT_INTERFACE,
241
242 /* .bInterfaceNumber = DYNAMIC */
243 .bAlternateSetting = 1,
244 .bNumEndpoints = 2,
245 .bInterfaceClass = 0x0a,
246 .bInterfaceSubClass = 0,
247 .bInterfaceProtocol = 0x02,
248 /* .iInterface = DYNAMIC */
249};
250
251/* full speed support: */
252
253static struct usb_endpoint_descriptor fs_mbim_notify_desc = {
254 .bLength = USB_DT_ENDPOINT_SIZE,
255 .bDescriptorType = USB_DT_ENDPOINT,
256
257 .bEndpointAddress = USB_DIR_IN,
258 .bmAttributes = USB_ENDPOINT_XFER_INT,
259 .wMaxPacketSize = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
260 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
261};
262
263static struct usb_endpoint_descriptor fs_mbim_in_desc = {
264 .bLength = USB_DT_ENDPOINT_SIZE,
265 .bDescriptorType = USB_DT_ENDPOINT,
266
267 .bEndpointAddress = USB_DIR_IN,
268 .bmAttributes = USB_ENDPOINT_XFER_BULK,
269};
270
271static struct usb_endpoint_descriptor fs_mbim_out_desc = {
272 .bLength = USB_DT_ENDPOINT_SIZE,
273 .bDescriptorType = USB_DT_ENDPOINT,
274
275 .bEndpointAddress = USB_DIR_OUT,
276 .bmAttributes = USB_ENDPOINT_XFER_BULK,
277};
278
279static struct usb_descriptor_header *mbim_fs_function[] = {
280 (struct usb_descriptor_header *) &mbim_iad_desc,
281 /* MBIM control descriptors */
282 (struct usb_descriptor_header *) &mbim_control_intf,
283 (struct usb_descriptor_header *) &mbim_header_desc,
284 (struct usb_descriptor_header *) &mbb_desc,
285 (struct usb_descriptor_header *) &fs_mbim_notify_desc,
286 /* data interface, altsettings 0 and 1 */
287 (struct usb_descriptor_header *) &mbim_data_nop_intf,
288 (struct usb_descriptor_header *) &mbim_data_intf,
289 (struct usb_descriptor_header *) &fs_mbim_in_desc,
290 (struct usb_descriptor_header *) &fs_mbim_out_desc,
291 NULL,
292};
293
294/* high speed support: */
295
296static struct usb_endpoint_descriptor hs_mbim_notify_desc = {
297 .bLength = USB_DT_ENDPOINT_SIZE,
298 .bDescriptorType = USB_DT_ENDPOINT,
299
300 .bEndpointAddress = USB_DIR_IN,
301 .bmAttributes = USB_ENDPOINT_XFER_INT,
302 .wMaxPacketSize = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
303 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
304};
305static struct usb_endpoint_descriptor hs_mbim_in_desc = {
306 .bLength = USB_DT_ENDPOINT_SIZE,
307 .bDescriptorType = USB_DT_ENDPOINT,
308
309 .bEndpointAddress = USB_DIR_IN,
310 .bmAttributes = USB_ENDPOINT_XFER_BULK,
311 .wMaxPacketSize = cpu_to_le16(512),
312};
313
314static struct usb_endpoint_descriptor hs_mbim_out_desc = {
315 .bLength = USB_DT_ENDPOINT_SIZE,
316 .bDescriptorType = USB_DT_ENDPOINT,
317
318 .bEndpointAddress = USB_DIR_OUT,
319 .bmAttributes = USB_ENDPOINT_XFER_BULK,
320 .wMaxPacketSize = cpu_to_le16(512),
321};
322
323static struct usb_descriptor_header *mbim_hs_function[] = {
324 (struct usb_descriptor_header *) &mbim_iad_desc,
325 /* MBIM control descriptors */
326 (struct usb_descriptor_header *) &mbim_control_intf,
327 (struct usb_descriptor_header *) &mbim_header_desc,
328 (struct usb_descriptor_header *) &mbb_desc,
329 (struct usb_descriptor_header *) &hs_mbim_notify_desc,
330 /* data interface, altsettings 0 and 1 */
331 (struct usb_descriptor_header *) &mbim_data_nop_intf,
332 (struct usb_descriptor_header *) &mbim_data_intf,
333 (struct usb_descriptor_header *) &hs_mbim_in_desc,
334 (struct usb_descriptor_header *) &hs_mbim_out_desc,
335 NULL,
336};
337
338/* string descriptors: */
339
340#define STRING_CTRL_IDX 0
341#define STRING_DATA_IDX 1
342
343static struct usb_string mbim_string_defs[] = {
344 [STRING_CTRL_IDX].s = "MBIM Control",
345 [STRING_DATA_IDX].s = "MBIM Data",
346 { } /* end of list */
347};
348
349static struct usb_gadget_strings mbim_string_table = {
350 .language = 0x0409, /* en-us */
351 .strings = mbim_string_defs,
352};
353
354static struct usb_gadget_strings *mbim_strings[] = {
355 &mbim_string_table,
356 NULL,
357};
358
359/*
360 * Here are options for the Datagram Pointer table (NDP) parser.
361 * There are 2 different formats: NDP16 and NDP32 in the spec (ch. 3),
362 * in NDP16 offsets and sizes fields are 1 16bit word wide,
363 * in NDP32 -- 2 16bit words wide. Also signatures are different.
364 * To make the parser code the same, put the differences in the structure,
365 * and switch pointers to the structures when the format is changed.
366 */
367
368struct ndp_parser_opts {
369 u32 nth_sign;
370 u32 ndp_sign;
371 unsigned nth_size;
372 unsigned ndp_size;
373 unsigned ndplen_align;
374 /* sizes in u16 units */
375 unsigned dgram_item_len; /* index or length */
376 unsigned block_length;
377 unsigned fp_index;
378 unsigned reserved1;
379 unsigned reserved2;
380 unsigned next_fp_index;
381};
382
383#define INIT_NDP16_OPTS { \
384 .nth_sign = USB_CDC_NCM_NTH16_SIGN, \
385 .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \
386 .nth_size = sizeof(struct usb_cdc_ncm_nth16), \
387 .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \
388 .ndplen_align = 4, \
389 .dgram_item_len = 1, \
390 .block_length = 1, \
391 .fp_index = 1, \
392 .reserved1 = 0, \
393 .reserved2 = 0, \
394 .next_fp_index = 1, \
395}
396
397#define INIT_NDP32_OPTS { \
398 .nth_sign = USB_CDC_NCM_NTH32_SIGN, \
399 .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \
400 .nth_size = sizeof(struct usb_cdc_ncm_nth32), \
401 .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \
402 .ndplen_align = 8, \
403 .dgram_item_len = 2, \
404 .block_length = 2, \
405 .fp_index = 2, \
406 .reserved1 = 1, \
407 .reserved2 = 2, \
408 .next_fp_index = 2, \
409}
410
411static struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS;
412static struct ndp_parser_opts ndp32_opts = INIT_NDP32_OPTS;
413
414static inline int mbim_lock(atomic_t *excl)
415{
416 if (atomic_inc_return(excl) == 1) {
417 return 0;
418 } else {
419 atomic_dec(excl);
420 return -EBUSY;
421 }
422}
423
424static inline void mbim_unlock(atomic_t *excl)
425{
426 atomic_dec(excl);
427}
428
429static struct ctrl_pkt *mbim_alloc_ctrl_pkt(unsigned len, gfp_t flags)
430{
431 struct ctrl_pkt *pkt;
432
433 pkt = kzalloc(sizeof(struct ctrl_pkt), flags);
434 if (!pkt)
435 return ERR_PTR(-ENOMEM);
436
437 pkt->buf = kmalloc(len, flags);
438 if (!pkt->buf) {
439 kfree(pkt);
440 return ERR_PTR(-ENOMEM);
441 }
442 pkt->len = len;
443
444 return pkt;
445}
446
447static void mbim_free_ctrl_pkt(struct ctrl_pkt *pkt)
448{
449 if (pkt) {
450 kfree(pkt->buf);
451 kfree(pkt);
452 }
453}
454
455static struct usb_request *mbim_alloc_req(struct usb_ep *ep, int buffer_size)
456{
457 struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL);
458 if (!req)
459 return NULL;
460
461 req->buf = kmalloc(buffer_size, GFP_KERNEL);
462 if (!req->buf) {
463 usb_ep_free_request(ep, req);
464 return NULL;
465 }
466 req->length = buffer_size;
467 return req;
468}
469
470void fmbim_free_req(struct usb_ep *ep, struct usb_request *req)
471{
472 if (req) {
473 kfree(req->buf);
474 usb_ep_free_request(ep, req);
475 }
476}
477
478static void fmbim_ctrl_response_available(struct f_mbim *dev)
479{
480 struct usb_request *req = dev->not_port.notify_req;
481 struct usb_cdc_notification *event = NULL;
482 unsigned long flags;
483 int ret;
484
485 int notif_c = 0;
486
487 pr_info("dev:%p portno#%d\n", dev, dev->port_num);
488
489 spin_lock_irqsave(&dev->lock, flags);
490
491 if (!atomic_read(&dev->online)) {
492 pr_info("dev:%p is not online\n", dev);
493 spin_unlock_irqrestore(&dev->lock, flags);
494 return;
495 }
496
497 if (!req) {
498 pr_info("dev:%p req is NULL\n", dev);
499 spin_unlock_irqrestore(&dev->lock, flags);
500 return;
501 }
502
503 if (!req->buf) {
504 pr_info("dev:%p req->buf is NULL\n", dev);
505 spin_unlock_irqrestore(&dev->lock, flags);
506 return;
507 }
508
509 notif_c = atomic_inc_return(&dev->not_port.notify_count);
510 pr_info("atomic_inc_return[notif_c] = %d", notif_c);
511
512 event = req->buf;
513 event->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
514 | USB_RECIP_INTERFACE;
515 event->bNotificationType = USB_CDC_NOTIFY_RESPONSE_AVAILABLE;
516 event->wValue = cpu_to_le16(0);
517 event->wIndex = cpu_to_le16(dev->ctrl_id);
518 event->wLength = cpu_to_le16(0);
519 spin_unlock_irqrestore(&dev->lock, flags);
520
521 pr_info("Call usb_ep_queue");
522
523 ret = usb_ep_queue(dev->not_port.notify,
524 dev->not_port.notify_req, GFP_ATOMIC);
525 if (ret) {
526 atomic_dec(&dev->not_port.notify_count);
527 pr_err("ep enqueue error %d\n", ret);
528 }
529
530 pr_info("Succcessfull Exit");
531}
532
533static int
534fmbim_send_cpkt_response(struct f_mbim *gr, struct ctrl_pkt *cpkt)
535{
536 struct f_mbim *dev = gr;
537 unsigned long flags;
538
539 if (!gr || !cpkt) {
540 pr_err("Invalid cpkt, dev:%p cpkt:%p\n",
541 gr, cpkt);
542 return -ENODEV;
543 }
544
545 pr_info("dev:%p port_num#%d\n", dev, dev->port_num);
546
547 if (!atomic_read(&dev->online)) {
548 pr_info("dev:%p is not connected\n", dev);
549 mbim_free_ctrl_pkt(cpkt);
550 return 0;
551 }
552
553 spin_lock_irqsave(&dev->lock, flags);
Anna Perel40c550c2012-04-11 14:09:27 +0300554 list_add_tail(&cpkt->list, &dev->cpkt_resp_q);
Anna Perela8c991d2012-04-09 16:44:46 +0300555 spin_unlock_irqrestore(&dev->lock, flags);
556
557 fmbim_ctrl_response_available(dev);
558
559 return 0;
560}
561
562/* ---------------------------- BAM INTERFACE ----------------------------- */
563
564static int mbim_bam_setup(int no_ports)
565{
566 int ret;
567
568 pr_info("no_ports:%d\n", no_ports);
569
570 ret = bam_data_setup(no_ports);
571 if (ret) {
572 pr_err("bam_data_setup failed err: %d\n", ret);
573 return ret;
574 }
575
576 pr_info("Initialized %d ports\n", no_ports);
577 return 0;
578}
579
580static int mbim_bam_connect(struct f_mbim *dev)
581{
582 int ret;
583
584 pr_info("dev:%p portno:%d\n", dev, dev->port_num);
585
586 ret = bam_data_connect(&dev->bam_port, dev->port_num, dev->port_num);
587 if (ret) {
588 pr_err("bam_data_setup failed: err:%d\n",
589 ret);
590 return ret;
591 } else {
592 pr_info("mbim bam connected\n");
593 }
594
595 return 0;
596}
597
598static int mbim_bam_disconnect(struct f_mbim *dev)
599{
600 pr_info("dev:%p port:%d. Do nothing.\n",
601 dev, dev->port_num);
602
603 /* bam_data_disconnect(&dev->bam_port, dev->port_num); */
604
605 return 0;
606}
607
608/* -------------------------------------------------------------------------*/
609
610static inline void mbim_reset_values(struct f_mbim *mbim)
611{
612 mbim->parser_opts = &ndp16_opts;
613
614 mbim->ntb_input_size = NTB_DEFAULT_IN_SIZE;
615
616 atomic_set(&mbim->not_port.notify_count, 0);
617 atomic_set(&mbim->online, 0);
618}
619
Anna Perel86ea7c92012-04-24 14:31:29 +0300620static void mbim_reset_function_queue(struct f_mbim *dev)
621{
622 struct ctrl_pkt *cpkt = NULL;
623
624 pr_debug("Queue empty packet for QBI");
625
626 spin_lock(&dev->lock);
627 if (!dev->is_open) {
628 pr_err("%s: mbim file handler %p is not open", __func__, dev);
629 spin_unlock(&dev->lock);
630 return;
631 }
632
633 cpkt = mbim_alloc_ctrl_pkt(0, GFP_ATOMIC);
634 if (!cpkt) {
635 pr_err("%s: Unable to allocate reset function pkt\n", __func__);
636 spin_unlock(&dev->lock);
637 return;
638 }
639
640 list_add_tail(&cpkt->list, &dev->cpkt_req_q);
641 spin_unlock(&dev->lock);
642
643 pr_debug("%s: Wake up read queue", __func__);
644 wake_up(&dev->read_wq);
645}
646
647static void fmbim_reset_cmd_complete(struct usb_ep *ep, struct usb_request *req)
648{
649 struct f_mbim *dev = req->context;
650
651 mbim_reset_function_queue(dev);
652}
653
654static void mbim_clear_queues(struct f_mbim *mbim)
655{
656 struct ctrl_pkt *cpkt = NULL;
657 struct list_head *act, *tmp;
658
659 spin_lock(&mbim->lock);
660 list_for_each_safe(act, tmp, &mbim->cpkt_req_q) {
661 cpkt = list_entry(act, struct ctrl_pkt, list);
662 list_del(&cpkt->list);
663 mbim_free_ctrl_pkt(cpkt);
664 }
665 list_for_each_safe(act, tmp, &mbim->cpkt_resp_q) {
666 cpkt = list_entry(act, struct ctrl_pkt, list);
667 list_del(&cpkt->list);
668 mbim_free_ctrl_pkt(cpkt);
669 }
670 spin_unlock(&mbim->lock);
671}
672
Anna Perela8c991d2012-04-09 16:44:46 +0300673/*
674 * Context: mbim->lock held
675 */
676static void mbim_do_notify(struct f_mbim *mbim)
677{
678 struct usb_request *req = mbim->not_port.notify_req;
679 struct usb_cdc_notification *event;
680 struct usb_composite_dev *cdev = mbim->cdev;
681 __le32 *data;
682 int status;
683
684 pr_info("notify_state: %d", mbim->not_port.notify_state);
685
686 if (!req)
687 return;
688
689 event = req->buf;
690
691 switch (mbim->not_port.notify_state) {
692
693 case NCM_NOTIFY_NONE:
694 return;
695
696 case NCM_NOTIFY_CONNECT:
697 event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION;
698 if (mbim->is_open)
699 event->wValue = cpu_to_le16(1);
700 else
701 event->wValue = cpu_to_le16(0);
702 event->wLength = 0;
703 req->length = sizeof *event;
704
705 pr_info("notify connect %s\n",
706 mbim->is_open ? "true" : "false");
707 mbim->not_port.notify_state = NCM_NOTIFY_NONE;
708 break;
709
710 case NCM_NOTIFY_SPEED:
711 event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
712 event->wValue = cpu_to_le16(0);
713 event->wLength = cpu_to_le16(8);
714 req->length = NCM_STATUS_BYTECOUNT;
715
716 /* SPEED_CHANGE data is up/down speeds in bits/sec */
717 data = req->buf + sizeof *event;
718 data[0] = cpu_to_le32(mbim_bitrate(cdev->gadget));
719 data[1] = data[0];
720
721 pr_info("notify speed %d\n",
722 mbim_bitrate(cdev->gadget));
723 mbim->not_port.notify_state = NCM_NOTIFY_CONNECT;
724 break;
725 }
726 event->bmRequestType = 0xA1;
727 event->wIndex = cpu_to_le16(mbim->ctrl_id);
728
729 mbim->not_port.notify_req = NULL;
730 /*
731 * In double buffering if there is a space in FIFO,
732 * completion callback can be called right after the call,
733 * so unlocking
734 */
735 spin_unlock(&mbim->lock);
736 status = usb_ep_queue(mbim->not_port.notify, req, GFP_ATOMIC);
737 spin_lock(&mbim->lock);
738 if (status < 0) {
739 mbim->not_port.notify_req = req;
740 atomic_dec(&mbim->not_port.notify_count);
741 pr_err("usb_ep_queue failed, err: %d", status);
742 }
743}
744
745/*
746 * Context: mbim->lock held
747 */
748static void mbim_notify(struct f_mbim *mbim)
749{
750 /*
751 * If mbim_notify() is called before the second (CONNECT)
752 * notification is sent, then it will reset to send the SPEED
753 * notificaion again (and again, and again), but it's not a problem
754 */
755 pr_info("dev:%p\n", mbim);
756
757 mbim->not_port.notify_state = NCM_NOTIFY_SPEED;
758 mbim_do_notify(mbim);
759}
760
761static void mbim_notify_complete(struct usb_ep *ep, struct usb_request *req)
762{
763 struct f_mbim *mbim = req->context;
764 struct usb_cdc_notification *event = req->buf;
765
766 int notif_c = 0;
767
768 pr_info("dev:%p\n", mbim);
769
770 spin_lock(&mbim->lock);
771 switch (req->status) {
772 case 0:
773 pr_info("Notification %02x sent\n",
774 event->bNotificationType);
775
776 notif_c = atomic_dec_return(&mbim->not_port.notify_count);
777
778 if (notif_c != 0) {
779 pr_info("Continue to mbim_do_notify()");
780 break;
781 } else {
782 pr_info("notify_count decreased to 0. Do not notify");
783 spin_unlock(&mbim->lock);
784 return;
785 }
786
787 break;
788
789 case -ECONNRESET:
790 case -ESHUTDOWN:
791 /* connection gone */
792 mbim->not_port.notify_state = NCM_NOTIFY_NONE;
793 atomic_set(&mbim->not_port.notify_count, 0);
794 pr_info("ESHUTDOWN/ECONNRESET, connection gone");
Anna Perel86ea7c92012-04-24 14:31:29 +0300795 spin_unlock(&mbim->lock);
796 mbim_clear_queues(mbim);
797 mbim_reset_function_queue(mbim);
Anna Perela8c991d2012-04-09 16:44:46 +0300798 break;
799 default:
800 pr_err("Unknown event %02x --> %d\n",
801 event->bNotificationType, req->status);
802 break;
803 }
804
805 mbim->not_port.notify_req = req;
806 mbim_do_notify(mbim);
807
808 spin_unlock(&mbim->lock);
809
810 pr_info("dev:%p Exit\n", mbim);
811}
812
813static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req)
814{
815 /* now for SET_NTB_INPUT_SIZE only */
816 unsigned in_size = 0;
817 struct usb_function *f = req->context;
818 struct f_mbim *mbim = func_to_mbim(f);
819 struct mbim_ntb_input_size *ntb = NULL;
820
821 pr_info("dev:%p\n", mbim);
822
823 req->context = NULL;
824 if (req->status || req->actual != req->length) {
825 pr_err("Bad control-OUT transfer\n");
826 goto invalid;
827 }
828
829 if (req->length == 4) {
830 in_size = get_unaligned_le32(req->buf);
831 if (in_size < USB_CDC_NCM_NTB_MIN_IN_SIZE ||
832 in_size > le32_to_cpu(ntb_parameters.dwNtbInMaxSize)) {
833 pr_err("Illegal INPUT SIZE (%d) from host\n", in_size);
834 goto invalid;
835 }
836 } else if (req->length == 8) {
837 ntb = (struct mbim_ntb_input_size *)req->buf;
838 in_size = get_unaligned_le32(&(ntb->ntb_input_size));
839 if (in_size < USB_CDC_NCM_NTB_MIN_IN_SIZE ||
840 in_size > le32_to_cpu(ntb_parameters.dwNtbInMaxSize)) {
841 pr_err("Illegal INPUT SIZE (%d) from host\n", in_size);
842 goto invalid;
843 }
844 mbim->ntb_max_datagrams =
845 get_unaligned_le16(&(ntb->ntb_max_datagrams));
846 } else {
847 pr_err("Illegal NTB length %d\n", in_size);
848 goto invalid;
849 }
850
851 pr_info("Set NTB INPUT SIZE %d\n", in_size);
852
853 mbim->ntb_input_size = in_size;
854 return;
855
856invalid:
857 usb_ep_set_halt(ep);
858
859 pr_err("dev:%p Failed\n", mbim);
860
861 return;
862}
863
864static void
865fmbim_cmd_complete(struct usb_ep *ep, struct usb_request *req)
866{
867 struct f_mbim *dev = req->context;
868 struct ctrl_pkt *cpkt = NULL;
869 int len = req->actual;
870
871 if (!dev) {
872 pr_err("mbim dev is null\n");
873 return;
874 }
875
876 if (req->status < 0) {
877 pr_err("mbim command error %d\n", req->status);
878 return;
879 }
880
881 pr_info("dev:%p port#%d\n", dev, dev->port_num);
882
883 spin_lock(&dev->lock);
884 if (!dev->is_open) {
885 pr_err("mbim file handler %p is not open", dev);
886 spin_unlock(&dev->lock);
887 return;
888 }
889
890 cpkt = mbim_alloc_ctrl_pkt(len, GFP_ATOMIC);
891 if (!cpkt) {
892 pr_err("Unable to allocate ctrl pkt\n");
893 spin_unlock(&dev->lock);
894 return;
895 }
896
897 pr_info("Add to cpkt_req_q packet with len = %d\n", len);
898 memcpy(cpkt->buf, req->buf, len);
899 list_add_tail(&cpkt->list, &dev->cpkt_req_q);
900 spin_unlock(&dev->lock);
901
902 /* wakeup read thread */
903 pr_info("Wake up read queue");
904 wake_up(&dev->read_wq);
905
906 return;
907}
908
909static int
910mbim_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
911{
912 struct f_mbim *mbim = func_to_mbim(f);
913 struct usb_composite_dev *cdev = mbim->cdev;
914 struct usb_request *req = cdev->req;
915 struct ctrl_pkt *cpkt = NULL;
916 int value = -EOPNOTSUPP;
917 u16 w_index = le16_to_cpu(ctrl->wIndex);
918 u16 w_value = le16_to_cpu(ctrl->wValue);
919 u16 w_length = le16_to_cpu(ctrl->wLength);
920
921 /*
922 * composite driver infrastructure handles everything except
923 * CDC class messages; interface activation uses set_alt().
924 */
925
926 if (!atomic_read(&mbim->online)) {
927 pr_info("usb cable is not connected\n");
928 return -ENOTCONN;
929 }
930
931 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
932 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
933 | USB_CDC_RESET_FUNCTION:
934
935 pr_info("USB_CDC_RESET_FUNCTION");
936 value = 0;
Anna Perel86ea7c92012-04-24 14:31:29 +0300937 req->complete = fmbim_reset_cmd_complete;
938 req->context = mbim;
Anna Perela8c991d2012-04-09 16:44:46 +0300939 break;
940
941 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
942 | USB_CDC_SEND_ENCAPSULATED_COMMAND:
943
944 pr_info("USB_CDC_SEND_ENCAPSULATED_COMMAND");
945
946 if (w_length > req->length) {
947 pr_err("w_length > req->length: %d > %d",
948 w_length, req->length);
949 }
950 value = w_length;
951 req->complete = fmbim_cmd_complete;
952 req->context = mbim;
953 break;
954
955 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
956 | USB_CDC_GET_ENCAPSULATED_RESPONSE:
957
958 pr_info("USB_CDC_GET_ENCAPSULATED_RESPONSE");
959
960 if (w_value) {
961 pr_err("w_length > 0: %d", w_length);
962 break;
963 }
964
965 pr_info("req%02x.%02x v%04x i%04x l%d\n",
966 ctrl->bRequestType, ctrl->bRequest,
967 w_value, w_index, w_length);
968
969 spin_lock(&mbim->lock);
970 if (list_empty(&mbim->cpkt_resp_q)) {
971 pr_err("ctrl resp queue empty\n");
972 spin_unlock(&mbim->lock);
973 break;
974 }
975
976 cpkt = list_first_entry(&mbim->cpkt_resp_q,
977 struct ctrl_pkt, list);
978 list_del(&cpkt->list);
979 spin_unlock(&mbim->lock);
980
981 value = min_t(unsigned, w_length, cpkt->len);
982 memcpy(req->buf, cpkt->buf, value);
983 mbim_free_ctrl_pkt(cpkt);
984
985 pr_info("copied encapsulated_response %d bytes",
986 value);
987
988 break;
989
990 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
991 | USB_CDC_GET_NTB_PARAMETERS:
992
993 pr_info("USB_CDC_GET_NTB_PARAMETERS");
994
995 if (w_length == 0 || w_value != 0 || w_index != mbim->ctrl_id)
996 break;
997
998 value = w_length > sizeof ntb_parameters ?
999 sizeof ntb_parameters : w_length;
1000 memcpy(req->buf, &ntb_parameters, value);
1001 break;
1002
1003 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
1004 | USB_CDC_GET_NTB_INPUT_SIZE:
1005
1006 pr_info("USB_CDC_GET_NTB_INPUT_SIZE");
1007
1008 if (w_length < 4 || w_value != 0 || w_index != mbim->ctrl_id)
1009 break;
1010
1011 put_unaligned_le32(mbim->ntb_input_size, req->buf);
1012 value = 4;
1013 pr_info("Reply to host INPUT SIZE %d\n",
1014 mbim->ntb_input_size);
1015 break;
1016
1017 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
1018 | USB_CDC_SET_NTB_INPUT_SIZE:
1019
1020 pr_info("USB_CDC_SET_NTB_INPUT_SIZE");
1021
1022 if (w_length != 4 && w_length != 8) {
1023 pr_err("wrong NTB length %d", w_length);
1024 break;
1025 }
1026
1027 if (w_value != 0 || w_index != mbim->ctrl_id)
1028 break;
1029
1030 req->complete = mbim_ep0out_complete;
1031 req->length = w_length;
1032 req->context = f;
1033
1034 value = req->length;
1035 break;
1036
1037 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
1038 | USB_CDC_GET_NTB_FORMAT:
1039 {
1040 uint16_t format;
1041
1042 pr_info("USB_CDC_GET_NTB_FORMAT");
1043
1044 if (w_length < 2 || w_value != 0 || w_index != mbim->ctrl_id)
1045 break;
1046
1047 format = (mbim->parser_opts == &ndp16_opts) ? 0x0000 : 0x0001;
1048 put_unaligned_le16(format, req->buf);
1049 value = 2;
1050 pr_info("NTB FORMAT: sending %d\n", format);
1051 break;
1052 }
1053
1054 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
1055 | USB_CDC_SET_NTB_FORMAT:
1056 {
1057 pr_info("USB_CDC_SET_NTB_FORMAT");
1058
1059 if (w_length != 0 || w_index != mbim->ctrl_id)
1060 break;
1061 switch (w_value) {
1062 case 0x0000:
1063 mbim->parser_opts = &ndp16_opts;
1064 pr_info("NCM16 selected\n");
1065 break;
1066 case 0x0001:
1067 mbim->parser_opts = &ndp32_opts;
1068 pr_info("NCM32 selected\n");
1069 break;
1070 default:
1071 break;
1072 }
1073 value = 0;
1074 break;
1075 }
1076
1077 /* optional in mbim descriptor: */
1078 /* case USB_CDC_GET_MAX_DATAGRAM_SIZE: */
1079 /* case USB_CDC_SET_MAX_DATAGRAM_SIZE: */
1080
1081 default:
1082 pr_err("invalid control req: %02x.%02x v%04x i%04x l%d\n",
1083 ctrl->bRequestType, ctrl->bRequest,
1084 w_value, w_index, w_length);
1085 }
1086
1087 /* respond with data transfer or status phase? */
1088 if (value >= 0) {
1089 pr_info("control request: %02x.%02x v%04x i%04x l%d\n",
1090 ctrl->bRequestType, ctrl->bRequest,
1091 w_value, w_index, w_length);
Anna Perel2dfcaca2012-04-18 17:25:59 +03001092 req->zero = (value < w_length);
Anna Perela8c991d2012-04-09 16:44:46 +03001093 req->length = value;
1094 value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
1095 if (value < 0) {
1096 pr_err("queueing req failed: %02x.%02x, err %d\n",
1097 ctrl->bRequestType,
1098 ctrl->bRequest, value);
1099 }
1100 } else {
1101 pr_err("ctrl req err %d: %02x.%02x v%04x i%04x l%d\n",
1102 value, ctrl->bRequestType, ctrl->bRequest,
1103 w_value, w_index, w_length);
1104 }
1105
1106 /* device either stalls (value < 0) or reports success */
1107 return value;
1108}
1109
1110static int mbim_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
1111{
1112 struct f_mbim *mbim = func_to_mbim(f);
1113 struct usb_composite_dev *cdev = mbim->cdev;
1114 int ret = 0;
1115
1116 /* Control interface has only altsetting 0 */
1117 if (intf == mbim->ctrl_id) {
1118
1119 pr_info("CONTROL_INTERFACE");
1120
1121 if (alt != 0)
1122 goto fail;
1123
1124 if (mbim->not_port.notify->driver_data) {
1125 pr_info("reset mbim control %d\n", intf);
1126 usb_ep_disable(mbim->not_port.notify);
1127 }
1128
1129 ret = config_ep_by_speed(cdev->gadget, f,
1130 mbim->not_port.notify);
1131 if (ret) {
1132 mbim->not_port.notify->desc = NULL;
1133 pr_err("Failed configuring notify ep %s: err %d\n",
1134 mbim->not_port.notify->name, ret);
1135 return ret;
1136 }
1137
1138 ret = usb_ep_enable(mbim->not_port.notify);
1139 if (ret) {
1140 pr_err("usb ep#%s enable failed, err#%d\n",
1141 mbim->not_port.notify->name, ret);
1142 return ret;
1143 }
1144 mbim->not_port.notify->driver_data = mbim;
1145
1146 /* Data interface has two altsettings, 0 and 1 */
1147 } else if (intf == mbim->data_id) {
1148
1149 pr_info("DATA_INTERFACE");
1150
1151 if (alt > 1)
1152 goto fail;
1153
1154 if (mbim->bam_port.in->driver_data) {
1155 pr_info("reset mbim\n");
1156 mbim_reset_values(mbim);
1157 mbim_bam_disconnect(mbim);
1158 }
1159
1160 /*
1161 * CDC Network only sends data in non-default altsettings.
1162 * Changing altsettings resets filters, statistics, etc.
1163 */
1164 if (alt == 1) {
1165 pr_info("Alt set 1, initialize ports");
1166
1167 if (!mbim->bam_port.in->desc) {
1168
1169 pr_info("Choose endpoints");
1170
1171 ret = config_ep_by_speed(cdev->gadget, f,
1172 mbim->bam_port.in);
1173 if (ret) {
1174 mbim->bam_port.in->desc = NULL;
1175 pr_err("IN ep %s failed: %d\n",
1176 mbim->bam_port.in->name, ret);
1177 return ret;
1178 }
1179
1180 pr_info("Set mbim port in_desc = 0x%p",
1181 mbim->bam_port.in->desc);
1182
1183 ret = config_ep_by_speed(cdev->gadget, f,
1184 mbim->bam_port.out);
1185 if (ret) {
1186 mbim->bam_port.out->desc = NULL;
1187 pr_err("OUT ep %s failed: %d\n",
1188 mbim->bam_port.out->name, ret);
1189 return ret;
1190 }
1191
1192 pr_info("Set mbim port out_desc = 0x%p",
1193 mbim->bam_port.out->desc);
1194 } else {
1195 pr_info("PORTS already SET");
1196 }
1197
1198 pr_info("Activate mbim\n");
1199 mbim_bam_connect(mbim);
1200 }
1201
1202 spin_lock(&mbim->lock);
1203 mbim_notify(mbim);
1204 spin_unlock(&mbim->lock);
1205 } else {
1206 goto fail;
1207 }
1208
1209 atomic_set(&mbim->online, 1);
1210
1211 pr_info("SET DEVICE ONLINE");
1212
1213 /* wakeup file threads */
1214 wake_up(&mbim->read_wq);
1215 wake_up(&mbim->write_wq);
1216
1217 return 0;
1218
1219fail:
1220 pr_err("ERROR: Illegal Interface");
1221 return -EINVAL;
1222}
1223
1224/*
1225 * Because the data interface supports multiple altsettings,
1226 * this MBIM function *MUST* implement a get_alt() method.
1227 */
1228static int mbim_get_alt(struct usb_function *f, unsigned intf)
1229{
1230 struct f_mbim *mbim = func_to_mbim(f);
1231
1232 if (intf == mbim->ctrl_id)
1233 return 0;
1234 return mbim->bam_port.in->driver_data ? 1 : 0;
1235}
1236
1237static void mbim_disable(struct usb_function *f)
1238{
1239 struct f_mbim *mbim = func_to_mbim(f);
1240
1241 pr_info("SET DEVICE OFFLINE");
1242 atomic_set(&mbim->online, 0);
1243
Anna Perel86ea7c92012-04-24 14:31:29 +03001244 mbim_clear_queues(mbim);
1245 mbim_reset_function_queue(mbim);
Anna Perela8c991d2012-04-09 16:44:46 +03001246
1247 mbim_bam_disconnect(mbim);
1248
1249 if (mbim->not_port.notify->driver_data) {
1250 usb_ep_disable(mbim->not_port.notify);
1251 mbim->not_port.notify->driver_data = NULL;
1252 }
1253
1254 pr_info("mbim deactivated\n");
1255}
1256
1257/*---------------------- function driver setup/binding ---------------------*/
1258
1259static int
1260mbim_bind(struct usb_configuration *c, struct usb_function *f)
1261{
1262 struct usb_composite_dev *cdev = c->cdev;
1263 struct f_mbim *mbim = func_to_mbim(f);
1264 int status;
1265 struct usb_ep *ep;
1266
1267 pr_info("Enter");
1268
1269 mbim->cdev = cdev;
1270
1271 /* allocate instance-specific interface IDs */
1272 status = usb_interface_id(c, f);
1273 if (status < 0)
1274 goto fail;
1275 mbim->ctrl_id = status;
1276 mbim_iad_desc.bFirstInterface = status;
1277
1278 mbim_control_intf.bInterfaceNumber = status;
1279 mbim_union_desc.bMasterInterface0 = status;
1280
1281 status = usb_interface_id(c, f);
1282 if (status < 0)
1283 goto fail;
1284 mbim->data_id = status;
1285
1286 mbim_data_nop_intf.bInterfaceNumber = status;
1287 mbim_data_intf.bInterfaceNumber = status;
1288 mbim_union_desc.bSlaveInterface0 = status;
1289
1290 status = -ENODEV;
1291
1292 /* allocate instance-specific endpoints */
1293 ep = usb_ep_autoconfig(cdev->gadget, &fs_mbim_in_desc);
1294 if (!ep) {
1295 pr_err("usb epin autoconfig failed\n");
1296 goto fail;
1297 }
1298 pr_info("usb epin autoconfig succeeded\n");
1299 ep->driver_data = cdev; /* claim */
1300 mbim->bam_port.in = ep;
1301
1302 ep = usb_ep_autoconfig(cdev->gadget, &fs_mbim_out_desc);
1303 if (!ep) {
1304 pr_err("usb epout autoconfig failed\n");
1305 goto fail;
1306 }
1307 pr_info("usb epout autoconfig succeeded\n");
1308 ep->driver_data = cdev; /* claim */
1309 mbim->bam_port.out = ep;
1310
1311 ep = usb_ep_autoconfig(cdev->gadget, &fs_mbim_notify_desc);
1312 if (!ep) {
1313 pr_err("usb notify ep autoconfig failed\n");
1314 goto fail;
1315 }
1316 pr_info("usb notify ep autoconfig succeeded\n");
1317 mbim->not_port.notify = ep;
1318 ep->driver_data = cdev; /* claim */
1319
1320 status = -ENOMEM;
1321
1322 /* allocate notification request and buffer */
1323 mbim->not_port.notify_req = mbim_alloc_req(ep, NCM_STATUS_BYTECOUNT);
1324 if (!mbim->not_port.notify_req) {
1325 pr_info("failed to allocate notify request\n");
1326 goto fail;
1327 }
1328 pr_info("allocated notify ep request & request buffer\n");
1329
1330 mbim->not_port.notify_req->context = mbim;
1331 mbim->not_port.notify_req->complete = mbim_notify_complete;
1332
1333 /* copy descriptors, and track endpoint copies */
1334 f->descriptors = usb_copy_descriptors(mbim_fs_function);
1335 if (!f->descriptors)
1336 goto fail;
1337
1338 /*
1339 * support all relevant hardware speeds... we expect that when
1340 * hardware is dual speed, all bulk-capable endpoints work at
1341 * both speeds
1342 */
1343 if (gadget_is_dualspeed(c->cdev->gadget)) {
1344 hs_mbim_in_desc.bEndpointAddress =
1345 fs_mbim_in_desc.bEndpointAddress;
1346 hs_mbim_out_desc.bEndpointAddress =
1347 fs_mbim_out_desc.bEndpointAddress;
1348 hs_mbim_notify_desc.bEndpointAddress =
1349 fs_mbim_notify_desc.bEndpointAddress;
1350
1351 /* copy descriptors, and track endpoint copies */
1352 f->hs_descriptors = usb_copy_descriptors(mbim_hs_function);
1353 if (!f->hs_descriptors)
1354 goto fail;
1355 }
1356
1357 pr_info("mbim(%d): %s speed IN/%s OUT/%s NOTIFY/%s\n",
1358 mbim->port_num,
1359 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
1360 mbim->bam_port.in->name, mbim->bam_port.out->name,
1361 mbim->not_port.notify->name);
1362
1363 return 0;
1364
1365fail:
1366 pr_err("%s failed to bind, err %d\n", f->name, status);
1367
1368 if (f->descriptors)
1369 usb_free_descriptors(f->descriptors);
1370
1371 if (mbim->not_port.notify_req) {
1372 kfree(mbim->not_port.notify_req->buf);
1373 usb_ep_free_request(mbim->not_port.notify,
1374 mbim->not_port.notify_req);
1375 }
1376
1377 /* we might as well release our claims on endpoints */
1378 if (mbim->not_port.notify)
1379 mbim->not_port.notify->driver_data = NULL;
1380 if (mbim->bam_port.out)
1381 mbim->bam_port.out->driver_data = NULL;
1382 if (mbim->bam_port.in)
1383 mbim->bam_port.in->driver_data = NULL;
1384
1385 return status;
1386}
1387
1388static void mbim_unbind(struct usb_configuration *c, struct usb_function *f)
1389{
1390 struct f_mbim *mbim = func_to_mbim(f);
1391
1392 if (gadget_is_dualspeed(c->cdev->gadget))
1393 usb_free_descriptors(f->hs_descriptors);
1394 usb_free_descriptors(f->descriptors);
1395
1396 kfree(mbim->not_port.notify_req->buf);
1397 usb_ep_free_request(mbim->not_port.notify, mbim->not_port.notify_req);
1398}
1399
1400/**
1401 * mbim_bind_config - add MBIM link to a configuration
1402 * @c: the configuration to support the network link
1403 * Context: single threaded during gadget setup
1404 * Returns zero on success, else negative errno.
1405 */
1406int mbim_bind_config(struct usb_configuration *c, unsigned portno)
1407{
1408 struct f_mbim *mbim = NULL;
1409 int status = 0;
1410
1411 pr_info("port number %u", portno);
1412
1413 if (portno >= nr_mbim_ports) {
1414 pr_err("Can not add port %u. Max ports = %d",
1415 portno, nr_mbim_ports);
1416 return -ENODEV;
1417 }
1418
1419 status = mbim_bam_setup(nr_mbim_ports);
1420 if (status) {
1421 pr_err("bam setup failed");
1422 return status;
1423 }
1424
1425 /* maybe allocate device-global string IDs */
1426 if (mbim_string_defs[0].id == 0) {
1427
1428 /* control interface label */
1429 status = usb_string_id(c->cdev);
1430 if (status < 0)
1431 return status;
1432 mbim_string_defs[STRING_CTRL_IDX].id = status;
1433 mbim_control_intf.iInterface = status;
1434
1435 /* data interface label */
1436 status = usb_string_id(c->cdev);
1437 if (status < 0)
1438 return status;
1439 mbim_string_defs[STRING_DATA_IDX].id = status;
1440 mbim_data_nop_intf.iInterface = status;
1441 mbim_data_intf.iInterface = status;
1442 }
1443
1444 /* allocate and initialize one new instance */
1445 mbim = mbim_ports[0].port;
1446 if (!mbim) {
1447 pr_info("mbim struct not allocated");
1448 return -ENOMEM;
1449 }
1450
1451 mbim->cdev = c->cdev;
1452
1453 spin_lock_init(&mbim->lock);
1454
1455 mbim_reset_values(mbim);
1456
1457 mbim->function.name = "usb_mbim";
1458 mbim->function.strings = mbim_strings;
1459 mbim->function.bind = mbim_bind;
1460 mbim->function.unbind = mbim_unbind;
1461 mbim->function.set_alt = mbim_set_alt;
1462 mbim->function.get_alt = mbim_get_alt;
1463 mbim->function.setup = mbim_setup;
1464 mbim->function.disable = mbim_disable;
1465
1466 INIT_LIST_HEAD(&mbim->cpkt_req_q);
1467 INIT_LIST_HEAD(&mbim->cpkt_resp_q);
1468
1469 status = usb_add_function(c, &mbim->function);
1470
1471 pr_info("Exit status %d", status);
1472
1473 return status;
1474}
1475
1476/* ------------ MBIM DRIVER File Operations API for USER SPACE ------------ */
1477
1478static ssize_t
1479mbim_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
1480{
1481 struct f_mbim *dev = fp->private_data;
1482 struct ctrl_pkt *cpkt = NULL;
1483 int ret = 0;
1484
1485 pr_debug("Enter(%d)\n", count);
1486
1487 if (!dev) {
1488 pr_err("Received NULL mbim pointer\n");
1489 return -ENODEV;
1490 }
1491
1492 if (count > MBIM_BULK_BUFFER_SIZE) {
1493 pr_err("Buffer size is too big %d, should be at most %d\n",
1494 count, MBIM_BULK_BUFFER_SIZE);
1495 return -EINVAL;
1496 }
1497
1498 if (mbim_lock(&dev->read_excl)) {
1499 pr_err("Previous reading is not finished yet\n");
1500 return -EBUSY;
1501 }
1502
1503 /* block until mbim online */
1504 while (!(atomic_read(&dev->online) || atomic_read(&dev->error))) {
1505 pr_err("USB cable not connected. Wait.\n");
1506 ret = wait_event_interruptible(dev->read_wq,
1507 (atomic_read(&dev->online) ||
1508 atomic_read(&dev->error)));
1509 if (ret < 0) {
1510 mbim_unlock(&dev->read_excl);
1511 return 0;
1512 }
1513 }
1514
1515 if (atomic_read(&dev->error)) {
1516 mbim_unlock(&dev->read_excl);
1517 return -EIO;
1518 }
1519
1520 while (list_empty(&dev->cpkt_req_q)) {
1521 pr_err("Requests list is empty. Wait.\n");
1522 ret = wait_event_interruptible(dev->read_wq,
1523 !list_empty(&dev->cpkt_req_q));
1524 if (ret < 0) {
1525 pr_err("Waiting failed\n");
1526 mbim_unlock(&dev->read_excl);
1527 return 0;
1528 }
1529 pr_debug("Received request packet\n");
1530 }
1531
1532 cpkt = list_first_entry(&dev->cpkt_req_q, struct ctrl_pkt,
1533 list);
1534 if (cpkt->len > count) {
1535 mbim_unlock(&dev->read_excl);
1536 pr_err("cpkt size too big:%d > buf size:%d\n",
1537 cpkt->len, count);
1538 return -ENOMEM;
1539 }
1540
1541 pr_debug("cpkt size:%d\n", cpkt->len);
1542
1543 list_del(&cpkt->list);
1544 mbim_unlock(&dev->read_excl);
1545
1546 ret = copy_to_user(buf, cpkt->buf, cpkt->len);
1547 if (ret) {
1548 pr_err("copy_to_user failed: err %d\n", ret);
1549 ret = 0;
1550 } else {
1551 pr_debug("copied %d bytes to user\n", cpkt->len);
1552 ret = cpkt->len;
1553 }
1554
1555 mbim_free_ctrl_pkt(cpkt);
1556
1557 return ret;
1558}
1559
1560static ssize_t
1561mbim_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos)
1562{
1563 struct f_mbim *dev = fp->private_data;
1564 struct ctrl_pkt *cpkt = NULL;
1565 int ret = 0;
1566
1567 pr_debug("Enter(%d)", count);
1568
1569 if (!dev) {
1570 pr_err("Received NULL mbim pointer\n");
1571 return -ENODEV;
1572 }
1573
1574 if (!count) {
1575 pr_err("zero length ctrl pkt\n");
1576 return -ENODEV;
1577 }
1578
1579 if (count > MAX_CTRL_PKT_SIZE) {
1580 pr_err("given pkt size too big:%d > max_pkt_size:%d\n",
1581 count, MAX_CTRL_PKT_SIZE);
1582 return -ENOMEM;
1583 }
1584
1585 if (mbim_lock(&dev->write_excl)) {
1586 pr_err("Previous writing not finished yet\n");
1587 return -EBUSY;
1588 }
1589
1590 if (!atomic_read(&dev->online)) {
1591 pr_err("USB cable not connected\n");
1592 mbim_unlock(&dev->write_excl);
1593 return -EPIPE;
1594 }
1595
1596 cpkt = mbim_alloc_ctrl_pkt(count, GFP_KERNEL);
1597 if (!cpkt) {
1598 pr_err("failed to allocate ctrl pkt\n");
1599 mbim_unlock(&dev->write_excl);
1600 return -ENOMEM;
1601 }
1602
1603 ret = copy_from_user(cpkt->buf, buf, count);
1604 if (ret) {
1605 pr_err("copy_from_user failed err:%d\n", ret);
1606 mbim_free_ctrl_pkt(cpkt);
1607 mbim_unlock(&dev->write_excl);
1608 return 0;
1609 }
1610
1611 fmbim_send_cpkt_response(dev, cpkt);
1612
1613 mbim_unlock(&dev->write_excl);
1614
1615 pr_debug("Exit(%d)", count);
1616
1617 return count;
1618}
1619
1620static int mbim_open(struct inode *ip, struct file *fp)
1621{
1622 pr_info("Open mbim driver\n");
1623
1624 while (!_mbim_dev) {
1625 pr_err("mbim_dev not created yet\n");
1626 return -ENODEV;
1627 }
1628
1629 if (mbim_lock(&_mbim_dev->open_excl)) {
1630 pr_err("Already opened\n");
1631 return -EBUSY;
1632 }
1633
1634 pr_info("Lock mbim_dev->open_excl for open\n");
1635
1636 if (!atomic_read(&_mbim_dev->online))
1637 pr_err("USB cable not connected\n");
1638
Anna Perela8c991d2012-04-09 16:44:46 +03001639 fp->private_data = _mbim_dev;
1640
1641 atomic_set(&_mbim_dev->error, 0);
1642
1643 spin_lock(&_mbim_dev->lock);
1644 _mbim_dev->is_open = true;
1645 mbim_notify(_mbim_dev);
1646 spin_unlock(&_mbim_dev->lock);
1647
1648 pr_info("Exit, mbim file opened\n");
1649
1650 return 0;
1651}
1652
1653static int mbim_release(struct inode *ip, struct file *fp)
1654{
1655 struct f_mbim *mbim = fp->private_data;
1656
1657 pr_info("Close mbim file");
1658
1659 spin_lock(&mbim->lock);
1660 mbim->is_open = false;
1661 mbim_notify(mbim);
1662 spin_unlock(&mbim->lock);
1663
Anna Perela8c991d2012-04-09 16:44:46 +03001664 mbim_unlock(&_mbim_dev->open_excl);
1665
1666 return 0;
1667}
1668
1669static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
1670{
1671 struct f_mbim *mbim = fp->private_data;
1672 int ret = 0;
1673
1674 pr_info("Received command %d", cmd);
1675
1676 if (mbim_lock(&mbim->ioctl_excl))
1677 return -EBUSY;
1678
1679 switch (cmd) {
1680 case MBIM_GET_NTB_SIZE:
1681 ret = copy_to_user((void __user *)arg,
1682 &mbim->ntb_input_size, sizeof(mbim->ntb_input_size));
1683 if (ret) {
1684 pr_err("copying to user space failed");
1685 ret = -EFAULT;
1686 }
1687 pr_info("Sent NTB size %d", mbim->ntb_input_size);
1688 break;
1689 case MBIM_GET_DATAGRAM_COUNT:
1690 ret = copy_to_user((void __user *)arg,
1691 &mbim->ntb_max_datagrams,
1692 sizeof(mbim->ntb_max_datagrams));
1693 if (ret) {
1694 pr_err("copying to user space failed");
1695 ret = -EFAULT;
1696 }
1697 pr_info("Sent NTB datagrams count %d",
1698 mbim->ntb_max_datagrams);
1699 break;
1700 default:
1701 pr_err("wrong parameter");
1702 ret = -EINVAL;
1703 }
1704
1705 mbim_unlock(&mbim->ioctl_excl);
1706
1707 return ret;
1708}
1709
1710/* file operations for MBIM device /dev/android_mbim */
1711static const struct file_operations mbim_fops = {
1712 .owner = THIS_MODULE,
1713 .open = mbim_open,
1714 .release = mbim_release,
1715 .read = mbim_read,
1716 .write = mbim_write,
1717 .unlocked_ioctl = mbim_ioctl,
1718};
1719
1720static struct miscdevice mbim_device = {
1721 .minor = MISC_DYNAMIC_MINOR,
1722 .name = "android_mbim",
1723 .fops = &mbim_fops,
1724};
1725
1726static int mbim_init(int instances)
1727{
1728 int i;
1729 struct f_mbim *dev = NULL;
1730 int ret;
1731
1732 pr_info("initialize %d instances\n", instances);
1733
1734 if (instances > NR_MBIM_PORTS) {
1735 pr_err("Max-%d instances supported\n", NR_MBIM_PORTS);
1736 return -EINVAL;
1737 }
1738
1739 for (i = 0; i < instances; i++) {
1740 dev = kzalloc(sizeof(struct f_mbim), GFP_KERNEL);
1741 if (!dev) {
1742 pr_err("Failed to allocate mbim dev\n");
1743 ret = -ENOMEM;
1744 goto fail_probe;
1745 }
1746
1747 dev->port_num = i;
1748 spin_lock_init(&dev->lock);
1749 INIT_LIST_HEAD(&dev->cpkt_req_q);
1750 INIT_LIST_HEAD(&dev->cpkt_resp_q);
1751
1752 mbim_ports[i].port = dev;
1753 mbim_ports[i].port_num = i;
1754
1755 init_waitqueue_head(&dev->read_wq);
1756 init_waitqueue_head(&dev->write_wq);
1757
1758 atomic_set(&dev->open_excl, 0);
1759 atomic_set(&dev->ioctl_excl, 0);
1760 atomic_set(&dev->read_excl, 0);
1761 atomic_set(&dev->write_excl, 0);
1762
1763 nr_mbim_ports++;
1764
1765 }
1766
1767 _mbim_dev = dev;
1768 ret = misc_register(&mbim_device);
1769 if (ret) {
1770 pr_err("mbim driver failed to register");
1771 goto fail_probe;
1772 }
1773
1774 pr_info("Initialized %d ports\n", nr_mbim_ports);
1775
1776 return ret;
1777
1778fail_probe:
1779 pr_err("Failed");
1780 for (i = 0; i < nr_mbim_ports; i++) {
1781 kfree(mbim_ports[i].port);
1782 mbim_ports[i].port = NULL;
1783 }
1784
1785 return ret;
1786}
1787
1788static void fmbim_cleanup(void)
1789{
1790 int i = 0;
1791
1792 pr_info("Enter");
1793
1794 for (i = 0; i < nr_mbim_ports; i++) {
1795 kfree(mbim_ports[i].port);
1796 mbim_ports[i].port = NULL;
1797 }
1798 nr_mbim_ports = 0;
1799
1800 misc_deregister(&mbim_device);
1801
1802 _mbim_dev = NULL;
1803}
1804