blob: eea217ae83c734d066d20b5e8b5398daefbd9b79 [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
Hemant Kumar67107002013-02-11 13:24:08 -080046/*for xport : HSUSB*/
47static const char * const serial_hsusb_bridge_names[] = {
48 "serial_hsusb_data",
49 "serial_hsusb_ctrl",
50};
51
52static const char * const rmnet_hsusb_bridge_names[] = {
53 "rmnet_hsusb_data",
54 "rmnet_hsusb_ctrl",
55};
56
57/* since driver supports multiple instances, on smp systems
58 * probe might get called from multiple cores, hence use lock
59 * to identify unclaimed bridge device instance
60 */
61static DEFINE_MUTEX(brdg_claim_lock);
62
Hemant Kumar14401d52011-11-03 16:40:32 -070063static struct workqueue_struct *bridge_wq;
64
65static unsigned int fctrl_support = FLOW_CTRL_SUPPORT;
66module_param(fctrl_support, uint, S_IRUGO | S_IWUSR);
67
68static unsigned int fctrl_en_thld = FLOW_CTRL_EN_THRESHOLD;
69module_param(fctrl_en_thld, uint, S_IRUGO | S_IWUSR);
70
71static unsigned int fctrl_dis_thld = FLOW_CTRL_DISABLE;
72module_param(fctrl_dis_thld, uint, S_IRUGO | S_IWUSR);
73
74unsigned int max_rx_urbs = MAX_RX_URBS;
75module_param(max_rx_urbs, uint, S_IRUGO | S_IWUSR);
76
77unsigned int stop_submit_urb_limit = STOP_SUBMIT_URB_LIMIT;
78module_param(stop_submit_urb_limit, uint, S_IRUGO | S_IWUSR);
79
Hemant Kumar73eff1c2012-01-09 18:49:11 -080080static unsigned tx_urb_mult = 20;
81module_param(tx_urb_mult, uint, S_IRUGO|S_IWUSR);
82
Hemant Kumar67107002013-02-11 13:24:08 -080083#define TX_HALT 0
84#define RX_HALT 1
85#define SUSPENDED 2
86#define CLAIMED 3
Hemant Kumar14401d52011-11-03 16:40:32 -070087
88struct data_bridge {
89 struct usb_interface *intf;
90 struct usb_device *udev;
Jack Pham9b0a0e52012-02-28 18:05:14 -080091 int id;
Hemant Kumarc2b17782013-02-03 15:56:29 -080092 char *name;
Jack Pham9b0a0e52012-02-28 18:05:14 -080093
Hemant Kumar14401d52011-11-03 16:40:32 -070094 unsigned int bulk_in;
95 unsigned int bulk_out;
Hemant Kumar06b7e432012-01-19 22:13:50 -080096 int err;
Hemant Kumar14401d52011-11-03 16:40:32 -070097
98 /* keep track of in-flight URBs */
99 struct usb_anchor tx_active;
100 struct usb_anchor rx_active;
101
Hemant Kumar14401d52011-11-03 16:40:32 -0700102 struct list_head rx_idle;
103 struct sk_buff_head rx_done;
104
105 struct workqueue_struct *wq;
106 struct work_struct process_rx_w;
107
108 struct bridge *brdg;
109
110 /* work queue function for handling halt conditions */
111 struct work_struct kevent;
112
113 unsigned long flags;
114
115 struct platform_device *pdev;
116
117 /* counters */
118 atomic_t pending_txurbs;
119 unsigned int txurb_drp_cnt;
120 unsigned long to_host;
121 unsigned long to_modem;
122 unsigned int tx_throttled_cnt;
123 unsigned int tx_unthrottled_cnt;
124 unsigned int rx_throttled_cnt;
125 unsigned int rx_unthrottled_cnt;
126};
127
128static struct data_bridge *__dev[MAX_BRIDGE_DEVICES];
129
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800130static unsigned int get_timestamp(void);
131static void dbg_timestamp(char *, struct sk_buff *);
Hemant Kumar14401d52011-11-03 16:40:32 -0700132static int submit_rx_urb(struct data_bridge *dev, struct urb *urb,
133 gfp_t flags);
134
Hemant Kumar67107002013-02-11 13:24:08 -0800135/* Find an unclaimed bridge device instance */
136static int get_bridge_dev_idx(void)
137{
138 struct data_bridge *dev;
139 int i;
140
141 mutex_lock(&brdg_claim_lock);
142 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
143 dev = __dev[i];
144 if (!test_bit(CLAIMED, &dev->flags)) {
145 set_bit(CLAIMED, &dev->flags);
146 mutex_unlock(&brdg_claim_lock);
147 return i;
148 }
149 }
150 mutex_unlock(&brdg_claim_lock);
151
152 return -ENODEV;
153}
154
Hemant Kumarc2b17782013-02-03 15:56:29 -0800155static int get_data_bridge_chid(char *xport_name)
156{
157 struct data_bridge *dev;
158 int i;
159
160 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
161 dev = __dev[i];
162 if (!strncmp(dev->name, xport_name, BRIDGE_NAME_MAX_LEN))
163 return i;
164 }
165
166 return -ENODEV;
167}
168
Hemant Kumar14401d52011-11-03 16:40:32 -0700169static inline bool rx_halted(struct data_bridge *dev)
170{
171 return test_bit(RX_HALT, &dev->flags);
172}
173
174static inline bool rx_throttled(struct bridge *brdg)
175{
176 return test_bit(RX_THROTTLED, &brdg->flags);
177}
178
Hemant Kumar262682a2013-02-01 09:46:45 -0800179static void free_rx_urbs(struct data_bridge *dev)
180{
181 struct list_head *head;
182 struct urb *rx_urb;
183 unsigned long flags;
184
185 head = &dev->rx_idle;
186 spin_lock_irqsave(&dev->rx_done.lock, flags);
187 while (!list_empty(head)) {
188 rx_urb = list_entry(head->next, struct urb, urb_list);
189 list_del(&rx_urb->urb_list);
190 usb_free_urb(rx_urb);
191 }
192 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
193}
194
Hemant Kumar14401d52011-11-03 16:40:32 -0700195int data_bridge_unthrottle_rx(unsigned int id)
196{
197 struct data_bridge *dev;
198
199 if (id >= MAX_BRIDGE_DEVICES)
200 return -EINVAL;
201
202 dev = __dev[id];
Jack Phama7c92672011-11-29 16:38:21 -0800203 if (!dev || !dev->brdg)
Hemant Kumar14401d52011-11-03 16:40:32 -0700204 return -ENODEV;
205
206 dev->rx_unthrottled_cnt++;
207 queue_work(dev->wq, &dev->process_rx_w);
208
209 return 0;
210}
211EXPORT_SYMBOL(data_bridge_unthrottle_rx);
212
213static void data_bridge_process_rx(struct work_struct *work)
214{
215 int retval;
216 unsigned long flags;
217 struct urb *rx_idle;
218 struct sk_buff *skb;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800219 struct timestamp_info *info;
Hemant Kumar14401d52011-11-03 16:40:32 -0700220 struct data_bridge *dev =
221 container_of(work, struct data_bridge, process_rx_w);
222
223 struct bridge *brdg = dev->brdg;
224
225 if (!brdg || !brdg->ops.send_pkt || rx_halted(dev))
226 return;
227
228 while (!rx_throttled(brdg) && (skb = skb_dequeue(&dev->rx_done))) {
229 dev->to_host++;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800230 info = (struct timestamp_info *)skb->cb;
231 info->rx_done_sent = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700232 /* hand off sk_buff to client,they'll need to free it */
233 retval = brdg->ops.send_pkt(brdg->ctx, skb, skb->len);
234 if (retval == -ENOTCONN || retval == -EINVAL) {
235 return;
236 } else if (retval == -EBUSY) {
237 dev->rx_throttled_cnt++;
238 break;
239 }
240 }
241
242 spin_lock_irqsave(&dev->rx_done.lock, flags);
Hemant Kumar14401d52011-11-03 16:40:32 -0700243 while (!list_empty(&dev->rx_idle)) {
Hemant Kumarfd2d5e52011-12-22 17:51:53 -0800244 if (dev->rx_done.qlen > stop_submit_urb_limit)
245 break;
Hemant Kumar14401d52011-11-03 16:40:32 -0700246
247 rx_idle = list_first_entry(&dev->rx_idle, struct urb, urb_list);
248 list_del(&rx_idle->urb_list);
249 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
250 retval = submit_rx_urb(dev, rx_idle, GFP_KERNEL);
251 spin_lock_irqsave(&dev->rx_done.lock, flags);
Hemant Kumar184765b2011-12-27 13:20:45 -0800252 if (retval) {
253 list_add_tail(&rx_idle->urb_list, &dev->rx_idle);
Hemant Kumar14401d52011-11-03 16:40:32 -0700254 break;
Hemant Kumar184765b2011-12-27 13:20:45 -0800255 }
Hemant Kumar14401d52011-11-03 16:40:32 -0700256 }
257 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
258}
259
260static void data_bridge_read_cb(struct urb *urb)
261{
262 struct bridge *brdg;
263 struct sk_buff *skb = urb->context;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800264 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
265 struct data_bridge *dev = info->dev;
Hemant Kumar14401d52011-11-03 16:40:32 -0700266 bool queue = 0;
267
Hemant Kumar262682a2013-02-01 09:46:45 -0800268 /*usb device disconnect*/
269 if (urb->dev->state == USB_STATE_NOTATTACHED)
270 urb->status = -ECONNRESET;
271
Hemant Kumar14401d52011-11-03 16:40:32 -0700272 brdg = dev->brdg;
Hemant Kumar14401d52011-11-03 16:40:32 -0700273 skb_put(skb, urb->actual_length);
274
275 switch (urb->status) {
276 case 0: /* success */
277 queue = 1;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800278 info->rx_done = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700279 spin_lock(&dev->rx_done.lock);
280 __skb_queue_tail(&dev->rx_done, skb);
281 spin_unlock(&dev->rx_done.lock);
282 break;
283
284 /*do not resubmit*/
285 case -EPIPE:
286 set_bit(RX_HALT, &dev->flags);
Jack Phame8741502012-06-13 17:34:07 -0700287 dev_err(&dev->intf->dev, "%s: epout halted\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -0700288 schedule_work(&dev->kevent);
289 /* FALLTHROUGH */
290 case -ESHUTDOWN:
291 case -ENOENT: /* suspended */
292 case -ECONNRESET: /* unplug */
293 case -EPROTO:
294 dev_kfree_skb_any(skb);
295 break;
296
297 /*resubmit */
298 case -EOVERFLOW: /*babble error*/
299 default:
300 queue = 1;
301 dev_kfree_skb_any(skb);
302 pr_debug_ratelimited("%s: non zero urb status = %d\n",
303 __func__, urb->status);
304 break;
305 }
306
307 spin_lock(&dev->rx_done.lock);
308 list_add_tail(&urb->urb_list, &dev->rx_idle);
309 spin_unlock(&dev->rx_done.lock);
310
311 if (queue)
312 queue_work(dev->wq, &dev->process_rx_w);
313}
314
315static int submit_rx_urb(struct data_bridge *dev, struct urb *rx_urb,
316 gfp_t flags)
317{
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800318 struct sk_buff *skb;
319 struct timestamp_info *info;
320 int retval = -EINVAL;
321 unsigned int created;
Hemant Kumar14401d52011-11-03 16:40:32 -0700322
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800323 created = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700324 skb = alloc_skb(RMNET_RX_BUFSIZE, flags);
Hemant Kumar184765b2011-12-27 13:20:45 -0800325 if (!skb)
Hemant Kumar14401d52011-11-03 16:40:32 -0700326 return -ENOMEM;
Hemant Kumar14401d52011-11-03 16:40:32 -0700327
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800328 info = (struct timestamp_info *)skb->cb;
329 info->dev = dev;
330 info->created = created;
Hemant Kumar14401d52011-11-03 16:40:32 -0700331
332 usb_fill_bulk_urb(rx_urb, dev->udev, dev->bulk_in,
333 skb->data, RMNET_RX_BUFSIZE,
334 data_bridge_read_cb, skb);
335
336 if (test_bit(SUSPENDED, &dev->flags))
337 goto suspended;
338
339 usb_anchor_urb(rx_urb, &dev->rx_active);
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800340 info->rx_queued = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700341 retval = usb_submit_urb(rx_urb, flags);
342 if (retval)
343 goto fail;
344
Hemant Kumarb72233f2012-04-04 13:21:44 -0700345 usb_mark_last_busy(dev->udev);
Hemant Kumar14401d52011-11-03 16:40:32 -0700346 return 0;
347fail:
348 usb_unanchor_urb(rx_urb);
349suspended:
350 dev_kfree_skb_any(skb);
Hemant Kumar184765b2011-12-27 13:20:45 -0800351
Hemant Kumar14401d52011-11-03 16:40:32 -0700352 return retval;
353}
354
355static int data_bridge_prepare_rx(struct data_bridge *dev)
356{
357 int i;
358 struct urb *rx_urb;
Hemant Kumar262682a2013-02-01 09:46:45 -0800359 int retval = 0;
Hemant Kumar14401d52011-11-03 16:40:32 -0700360
361 for (i = 0; i < max_rx_urbs; i++) {
362 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
Hemant Kumar262682a2013-02-01 09:46:45 -0800363 if (!rx_urb) {
364 retval = -ENOMEM;
365 goto free_urbs;
366 }
Hemant Kumar14401d52011-11-03 16:40:32 -0700367
368 list_add_tail(&rx_urb->urb_list, &dev->rx_idle);
369 }
Hemant Kumar262682a2013-02-01 09:46:45 -0800370
371 return 0;
372
373free_urbs:
374 free_rx_urbs(dev);
375 return retval;
Hemant Kumar14401d52011-11-03 16:40:32 -0700376}
377
378int data_bridge_open(struct bridge *brdg)
379{
380 struct data_bridge *dev;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800381 int ch_id;
Hemant Kumar14401d52011-11-03 16:40:32 -0700382
383 if (!brdg) {
384 err("bridge is null\n");
385 return -EINVAL;
386 }
387
Hemant Kumarc2b17782013-02-03 15:56:29 -0800388 ch_id = get_data_bridge_chid(brdg->name);
389 if (ch_id < 0 || ch_id >= MAX_BRIDGE_DEVICES) {
390 err("%s: %s dev not found\n", __func__, brdg->name);
391 return ch_id;
Hemant Kumar14401d52011-11-03 16:40:32 -0700392 }
393
Hemant Kumarc2b17782013-02-03 15:56:29 -0800394 brdg->ch_id = ch_id;
395
396 dev = __dev[ch_id];
397
Jack Phame8741502012-06-13 17:34:07 -0700398 dev_dbg(&dev->intf->dev, "%s: dev:%p\n", __func__, dev);
Hemant Kumar14401d52011-11-03 16:40:32 -0700399
400 dev->brdg = brdg;
Hemant Kumar06b7e432012-01-19 22:13:50 -0800401 dev->err = 0;
Hemant Kumar14401d52011-11-03 16:40:32 -0700402 atomic_set(&dev->pending_txurbs, 0);
403 dev->to_host = 0;
404 dev->to_modem = 0;
405 dev->txurb_drp_cnt = 0;
406 dev->tx_throttled_cnt = 0;
407 dev->tx_unthrottled_cnt = 0;
408 dev->rx_throttled_cnt = 0;
409 dev->rx_unthrottled_cnt = 0;
410
411 queue_work(dev->wq, &dev->process_rx_w);
412
413 return 0;
414}
415EXPORT_SYMBOL(data_bridge_open);
416
417void data_bridge_close(unsigned int id)
418{
419 struct data_bridge *dev;
420 struct sk_buff *skb;
421 unsigned long flags;
422
423 if (id >= MAX_BRIDGE_DEVICES)
424 return;
425
426 dev = __dev[id];
Jack Phama7c92672011-11-29 16:38:21 -0800427 if (!dev || !dev->brdg)
Hemant Kumar14401d52011-11-03 16:40:32 -0700428 return;
429
Jack Phame8741502012-06-13 17:34:07 -0700430 dev_dbg(&dev->intf->dev, "%s:\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -0700431
Pavankumar Kondeti50f38152013-01-17 16:04:53 +0530432 cancel_work_sync(&dev->kevent);
433 cancel_work_sync(&dev->process_rx_w);
434
Hemant Kumar262682a2013-02-01 09:46:45 -0800435 usb_kill_anchored_urbs(&dev->tx_active);
436 usb_kill_anchored_urbs(&dev->rx_active);
Hemant Kumar14401d52011-11-03 16:40:32 -0700437
438 spin_lock_irqsave(&dev->rx_done.lock, flags);
439 while ((skb = __skb_dequeue(&dev->rx_done)))
440 dev_kfree_skb_any(skb);
441 spin_unlock_irqrestore(&dev->rx_done.lock, flags);
442
443 dev->brdg = NULL;
444}
445EXPORT_SYMBOL(data_bridge_close);
446
447static void defer_kevent(struct work_struct *work)
448{
449 int status;
450 struct data_bridge *dev =
451 container_of(work, struct data_bridge, kevent);
452
453 if (!dev)
454 return;
455
456 if (test_bit(TX_HALT, &dev->flags)) {
457 usb_unlink_anchored_urbs(&dev->tx_active);
458
459 status = usb_autopm_get_interface(dev->intf);
460 if (status < 0) {
Jack Pham4380e002012-08-30 19:06:24 -0700461 dev_dbg(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700462 "can't acquire interface, status %d\n", status);
463 return;
464 }
465
466 status = usb_clear_halt(dev->udev, dev->bulk_out);
467 usb_autopm_put_interface(dev->intf);
468 if (status < 0 && status != -EPIPE && status != -ESHUTDOWN)
Jack Phame8741502012-06-13 17:34:07 -0700469 dev_err(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700470 "can't clear tx halt, status %d\n", status);
471 else
472 clear_bit(TX_HALT, &dev->flags);
473 }
474
475 if (test_bit(RX_HALT, &dev->flags)) {
476 usb_unlink_anchored_urbs(&dev->rx_active);
477
478 status = usb_autopm_get_interface(dev->intf);
479 if (status < 0) {
Jack Pham4380e002012-08-30 19:06:24 -0700480 dev_dbg(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700481 "can't acquire interface, status %d\n", status);
482 return;
483 }
484
485 status = usb_clear_halt(dev->udev, dev->bulk_in);
486 usb_autopm_put_interface(dev->intf);
487 if (status < 0 && status != -EPIPE && status != -ESHUTDOWN)
Jack Phame8741502012-06-13 17:34:07 -0700488 dev_err(&dev->intf->dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700489 "can't clear rx halt, status %d\n", status);
490 else {
491 clear_bit(RX_HALT, &dev->flags);
492 if (dev->brdg)
493 queue_work(dev->wq, &dev->process_rx_w);
494 }
495 }
496}
497
498static void data_bridge_write_cb(struct urb *urb)
499{
500 struct sk_buff *skb = urb->context;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800501 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
502 struct data_bridge *dev = info->dev;
Hemant Kumar14401d52011-11-03 16:40:32 -0700503 struct bridge *brdg = dev->brdg;
504 int pending;
505
506 pr_debug("%s: dev:%p\n", __func__, dev);
507
508 switch (urb->status) {
509 case 0: /*success*/
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800510 dbg_timestamp("UL", skb);
Hemant Kumar14401d52011-11-03 16:40:32 -0700511 break;
Hemant Kumar06b7e432012-01-19 22:13:50 -0800512 case -EPROTO:
513 dev->err = -EPROTO;
514 break;
Hemant Kumar14401d52011-11-03 16:40:32 -0700515 case -EPIPE:
516 set_bit(TX_HALT, &dev->flags);
Jack Phame8741502012-06-13 17:34:07 -0700517 dev_err(&dev->intf->dev, "%s: epout halted\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -0700518 schedule_work(&dev->kevent);
519 /* FALLTHROUGH */
520 case -ESHUTDOWN:
521 case -ENOENT: /* suspended */
522 case -ECONNRESET: /* unplug */
523 case -EOVERFLOW: /*babble error*/
524 /* FALLTHROUGH */
525 default:
526 pr_debug_ratelimited("%s: non zero urb status = %d\n",
527 __func__, urb->status);
528 }
529
530 usb_free_urb(urb);
531 dev_kfree_skb_any(skb);
532
533 pending = atomic_dec_return(&dev->pending_txurbs);
534
535 /*flow ctrl*/
536 if (brdg && fctrl_support && pending <= fctrl_dis_thld &&
537 test_and_clear_bit(TX_THROTTLED, &brdg->flags)) {
538 pr_debug_ratelimited("%s: disable flow ctrl: pend urbs:%u\n",
539 __func__, pending);
540 dev->tx_unthrottled_cnt++;
541 if (brdg->ops.unthrottle_tx)
542 brdg->ops.unthrottle_tx(brdg->ctx);
543 }
544
Hemant Kumar262682a2013-02-01 09:46:45 -0800545 /* if we are here after device disconnect
546 * usb_unbind_interface() takes care of
547 * residual pm_autopm_get_interface_* calls
548 */
549 if (urb->dev->state != USB_STATE_NOTATTACHED)
550 usb_autopm_put_interface_async(dev->intf);
Hemant Kumar14401d52011-11-03 16:40:32 -0700551}
552
553int data_bridge_write(unsigned int id, struct sk_buff *skb)
554{
555 int result;
556 int size = skb->len;
557 int pending;
558 struct urb *txurb;
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800559 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
Hemant Kumar14401d52011-11-03 16:40:32 -0700560 struct data_bridge *dev = __dev[id];
561 struct bridge *brdg;
562
Hemant Kumar06b7e432012-01-19 22:13:50 -0800563 if (!dev || !dev->brdg || dev->err || !usb_get_intfdata(dev->intf))
Hemant Kumar14401d52011-11-03 16:40:32 -0700564 return -ENODEV;
565
566 brdg = dev->brdg;
Hemant Kumarc8a3d312011-12-27 15:41:32 -0800567 if (!brdg)
568 return -ENODEV;
Hemant Kumar14401d52011-11-03 16:40:32 -0700569
Jack Phame8741502012-06-13 17:34:07 -0700570 dev_dbg(&dev->intf->dev, "%s: write (%d bytes)\n", __func__, skb->len);
Hemant Kumar14401d52011-11-03 16:40:32 -0700571
572 result = usb_autopm_get_interface(dev->intf);
573 if (result < 0) {
Jack Pham4380e002012-08-30 19:06:24 -0700574 dev_dbg(&dev->intf->dev, "%s: resume failure\n", __func__);
Hemant Kumar93387bd2012-06-08 15:55:26 -0700575 goto pm_error;
Hemant Kumar14401d52011-11-03 16:40:32 -0700576 }
577
578 txurb = usb_alloc_urb(0, GFP_KERNEL);
579 if (!txurb) {
Jack Phame8741502012-06-13 17:34:07 -0700580 dev_err(&dev->intf->dev, "%s: error allocating read urb\n",
Hemant Kumar14401d52011-11-03 16:40:32 -0700581 __func__);
582 result = -ENOMEM;
583 goto error;
584 }
585
586 /* store dev pointer in skb */
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800587 info->dev = dev;
588 info->tx_queued = get_timestamp();
Hemant Kumar14401d52011-11-03 16:40:32 -0700589
590 usb_fill_bulk_urb(txurb, dev->udev, dev->bulk_out,
591 skb->data, skb->len, data_bridge_write_cb, skb);
592
Jack Pham5a10c6f2012-06-26 11:41:28 -0700593 txurb->transfer_flags |= URB_ZERO_PACKET;
594
Hemant Kumar14401d52011-11-03 16:40:32 -0700595 pending = atomic_inc_return(&dev->pending_txurbs);
596 usb_anchor_urb(txurb, &dev->tx_active);
597
Hemant Kumar73eff1c2012-01-09 18:49:11 -0800598 if (atomic_read(&dev->pending_txurbs) % tx_urb_mult)
599 txurb->transfer_flags |= URB_NO_INTERRUPT;
600
Hemant Kumar14401d52011-11-03 16:40:32 -0700601 result = usb_submit_urb(txurb, GFP_KERNEL);
602 if (result < 0) {
603 usb_unanchor_urb(txurb);
604 atomic_dec(&dev->pending_txurbs);
Jack Phame8741502012-06-13 17:34:07 -0700605 dev_err(&dev->intf->dev, "%s: submit URB error %d\n",
Hemant Kumar14401d52011-11-03 16:40:32 -0700606 __func__, result);
607 goto free_urb;
608 }
609
610 dev->to_modem++;
Jack Phame8741502012-06-13 17:34:07 -0700611 dev_dbg(&dev->intf->dev, "%s: pending_txurbs: %u\n", __func__, pending);
Hemant Kumar14401d52011-11-03 16:40:32 -0700612
613 /* flow control: last urb submitted but return -EBUSY */
614 if (fctrl_support && pending > fctrl_en_thld) {
615 set_bit(TX_THROTTLED, &brdg->flags);
616 dev->tx_throttled_cnt++;
617 pr_debug_ratelimited("%s: enable flow ctrl pend txurbs:%u\n",
618 __func__, pending);
619 return -EBUSY;
620 }
621
622 return size;
623
624free_urb:
625 usb_free_urb(txurb);
626error:
627 dev->txurb_drp_cnt++;
628 usb_autopm_put_interface(dev->intf);
Hemant Kumar93387bd2012-06-08 15:55:26 -0700629pm_error:
Hemant Kumar14401d52011-11-03 16:40:32 -0700630 return result;
631}
632EXPORT_SYMBOL(data_bridge_write);
633
Pavankumar Kondetif408df32013-02-25 21:42:18 +0530634static int bridge_resume(struct usb_interface *iface)
Hemant Kumar14401d52011-11-03 16:40:32 -0700635{
Pavankumar Kondetif408df32013-02-25 21:42:18 +0530636 int retval = 0;
637 struct data_bridge *dev = usb_get_intfdata(iface);
Hemant Kumar14401d52011-11-03 16:40:32 -0700638
Pavankumar Kondetif408df32013-02-25 21:42:18 +0530639 clear_bit(SUSPENDED, &dev->flags);
Hemant Kumar14401d52011-11-03 16:40:32 -0700640
Hemant Kumar14401d52011-11-03 16:40:32 -0700641 if (dev->brdg)
642 queue_work(dev->wq, &dev->process_rx_w);
643
Pavankumar Kondetif408df32013-02-25 21:42:18 +0530644 retval = ctrl_bridge_resume(dev->id);
Jack Pham9b0a0e52012-02-28 18:05:14 -0800645
Hemant Kumar14401d52011-11-03 16:40:32 -0700646 return retval;
647}
648
Hemant Kumar14401d52011-11-03 16:40:32 -0700649static int bridge_suspend(struct usb_interface *intf, pm_message_t message)
650{
651 int retval;
652 struct data_bridge *dev = usb_get_intfdata(intf);
Hemant Kumar14401d52011-11-03 16:40:32 -0700653
Pavankumar Kondetif408df32013-02-25 21:42:18 +0530654 if (atomic_read(&dev->pending_txurbs))
655 return -EBUSY;
Jack Pham9b0a0e52012-02-28 18:05:14 -0800656
Pavankumar Kondetif408df32013-02-25 21:42:18 +0530657 retval = ctrl_bridge_suspend(dev->id);
658 if (retval)
659 return retval;
660
661 set_bit(SUSPENDED, &dev->flags);
662 usb_kill_anchored_urbs(&dev->rx_active);
663
664 return 0;
Hemant Kumar14401d52011-11-03 16:40:32 -0700665}
666
667static int data_bridge_probe(struct usb_interface *iface,
668 struct usb_host_endpoint *bulk_in,
Hemant Kumarc2b17782013-02-03 15:56:29 -0800669 struct usb_host_endpoint *bulk_out, char *name, int id)
Hemant Kumar14401d52011-11-03 16:40:32 -0700670{
671 struct data_bridge *dev;
Hemant Kumar262682a2013-02-01 09:46:45 -0800672 int retval;
Hemant Kumar14401d52011-11-03 16:40:32 -0700673
Hemant Kumar262682a2013-02-01 09:46:45 -0800674 dev = __dev[id];
Hemant Kumar14401d52011-11-03 16:40:32 -0700675 if (!dev) {
Hemant Kumar262682a2013-02-01 09:46:45 -0800676 err("%s: device not found\n", __func__);
677 return -ENODEV;
Hemant Kumar14401d52011-11-03 16:40:32 -0700678 }
679
Hemant Kumarc2b17782013-02-03 15:56:29 -0800680 dev->pdev = platform_device_alloc(name, -1);
Hemant Kumar14401d52011-11-03 16:40:32 -0700681 if (!dev->pdev) {
682 err("%s: unable to allocate platform device\n", __func__);
683 kfree(dev);
684 return -ENOMEM;
685 }
686
Hemant Kumar67107002013-02-11 13:24:08 -0800687 /*clear all bits except claimed bit*/
688 clear_bit(RX_HALT, &dev->flags);
689 clear_bit(TX_HALT, &dev->flags);
690 clear_bit(SUSPENDED, &dev->flags);
691
Jack Pham9b0a0e52012-02-28 18:05:14 -0800692 dev->id = id;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800693 dev->name = name;
Hemant Kumar14401d52011-11-03 16:40:32 -0700694 dev->udev = interface_to_usbdev(iface);
695 dev->intf = iface;
696
697 dev->bulk_in = usb_rcvbulkpipe(dev->udev,
698 bulk_in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
699
700 dev->bulk_out = usb_sndbulkpipe(dev->udev,
701 bulk_out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
702
703 usb_set_intfdata(iface, dev);
704
Hemant Kumar14401d52011-11-03 16:40:32 -0700705 /*allocate list of rx urbs*/
Hemant Kumar262682a2013-02-01 09:46:45 -0800706 retval = data_bridge_prepare_rx(dev);
707 if (retval) {
708 platform_device_put(dev->pdev);
709 return retval;
710 }
Hemant Kumar14401d52011-11-03 16:40:32 -0700711
712 platform_device_add(dev->pdev);
713
714 return 0;
715}
716
717#if defined(CONFIG_DEBUG_FS)
Hemant Kumar67107002013-02-11 13:24:08 -0800718#define DEBUG_BUF_SIZE 4096
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800719
720static unsigned int record_timestamp;
721module_param(record_timestamp, uint, S_IRUGO | S_IWUSR);
722
723static struct timestamp_buf dbg_data = {
724 .idx = 0,
725 .lck = __RW_LOCK_UNLOCKED(lck)
726};
727
728/*get_timestamp - returns time of day in us */
729static unsigned int get_timestamp(void)
730{
731 struct timeval tval;
732 unsigned int stamp;
733
734 if (!record_timestamp)
735 return 0;
736
737 do_gettimeofday(&tval);
738 /* 2^32 = 4294967296. Limit to 4096s. */
739 stamp = tval.tv_sec & 0xFFF;
740 stamp = stamp * 1000000 + tval.tv_usec;
741 return stamp;
742}
743
744static void dbg_inc(unsigned *idx)
745{
746 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
747}
748
749/**
750* dbg_timestamp - Stores timestamp values of a SKB life cycle
751* to debug buffer
752* @event: "UL": Uplink Data
753* @skb: SKB used to store timestamp values to debug buffer
754*/
755static void dbg_timestamp(char *event, struct sk_buff * skb)
756{
757 unsigned long flags;
758 struct timestamp_info *info = (struct timestamp_info *)skb->cb;
759
760 if (!record_timestamp)
761 return;
762
763 write_lock_irqsave(&dbg_data.lck, flags);
764
765 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
766 "%p %u[%s] %u %u %u %u %u %u\n",
767 skb, skb->len, event, info->created, info->rx_queued,
768 info->rx_done, info->rx_done_sent, info->tx_queued,
769 get_timestamp());
770
771 dbg_inc(&dbg_data.idx);
772
773 write_unlock_irqrestore(&dbg_data.lck, flags);
774}
775
776/* show_timestamp: displays the timestamp buffer */
777static ssize_t show_timestamp(struct file *file, char __user *ubuf,
778 size_t count, loff_t *ppos)
779{
780 unsigned long flags;
781 unsigned i;
782 unsigned j = 0;
783 char *buf;
784 int ret = 0;
785
786 if (!record_timestamp)
787 return 0;
788
Hemant Kumar67107002013-02-11 13:24:08 -0800789 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800790 if (!buf)
791 return -ENOMEM;
792
793 read_lock_irqsave(&dbg_data.lck, flags);
794
795 i = dbg_data.idx;
796 for (dbg_inc(&i); i != dbg_data.idx; dbg_inc(&i)) {
797 if (!strnlen(dbg_data.buf[i], DBG_DATA_MSG))
798 continue;
Hemant Kumar67107002013-02-11 13:24:08 -0800799 j += scnprintf(buf + j, DEBUG_BUF_SIZE - j,
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800800 "%s\n", dbg_data.buf[i]);
801 }
802
803 read_unlock_irqrestore(&dbg_data.lck, flags);
804
805 ret = simple_read_from_buffer(ubuf, count, ppos, buf, j);
806
807 kfree(buf);
808
809 return ret;
810}
811
812const struct file_operations data_timestamp_ops = {
813 .read = show_timestamp,
814};
815
Hemant Kumar14401d52011-11-03 16:40:32 -0700816static ssize_t data_bridge_read_stats(struct file *file, char __user *ubuf,
817 size_t count, loff_t *ppos)
818{
819 struct data_bridge *dev;
820 char *buf;
821 int ret;
822 int i;
823 int temp = 0;
824
825 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
826 if (!buf)
827 return -ENOMEM;
828
Hemant Kumar67107002013-02-11 13:24:08 -0800829 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
Hemant Kumar14401d52011-11-03 16:40:32 -0700830 dev = __dev[i];
831 if (!dev)
832 continue;
833
834 temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
835 "\nName#%s dev %p\n"
836 "pending tx urbs: %u\n"
837 "tx urb drp cnt: %u\n"
838 "to host: %lu\n"
839 "to mdm: %lu\n"
840 "tx throttled cnt: %u\n"
841 "tx unthrottled cnt: %u\n"
842 "rx throttled cnt: %u\n"
843 "rx unthrottled cnt: %u\n"
844 "rx done skb qlen: %u\n"
Hemant Kumar06b7e432012-01-19 22:13:50 -0800845 "dev err: %d\n"
Hemant Kumar14401d52011-11-03 16:40:32 -0700846 "suspended: %d\n"
847 "TX_HALT: %d\n"
848 "RX_HALT: %d\n",
Hemant Kumar67107002013-02-11 13:24:08 -0800849 dev->name, dev,
Hemant Kumar14401d52011-11-03 16:40:32 -0700850 atomic_read(&dev->pending_txurbs),
851 dev->txurb_drp_cnt,
852 dev->to_host,
853 dev->to_modem,
854 dev->tx_throttled_cnt,
855 dev->tx_unthrottled_cnt,
856 dev->rx_throttled_cnt,
857 dev->rx_unthrottled_cnt,
858 dev->rx_done.qlen,
Hemant Kumar06b7e432012-01-19 22:13:50 -0800859 dev->err,
Hemant Kumar14401d52011-11-03 16:40:32 -0700860 test_bit(SUSPENDED, &dev->flags),
861 test_bit(TX_HALT, &dev->flags),
862 test_bit(RX_HALT, &dev->flags));
863
864 }
865
866 ret = simple_read_from_buffer(ubuf, count, ppos, buf, temp);
867
868 kfree(buf);
869
870 return ret;
871}
872
873static ssize_t data_bridge_reset_stats(struct file *file,
874 const char __user *buf, size_t count, loff_t *ppos)
875{
876 struct data_bridge *dev;
877 int i;
878
Hemant Kumar67107002013-02-11 13:24:08 -0800879 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
Hemant Kumar14401d52011-11-03 16:40:32 -0700880 dev = __dev[i];
881 if (!dev)
882 continue;
883
884 dev->to_host = 0;
885 dev->to_modem = 0;
886 dev->txurb_drp_cnt = 0;
887 dev->tx_throttled_cnt = 0;
888 dev->tx_unthrottled_cnt = 0;
889 dev->rx_throttled_cnt = 0;
890 dev->rx_unthrottled_cnt = 0;
891 }
892 return count;
893}
894
895const struct file_operations data_stats_ops = {
896 .read = data_bridge_read_stats,
897 .write = data_bridge_reset_stats,
898};
899
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800900static struct dentry *data_dent;
901static struct dentry *data_dfile_stats;
902static struct dentry *data_dfile_tstamp;
903
Hemant Kumar14401d52011-11-03 16:40:32 -0700904static void data_bridge_debugfs_init(void)
905{
906 data_dent = debugfs_create_dir("data_hsic_bridge", 0);
907 if (IS_ERR(data_dent))
908 return;
909
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800910 data_dfile_stats = debugfs_create_file("status", 0644, data_dent, 0,
911 &data_stats_ops);
912 if (!data_dfile_stats || IS_ERR(data_dfile_stats)) {
913 debugfs_remove(data_dent);
914 return;
915 }
916
917 data_dfile_tstamp = debugfs_create_file("timestamp", 0644, data_dent,
918 0, &data_timestamp_ops);
919 if (!data_dfile_tstamp || IS_ERR(data_dfile_tstamp))
Hemant Kumar14401d52011-11-03 16:40:32 -0700920 debugfs_remove(data_dent);
921}
922
923static void data_bridge_debugfs_exit(void)
924{
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800925 debugfs_remove(data_dfile_stats);
926 debugfs_remove(data_dfile_tstamp);
Hemant Kumar14401d52011-11-03 16:40:32 -0700927 debugfs_remove(data_dent);
928}
929
930#else
931static void data_bridge_debugfs_init(void) { }
932static void data_bridge_debugfs_exit(void) { }
Hemant Kumarc72ab2b2012-01-10 12:33:49 -0800933static void dbg_timestamp(char *event, struct sk_buff * skb)
934{
935 return;
936}
937
938static unsigned int get_timestamp(void)
939{
940 return 0;
941}
942
Hemant Kumar14401d52011-11-03 16:40:32 -0700943#endif
944
945static int __devinit
946bridge_probe(struct usb_interface *iface, const struct usb_device_id *id)
947{
948 struct usb_host_endpoint *endpoint = NULL;
949 struct usb_host_endpoint *bulk_in = NULL;
950 struct usb_host_endpoint *bulk_out = NULL;
951 struct usb_host_endpoint *int_in = NULL;
952 struct usb_device *udev;
953 int i;
954 int status = 0;
955 int numends;
Hemant Kumar67107002013-02-11 13:24:08 -0800956 int ch_id;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800957 char **bname = (char **)id->driver_info;
Hemant Kumar14401d52011-11-03 16:40:32 -0700958
959 if (iface->num_altsetting != 1) {
960 err("%s invalid num_altsetting %u\n",
961 __func__, iface->num_altsetting);
962 return -EINVAL;
963 }
964
Jack Pham1b1ba472012-06-13 16:40:15 -0700965 udev = interface_to_usbdev(iface);
966 usb_get_dev(udev);
967
Hemant Kumar14401d52011-11-03 16:40:32 -0700968 numends = iface->cur_altsetting->desc.bNumEndpoints;
969 for (i = 0; i < numends; i++) {
970 endpoint = iface->cur_altsetting->endpoint + i;
971 if (!endpoint) {
Jack Phame8741502012-06-13 17:34:07 -0700972 dev_err(&iface->dev, "%s: invalid endpoint %u\n",
Hemant Kumar14401d52011-11-03 16:40:32 -0700973 __func__, i);
974 status = -EINVAL;
975 goto out;
976 }
977
978 if (usb_endpoint_is_bulk_in(&endpoint->desc))
979 bulk_in = endpoint;
980 else if (usb_endpoint_is_bulk_out(&endpoint->desc))
981 bulk_out = endpoint;
982 else if (usb_endpoint_is_int_in(&endpoint->desc))
983 int_in = endpoint;
984 }
985
986 if (!bulk_in || !bulk_out || !int_in) {
Jack Phame8741502012-06-13 17:34:07 -0700987 dev_err(&iface->dev, "%s: invalid endpoints\n", __func__);
Hemant Kumar14401d52011-11-03 16:40:32 -0700988 status = -EINVAL;
989 goto out;
990 }
991
Hemant Kumar67107002013-02-11 13:24:08 -0800992 ch_id = get_bridge_dev_idx();
993 if (ch_id < 0) {
994 err("%s all bridge channels claimed. Probe failed\n", __func__);
995 return -ENODEV;
996 }
997
Hemant Kumarc2b17782013-02-03 15:56:29 -0800998 status = data_bridge_probe(iface, bulk_in, bulk_out,
999 bname[BRIDGE_DATA_IDX], ch_id);
Hemant Kumar14401d52011-11-03 16:40:32 -07001000 if (status < 0) {
Jack Phame8741502012-06-13 17:34:07 -07001001 dev_err(&iface->dev, "data_bridge_probe failed %d\n", status);
Hemant Kumar14401d52011-11-03 16:40:32 -07001002 goto out;
1003 }
1004
Hemant Kumarc2b17782013-02-03 15:56:29 -08001005 status = ctrl_bridge_probe(iface, int_in, bname[BRIDGE_CTRL_IDX],
1006 ch_id);
Hemant Kumar14401d52011-11-03 16:40:32 -07001007 if (status < 0) {
Jack Phame8741502012-06-13 17:34:07 -07001008 dev_err(&iface->dev, "ctrl_bridge_probe failed %d\n", status);
Hemant Kumar262682a2013-02-01 09:46:45 -08001009 goto error;
Hemant Kumar14401d52011-11-03 16:40:32 -07001010 }
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001011
Hemant Kumar14401d52011-11-03 16:40:32 -07001012 return 0;
1013
Hemant Kumar262682a2013-02-01 09:46:45 -08001014error:
Pavankumar Kondeti90851542013-03-22 13:26:00 +05301015 platform_device_unregister(__dev[ch_id]->pdev);
Hemant Kumar262682a2013-02-01 09:46:45 -08001016 free_rx_urbs(__dev[ch_id]);
Hemant Kumar14401d52011-11-03 16:40:32 -07001017 usb_set_intfdata(iface, NULL);
Hemant Kumar14401d52011-11-03 16:40:32 -07001018out:
1019 usb_put_dev(udev);
1020
1021 return status;
1022}
1023
1024static void bridge_disconnect(struct usb_interface *intf)
1025{
1026 struct data_bridge *dev = usb_get_intfdata(intf);
Hemant Kumar14401d52011-11-03 16:40:32 -07001027
1028 if (!dev) {
1029 err("%s: data device not found\n", __func__);
1030 return;
1031 }
1032
Hemant Kumar67107002013-02-11 13:24:08 -08001033 /*set device name to none to get correct channel id
1034 * at the time of bridge open
1035 */
1036 dev->name = "none";
1037
Hemant Kumar45bdca82012-09-02 11:10:35 -07001038 ctrl_bridge_disconnect(dev->id);
Jack Pham1b1ba472012-06-13 16:40:15 -07001039 platform_device_unregister(dev->pdev);
Hemant Kumar14401d52011-11-03 16:40:32 -07001040 usb_set_intfdata(intf, NULL);
Hemant Kumar14401d52011-11-03 16:40:32 -07001041
Hemant Kumar262682a2013-02-01 09:46:45 -08001042 free_rx_urbs(dev);
Hemant Kumar14401d52011-11-03 16:40:32 -07001043
1044 usb_put_dev(dev->udev);
Hemant Kumar67107002013-02-11 13:24:08 -08001045
1046 clear_bit(CLAIMED, &dev->flags);
Hemant Kumar14401d52011-11-03 16:40:32 -07001047}
1048
Hemant Kumarc2b17782013-02-03 15:56:29 -08001049/*driver info stores data/ctrl bridge name used to match bridge xport name*/
Hemant Kumar14401d52011-11-03 16:40:32 -07001050static const struct usb_device_id bridge_ids[] = {
Hemant Kumarc2b17782013-02-03 15:56:29 -08001051 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9001, 2),
1052 .driver_info = (unsigned long)serial_hsic_bridge_names,
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001053 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001054 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9001, 3),
1055 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001056 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001057 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9034, 2),
1058 .driver_info = (unsigned long)serial_hsic_bridge_names,
Hemant Kumar67a4fd02012-01-05 15:44:36 -08001059 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001060 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9034, 3),
1061 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
Hemant Kumare97cbb32012-02-24 13:00:57 -08001062 },
Hemant Kumarc2b17782013-02-03 15:56:29 -08001063 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 3),
1064 .driver_info = (unsigned long)serial_hsic_bridge_names,
1065 },
1066 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 4),
1067 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
1068 },
1069 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904c, 3),
1070 .driver_info = (unsigned long)serial_hsic_bridge_names,
1071 },
1072 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904c, 5),
1073 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
1074 },
1075 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9075, 3),
1076 .driver_info = (unsigned long)serial_hsic_bridge_names,
1077 },
1078 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9075, 5),
1079 .driver_info = (unsigned long)rmnet_hsic_bridge_names,
Hemant Kumarce3c5bf2012-12-06 15:52:02 -08001080 },
Hemant Kumar67107002013-02-11 13:24:08 -08001081 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9079, 3),
1082 .driver_info = (unsigned long)serial_hsusb_bridge_names,
1083 },
1084 { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9079, 4),
1085 .driver_info = (unsigned long)rmnet_hsusb_bridge_names,
1086 },
Jack Phamb1ad7152011-12-07 10:58:11 -08001087
1088 { } /* Terminating entry */
Hemant Kumar14401d52011-11-03 16:40:32 -07001089};
Hemant Kumar14401d52011-11-03 16:40:32 -07001090MODULE_DEVICE_TABLE(usb, bridge_ids);
1091
1092static struct usb_driver bridge_driver = {
1093 .name = "mdm_bridge",
1094 .probe = bridge_probe,
1095 .disconnect = bridge_disconnect,
1096 .id_table = bridge_ids,
1097 .suspend = bridge_suspend,
1098 .resume = bridge_resume,
1099 .supports_autosuspend = 1,
1100};
1101
1102static int __init bridge_init(void)
1103{
Hemant Kumar262682a2013-02-01 09:46:45 -08001104 struct data_bridge *dev;
1105 int ret;
1106 int i = 0;
1107
1108 ret = ctrl_bridge_init();
1109 if (ret)
1110 return ret;
1111
1112 bridge_wq = create_singlethread_workqueue("mdm_bridge");
1113 if (!bridge_wq) {
1114 pr_err("%s: Unable to create workqueue:bridge\n", __func__);
1115 ret = -ENOMEM;
1116 goto free_ctrl;
1117 }
1118
1119 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
1120
1121 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1122 if (!dev) {
1123 err("%s: unable to allocate dev\n", __func__);
1124 ret = -ENOMEM;
1125 goto error;
1126 }
1127
1128 dev->wq = bridge_wq;
1129
Hemant Kumarc2b17782013-02-03 15:56:29 -08001130 /*transport name will be set during probe*/
Hemant Kumar67107002013-02-11 13:24:08 -08001131 dev->name = "none";
Hemant Kumarc2b17782013-02-03 15:56:29 -08001132
Hemant Kumar262682a2013-02-01 09:46:45 -08001133 init_usb_anchor(&dev->tx_active);
1134 init_usb_anchor(&dev->rx_active);
Hemant Kumar262682a2013-02-01 09:46:45 -08001135
1136 INIT_LIST_HEAD(&dev->rx_idle);
1137
1138 skb_queue_head_init(&dev->rx_done);
1139
1140 INIT_WORK(&dev->kevent, defer_kevent);
1141 INIT_WORK(&dev->process_rx_w, data_bridge_process_rx);
1142
1143 __dev[i] = dev;
1144 }
Hemant Kumar14401d52011-11-03 16:40:32 -07001145
1146 ret = usb_register(&bridge_driver);
1147 if (ret) {
1148 err("%s: unable to register mdm_bridge driver", __func__);
Hemant Kumar262682a2013-02-01 09:46:45 -08001149 goto error;
Hemant Kumar14401d52011-11-03 16:40:32 -07001150 }
1151
1152 data_bridge_debugfs_init();
1153
1154 return 0;
Hemant Kumar262682a2013-02-01 09:46:45 -08001155
1156error:
1157 while (--i >= 0) {
1158 kfree(__dev[i]);
1159 __dev[i] = NULL;
1160 }
1161 destroy_workqueue(bridge_wq);
1162free_ctrl:
1163 ctrl_bridge_exit();
1164 return ret;
Hemant Kumar14401d52011-11-03 16:40:32 -07001165}
1166
1167static void __exit bridge_exit(void)
1168{
Hemant Kumar262682a2013-02-01 09:46:45 -08001169 int i;
1170
1171 usb_deregister(&bridge_driver);
Hemant Kumar14401d52011-11-03 16:40:32 -07001172 data_bridge_debugfs_exit();
1173 destroy_workqueue(bridge_wq);
Hemant Kumar262682a2013-02-01 09:46:45 -08001174
1175 for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
1176 kfree(__dev[i]);
1177 __dev[i] = NULL;
1178 }
1179
1180 ctrl_bridge_exit();
Hemant Kumar14401d52011-11-03 16:40:32 -07001181}
1182
1183module_init(bridge_init);
1184module_exit(bridge_exit);
1185
1186MODULE_DESCRIPTION("Qualcomm modem data bridge driver");
1187MODULE_LICENSE("GPL v2");