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