blob: 770a225e1a0ac15e5c68fc6a595af7334181f854 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/slab.h>
15#include <linux/kernel.h>
16#include <linux/device.h>
17#include <linux/usb/android_composite.h>
18#include <linux/spinlock.h>
19
20#include <linux/platform_data/usb_rmnet.h>
21#include "u_rmnet.h"
22#include "gadget_chips.h"
23
24
25#define RMNET_NOTIFY_INTERVAL 5
26#define RMNET_MAX_NOTIFY_SIZE sizeof(struct usb_cdc_notification)
27
28struct rmnet_descs {
29 struct usb_endpoint_descriptor *in;
30 struct usb_endpoint_descriptor *out;
31 struct usb_endpoint_descriptor *notify;
32};
33
34#define ACM_CTRL_DTR (1 << 0)
35
36/* TODO: use separate structures for data and
37 * control paths
38 */
39struct f_rmnet {
40 struct grmnet port;
41 int ifc_id;
42 u8 port_num;
43 atomic_t online;
44 struct usb_composite_dev *cdev;
45
46 spinlock_t lock;
47
48 /* usb descriptors */
49 struct rmnet_descs fs;
50 struct rmnet_descs hs;
51
52 /* usb eps*/
53 struct usb_ep *notify;
54 struct usb_endpoint_descriptor *notify_desc;
55 struct usb_request *notify_req;
56
57 /* control info */
58 struct list_head cpkt_resp_q;
59 atomic_t notify_count;
60 unsigned long cpkts_len;
61};
62
63#define NR_PORTS 1
64static unsigned int nr_ports;
65static struct rmnet_ports {
66 unsigned port_num;
67 struct f_rmnet *port;
68#ifdef CONFIG_USB_ANDROID
69 struct android_usb_function android_f;
70#endif
71} ports[NR_PORTS];
72
73static struct usb_interface_descriptor rmnet_interface_desc = {
74 .bLength = USB_DT_INTERFACE_SIZE,
75 .bDescriptorType = USB_DT_INTERFACE,
76 .bNumEndpoints = 3,
77 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
78 .bInterfaceSubClass = USB_CLASS_VENDOR_SPEC,
79 .bInterfaceProtocol = USB_CLASS_VENDOR_SPEC,
80 /* .iInterface = DYNAMIC */
81};
82
83/* Full speed support */
84static struct usb_endpoint_descriptor rmnet_fs_notify_desc = {
85 .bLength = USB_DT_ENDPOINT_SIZE,
86 .bDescriptorType = USB_DT_ENDPOINT,
87 .bEndpointAddress = USB_DIR_IN,
88 .bmAttributes = USB_ENDPOINT_XFER_INT,
89 .wMaxPacketSize = __constant_cpu_to_le16(RMNET_MAX_NOTIFY_SIZE),
90 .bInterval = 1 << RMNET_NOTIFY_INTERVAL,
91};
92
93static struct usb_endpoint_descriptor rmnet_fs_in_desc = {
94 .bLength = USB_DT_ENDPOINT_SIZE,
95 .bDescriptorType = USB_DT_ENDPOINT,
96 .bEndpointAddress = USB_DIR_IN,
97 .bmAttributes = USB_ENDPOINT_XFER_BULK,
98 .wMaxPacketSize = __constant_cpu_to_le16(64),
99};
100
101static struct usb_endpoint_descriptor rmnet_fs_out_desc = {
102 .bLength = USB_DT_ENDPOINT_SIZE,
103 .bDescriptorType = USB_DT_ENDPOINT,
104 .bEndpointAddress = USB_DIR_OUT,
105 .bmAttributes = USB_ENDPOINT_XFER_BULK,
106 .wMaxPacketSize = __constant_cpu_to_le16(64),
107};
108
109static struct usb_descriptor_header *rmnet_fs_function[] = {
110 (struct usb_descriptor_header *) &rmnet_interface_desc,
111 (struct usb_descriptor_header *) &rmnet_fs_notify_desc,
112 (struct usb_descriptor_header *) &rmnet_fs_in_desc,
113 (struct usb_descriptor_header *) &rmnet_fs_out_desc,
114 NULL,
115};
116
117/* High speed support */
118static struct usb_endpoint_descriptor rmnet_hs_notify_desc = {
119 .bLength = USB_DT_ENDPOINT_SIZE,
120 .bDescriptorType = USB_DT_ENDPOINT,
121 .bEndpointAddress = USB_DIR_IN,
122 .bmAttributes = USB_ENDPOINT_XFER_INT,
123 .wMaxPacketSize = __constant_cpu_to_le16(RMNET_MAX_NOTIFY_SIZE),
124 .bInterval = RMNET_NOTIFY_INTERVAL + 4,
125};
126
127static struct usb_endpoint_descriptor rmnet_hs_in_desc = {
128 .bLength = USB_DT_ENDPOINT_SIZE,
129 .bDescriptorType = USB_DT_ENDPOINT,
130 .bEndpointAddress = USB_DIR_IN,
131 .bmAttributes = USB_ENDPOINT_XFER_BULK,
132 .wMaxPacketSize = __constant_cpu_to_le16(512),
133};
134
135static struct usb_endpoint_descriptor rmnet_hs_out_desc = {
136 .bLength = USB_DT_ENDPOINT_SIZE,
137 .bDescriptorType = USB_DT_ENDPOINT,
138 .bEndpointAddress = USB_DIR_OUT,
139 .bmAttributes = USB_ENDPOINT_XFER_BULK,
140 .wMaxPacketSize = __constant_cpu_to_le16(512),
141};
142
143static struct usb_descriptor_header *rmnet_hs_function[] = {
144 (struct usb_descriptor_header *) &rmnet_interface_desc,
145 (struct usb_descriptor_header *) &rmnet_hs_notify_desc,
146 (struct usb_descriptor_header *) &rmnet_hs_in_desc,
147 (struct usb_descriptor_header *) &rmnet_hs_out_desc,
148 NULL,
149};
150
151/* String descriptors */
152
153static struct usb_string rmnet_string_defs[] = {
154 [0].s = "RmNet",
155 { } /* end of list */
156};
157
158static struct usb_gadget_strings rmnet_string_table = {
159 .language = 0x0409, /* en-us */
160 .strings = rmnet_string_defs,
161};
162
163static struct usb_gadget_strings *rmnet_strings[] = {
164 &rmnet_string_table,
165 NULL,
166};
167
168/* ------- misc functions --------------------*/
169
170static inline struct f_rmnet *func_to_rmnet(struct usb_function *f)
171{
172 return container_of(f, struct f_rmnet, port.func);
173}
174
175static inline struct f_rmnet *port_to_rmnet(struct grmnet *r)
176{
177 return container_of(r, struct f_rmnet, port);
178}
179
180static struct usb_request *
181frmnet_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags)
182{
183 struct usb_request *req;
184
185 req = usb_ep_alloc_request(ep, flags);
186 if (!req)
187 return ERR_PTR(-ENOMEM);
188
189 req->buf = kmalloc(len, flags);
190 if (!req->buf) {
191 usb_ep_free_request(ep, req);
192 return ERR_PTR(-ENOMEM);
193 }
194
195 req->length = len;
196
197 return req;
198}
199
200void frmnet_free_req(struct usb_ep *ep, struct usb_request *req)
201{
202 kfree(req->buf);
203 usb_ep_free_request(ep, req);
204}
205
206static struct rmnet_ctrl_pkt *rmnet_alloc_ctrl_pkt(unsigned len, gfp_t flags)
207{
208 struct rmnet_ctrl_pkt *pkt;
209
210 pkt = kzalloc(sizeof(struct rmnet_ctrl_pkt), flags);
211 if (!pkt)
212 return ERR_PTR(-ENOMEM);
213
214 pkt->buf = kmalloc(len, flags);
215 if (!pkt->buf) {
216 kfree(pkt);
217 return ERR_PTR(-ENOMEM);
218 }
219 pkt->len = len;
220
221 return pkt;
222}
223
224static void rmnet_free_ctrl_pkt(struct rmnet_ctrl_pkt *pkt)
225{
226 kfree(pkt->buf);
227 kfree(pkt);
228}
229
230/* -------------------------------------------*/
231
232static int gport_setup(int no_ports)
233{
234 int ret;
235
236 pr_debug("%s: no_ports:%d\n", __func__, no_ports);
237
238 ret = gbam_setup(no_ports);
239 if (ret)
240 return ret;
241
242 ret = gsmd_ctrl_setup(no_ports);
243 if (ret)
244 return ret;
245
246 return 0;
247}
248
249static int gport_connect(struct f_rmnet *dev)
250{
251 int ret;
252
253 pr_debug("%s:dev:%p portno:%d\n",
254 __func__, dev, dev->port_num);
255
256 ret = gsmd_ctrl_connect(&dev->port, dev->port_num);
257 if (ret) {
258 pr_err("%s: gsmd_ctrl_connect failed: err:%d\n",
259 __func__, ret);
260 return ret;
261 }
262
263 ret = gbam_connect(&dev->port, dev->port_num);
264 if (ret) {
265 pr_err("%s: gbam_connect failed: err:%d\n",
266 __func__, ret);
267 return ret;
268 }
269
270 return 0;
271}
272
273static int gport_disconnect(struct f_rmnet *dev)
274{
275 pr_debug("%s:dev:%p portno:%d\n",
276 __func__, dev, dev->port_num);
277
278 gbam_disconnect(&dev->port, dev->port_num);
279
280 gsmd_ctrl_disconnect(&dev->port, dev->port_num);
281
282 return 0;
283}
284
285static int frmnet_remove(struct platform_device *dev)
286{
287 /* TBD:
288 * 1. Unregister android function
289 * 2. Free name from ports
290 * 3. Free rmnet device
291 * 4. Free Copy Descriptors
292 */
293 return 0;
294}
295
296static void frmnet_unbind(struct usb_configuration *c, struct usb_function *f)
297{
298 struct f_rmnet *dev = func_to_rmnet(f);
299
300 pr_debug("%s: portno:%d\n", __func__, dev->port_num);
301
302 if (gadget_is_dualspeed(c->cdev->gadget))
303 usb_free_descriptors(f->hs_descriptors);
304 usb_free_descriptors(f->descriptors);
305
306 frmnet_free_req(dev->notify, dev->notify_req);
307
308 kfree(dev);
309}
310
311static void frmnet_disable(struct usb_function *f)
312{
313 struct f_rmnet *dev = func_to_rmnet(f);
314
315 pr_debug("%s: port#%d\n", __func__, dev->port_num);
316
317 usb_ep_disable(dev->notify);
318
319 atomic_set(&dev->online, 0);
320
321 gport_disconnect(dev);
322}
323
324static int
325frmnet_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
326{
327 struct f_rmnet *dev = func_to_rmnet(f);
328 struct usb_composite_dev *cdev = dev->cdev;
329 int ret;
330
331 pr_debug("%s:dev:%p port#%d\n", __func__, dev, dev->port_num);
332
333 if (dev->notify->driver_data) {
334 pr_debug("%s: reset port:%d\n", __func__, dev->port_num);
335 usb_ep_disable(dev->notify);
336 }
337 dev->notify_desc = ep_choose(cdev->gadget,
338 dev->hs.notify,
339 dev->fs.notify);
340 ret = usb_ep_enable(dev->notify, dev->notify_desc);
341 if (ret) {
342 pr_err("%s: usb ep#%s enable failed, err#%d\n",
343 __func__, dev->notify->name, ret);
344 return ret;
345 }
346 dev->notify->driver_data = dev;
347
348 if (dev->port.in->driver_data) {
349 pr_debug("%s: reset port:%d\n", __func__, dev->port_num);
350 gport_disconnect(dev);
351 }
352
353 dev->port.in_desc = ep_choose(cdev->gadget,
354 dev->hs.in, dev->fs.in);
355 dev->port.out_desc = ep_choose(cdev->gadget,
356 dev->hs.out, dev->fs.out);
357
358 ret = gport_connect(dev);
359
360 atomic_set(&dev->online, 1);
361
362 return ret;
363}
364
365static void frmnet_ctrl_response_available(struct f_rmnet *dev)
366{
367 struct usb_request *req = dev->notify_req;
368 struct usb_cdc_notification *event;
369 unsigned long flags;
370 int ret;
371
372 pr_debug("%s:dev:%p portno#%d\n", __func__, dev, dev->port_num);
373
374 spin_lock_irqsave(&dev->lock, flags);
375 if (!atomic_read(&dev->online) || !req || !req->buf) {
376 spin_unlock_irqrestore(&dev->lock, flags);
377 return;
378 }
379
380 if (atomic_inc_return(&dev->notify_count) != 1) {
381 spin_unlock_irqrestore(&dev->lock, flags);
382 return;
383 }
384
385 event = req->buf;
386 event->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
387 | USB_RECIP_INTERFACE;
388 event->bNotificationType = USB_CDC_NOTIFY_RESPONSE_AVAILABLE;
389 event->wValue = cpu_to_le16(0);
390 event->wIndex = cpu_to_le16(dev->ifc_id);
391 event->wLength = cpu_to_le16(0);
392 spin_unlock_irqrestore(&dev->lock, flags);
393
394 ret = usb_ep_queue(dev->notify, dev->notify_req, GFP_ATOMIC);
395 if (ret) {
396 atomic_dec(&dev->notify_count);
397 pr_debug("ep enqueue error %d\n", ret);
398 }
399}
400
401static int
402frmnet_send_cpkt_response(struct grmnet *gr, struct rmnet_ctrl_pkt *cpkt)
403{
404 struct f_rmnet *dev;
405 unsigned long flags;
406
407 if (!gr || !cpkt) {
408 pr_err("%s: Invalid grmnet/cpkt, grmnet:%p cpkt:%p\n",
409 __func__, gr, cpkt);
410 return -ENODEV;
411 }
412
413 dev = port_to_rmnet(gr);
414
415 pr_debug("%s: dev:%p port#%d\n", __func__, dev, dev->port_num);
416
417 if (!atomic_read(&dev->online)) {
418 rmnet_free_ctrl_pkt(cpkt);
419 return 0;
420 }
421
422 spin_lock_irqsave(&dev->lock, flags);
423 list_add(&cpkt->list, &dev->cpkt_resp_q);
424 spin_unlock_irqrestore(&dev->lock, flags);
425
426 frmnet_ctrl_response_available(dev);
427
428 return 0;
429}
430
431static void
432frmnet_cmd_complete(struct usb_ep *ep, struct usb_request *req)
433{
434 struct f_rmnet *dev = req->context;
435 struct usb_composite_dev *cdev;
436 struct rmnet_ctrl_pkt *cpkt;
437
438 if (!dev) {
439 pr_err("%s: rmnet dev is null\n", __func__);
440 return;
441 }
442
443 pr_debug("%s: dev:%p port#%d\n", __func__, dev, dev->port_num);
444
445 cdev = dev->cdev;
446
447 cpkt = rmnet_alloc_ctrl_pkt(req->actual, GFP_ATOMIC);
448 if (IS_ERR(cpkt)) {
449 pr_err("%s: Unable to allocate ctrl pkt\n", __func__);
450 return;
451 }
452
453 memcpy(cpkt->buf, req->buf, req->actual);
454
455 if (dev->port.send_cpkt_request)
456 dev->port.send_cpkt_request(&dev->port, dev->port_num, cpkt);
457}
458
459static void frmnet_notify_complete(struct usb_ep *ep, struct usb_request *req)
460{
461 struct f_rmnet *dev = req->context;
462 int status = req->status;
463
464 pr_debug("%s: dev:%p port#%d\n", __func__, dev, dev->port_num);
465
466 switch (status) {
467 case -ECONNRESET:
468 case -ESHUTDOWN:
469 /* connection gone */
470 atomic_set(&dev->notify_count, 0);
471 break;
472 default:
473 pr_err("rmnet notify ep error %d\n", status);
474 /* FALLTHROUGH */
475 case 0:
476 if (atomic_dec_and_test(&dev->notify_count))
477 break;
478
479 status = usb_ep_queue(dev->notify, req, GFP_ATOMIC);
480 if (status) {
481 atomic_dec(&dev->notify_count);
482 pr_debug("ep enqueue error %d\n", status);
483 }
484 break;
485 }
486}
487
488static int
489frmnet_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
490{
491 struct f_rmnet *dev = func_to_rmnet(f);
492 struct usb_composite_dev *cdev = dev->cdev;
493 struct usb_request *req = cdev->req;
494 u16 w_index = le16_to_cpu(ctrl->wIndex);
495 u16 w_value = le16_to_cpu(ctrl->wValue);
496 u16 w_length = le16_to_cpu(ctrl->wLength);
497 int ret = -EOPNOTSUPP;
498
499 pr_debug("%s:dev:%p port#%d\n", __func__, dev, dev->port_num);
500
501 if (!atomic_read(&dev->online)) {
502 pr_debug("%s: usb cable is not connected\n", __func__);
503 return -ENOTCONN;
504 }
505
506 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
507
508 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
509 | USB_CDC_SEND_ENCAPSULATED_COMMAND:
510 if (w_length > req->length)
511 goto invalid;
512 ret = w_length;
513 req->complete = frmnet_cmd_complete;
514 req->context = dev;
515 break;
516
517
518 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
519 | USB_CDC_GET_ENCAPSULATED_RESPONSE:
520 if (w_value)
521 goto invalid;
522 else {
523 unsigned len;
524 struct rmnet_ctrl_pkt *cpkt;
525
526 spin_lock(&dev->lock);
527 if (list_empty(&dev->cpkt_resp_q)) {
528 pr_err("ctrl resp queue empty "
529 " req%02x.%02x v%04x i%04x l%d\n",
530 ctrl->bRequestType, ctrl->bRequest,
531 w_value, w_index, w_length);
532 spin_unlock(&dev->lock);
533 goto invalid;
534 }
535
536 cpkt = list_first_entry(&dev->cpkt_resp_q,
537 struct rmnet_ctrl_pkt, list);
538 list_del(&cpkt->list);
539 spin_unlock(&dev->lock);
540
541 len = min_t(unsigned, w_length, cpkt->len);
542 memcpy(req->buf, cpkt->buf, len);
543 ret = len;
544
545 rmnet_free_ctrl_pkt(cpkt);
546 }
547 break;
548 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
549 | USB_CDC_REQ_SET_CONTROL_LINE_STATE:
550 if (dev->port.send_cbits_tomodem)
551 dev->port.send_cbits_tomodem(&dev->port,
552 dev->port_num,
553 w_value);
554 ret = 0;
555
556 break;
557 default:
558
559invalid:
560 DBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
561 ctrl->bRequestType, ctrl->bRequest,
562 w_value, w_index, w_length);
563 }
564
565 /* respond with data transfer or status phase? */
566 if (ret >= 0) {
567 VDBG(cdev, "rmnet req%02x.%02x v%04x i%04x l%d\n",
568 ctrl->bRequestType, ctrl->bRequest,
569 w_value, w_index, w_length);
570 req->zero = (ret < w_length);
571 req->length = ret;
572 ret = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
573 if (ret < 0)
574 ERROR(cdev, "rmnet ep0 enqueue err %d\n", ret);
575 }
576
577 return ret;
578}
579
580static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
581{
582 struct f_rmnet *dev = func_to_rmnet(f);
583 struct usb_ep *ep;
584 struct usb_composite_dev *cdev = c->cdev;
585 int ret = -ENODEV;
586
587 dev->ifc_id = usb_interface_id(c, f);
588 if (dev->ifc_id < 0) {
589 pr_err("%s: unable to allocate ifc id, err:%d",
590 __func__, dev->ifc_id);
591 return dev->ifc_id;
592 }
593 rmnet_interface_desc.bInterfaceNumber = dev->ifc_id;
594
595 ep = usb_ep_autoconfig(cdev->gadget, &rmnet_fs_in_desc);
596 if (!ep) {
597 pr_err("%s: usb epin autoconfig failed\n", __func__);
598 return -ENODEV;
599 }
600 dev->port.in = ep;
601 ep->driver_data = cdev;
602
603 ep = usb_ep_autoconfig(cdev->gadget, &rmnet_fs_out_desc);
604 if (!ep) {
605 pr_err("%s: usb epout autoconfig failed\n", __func__);
606 ret = -ENODEV;
607 goto ep_auto_out_fail;
608 }
609 dev->port.out = ep;
610 ep->driver_data = cdev;
611
612 ep = usb_ep_autoconfig(cdev->gadget, &rmnet_fs_notify_desc);
613 if (!ep) {
614 pr_err("%s: usb epnotify autoconfig failed\n", __func__);
615 ret = -ENODEV;
616 goto ep_auto_notify_fail;
617 }
618 dev->notify = ep;
619 ep->driver_data = cdev;
620
621 dev->notify_req = frmnet_alloc_req(ep,
622 sizeof(struct usb_cdc_notification) + 2,
623 GFP_KERNEL);
624 if (IS_ERR(dev->notify_req)) {
625 pr_err("%s: unable to allocate memory for notify req\n",
626 __func__);
627 ret = -ENOMEM;
628 goto ep_notify_alloc_fail;
629 }
630
631 dev->notify_req->complete = frmnet_notify_complete;
632 dev->notify_req->context = dev;
633
634 f->descriptors = usb_copy_descriptors(rmnet_fs_function);
635
636 dev->fs.in = usb_find_endpoint(rmnet_fs_function,
637 f->descriptors,
638 &rmnet_fs_in_desc);
639 dev->fs.out = usb_find_endpoint(rmnet_fs_function,
640 f->descriptors,
641 &rmnet_fs_out_desc);
642 dev->fs.notify = usb_find_endpoint(rmnet_fs_function,
643 f->descriptors,
644 &rmnet_fs_notify_desc);
645
646 if (gadget_is_dualspeed(cdev->gadget)) {
647 rmnet_hs_in_desc.bEndpointAddress =
648 rmnet_fs_in_desc.bEndpointAddress;
649 rmnet_hs_out_desc.bEndpointAddress =
650 rmnet_fs_out_desc.bEndpointAddress;
651 rmnet_hs_notify_desc.bEndpointAddress =
652 rmnet_fs_notify_desc.bEndpointAddress;
653
654 /* copy descriptors, and track endpoint copies */
655 f->hs_descriptors = usb_copy_descriptors(rmnet_hs_function);
656
657 dev->hs.in = usb_find_endpoint(rmnet_hs_function,
658 f->hs_descriptors, &rmnet_hs_in_desc);
659 dev->hs.out = usb_find_endpoint(rmnet_hs_function,
660 f->hs_descriptors, &rmnet_hs_out_desc);
661 dev->hs.notify = usb_find_endpoint(rmnet_hs_function,
662 f->hs_descriptors, &rmnet_hs_notify_desc);
663 }
664
665 pr_info("%s: RmNet(%d) %s Speed, IN:%s OUT:%s\n",
666 __func__, dev->port_num,
667 gadget_is_dualspeed(cdev->gadget) ? "dual" : "full",
668 dev->port.in->name, dev->port.out->name);
669
670 return 0;
671
672ep_notify_alloc_fail:
673 dev->notify->driver_data = NULL;
674 dev->notify = NULL;
675ep_auto_notify_fail:
676 dev->port.out->driver_data = NULL;
677 dev->port.out = NULL;
678ep_auto_out_fail:
679 dev->port.in->driver_data = NULL;
680 dev->port.in = NULL;
681
682 return ret;
683}
684
685#ifdef CONFIG_USB_ANDROID
686static int frmnet_bind_config(struct usb_configuration *c)
687{
688 static unsigned portno;
689 int status;
690 struct f_rmnet *dev;
691 struct usb_function *f;
692 unsigned long flags;
693
694 pr_debug("%s: usb config:%p\n", __func__, c);
695
696 if (portno >= nr_ports) {
697 pr_err("%s: supporting ports#%u port_id:%u", __func__,
698 nr_ports, portno);
699 return -ENODEV;
700 }
701
702 if (rmnet_string_defs[0].id == 0) {
703 status = usb_string_id(c->cdev);
704 if (status < 0) {
705 pr_err("%s: failed to get string id, err:%d\n",
706 __func__, status);
707 return status;
708 }
709 rmnet_string_defs[0].id = status;
710 }
711
712 dev = ports[portno].port;
713
714 spin_lock_irqsave(&dev->lock, flags);
715 dev->cdev = c->cdev;
716 f = &dev->port.func;
717 f->name = ports[portno].android_f.name;
718 portno++;
719 spin_unlock_irqrestore(&dev->lock, flags);
720
721 f->strings = rmnet_strings;
722 f->bind = frmnet_bind;
723 f->unbind = frmnet_unbind;
724 f->disable = frmnet_disable;
725 f->set_alt = frmnet_set_alt;
726 f->setup = frmnet_setup;
727 dev->port.send_cpkt_response = frmnet_send_cpkt_response;
728
729 status = usb_add_function(c, f);
730 if (status) {
731 pr_err("%s: usb add function failed: %d\n",
732 __func__, status);
733 kfree(ports[portno].android_f.name);
734 kfree(dev);
735 return status;
736 }
737
738 pr_debug("%s: complete\n", __func__);
739
740 return status;
741}
742
743static struct platform_driver usb_rmnet = {
744 .remove = frmnet_remove,
745 .driver = {
746 .name = "usb_rmnet",
747 .owner = THIS_MODULE,
748 },
749};
750
751static int __devinit frmnet_probe(struct platform_device *pdev)
752{
753 struct usb_rmnet_pdata *pdata = pdev->dev.platform_data;
754 int i;
755 struct f_rmnet *dev;
756 int ret;
757 int instances;
758
759 instances = 1;
760 if (pdata)
761 instances = pdata->num_instances;
762
763 pr_debug("%s: instances :%d\n", __func__, instances);
764
765 for (i = 0; i < instances; i++) {
766 dev = kzalloc(sizeof(struct f_rmnet), GFP_KERNEL);
767 if (!dev) {
768 pr_err("%s: Unable to allocate rmnet device\n",
769 __func__);
770 ret = -ENOMEM;
771 goto fail_probe;
772 }
773
774 dev->port_num = i;
775 spin_lock_init(&dev->lock);
776 INIT_LIST_HEAD(&dev->cpkt_resp_q);
777
778 ports[i].port = dev;
779 ports[i].port_num = i;
780 ports[i].android_f.name = kasprintf(GFP_KERNEL, "rmnet%d", i);
781 ports[i].android_f.bind_config = frmnet_bind_config;
782
783 pr_debug("%s: anroid f_name:%s\n", __func__,
784 ports[i].android_f.name);
785
786 nr_ports++;
787
788 android_register_function(&ports[i].android_f);
789 }
790
791 gport_setup(nr_ports);
792
793 return 0;
794
795fail_probe:
796 for (i = 0; i < nr_ports; i++) {
797 /* android_unregister_function(&ports[i].android_f); */
798 kfree(ports[i].android_f.name);
799 kfree(ports[i].port);
800 }
801
802 return ret;
803}
804
805static int __init frmnet_init(void)
806{
807 return platform_driver_probe(&usb_rmnet, frmnet_probe);
808}
809module_init(frmnet_init);
810
811static void __exit frmnet_exit(void)
812{
813 platform_driver_unregister(&usb_rmnet);
814}
815module_exit(frmnet_exit);
816
817MODULE_DESCRIPTION("rmnet function driver");
818MODULE_LICENSE("GPL v2");
819#endif