blob: 82a7e35165007291d8c4996482a15ff5a1612acc [file] [log] [blame]
Pavankumar Kondeti50f38152013-01-17 16:04:53 +05301/* Copyright (c) 2011-2013, Linux Foundation. All rights reserved.
Hemant Kumar14401d52011-11-03 16:40:32 -07002 *
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#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/module.h>
18#include <linux/debugfs.h>
19#include <linux/platform_device.h>
20#include <linux/uaccess.h>
21#include <linux/ratelimit.h>
22#include <mach/usb_bridge.h>
23
Hemant Kumare8f691f2012-10-03 17:15:28 -070024#define MAX_RX_URBS 100
Hemant Kumar14401d52011-11-03 16:40:32 -070025#define RMNET_RX_BUFSIZE 2048
26
Hemant Kumarfd2d5e52011-12-22 17:51:53 -080027#define STOP_SUBMIT_URB_LIMIT 500
Hemant Kumar14401d52011-11-03 16:40:32 -070028#define FLOW_CTRL_EN_THRESHOLD 500
29#define FLOW_CTRL_DISABLE 300
30#define FLOW_CTRL_SUPPORT 1
31
Hemant Kumarc2b17782013-02-03 15:56:29 -080032#define BRIDGE_DATA_IDX 0
33#define BRIDGE_CTRL_IDX 1
34
35/*for xport : HSIC*/
36static const char * const serial_hsic_bridge_names[] = {
37 "serial_hsic_data",
38 "serial_hsic_ctrl",
39};
40
41static const char * const rmnet_hsic_bridge_names[] = {
42 "rmnet_hsic_data",
43 "rmnet_hsic_ctrl",
Hemant Kumar14401d52011-11-03 16:40:32 -070044};
45
46static struct workqueue_struct *bridge_wq;
47
48static unsigned int fctrl_support = FLOW_CTRL_SUPPORT;
49module_param(fctrl_support, uint, S_IRUGO | S_IWUSR);
50
51static unsigned int fctrl_en_thld = FLOW_CTRL_EN_THRESHOLD;
52module_param(fctrl_en_thld, uint, S_IRUGO | S_IWUSR);
53
54static unsigned int fctrl_dis_thld = FLOW_CTRL_DISABLE;
55module_param(fctrl_dis_thld, uint, S_IRUGO | S_IWUSR);
56
57unsigned int max_rx_urbs = MAX_RX_URBS;
58module_param(max_rx_urbs, uint, S_IRUGO | S_IWUSR);
59
60unsigned int stop_submit_urb_limit = STOP_SUBMIT_URB_LIMIT;
61module_param(stop_submit_urb_limit, uint, S_IRUGO | S_IWUSR);
62
Hemant Kumar73eff1c2012-01-09 18:49:11 -080063static unsigned tx_urb_mult = 20;
64module_param(tx_urb_mult, uint, S_IRUGO|S_IWUSR);
65
Hemant Kumar14401d52011-11-03 16:40:32 -070066#define TX_HALT BIT(0)
67#define RX_HALT BIT(1)
68#define SUSPENDED BIT(2)
69
70struct data_bridge {
71 struct usb_interface *intf;
72 struct usb_device *udev;
Jack Pham9b0a0e52012-02-28 18:05:14 -080073 int id;
Hemant Kumarc2b17782013-02-03 15:56:29 -080074 char *name;
Jack Pham9b0a0e52012-02-28 18:05:14 -080075
Hemant Kumar14401d52011-11-03 16:40:32 -070076 unsigned int bulk_in;
77 unsigned int bulk_out;
Hemant Kumar06b7e432012-01-19 22:13:50 -080078 int err;
Hemant Kumar14401d52011-11-03 16:40:32 -070079
80 /* keep track of in-flight URBs */
81 struct usb_anchor tx_active;
82 struct usb_anchor rx_active;
83
84 /* keep track of outgoing URBs during suspend */
85 struct usb_anchor delayed;
86
87 struct list_head rx_idle;
88 struct sk_buff_head rx_done;
89
90 struct workqueue_struct *wq;
91 struct work_struct process_rx_w;
92
93 struct bridge *brdg;
94
95 /* work queue function for handling halt conditions */
96 struct work_struct kevent;
97
98 unsigned long flags;
99
100 struct platform_device *pdev;
101
102 /* counters */
103 atomic_t pending_txurbs;
104 unsigned int txurb_drp_cnt;
105 unsigned long to_host;
106 unsigned long to_modem;
107 unsigned int tx_throttled_cnt;
108 unsigned int tx_unthrottled_cnt;
109 unsigned int rx_throttled_cnt;
110 unsigned int rx_unthrottled_cnt;
111};
112
113static struct data_bridge *__dev[MAX_BRIDGE_DEVICES];
114
115/* counter used for indexing data bridge devices */
116static int ch_id;
117
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800118static unsigned int get_timestamp(void);
119static void dbg_timestamp(char *, struct sk_buff *);
Hemant Kumar14401d52011-11-03 16:40:32 -0700120static int submit_rx_urb(struct data_bridge *dev, struct urb *urb,
121 gfp_t flags);
122
Hemant Kumarc2b17782013-02-03 15:56:29 -0800123static int get_data_bridge_chid(char *xport_name)
124{
125 struct data_bridge *dev;
126 int i;
127
128 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
129 dev = __dev[i];
130 if (!strncmp(dev->name, xport_name, BRIDGE_NAME_MAX_LEN))
131 return i;
132 }
133
134 return -ENODEV;
135}
136
Hemant Kumar14401d52011-11-03 16:40:32 -0700137static inline bool rx_halted(struct data_bridge *dev)
138{
139 return test_bit(RX_HALT, &dev->flags);
140}
141
142static inline bool rx_throttled(struct bridge *brdg)
143{
144 return test_bit(RX_THROTTLED, &brdg->flags);
145}
146
Hemant Kumar262682a2013-02-01 09:46:45 -0800147static void free_rx_urbs(struct data_bridge *dev)
148{
149 struct list_head *head;
150 struct urb *rx_urb;
151 unsigned long flags;
152
153 head = &dev->rx_idle;
154 spin_lock_irqsave(&dev->rx_done.lock, flags);
155 while (!list_empty(head)) {
156 rx_urb = list_entry(head->next, struct urb, urb_list);
157 list_del(&rx_urb->urb_list);
158 usb_free_urb(rx_urb);
159 }
160 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
161}
162
Hemant Kumar14401d52011-11-03 16:40:32 -0700163int data_bridge_unthrottle_rx(unsigned int id)
164{
165 struct data_bridge *dev;
166
167 if (id >= MAX_BRIDGE_DEVICES)
168 return -EINVAL;
169
170 dev = __dev[id];
Jack Phama7c92672011-11-29 16:38:21 -0800171 if (!dev || !dev->brdg)
Hemant Kumar14401d52011-11-03 16:40:32 -0700172 return -ENODEV;
173
174 dev->rx_unthrottled_cnt++;
175 queue_work(dev->wq, &dev->process_rx_w);
176
177 return 0;
178}
179EXPORT_SYMBOL(data_bridge_unthrottle_rx);
180
181static void data_bridge_process_rx(struct work_struct *work)
182{
183 int retval;
184 unsigned long flags;
185 struct urb *rx_idle;
186 struct sk_buff *skb;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800187 struct timestamp_info *info;
Hemant Kumar14401d52011-11-03 16:40:32 -0700188 struct data_bridge *dev =
189 container_of(work, struct data_bridge, process_rx_w);
190
191 struct bridge *brdg = dev->brdg;
192
193 if (!brdg || !brdg->ops.send_pkt || rx_halted(dev))
194 return;
195
196 while (!rx_throttled(brdg) && (skb = skb_dequeue(&dev->rx_done))) {
197 dev->to_host++;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800198 info = (struct timestamp_info *)skb->cb;
199 info->rx_done_sent = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700200 /* hand off sk_buff to client,they'll need to free it */
201 retval = brdg->ops.send_pkt(brdg->ctx, skb, skb->len);
202 if (retval == -ENOTCONN || retval == -EINVAL) {
203 return;
204 } else if (retval == -EBUSY) {
205 dev->rx_throttled_cnt++;
206 break;
207 }
208 }
209
210 spin_lock_irqsave(&dev->rx_done.lock, flags);
Hemant Kumar14401d52011-11-03 16:40:32 -0700211 while (!list_empty(&dev->rx_idle)) {
Hemant Kumarfd2d5e52011-12-22 17:51:53 -0800212 if (dev->rx_done.qlen > stop_submit_urb_limit)
213 break;
Hemant Kumar14401d52011-11-03 16:40:32 -0700214
215 rx_idle = list_first_entry(&dev->rx_idle, struct urb, urb_list);
216 list_del(&rx_idle->urb_list);
217 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
218 retval = submit_rx_urb(dev, rx_idle, GFP_KERNEL);
219 spin_lock_irqsave(&dev->rx_done.lock, flags);
Hemant Kumar184765b2011-12-27 13:20:45 -0800220 if (retval) {
221 list_add_tail(&rx_idle->urb_list, &dev->rx_idle);
Hemant Kumar14401d52011-11-03 16:40:32 -0700222 break;
Hemant Kumar184765b2011-12-27 13:20:45 -0800223 }
Hemant Kumar14401d52011-11-03 16:40:32 -0700224 }
225 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
226}
227
228static void data_bridge_read_cb(struct urb *urb)
229{
230 struct bridge *brdg;
231 struct sk_buff *skb = urb->context;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800232 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
233 struct data_bridge *dev = info->dev;
Hemant Kumar14401d52011-11-03 16:40:32 -0700234 bool queue = 0;
235
Hemant Kumar262682a2013-02-01 09:46:45 -0800236 /*usb device disconnect*/
237 if (urb->dev->state == USB_STATE_NOTATTACHED)
238 urb->status = -ECONNRESET;
239
Hemant Kumar14401d52011-11-03 16:40:32 -0700240 brdg = dev->brdg;
Hemant Kumar14401d52011-11-03 16:40:32 -0700241 skb_put(skb, urb->actual_length);
242
243 switch (urb->status) {
244 case 0: /* success */
245 queue = 1;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800246 info->rx_done = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700247 spin_lock(&dev->rx_done.lock);
248 __skb_queue_tail(&dev->rx_done, skb);
249 spin_unlock(&dev->rx_done.lock);
250 break;
251
252 /*do not resubmit*/
253 case -EPIPE:
254 set_bit(RX_HALT, &dev->flags);
Jack Phame8741502012-06-13 17:34:07 -0700255 dev_err(&dev->intf->dev, "%s: epout halted\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -0700256 schedule_work(&dev->kevent);
257 /* FALLTHROUGH */
258 case -ESHUTDOWN:
259 case -ENOENT: /* suspended */
260 case -ECONNRESET: /* unplug */
261 case -EPROTO:
262 dev_kfree_skb_any(skb);
263 break;
264
265 /*resubmit */
266 case -EOVERFLOW: /*babble error*/
267 default:
268 queue = 1;
269 dev_kfree_skb_any(skb);
270 pr_debug_ratelimited("%s: non zero urb status = %d\n",
271 __func__, urb->status);
272 break;
273 }
274
275 spin_lock(&dev->rx_done.lock);
276 list_add_tail(&urb->urb_list, &dev->rx_idle);
277 spin_unlock(&dev->rx_done.lock);
278
279 if (queue)
280 queue_work(dev->wq, &dev->process_rx_w);
281}
282
283static int submit_rx_urb(struct data_bridge *dev, struct urb *rx_urb,
284 gfp_t flags)
285{
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800286 struct sk_buff *skb;
287 struct timestamp_info *info;
288 int retval = -EINVAL;
289 unsigned int created;
Hemant Kumar14401d52011-11-03 16:40:32 -0700290
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800291 created = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700292 skb = alloc_skb(RMNET_RX_BUFSIZE, flags);
Hemant Kumar184765b2011-12-27 13:20:45 -0800293 if (!skb)
Hemant Kumar14401d52011-11-03 16:40:32 -0700294 return -ENOMEM;
Hemant Kumar14401d52011-11-03 16:40:32 -0700295
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800296 info = (struct timestamp_info *)skb->cb;
297 info->dev = dev;
298 info->created = created;
Hemant Kumar14401d52011-11-03 16:40:32 -0700299
300 usb_fill_bulk_urb(rx_urb, dev->udev, dev->bulk_in,
301 skb->data, RMNET_RX_BUFSIZE,
302 data_bridge_read_cb, skb);
303
304 if (test_bit(SUSPENDED, &dev->flags))
305 goto suspended;
306
307 usb_anchor_urb(rx_urb, &dev->rx_active);
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800308 info->rx_queued = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700309 retval = usb_submit_urb(rx_urb, flags);
310 if (retval)
311 goto fail;
312
Hemant Kumarb72233f2012-04-04 13:21:44 -0700313 usb_mark_last_busy(dev->udev);
Hemant Kumar14401d52011-11-03 16:40:32 -0700314 return 0;
315fail:
316 usb_unanchor_urb(rx_urb);
317suspended:
318 dev_kfree_skb_any(skb);
Hemant Kumar184765b2011-12-27 13:20:45 -0800319
Hemant Kumar14401d52011-11-03 16:40:32 -0700320 return retval;
321}
322
323static int data_bridge_prepare_rx(struct data_bridge *dev)
324{
325 int i;
326 struct urb *rx_urb;
Hemant Kumar262682a2013-02-01 09:46:45 -0800327 int retval = 0;
Hemant Kumar14401d52011-11-03 16:40:32 -0700328
329 for (i = 0; i < max_rx_urbs; i++) {
330 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
Hemant Kumar262682a2013-02-01 09:46:45 -0800331 if (!rx_urb) {
332 retval = -ENOMEM;
333 goto free_urbs;
334 }
Hemant Kumar14401d52011-11-03 16:40:32 -0700335
336 list_add_tail(&rx_urb->urb_list, &dev->rx_idle);
337 }
Hemant Kumar262682a2013-02-01 09:46:45 -0800338
339 return 0;
340
341free_urbs:
342 free_rx_urbs(dev);
343 return retval;
Hemant Kumar14401d52011-11-03 16:40:32 -0700344}
345
346int data_bridge_open(struct bridge *brdg)
347{
348 struct data_bridge *dev;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800349 int ch_id;
Hemant Kumar14401d52011-11-03 16:40:32 -0700350
351 if (!brdg) {
352 err("bridge is null\n");
353 return -EINVAL;
354 }
355
Hemant Kumarc2b17782013-02-03 15:56:29 -0800356 ch_id = get_data_bridge_chid(brdg->name);
357 if (ch_id < 0 || ch_id >= MAX_BRIDGE_DEVICES) {
358 err("%s: %s dev not found\n", __func__, brdg->name);
359 return ch_id;
Hemant Kumar14401d52011-11-03 16:40:32 -0700360 }
361
Hemant Kumarc2b17782013-02-03 15:56:29 -0800362 brdg->ch_id = ch_id;
363
364 dev = __dev[ch_id];
365
Jack Phame8741502012-06-13 17:34:07 -0700366 dev_dbg(&dev->intf->dev, "%s: dev:%p\n", __func__, dev);
Hemant Kumar14401d52011-11-03 16:40:32 -0700367
368 dev->brdg = brdg;
Hemant Kumar06b7e432012-01-19 22:13:50 -0800369 dev->err = 0;
Hemant Kumar14401d52011-11-03 16:40:32 -0700370 atomic_set(&dev->pending_txurbs, 0);
371 dev->to_host = 0;
372 dev->to_modem = 0;
373 dev->txurb_drp_cnt = 0;
374 dev->tx_throttled_cnt = 0;
375 dev->tx_unthrottled_cnt = 0;
376 dev->rx_throttled_cnt = 0;
377 dev->rx_unthrottled_cnt = 0;
378
379 queue_work(dev->wq, &dev->process_rx_w);
380
381 return 0;
382}
383EXPORT_SYMBOL(data_bridge_open);
384
385void data_bridge_close(unsigned int id)
386{
387 struct data_bridge *dev;
388 struct sk_buff *skb;
389 unsigned long flags;
390
391 if (id >= MAX_BRIDGE_DEVICES)
392 return;
393
394 dev = __dev[id];
Jack Phama7c92672011-11-29 16:38:21 -0800395 if (!dev || !dev->brdg)
Hemant Kumar14401d52011-11-03 16:40:32 -0700396 return;
397
Jack Phame8741502012-06-13 17:34:07 -0700398 dev_dbg(&dev->intf->dev, "%s:\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -0700399
Pavankumar Kondeti50f38152013-01-17 16:04:53 +0530400 cancel_work_sync(&dev->kevent);
401 cancel_work_sync(&dev->process_rx_w);
402
Hemant Kumar262682a2013-02-01 09:46:45 -0800403 usb_kill_anchored_urbs(&dev->tx_active);
404 usb_kill_anchored_urbs(&dev->rx_active);
405 usb_kill_anchored_urbs(&dev->delayed);
Hemant Kumar14401d52011-11-03 16:40:32 -0700406
407 spin_lock_irqsave(&dev->rx_done.lock, flags);
408 while ((skb = __skb_dequeue(&dev->rx_done)))
409 dev_kfree_skb_any(skb);
410 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
411
412 dev->brdg = NULL;
413}
414EXPORT_SYMBOL(data_bridge_close);
415
416static void defer_kevent(struct work_struct *work)
417{
418 int status;
419 struct data_bridge *dev =
420 container_of(work, struct data_bridge, kevent);
421
422 if (!dev)
423 return;
424
425 if (test_bit(TX_HALT, &dev->flags)) {
426 usb_unlink_anchored_urbs(&dev->tx_active);
427
428 status = usb_autopm_get_interface(dev->intf);
429 if (status < 0) {
Jack Pham4380e002012-08-30 19:06:24 -0700430 dev_dbg(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700431 "can't acquire interface, status %d\n", status);
432 return;
433 }
434
435 status = usb_clear_halt(dev->udev, dev->bulk_out);
436 usb_autopm_put_interface(dev->intf);
437 if (status < 0 && status != -EPIPE && status != -ESHUTDOWN)
Jack Phame8741502012-06-13 17:34:07 -0700438 dev_err(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700439 "can't clear tx halt, status %d\n", status);
440 else
441 clear_bit(TX_HALT, &dev->flags);
442 }
443
444 if (test_bit(RX_HALT, &dev->flags)) {
445 usb_unlink_anchored_urbs(&dev->rx_active);
446
447 status = usb_autopm_get_interface(dev->intf);
448 if (status < 0) {
Jack Pham4380e002012-08-30 19:06:24 -0700449 dev_dbg(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700450 "can't acquire interface, status %d\n", status);
451 return;
452 }
453
454 status = usb_clear_halt(dev->udev, dev->bulk_in);
455 usb_autopm_put_interface(dev->intf);
456 if (status < 0 && status != -EPIPE && status != -ESHUTDOWN)
Jack Phame8741502012-06-13 17:34:07 -0700457 dev_err(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700458 "can't clear rx halt, status %d\n", status);
459 else {
460 clear_bit(RX_HALT, &dev->flags);
461 if (dev->brdg)
462 queue_work(dev->wq, &dev->process_rx_w);
463 }
464 }
465}
466
467static void data_bridge_write_cb(struct urb *urb)
468{
469 struct sk_buff *skb = urb->context;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800470 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
471 struct data_bridge *dev = info->dev;
Hemant Kumar14401d52011-11-03 16:40:32 -0700472 struct bridge *brdg = dev->brdg;
473 int pending;
474
475 pr_debug("%s: dev:%p\n", __func__, dev);
476
477 switch (urb->status) {
478 case 0: /*success*/
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800479 dbg_timestamp("UL", skb);
Hemant Kumar14401d52011-11-03 16:40:32 -0700480 break;
Hemant Kumar06b7e432012-01-19 22:13:50 -0800481 case -EPROTO:
482 dev->err = -EPROTO;
483 break;
Hemant Kumar14401d52011-11-03 16:40:32 -0700484 case -EPIPE:
485 set_bit(TX_HALT, &dev->flags);
Jack Phame8741502012-06-13 17:34:07 -0700486 dev_err(&dev->intf->dev, "%s: epout halted\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -0700487 schedule_work(&dev->kevent);
488 /* FALLTHROUGH */
489 case -ESHUTDOWN:
490 case -ENOENT: /* suspended */
491 case -ECONNRESET: /* unplug */
492 case -EOVERFLOW: /*babble error*/
493 /* FALLTHROUGH */
494 default:
495 pr_debug_ratelimited("%s: non zero urb status = %d\n",
496 __func__, urb->status);
497 }
498
499 usb_free_urb(urb);
500 dev_kfree_skb_any(skb);
501
502 pending = atomic_dec_return(&dev->pending_txurbs);
503
504 /*flow ctrl*/
505 if (brdg && fctrl_support && pending <= fctrl_dis_thld &&
506 test_and_clear_bit(TX_THROTTLED, &brdg->flags)) {
507 pr_debug_ratelimited("%s: disable flow ctrl: pend urbs:%u\n",
508 __func__, pending);
509 dev->tx_unthrottled_cnt++;
510 if (brdg->ops.unthrottle_tx)
511 brdg->ops.unthrottle_tx(brdg->ctx);
512 }
513
Hemant Kumar262682a2013-02-01 09:46:45 -0800514 /* if we are here after device disconnect
515 * usb_unbind_interface() takes care of
516 * residual pm_autopm_get_interface_* calls
517 */
518 if (urb->dev->state != USB_STATE_NOTATTACHED)
519 usb_autopm_put_interface_async(dev->intf);
Hemant Kumar14401d52011-11-03 16:40:32 -0700520}
521
522int data_bridge_write(unsigned int id, struct sk_buff *skb)
523{
524 int result;
525 int size = skb->len;
526 int pending;
527 struct urb *txurb;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800528 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
Hemant Kumar14401d52011-11-03 16:40:32 -0700529 struct data_bridge *dev = __dev[id];
530 struct bridge *brdg;
531
Hemant Kumar06b7e432012-01-19 22:13:50 -0800532 if (!dev || !dev->brdg || dev->err || !usb_get_intfdata(dev->intf))
Hemant Kumar14401d52011-11-03 16:40:32 -0700533 return -ENODEV;
534
535 brdg = dev->brdg;
Hemant Kumarc8a3d312011-12-27 15:41:32 -0800536 if (!brdg)
537 return -ENODEV;
Hemant Kumar14401d52011-11-03 16:40:32 -0700538
Jack Phame8741502012-06-13 17:34:07 -0700539 dev_dbg(&dev->intf->dev, "%s: write (%d bytes)\n", __func__, skb->len);
Hemant Kumar14401d52011-11-03 16:40:32 -0700540
541 result = usb_autopm_get_interface(dev->intf);
542 if (result < 0) {
Jack Pham4380e002012-08-30 19:06:24 -0700543 dev_dbg(&dev->intf->dev, "%s: resume failure\n", __func__);
Hemant Kumar93387bd2012-06-08 15:55:26 -0700544 goto pm_error;
Hemant Kumar14401d52011-11-03 16:40:32 -0700545 }
546
547 txurb = usb_alloc_urb(0, GFP_KERNEL);
548 if (!txurb) {
Jack Phame8741502012-06-13 17:34:07 -0700549 dev_err(&dev->intf->dev, "%s: error allocating read urb\n",
Hemant Kumar14401d52011-11-03 16:40:32 -0700550 __func__);
551 result = -ENOMEM;
552 goto error;
553 }
554
555 /* store dev pointer in skb */
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800556 info->dev = dev;
557 info->tx_queued = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700558
559 usb_fill_bulk_urb(txurb, dev->udev, dev->bulk_out,
560 skb->data, skb->len, data_bridge_write_cb, skb);
561
Jack Pham5a10c6f2012-06-26 11:41:28 -0700562 txurb->transfer_flags |= URB_ZERO_PACKET;
563
Hemant Kumar14401d52011-11-03 16:40:32 -0700564 if (test_bit(SUSPENDED, &dev->flags)) {
565 usb_anchor_urb(txurb, &dev->delayed);
566 goto free_urb;
567 }
568
569 pending = atomic_inc_return(&dev->pending_txurbs);
570 usb_anchor_urb(txurb, &dev->tx_active);
571
Hemant Kumar73eff1c2012-01-09 18:49:11 -0800572 if (atomic_read(&dev->pending_txurbs) % tx_urb_mult)
573 txurb->transfer_flags |= URB_NO_INTERRUPT;
574
Hemant Kumar14401d52011-11-03 16:40:32 -0700575 result = usb_submit_urb(txurb, GFP_KERNEL);
576 if (result < 0) {
577 usb_unanchor_urb(txurb);
578 atomic_dec(&dev->pending_txurbs);
Jack Phame8741502012-06-13 17:34:07 -0700579 dev_err(&dev->intf->dev, "%s: submit URB error %d\n",
Hemant Kumar14401d52011-11-03 16:40:32 -0700580 __func__, result);
581 goto free_urb;
582 }
583
584 dev->to_modem++;
Jack Phame8741502012-06-13 17:34:07 -0700585 dev_dbg(&dev->intf->dev, "%s: pending_txurbs: %u\n", __func__, pending);
Hemant Kumar14401d52011-11-03 16:40:32 -0700586
587 /* flow control: last urb submitted but return -EBUSY */
588 if (fctrl_support && pending > fctrl_en_thld) {
589 set_bit(TX_THROTTLED, &brdg->flags);
590 dev->tx_throttled_cnt++;
591 pr_debug_ratelimited("%s: enable flow ctrl pend txurbs:%u\n",
592 __func__, pending);
593 return -EBUSY;
594 }
595
596 return size;
597
598free_urb:
599 usb_free_urb(txurb);
600error:
601 dev->txurb_drp_cnt++;
602 usb_autopm_put_interface(dev->intf);
Hemant Kumar93387bd2012-06-08 15:55:26 -0700603pm_error:
Hemant Kumar14401d52011-11-03 16:40:32 -0700604 return result;
605}
606EXPORT_SYMBOL(data_bridge_write);
607
608static int data_bridge_resume(struct data_bridge *dev)
609{
610 struct urb *urb;
611 int retval;
612
Jack Pham9b0a0e52012-02-28 18:05:14 -0800613 if (!test_and_clear_bit(SUSPENDED, &dev->flags))
614 return 0;
615
Hemant Kumar14401d52011-11-03 16:40:32 -0700616 while ((urb = usb_get_from_anchor(&dev->delayed))) {
617 usb_anchor_urb(urb, &dev->tx_active);
618 atomic_inc(&dev->pending_txurbs);
619 retval = usb_submit_urb(urb, GFP_ATOMIC);
620 if (retval < 0) {
621 atomic_dec(&dev->pending_txurbs);
622 usb_unanchor_urb(urb);
623
624 /* TODO: need to free urb data */
625 usb_scuttle_anchored_urbs(&dev->delayed);
626 break;
627 }
628 dev->to_modem++;
629 dev->txurb_drp_cnt--;
630 }
631
Hemant Kumar14401d52011-11-03 16:40:32 -0700632 if (dev->brdg)
633 queue_work(dev->wq, &dev->process_rx_w);
634
635 return 0;
636}
637
638static int bridge_resume(struct usb_interface *iface)
639{
640 int retval = 0;
641 int oldstate;
642 struct data_bridge *dev = usb_get_intfdata(iface);
Hemant Kumar14401d52011-11-03 16:40:32 -0700643
644 oldstate = iface->dev.power.power_state.event;
645 iface->dev.power.power_state.event = PM_EVENT_ON;
646
Jack Pham9b0a0e52012-02-28 18:05:14 -0800647 if (oldstate & PM_EVENT_SUSPEND) {
648 retval = data_bridge_resume(dev);
649 if (!retval)
650 retval = ctrl_bridge_resume(dev->id);
Hemant Kumar14401d52011-11-03 16:40:32 -0700651 }
Jack Pham9b0a0e52012-02-28 18:05:14 -0800652
Hemant Kumar14401d52011-11-03 16:40:32 -0700653 return retval;
654}
655
656static int data_bridge_suspend(struct data_bridge *dev, pm_message_t message)
657{
658 if (atomic_read(&dev->pending_txurbs) &&
659 (message.event & PM_EVENT_AUTO))
660 return -EBUSY;
661
662 set_bit(SUSPENDED, &dev->flags);
663
664 usb_kill_anchored_urbs(&dev->tx_active);
665 usb_kill_anchored_urbs(&dev->rx_active);
666
667 return 0;
668}
669
670static int bridge_suspend(struct usb_interface *intf, pm_message_t message)
671{
672 int retval;
673 struct data_bridge *dev = usb_get_intfdata(intf);
Hemant Kumar14401d52011-11-03 16:40:32 -0700674
675 retval = data_bridge_suspend(dev, message);
676 if (!retval) {
Jack Pham9b0a0e52012-02-28 18:05:14 -0800677 retval = ctrl_bridge_suspend(dev->id);
678 intf->dev.power.power_state.event = message.event;
Hemant Kumar14401d52011-11-03 16:40:32 -0700679 }
Jack Pham9b0a0e52012-02-28 18:05:14 -0800680
Hemant Kumar14401d52011-11-03 16:40:32 -0700681 return retval;
682}
683
684static int data_bridge_probe(struct usb_interface *iface,
685 struct usb_host_endpoint *bulk_in,
Hemant Kumarc2b17782013-02-03 15:56:29 -0800686 struct usb_host_endpoint *bulk_out, char *name, int id)
Hemant Kumar14401d52011-11-03 16:40:32 -0700687{
688 struct data_bridge *dev;
Hemant Kumar262682a2013-02-01 09:46:45 -0800689 int retval;
Hemant Kumar14401d52011-11-03 16:40:32 -0700690
Hemant Kumar262682a2013-02-01 09:46:45 -0800691 dev = __dev[id];
Hemant Kumar14401d52011-11-03 16:40:32 -0700692 if (!dev) {
Hemant Kumar262682a2013-02-01 09:46:45 -0800693 err("%s: device not found\n", __func__);
694 return -ENODEV;
Hemant Kumar14401d52011-11-03 16:40:32 -0700695 }
696
Hemant Kumarc2b17782013-02-03 15:56:29 -0800697 dev->pdev = platform_device_alloc(name, -1);
Hemant Kumar14401d52011-11-03 16:40:32 -0700698 if (!dev->pdev) {
699 err("%s: unable to allocate platform device\n", __func__);
700 kfree(dev);
701 return -ENOMEM;
702 }
703
Hemant Kumar262682a2013-02-01 09:46:45 -0800704 dev->flags = 0;
Jack Pham9b0a0e52012-02-28 18:05:14 -0800705 dev->id = id;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800706 dev->name = name;
Hemant Kumar14401d52011-11-03 16:40:32 -0700707 dev->udev = interface_to_usbdev(iface);
708 dev->intf = iface;
709
710 dev->bulk_in = usb_rcvbulkpipe(dev->udev,
711 bulk_in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
712
713 dev->bulk_out = usb_sndbulkpipe(dev->udev,
714 bulk_out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
715
716 usb_set_intfdata(iface, dev);
717
Hemant Kumar14401d52011-11-03 16:40:32 -0700718 /*allocate list of rx urbs*/
Hemant Kumar262682a2013-02-01 09:46:45 -0800719 retval = data_bridge_prepare_rx(dev);
720 if (retval) {
721 platform_device_put(dev->pdev);
722 return retval;
723 }
Hemant Kumar14401d52011-11-03 16:40:32 -0700724
725 platform_device_add(dev->pdev);
726
727 return 0;
728}
729
730#if defined(CONFIG_DEBUG_FS)
731#define DEBUG_BUF_SIZE 1024
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800732
733static unsigned int record_timestamp;
734module_param(record_timestamp, uint, S_IRUGO | S_IWUSR);
735
736static struct timestamp_buf dbg_data = {
737 .idx = 0,
738 .lck = __RW_LOCK_UNLOCKED(lck)
739};
740
741/*get_timestamp - returns time of day in us */
742static unsigned int get_timestamp(void)
743{
744 struct timeval tval;
745 unsigned int stamp;
746
747 if (!record_timestamp)
748 return 0;
749
750 do_gettimeofday(&tval);
751 /* 2^32 = 4294967296. Limit to 4096s. */
752 stamp = tval.tv_sec & 0xFFF;
753 stamp = stamp * 1000000 + tval.tv_usec;
754 return stamp;
755}
756
757static void dbg_inc(unsigned *idx)
758{
759 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
760}
761
762/**
763* dbg_timestamp - Stores timestamp values of a SKB life cycle
764* to debug buffer
765* @event: "UL": Uplink Data
766* @skb: SKB used to store timestamp values to debug buffer
767*/
768static void dbg_timestamp(char *event, struct sk_buff * skb)
769{
770 unsigned long flags;
771 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
772
773 if (!record_timestamp)
774 return;
775
776 write_lock_irqsave(&dbg_data.lck, flags);
777
778 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
779 "%p %u[%s] %u %u %u %u %u %u\n",
780 skb, skb->len, event, info->created, info->rx_queued,
781 info->rx_done, info->rx_done_sent, info->tx_queued,
782 get_timestamp());
783
784 dbg_inc(&dbg_data.idx);
785
786 write_unlock_irqrestore(&dbg_data.lck, flags);
787}
788
789/* show_timestamp: displays the timestamp buffer */
790static ssize_t show_timestamp(struct file *file, char __user *ubuf,
791 size_t count, loff_t *ppos)
792{
793 unsigned long flags;
794 unsigned i;
795 unsigned j = 0;
796 char *buf;
797 int ret = 0;
798
799 if (!record_timestamp)
800 return 0;
801
802 buf = kzalloc(sizeof(char) * 4 * DEBUG_BUF_SIZE, GFP_KERNEL);
803 if (!buf)
804 return -ENOMEM;
805
806 read_lock_irqsave(&dbg_data.lck, flags);
807
808 i = dbg_data.idx;
809 for (dbg_inc(&i); i != dbg_data.idx; dbg_inc(&i)) {
810 if (!strnlen(dbg_data.buf[i], DBG_DATA_MSG))
811 continue;
812 j += scnprintf(buf + j, (4 * DEBUG_BUF_SIZE) - j,
813 "%s\n", dbg_data.buf[i]);
814 }
815
816 read_unlock_irqrestore(&dbg_data.lck, flags);
817
818 ret = simple_read_from_buffer(ubuf, count, ppos, buf, j);
819
820 kfree(buf);
821
822 return ret;
823}
824
825const struct file_operations data_timestamp_ops = {
826 .read = show_timestamp,
827};
828
Hemant Kumar14401d52011-11-03 16:40:32 -0700829static ssize_t data_bridge_read_stats(struct file *file, char __user *ubuf,
830 size_t count, loff_t *ppos)
831{
832 struct data_bridge *dev;
833 char *buf;
834 int ret;
835 int i;
836 int temp = 0;
837
838 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
839 if (!buf)
840 return -ENOMEM;
841
842 for (i = 0; i < ch_id; i++) {
843 dev = __dev[i];
844 if (!dev)
845 continue;
846
847 temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
848 "\nName#%s dev %p\n"
849 "pending tx urbs: %u\n"
850 "tx urb drp cnt: %u\n"
851 "to host: %lu\n"
852 "to mdm: %lu\n"
853 "tx throttled cnt: %u\n"
854 "tx unthrottled cnt: %u\n"
855 "rx throttled cnt: %u\n"
856 "rx unthrottled cnt: %u\n"
857 "rx done skb qlen: %u\n"
Hemant Kumar06b7e432012-01-19 22:13:50 -0800858 "dev err: %d\n"
Hemant Kumar14401d52011-11-03 16:40:32 -0700859 "suspended: %d\n"
860 "TX_HALT: %d\n"
861 "RX_HALT: %d\n",
862 dev->pdev->name, dev,
863 atomic_read(&dev->pending_txurbs),
864 dev->txurb_drp_cnt,
865 dev->to_host,
866 dev->to_modem,
867 dev->tx_throttled_cnt,
868 dev->tx_unthrottled_cnt,
869 dev->rx_throttled_cnt,
870 dev->rx_unthrottled_cnt,
871 dev->rx_done.qlen,
Hemant Kumar06b7e432012-01-19 22:13:50 -0800872 dev->err,
Hemant Kumar14401d52011-11-03 16:40:32 -0700873 test_bit(SUSPENDED, &dev->flags),
874 test_bit(TX_HALT, &dev->flags),
875 test_bit(RX_HALT, &dev->flags));
876
877 }
878
879 ret = simple_read_from_buffer(ubuf, count, ppos, buf, temp);
880
881 kfree(buf);
882
883 return ret;
884}
885
886static ssize_t data_bridge_reset_stats(struct file *file,
887 const char __user *buf, size_t count, loff_t *ppos)
888{
889 struct data_bridge *dev;
890 int i;
891
892 for (i = 0; i < ch_id; i++) {
893 dev = __dev[i];
894 if (!dev)
895 continue;
896
897 dev->to_host = 0;
898 dev->to_modem = 0;
899 dev->txurb_drp_cnt = 0;
900 dev->tx_throttled_cnt = 0;
901 dev->tx_unthrottled_cnt = 0;
902 dev->rx_throttled_cnt = 0;
903 dev->rx_unthrottled_cnt = 0;
904 }
905 return count;
906}
907
908const struct file_operations data_stats_ops = {
909 .read = data_bridge_read_stats,
910 .write = data_bridge_reset_stats,
911};
912
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800913static struct dentry *data_dent;
914static struct dentry *data_dfile_stats;
915static struct dentry *data_dfile_tstamp;
916
Hemant Kumar14401d52011-11-03 16:40:32 -0700917static void data_bridge_debugfs_init(void)
918{
919 data_dent = debugfs_create_dir("data_hsic_bridge", 0);
920 if (IS_ERR(data_dent))
921 return;
922
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800923 data_dfile_stats = debugfs_create_file("status", 0644, data_dent, 0,
924 &data_stats_ops);
925 if (!data_dfile_stats || IS_ERR(data_dfile_stats)) {
926 debugfs_remove(data_dent);
927 return;
928 }
929
930 data_dfile_tstamp = debugfs_create_file("timestamp", 0644, data_dent,
931 0, &data_timestamp_ops);
932 if (!data_dfile_tstamp || IS_ERR(data_dfile_tstamp))
Hemant Kumar14401d52011-11-03 16:40:32 -0700933 debugfs_remove(data_dent);
934}
935
936static void data_bridge_debugfs_exit(void)
937{
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800938 debugfs_remove(data_dfile_stats);
939 debugfs_remove(data_dfile_tstamp);
Hemant Kumar14401d52011-11-03 16:40:32 -0700940 debugfs_remove(data_dent);
941}
942
943#else
944static void data_bridge_debugfs_init(void) { }
945static void data_bridge_debugfs_exit(void) { }
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800946static void dbg_timestamp(char *event, struct sk_buff * skb)
947{
948 return;
949}
950
951static unsigned int get_timestamp(void)
952{
953 return 0;
954}
955
Hemant Kumar14401d52011-11-03 16:40:32 -0700956#endif
957
958static int __devinit
959bridge_probe(struct usb_interface *iface, const struct usb_device_id *id)
960{
961 struct usb_host_endpoint *endpoint = NULL;
962 struct usb_host_endpoint *bulk_in = NULL;
963 struct usb_host_endpoint *bulk_out = NULL;
964 struct usb_host_endpoint *int_in = NULL;
965 struct usb_device *udev;
966 int i;
967 int status = 0;
968 int numends;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800969 char **bname = (char **)id->driver_info;
Hemant Kumar14401d52011-11-03 16:40:32 -0700970
971 if (iface->num_altsetting != 1) {
972 err("%s invalid num_altsetting %u\n",
973 __func__, iface->num_altsetting);
974 return -EINVAL;
975 }
976
Jack Pham1b1ba472012-06-13 16:40:15 -0700977 udev = interface_to_usbdev(iface);
978 usb_get_dev(udev);
979
Hemant Kumar14401d52011-11-03 16:40:32 -0700980 numends = iface->cur_altsetting->desc.bNumEndpoints;
981 for (i = 0; i < numends; i++) {
982 endpoint = iface->cur_altsetting->endpoint + i;
983 if (!endpoint) {
Jack Phame8741502012-06-13 17:34:07 -0700984 dev_err(&iface->dev, "%s: invalid endpoint %u\n",
Hemant Kumar14401d52011-11-03 16:40:32 -0700985 __func__, i);
986 status = -EINVAL;
987 goto out;
988 }
989
990 if (usb_endpoint_is_bulk_in(&endpoint->desc))
991 bulk_in = endpoint;
992 else if (usb_endpoint_is_bulk_out(&endpoint->desc))
993 bulk_out = endpoint;
994 else if (usb_endpoint_is_int_in(&endpoint->desc))
995 int_in = endpoint;
996 }
997
998 if (!bulk_in || !bulk_out || !int_in) {
Jack Phame8741502012-06-13 17:34:07 -0700999 dev_err(&iface->dev, "%s: invalid endpoints\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -07001000 status = -EINVAL;
1001 goto out;
1002 }
1003
Hemant Kumarc2b17782013-02-03 15:56:29 -08001004 status = data_bridge_probe(iface, bulk_in, bulk_out,
1005 bname[BRIDGE_DATA_IDX], ch_id);
Hemant Kumar14401d52011-11-03 16:40:32 -07001006 if (status < 0) {
Jack Phame8741502012-06-13 17:34:07 -07001007 dev_err(&iface->dev, "data_bridge_probe failed %d\n", status);
Hemant Kumar14401d52011-11-03 16:40:32 -07001008 goto out;
1009 }
1010
Hemant Kumarc2b17782013-02-03 15:56:29 -08001011 status = ctrl_bridge_probe(iface, int_in, bname[BRIDGE_CTRL_IDX],
1012 ch_id);
Hemant Kumar14401d52011-11-03 16:40:32 -07001013 if (status < 0) {
Jack Phame8741502012-06-13 17:34:07 -07001014 dev_err(&iface->dev, "ctrl_bridge_probe failed %d\n", status);
Hemant Kumar262682a2013-02-01 09:46:45 -08001015 goto error;
Hemant Kumar14401d52011-11-03 16:40:32 -07001016 }
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001017
Hemant Kumar14401d52011-11-03 16:40:32 -07001018 ch_id++;
1019
1020 return 0;
1021
Hemant Kumar262682a2013-02-01 09:46:45 -08001022error:
1023 platform_device_put(__dev[ch_id]->pdev);
1024 free_rx_urbs(__dev[ch_id]);
Hemant Kumar14401d52011-11-03 16:40:32 -07001025 usb_set_intfdata(iface, NULL);
Hemant Kumar14401d52011-11-03 16:40:32 -07001026out:
1027 usb_put_dev(udev);
1028
1029 return status;
1030}
1031
1032static void bridge_disconnect(struct usb_interface *intf)
1033{
1034 struct data_bridge *dev = usb_get_intfdata(intf);
Hemant Kumar14401d52011-11-03 16:40:32 -07001035
1036 if (!dev) {
1037 err("%s: data device not found\n", __func__);
1038 return;
1039 }
1040
Hemant Kumar14401d52011-11-03 16:40:32 -07001041 ch_id--;
Hemant Kumar45bdca82012-09-02 11:10:35 -07001042 ctrl_bridge_disconnect(dev->id);
Jack Pham1b1ba472012-06-13 16:40:15 -07001043 platform_device_unregister(dev->pdev);
Hemant Kumar14401d52011-11-03 16:40:32 -07001044 usb_set_intfdata(intf, NULL);
Hemant Kumar14401d52011-11-03 16:40:32 -07001045
Hemant Kumar262682a2013-02-01 09:46:45 -08001046 free_rx_urbs(dev);
Hemant Kumar14401d52011-11-03 16:40:32 -07001047
1048 usb_put_dev(dev->udev);
Hemant Kumar14401d52011-11-03 16:40:32 -07001049}
1050
Hemant Kumarc2b17782013-02-03 15:56:29 -08001051/*driver info stores data/ctrl bridge name used to match bridge xport name*/
Hemant Kumar14401d52011-11-03 16:40:32 -07001052static const struct usb_device_id bridge_ids[] = {
Hemant Kumarc2b17782013-02-03 15:56:29 -08001053 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9001, 2),
1054 .driver_info = (unsigned long)serial_hsic_bridge_names,
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001055 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001056 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9001, 3),
1057 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001058 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001059 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9034, 2),
1060 .driver_info = (unsigned long)serial_hsic_bridge_names,
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001061 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001062 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9034, 3),
1063 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
Hemant Kumare97cbb32012-02-24 13:00:57 -08001064 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001065 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 3),
1066 .driver_info = (unsigned long)serial_hsic_bridge_names,
1067 },
1068 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 4),
1069 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
1070 },
1071 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904c, 3),
1072 .driver_info = (unsigned long)serial_hsic_bridge_names,
1073 },
1074 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904c, 5),
1075 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
1076 },
1077 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9075, 3),
1078 .driver_info = (unsigned long)serial_hsic_bridge_names,
1079 },
1080 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9075, 5),
1081 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
Hemant Kumarce3c5bf2012-12-06 15:52:02 -08001082 },
Jack Phamb1ad7152011-12-07 10:58:11 -08001083
1084 { } /* Terminating entry */
Hemant Kumar14401d52011-11-03 16:40:32 -07001085};
Hemant Kumar14401d52011-11-03 16:40:32 -07001086MODULE_DEVICE_TABLE(usb, bridge_ids);
1087
1088static struct usb_driver bridge_driver = {
1089 .name = "mdm_bridge",
1090 .probe = bridge_probe,
1091 .disconnect = bridge_disconnect,
1092 .id_table = bridge_ids,
1093 .suspend = bridge_suspend,
1094 .resume = bridge_resume,
1095 .supports_autosuspend = 1,
1096};
1097
1098static int __init bridge_init(void)
1099{
Hemant Kumar262682a2013-02-01 09:46:45 -08001100 struct data_bridge *dev;
1101 int ret;
1102 int i = 0;
1103
1104 ret = ctrl_bridge_init();
1105 if (ret)
1106 return ret;
1107
1108 bridge_wq = create_singlethread_workqueue("mdm_bridge");
1109 if (!bridge_wq) {
1110 pr_err("%s: Unable to create workqueue:bridge\n", __func__);
1111 ret = -ENOMEM;
1112 goto free_ctrl;
1113 }
1114
1115 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
1116
1117 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1118 if (!dev) {
1119 err("%s: unable to allocate dev\n", __func__);
1120 ret = -ENOMEM;
1121 goto error;
1122 }
1123
1124 dev->wq = bridge_wq;
1125
Hemant Kumarc2b17782013-02-03 15:56:29 -08001126 /*transport name will be set during probe*/
1127 dev->name = "";
1128
Hemant Kumar262682a2013-02-01 09:46:45 -08001129 init_usb_anchor(&dev->tx_active);
1130 init_usb_anchor(&dev->rx_active);
1131 init_usb_anchor(&dev->delayed);
1132
1133 INIT_LIST_HEAD(&dev->rx_idle);
1134
1135 skb_queue_head_init(&dev->rx_done);
1136
1137 INIT_WORK(&dev->kevent, defer_kevent);
1138 INIT_WORK(&dev->process_rx_w, data_bridge_process_rx);
1139
1140 __dev[i] = dev;
1141 }
Hemant Kumar14401d52011-11-03 16:40:32 -07001142
1143 ret = usb_register(&bridge_driver);
1144 if (ret) {
1145 err("%s: unable to register mdm_bridge driver", __func__);
Hemant Kumar262682a2013-02-01 09:46:45 -08001146 goto error;
Hemant Kumar14401d52011-11-03 16:40:32 -07001147 }
1148
1149 data_bridge_debugfs_init();
1150
1151 return 0;
Hemant Kumar262682a2013-02-01 09:46:45 -08001152
1153error:
1154 while (--i >= 0) {
1155 kfree(__dev[i]);
1156 __dev[i] = NULL;
1157 }
1158 destroy_workqueue(bridge_wq);
1159free_ctrl:
1160 ctrl_bridge_exit();
1161 return ret;
Hemant Kumar14401d52011-11-03 16:40:32 -07001162}
1163
1164static void __exit bridge_exit(void)
1165{
Hemant Kumar262682a2013-02-01 09:46:45 -08001166 int i;
1167
1168 usb_deregister(&bridge_driver);
Hemant Kumar14401d52011-11-03 16:40:32 -07001169 data_bridge_debugfs_exit();
1170 destroy_workqueue(bridge_wq);
Hemant Kumar262682a2013-02-01 09:46:45 -08001171
1172 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
1173 kfree(__dev[i]);
1174 __dev[i] = NULL;
1175 }
1176
1177 ctrl_bridge_exit();
Hemant Kumar14401d52011-11-03 16:40:32 -07001178}
1179
1180module_init(bridge_init);
1181module_exit(bridge_exit);
1182
1183MODULE_DESCRIPTION("Qualcomm modem data bridge driver");
1184MODULE_LICENSE("GPL v2");