• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3   USB Driver layer for GSM modems
4 
5   Copyright (C) 2005  Matthias Urlichs <smurf@smurf.noris.de>
6 
7   Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
8 
9   History: see the git log.
10 
11   Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
12 
13   This driver exists because the "normal" serial driver doesn't work too well
14   with GSM modems. Issues:
15   - data loss -- one single Receive URB is not nearly enough
16   - controlling the baud rate doesn't make sense
17 */
18 
19 #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
20 #define DRIVER_DESC "USB Driver for GSM modems"
21 
22 #include <linux/kernel.h>
23 #include <linux/jiffies.h>
24 #include <linux/errno.h>
25 #include <linux/slab.h>
26 #include <linux/tty.h>
27 #include <linux/tty_flip.h>
28 #include <linux/module.h>
29 #include <linux/bitops.h>
30 #include <linux/uaccess.h>
31 #include <linux/usb.h>
32 #include <linux/usb/cdc.h>
33 #include <linux/usb/serial.h>
34 #include <linux/serial.h>
35 #include "usb-wwan.h"
36 
37 /*
38  * Generate DTR/RTS signals on the port using the SET_CONTROL_LINE_STATE request
39  * in CDC ACM.
40  */
usb_wwan_send_setup(struct usb_serial_port * port)41 static int usb_wwan_send_setup(struct usb_serial_port *port)
42 {
43 	struct usb_serial *serial = port->serial;
44 	struct usb_wwan_port_private *portdata;
45 	int val = 0;
46 	int ifnum;
47 	int res;
48 
49 	portdata = usb_get_serial_port_data(port);
50 
51 	if (portdata->dtr_state)
52 		val |= USB_CDC_CTRL_DTR;
53 	if (portdata->rts_state)
54 		val |= USB_CDC_CTRL_RTS;
55 
56 	ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
57 
58 	res = usb_autopm_get_interface(serial->interface);
59 	if (res)
60 		return res;
61 
62 	res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
63 				USB_CDC_REQ_SET_CONTROL_LINE_STATE,
64 				USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
65 				val, ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
66 
67 	usb_autopm_put_interface(port->serial->interface);
68 
69 	return res;
70 }
71 
usb_wwan_dtr_rts(struct usb_serial_port * port,int on)72 void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
73 {
74 	struct usb_wwan_port_private *portdata;
75 	struct usb_wwan_intf_private *intfdata;
76 
77 	intfdata = usb_get_serial_data(port->serial);
78 
79 	if (!intfdata->use_send_setup)
80 		return;
81 
82 	portdata = usb_get_serial_port_data(port);
83 	/* FIXME: locking */
84 	portdata->rts_state = on;
85 	portdata->dtr_state = on;
86 
87 	usb_wwan_send_setup(port);
88 }
89 EXPORT_SYMBOL(usb_wwan_dtr_rts);
90 
usb_wwan_tiocmget(struct tty_struct * tty)91 int usb_wwan_tiocmget(struct tty_struct *tty)
92 {
93 	struct usb_serial_port *port = tty->driver_data;
94 	unsigned int value;
95 	struct usb_wwan_port_private *portdata;
96 
97 	portdata = usb_get_serial_port_data(port);
98 
99 	value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
100 	    ((portdata->dtr_state) ? TIOCM_DTR : 0) |
101 	    ((portdata->cts_state) ? TIOCM_CTS : 0) |
102 	    ((portdata->dsr_state) ? TIOCM_DSR : 0) |
103 	    ((portdata->dcd_state) ? TIOCM_CAR : 0) |
104 	    ((portdata->ri_state) ? TIOCM_RNG : 0);
105 
106 	return value;
107 }
108 EXPORT_SYMBOL(usb_wwan_tiocmget);
109 
usb_wwan_tiocmset(struct tty_struct * tty,unsigned int set,unsigned int clear)110 int usb_wwan_tiocmset(struct tty_struct *tty,
111 		      unsigned int set, unsigned int clear)
112 {
113 	struct usb_serial_port *port = tty->driver_data;
114 	struct usb_wwan_port_private *portdata;
115 	struct usb_wwan_intf_private *intfdata;
116 
117 	portdata = usb_get_serial_port_data(port);
118 	intfdata = usb_get_serial_data(port->serial);
119 
120 	if (!intfdata->use_send_setup)
121 		return -EINVAL;
122 
123 	/* FIXME: what locks portdata fields ? */
124 	if (set & TIOCM_RTS)
125 		portdata->rts_state = 1;
126 	if (set & TIOCM_DTR)
127 		portdata->dtr_state = 1;
128 
129 	if (clear & TIOCM_RTS)
130 		portdata->rts_state = 0;
131 	if (clear & TIOCM_DTR)
132 		portdata->dtr_state = 0;
133 	return usb_wwan_send_setup(port);
134 }
135 EXPORT_SYMBOL(usb_wwan_tiocmset);
136 
usb_wwan_write(struct tty_struct * tty,struct usb_serial_port * port,const unsigned char * buf,int count)137 int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
138 		   const unsigned char *buf, int count)
139 {
140 	struct usb_wwan_port_private *portdata;
141 	struct usb_wwan_intf_private *intfdata;
142 	int i;
143 	int left, todo;
144 	struct urb *this_urb = NULL;	/* spurious */
145 	int err;
146 	unsigned long flags;
147 
148 	portdata = usb_get_serial_port_data(port);
149 	intfdata = usb_get_serial_data(port->serial);
150 
151 	dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count);
152 
153 	left = count;
154 	for (i = 0; left > 0 && i < N_OUT_URB; i++) {
155 		todo = left;
156 		if (todo > OUT_BUFLEN)
157 			todo = OUT_BUFLEN;
158 
159 		this_urb = portdata->out_urbs[i];
160 		if (test_and_set_bit(i, &portdata->out_busy)) {
161 			if (time_before(jiffies,
162 					portdata->tx_start_time[i] + 10 * HZ))
163 				continue;
164 			usb_unlink_urb(this_urb);
165 			continue;
166 		}
167 		dev_dbg(&port->dev, "%s: endpoint %d buf %d\n", __func__,
168 			usb_pipeendpoint(this_urb->pipe), i);
169 
170 		err = usb_autopm_get_interface_async(port->serial->interface);
171 		if (err < 0) {
172 			clear_bit(i, &portdata->out_busy);
173 			break;
174 		}
175 
176 		/* send the data */
177 		memcpy(this_urb->transfer_buffer, buf, todo);
178 		this_urb->transfer_buffer_length = todo;
179 
180 		spin_lock_irqsave(&intfdata->susp_lock, flags);
181 		if (intfdata->suspended) {
182 			usb_anchor_urb(this_urb, &portdata->delayed);
183 			spin_unlock_irqrestore(&intfdata->susp_lock, flags);
184 		} else {
185 			intfdata->in_flight++;
186 			spin_unlock_irqrestore(&intfdata->susp_lock, flags);
187 			err = usb_submit_urb(this_urb, GFP_ATOMIC);
188 			if (err) {
189 				dev_err(&port->dev,
190 					"%s: submit urb %d failed: %d\n",
191 					__func__, i, err);
192 				clear_bit(i, &portdata->out_busy);
193 				spin_lock_irqsave(&intfdata->susp_lock, flags);
194 				intfdata->in_flight--;
195 				spin_unlock_irqrestore(&intfdata->susp_lock,
196 						       flags);
197 				usb_autopm_put_interface_async(port->serial->interface);
198 				break;
199 			}
200 		}
201 
202 		portdata->tx_start_time[i] = jiffies;
203 		buf += todo;
204 		left -= todo;
205 	}
206 
207 	count -= left;
208 	dev_dbg(&port->dev, "%s: wrote (did %d)\n", __func__, count);
209 	return count;
210 }
211 EXPORT_SYMBOL(usb_wwan_write);
212 
usb_wwan_indat_callback(struct urb * urb)213 static void usb_wwan_indat_callback(struct urb *urb)
214 {
215 	int err;
216 	int endpoint;
217 	struct usb_serial_port *port;
218 	struct device *dev;
219 	unsigned char *data = urb->transfer_buffer;
220 	int status = urb->status;
221 
222 	endpoint = usb_pipeendpoint(urb->pipe);
223 	port = urb->context;
224 	dev = &port->dev;
225 
226 	if (status) {
227 		dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n",
228 			__func__, status, endpoint);
229 
230 		/* don't resubmit on fatal errors */
231 		if (status == -ESHUTDOWN || status == -ENOENT)
232 			return;
233 	} else {
234 		if (urb->actual_length) {
235 			tty_insert_flip_string(&port->port, data,
236 					urb->actual_length);
237 			tty_flip_buffer_push(&port->port);
238 		} else
239 			dev_dbg(dev, "%s: empty read urb received\n", __func__);
240 	}
241 	/* Resubmit urb so we continue receiving */
242 	err = usb_submit_urb(urb, GFP_ATOMIC);
243 	if (err) {
244 		if (err != -EPERM && err != -ENODEV) {
245 			dev_err(dev, "%s: resubmit read urb failed. (%d)\n",
246 				__func__, err);
247 			/* busy also in error unless we are killed */
248 			usb_mark_last_busy(port->serial->dev);
249 		}
250 	} else {
251 		usb_mark_last_busy(port->serial->dev);
252 	}
253 }
254 
usb_wwan_outdat_callback(struct urb * urb)255 static void usb_wwan_outdat_callback(struct urb *urb)
256 {
257 	struct usb_serial_port *port;
258 	struct usb_wwan_port_private *portdata;
259 	struct usb_wwan_intf_private *intfdata;
260 	unsigned long flags;
261 	int i;
262 
263 	port = urb->context;
264 	intfdata = usb_get_serial_data(port->serial);
265 
266 	usb_serial_port_softint(port);
267 	usb_autopm_put_interface_async(port->serial->interface);
268 	portdata = usb_get_serial_port_data(port);
269 	spin_lock_irqsave(&intfdata->susp_lock, flags);
270 	intfdata->in_flight--;
271 	spin_unlock_irqrestore(&intfdata->susp_lock, flags);
272 
273 	for (i = 0; i < N_OUT_URB; ++i) {
274 		if (portdata->out_urbs[i] == urb) {
275 			smp_mb__before_atomic();
276 			clear_bit(i, &portdata->out_busy);
277 			break;
278 		}
279 	}
280 }
281 
usb_wwan_write_room(struct tty_struct * tty)282 unsigned int usb_wwan_write_room(struct tty_struct *tty)
283 {
284 	struct usb_serial_port *port = tty->driver_data;
285 	struct usb_wwan_port_private *portdata;
286 	int i;
287 	unsigned int data_len = 0;
288 	struct urb *this_urb;
289 
290 	portdata = usb_get_serial_port_data(port);
291 
292 	for (i = 0; i < N_OUT_URB; i++) {
293 		this_urb = portdata->out_urbs[i];
294 		if (this_urb && !test_bit(i, &portdata->out_busy))
295 			data_len += OUT_BUFLEN;
296 	}
297 
298 	dev_dbg(&port->dev, "%s: %u\n", __func__, data_len);
299 	return data_len;
300 }
301 EXPORT_SYMBOL(usb_wwan_write_room);
302 
usb_wwan_chars_in_buffer(struct tty_struct * tty)303 unsigned int usb_wwan_chars_in_buffer(struct tty_struct *tty)
304 {
305 	struct usb_serial_port *port = tty->driver_data;
306 	struct usb_wwan_port_private *portdata;
307 	int i;
308 	unsigned int data_len = 0;
309 	struct urb *this_urb;
310 
311 	portdata = usb_get_serial_port_data(port);
312 
313 	for (i = 0; i < N_OUT_URB; i++) {
314 		this_urb = portdata->out_urbs[i];
315 		/* FIXME: This locking is insufficient as this_urb may
316 		   go unused during the test */
317 		if (this_urb && test_bit(i, &portdata->out_busy))
318 			data_len += this_urb->transfer_buffer_length;
319 	}
320 	dev_dbg(&port->dev, "%s: %u\n", __func__, data_len);
321 	return data_len;
322 }
323 EXPORT_SYMBOL(usb_wwan_chars_in_buffer);
324 
usb_wwan_open(struct tty_struct * tty,struct usb_serial_port * port)325 int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port)
326 {
327 	struct usb_wwan_port_private *portdata;
328 	struct usb_wwan_intf_private *intfdata;
329 	struct usb_serial *serial = port->serial;
330 	int i, err;
331 	struct urb *urb;
332 
333 	portdata = usb_get_serial_port_data(port);
334 	intfdata = usb_get_serial_data(serial);
335 
336 	if (port->interrupt_in_urb) {
337 		err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
338 		if (err) {
339 			dev_err(&port->dev, "%s: submit int urb failed: %d\n",
340 				__func__, err);
341 		}
342 	}
343 
344 	/* Start reading from the IN endpoint */
345 	for (i = 0; i < N_IN_URB; i++) {
346 		urb = portdata->in_urbs[i];
347 		if (!urb)
348 			continue;
349 		err = usb_submit_urb(urb, GFP_KERNEL);
350 		if (err) {
351 			dev_err(&port->dev,
352 				"%s: submit read urb %d failed: %d\n",
353 				__func__, i, err);
354 		}
355 	}
356 
357 	spin_lock_irq(&intfdata->susp_lock);
358 	if (++intfdata->open_ports == 1)
359 		serial->interface->needs_remote_wakeup = 1;
360 	spin_unlock_irq(&intfdata->susp_lock);
361 	/* this balances a get in the generic USB serial code */
362 	usb_autopm_put_interface(serial->interface);
363 
364 	return 0;
365 }
366 EXPORT_SYMBOL(usb_wwan_open);
367 
unbusy_queued_urb(struct urb * urb,struct usb_wwan_port_private * portdata)368 static void unbusy_queued_urb(struct urb *urb,
369 					struct usb_wwan_port_private *portdata)
370 {
371 	int i;
372 
373 	for (i = 0; i < N_OUT_URB; i++) {
374 		if (urb == portdata->out_urbs[i]) {
375 			clear_bit(i, &portdata->out_busy);
376 			break;
377 		}
378 	}
379 }
380 
usb_wwan_close(struct usb_serial_port * port)381 void usb_wwan_close(struct usb_serial_port *port)
382 {
383 	int i;
384 	struct usb_serial *serial = port->serial;
385 	struct usb_wwan_port_private *portdata;
386 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
387 	struct urb *urb;
388 
389 	portdata = usb_get_serial_port_data(port);
390 
391 	/*
392 	 * Need to take susp_lock to make sure port is not already being
393 	 * resumed, but no need to hold it due to the tty-port initialized
394 	 * flag.
395 	 */
396 	spin_lock_irq(&intfdata->susp_lock);
397 	if (--intfdata->open_ports == 0)
398 		serial->interface->needs_remote_wakeup = 0;
399 	spin_unlock_irq(&intfdata->susp_lock);
400 
401 	for (;;) {
402 		urb = usb_get_from_anchor(&portdata->delayed);
403 		if (!urb)
404 			break;
405 		unbusy_queued_urb(urb, portdata);
406 		usb_autopm_put_interface_async(serial->interface);
407 	}
408 
409 	for (i = 0; i < N_IN_URB; i++)
410 		usb_kill_urb(portdata->in_urbs[i]);
411 	for (i = 0; i < N_OUT_URB; i++)
412 		usb_kill_urb(portdata->out_urbs[i]);
413 	usb_kill_urb(port->interrupt_in_urb);
414 
415 	usb_autopm_get_interface_no_resume(serial->interface);
416 }
417 EXPORT_SYMBOL(usb_wwan_close);
418 
usb_wwan_setup_urb(struct usb_serial_port * port,int endpoint,int dir,void * ctx,char * buf,int len,void (* callback)(struct urb *))419 static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
420 				      int endpoint,
421 				      int dir, void *ctx, char *buf, int len,
422 				      void (*callback) (struct urb *))
423 {
424 	struct usb_serial *serial = port->serial;
425 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
426 	struct urb *urb;
427 
428 	urb = usb_alloc_urb(0, GFP_KERNEL);	/* No ISO */
429 	if (!urb)
430 		return NULL;
431 
432 	usb_fill_bulk_urb(urb, serial->dev,
433 			  usb_sndbulkpipe(serial->dev, endpoint) | dir,
434 			  buf, len, callback, ctx);
435 
436 	if (intfdata->use_zlp && dir == USB_DIR_OUT)
437 		urb->transfer_flags |= URB_ZERO_PACKET;
438 
439 	return urb;
440 }
441 
usb_wwan_port_probe(struct usb_serial_port * port)442 int usb_wwan_port_probe(struct usb_serial_port *port)
443 {
444 	struct usb_wwan_port_private *portdata;
445 	struct urb *urb;
446 	u8 *buffer;
447 	int i;
448 
449 	if (!port->bulk_in_size || !port->bulk_out_size)
450 		return -ENODEV;
451 
452 	portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
453 	if (!portdata)
454 		return -ENOMEM;
455 
456 	init_usb_anchor(&portdata->delayed);
457 
458 	for (i = 0; i < N_IN_URB; i++) {
459 		buffer = (u8 *)__get_free_page(GFP_KERNEL);
460 		if (!buffer)
461 			goto bail_out_error;
462 		portdata->in_buffer[i] = buffer;
463 
464 		urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress,
465 						USB_DIR_IN, port,
466 						buffer, IN_BUFLEN,
467 						usb_wwan_indat_callback);
468 		portdata->in_urbs[i] = urb;
469 	}
470 
471 	for (i = 0; i < N_OUT_URB; i++) {
472 		buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
473 		if (!buffer)
474 			goto bail_out_error2;
475 		portdata->out_buffer[i] = buffer;
476 
477 		urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress,
478 						USB_DIR_OUT, port,
479 						buffer, OUT_BUFLEN,
480 						usb_wwan_outdat_callback);
481 		portdata->out_urbs[i] = urb;
482 	}
483 
484 	usb_set_serial_port_data(port, portdata);
485 
486 	return 0;
487 
488 bail_out_error2:
489 	for (i = 0; i < N_OUT_URB; i++) {
490 		usb_free_urb(portdata->out_urbs[i]);
491 		kfree(portdata->out_buffer[i]);
492 	}
493 bail_out_error:
494 	for (i = 0; i < N_IN_URB; i++) {
495 		usb_free_urb(portdata->in_urbs[i]);
496 		free_page((unsigned long)portdata->in_buffer[i]);
497 	}
498 	kfree(portdata);
499 
500 	return -ENOMEM;
501 }
502 EXPORT_SYMBOL_GPL(usb_wwan_port_probe);
503 
usb_wwan_port_remove(struct usb_serial_port * port)504 void usb_wwan_port_remove(struct usb_serial_port *port)
505 {
506 	int i;
507 	struct usb_wwan_port_private *portdata;
508 
509 	portdata = usb_get_serial_port_data(port);
510 	usb_set_serial_port_data(port, NULL);
511 
512 	for (i = 0; i < N_IN_URB; i++) {
513 		usb_free_urb(portdata->in_urbs[i]);
514 		free_page((unsigned long)portdata->in_buffer[i]);
515 	}
516 	for (i = 0; i < N_OUT_URB; i++) {
517 		usb_free_urb(portdata->out_urbs[i]);
518 		kfree(portdata->out_buffer[i]);
519 	}
520 
521 	kfree(portdata);
522 }
523 EXPORT_SYMBOL(usb_wwan_port_remove);
524 
525 #ifdef CONFIG_PM
stop_urbs(struct usb_serial * serial)526 static void stop_urbs(struct usb_serial *serial)
527 {
528 	int i, j;
529 	struct usb_serial_port *port;
530 	struct usb_wwan_port_private *portdata;
531 
532 	for (i = 0; i < serial->num_ports; ++i) {
533 		port = serial->port[i];
534 		portdata = usb_get_serial_port_data(port);
535 		if (!portdata)
536 			continue;
537 		for (j = 0; j < N_IN_URB; j++)
538 			usb_kill_urb(portdata->in_urbs[j]);
539 		for (j = 0; j < N_OUT_URB; j++)
540 			usb_kill_urb(portdata->out_urbs[j]);
541 		usb_kill_urb(port->interrupt_in_urb);
542 	}
543 }
544 
usb_wwan_suspend(struct usb_serial * serial,pm_message_t message)545 int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
546 {
547 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
548 
549 	spin_lock_irq(&intfdata->susp_lock);
550 	if (PMSG_IS_AUTO(message)) {
551 		if (intfdata->in_flight) {
552 			spin_unlock_irq(&intfdata->susp_lock);
553 			return -EBUSY;
554 		}
555 	}
556 	intfdata->suspended = 1;
557 	spin_unlock_irq(&intfdata->susp_lock);
558 
559 	stop_urbs(serial);
560 
561 	return 0;
562 }
563 EXPORT_SYMBOL(usb_wwan_suspend);
564 
565 /* Caller must hold susp_lock. */
usb_wwan_submit_delayed_urbs(struct usb_serial_port * port)566 static int usb_wwan_submit_delayed_urbs(struct usb_serial_port *port)
567 {
568 	struct usb_serial *serial = port->serial;
569 	struct usb_wwan_intf_private *data = usb_get_serial_data(serial);
570 	struct usb_wwan_port_private *portdata;
571 	struct urb *urb;
572 	int err_count = 0;
573 	int err;
574 
575 	portdata = usb_get_serial_port_data(port);
576 
577 	for (;;) {
578 		urb = usb_get_from_anchor(&portdata->delayed);
579 		if (!urb)
580 			break;
581 
582 		err = usb_submit_urb(urb, GFP_ATOMIC);
583 		if (err) {
584 			dev_err(&port->dev, "%s: submit urb failed: %d\n",
585 					__func__, err);
586 			err_count++;
587 			unbusy_queued_urb(urb, portdata);
588 			usb_autopm_put_interface_async(serial->interface);
589 			continue;
590 		}
591 		data->in_flight++;
592 	}
593 
594 	if (err_count)
595 		return -EIO;
596 
597 	return 0;
598 }
599 
usb_wwan_resume(struct usb_serial * serial)600 int usb_wwan_resume(struct usb_serial *serial)
601 {
602 	int i, j;
603 	struct usb_serial_port *port;
604 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
605 	struct usb_wwan_port_private *portdata;
606 	struct urb *urb;
607 	int err;
608 	int err_count = 0;
609 
610 	spin_lock_irq(&intfdata->susp_lock);
611 	for (i = 0; i < serial->num_ports; i++) {
612 		port = serial->port[i];
613 
614 		if (!tty_port_initialized(&port->port))
615 			continue;
616 
617 		portdata = usb_get_serial_port_data(port);
618 
619 		if (port->interrupt_in_urb) {
620 			err = usb_submit_urb(port->interrupt_in_urb,
621 					GFP_ATOMIC);
622 			if (err) {
623 				dev_err(&port->dev,
624 					"%s: submit int urb failed: %d\n",
625 					__func__, err);
626 				err_count++;
627 			}
628 		}
629 
630 		err = usb_wwan_submit_delayed_urbs(port);
631 		if (err)
632 			err_count++;
633 
634 		for (j = 0; j < N_IN_URB; j++) {
635 			urb = portdata->in_urbs[j];
636 			err = usb_submit_urb(urb, GFP_ATOMIC);
637 			if (err < 0) {
638 				dev_err(&port->dev,
639 					"%s: submit read urb %d failed: %d\n",
640 					__func__, i, err);
641 				err_count++;
642 			}
643 		}
644 	}
645 	intfdata->suspended = 0;
646 	spin_unlock_irq(&intfdata->susp_lock);
647 
648 	if (err_count)
649 		return -EIO;
650 
651 	return 0;
652 }
653 EXPORT_SYMBOL(usb_wwan_resume);
654 #endif
655 
656 MODULE_AUTHOR(DRIVER_AUTHOR);
657 MODULE_DESCRIPTION(DRIVER_DESC);
658 MODULE_LICENSE("GPL v2");
659