linux/drivers/usb/serial/usb_wwan.c
<<
>>
Prefs
   1/*
   2  USB Driver layer for GSM modems
   3
   4  Copyright (C) 2005  Matthias Urlichs <smurf@smurf.noris.de>
   5
   6  This driver is free software; you can redistribute it and/or modify
   7  it under the terms of Version 2 of the GNU General Public License as
   8  published by the Free Software Foundation.
   9
  10  Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
  11
  12  History: see the git log.
  13
  14  Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
  15
  16  This driver exists because the "normal" serial driver doesn't work too well
  17  with GSM modems. Issues:
  18  - data loss -- one single Receive URB is not nearly enough
  19  - controlling the baud rate doesn't make sense
  20*/
  21
  22#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
  23#define DRIVER_DESC "USB Driver for GSM modems"
  24
  25#include <linux/kernel.h>
  26#include <linux/jiffies.h>
  27#include <linux/errno.h>
  28#include <linux/slab.h>
  29#include <linux/tty.h>
  30#include <linux/tty_flip.h>
  31#include <linux/module.h>
  32#include <linux/bitops.h>
  33#include <linux/uaccess.h>
  34#include <linux/usb.h>
  35#include <linux/usb/serial.h>
  36#include <linux/serial.h>
  37#include "usb-wwan.h"
  38
  39void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
  40{
  41        struct usb_wwan_port_private *portdata;
  42        struct usb_wwan_intf_private *intfdata;
  43
  44        intfdata = usb_get_serial_data(port->serial);
  45
  46        if (!intfdata->send_setup)
  47                return;
  48
  49        portdata = usb_get_serial_port_data(port);
  50        /* FIXME: locking */
  51        portdata->rts_state = on;
  52        portdata->dtr_state = on;
  53
  54        intfdata->send_setup(port);
  55}
  56EXPORT_SYMBOL(usb_wwan_dtr_rts);
  57
  58int usb_wwan_tiocmget(struct tty_struct *tty)
  59{
  60        struct usb_serial_port *port = tty->driver_data;
  61        unsigned int value;
  62        struct usb_wwan_port_private *portdata;
  63
  64        portdata = usb_get_serial_port_data(port);
  65
  66        value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
  67            ((portdata->dtr_state) ? TIOCM_DTR : 0) |
  68            ((portdata->cts_state) ? TIOCM_CTS : 0) |
  69            ((portdata->dsr_state) ? TIOCM_DSR : 0) |
  70            ((portdata->dcd_state) ? TIOCM_CAR : 0) |
  71            ((portdata->ri_state) ? TIOCM_RNG : 0);
  72
  73        return value;
  74}
  75EXPORT_SYMBOL(usb_wwan_tiocmget);
  76
  77int usb_wwan_tiocmset(struct tty_struct *tty,
  78                      unsigned int set, unsigned int clear)
  79{
  80        struct usb_serial_port *port = tty->driver_data;
  81        struct usb_wwan_port_private *portdata;
  82        struct usb_wwan_intf_private *intfdata;
  83
  84        portdata = usb_get_serial_port_data(port);
  85        intfdata = usb_get_serial_data(port->serial);
  86
  87        if (!intfdata->send_setup)
  88                return -EINVAL;
  89
  90        /* FIXME: what locks portdata fields ? */
  91        if (set & TIOCM_RTS)
  92                portdata->rts_state = 1;
  93        if (set & TIOCM_DTR)
  94                portdata->dtr_state = 1;
  95
  96        if (clear & TIOCM_RTS)
  97                portdata->rts_state = 0;
  98        if (clear & TIOCM_DTR)
  99                portdata->dtr_state = 0;
 100        return intfdata->send_setup(port);
 101}
 102EXPORT_SYMBOL(usb_wwan_tiocmset);
 103
 104static int get_serial_info(struct usb_serial_port *port,
 105                           struct serial_struct __user *retinfo)
 106{
 107        struct serial_struct tmp;
 108
 109        if (!retinfo)
 110                return -EFAULT;
 111
 112        memset(&tmp, 0, sizeof(tmp));
 113        tmp.line            = port->minor;
 114        tmp.port            = port->port_number;
 115        tmp.baud_base       = tty_get_baud_rate(port->port.tty);
 116        tmp.close_delay     = port->port.close_delay / 10;
 117        tmp.closing_wait    = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
 118                                 ASYNC_CLOSING_WAIT_NONE :
 119                                 port->port.closing_wait / 10;
 120
 121        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
 122                return -EFAULT;
 123        return 0;
 124}
 125
 126static int set_serial_info(struct usb_serial_port *port,
 127                           struct serial_struct __user *newinfo)
 128{
 129        struct serial_struct new_serial;
 130        unsigned int closing_wait, close_delay;
 131        int retval = 0;
 132
 133        if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
 134                return -EFAULT;
 135
 136        close_delay = new_serial.close_delay * 10;
 137        closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
 138                        ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
 139
 140        mutex_lock(&port->port.mutex);
 141
 142        if (!capable(CAP_SYS_ADMIN)) {
 143                if ((close_delay != port->port.close_delay) ||
 144                    (closing_wait != port->port.closing_wait))
 145                        retval = -EPERM;
 146                else
 147                        retval = -EOPNOTSUPP;
 148        } else {
 149                port->port.close_delay  = close_delay;
 150                port->port.closing_wait = closing_wait;
 151        }
 152
 153        mutex_unlock(&port->port.mutex);
 154        return retval;
 155}
 156
 157int usb_wwan_ioctl(struct tty_struct *tty,
 158                   unsigned int cmd, unsigned long arg)
 159{
 160        struct usb_serial_port *port = tty->driver_data;
 161
 162        dev_dbg(&port->dev, "%s cmd 0x%04x\n", __func__, cmd);
 163
 164        switch (cmd) {
 165        case TIOCGSERIAL:
 166                return get_serial_info(port,
 167                                       (struct serial_struct __user *) arg);
 168        case TIOCSSERIAL:
 169                return set_serial_info(port,
 170                                       (struct serial_struct __user *) arg);
 171        default:
 172                break;
 173        }
 174
 175        dev_dbg(&port->dev, "%s arg not supported\n", __func__);
 176
 177        return -ENOIOCTLCMD;
 178}
 179EXPORT_SYMBOL(usb_wwan_ioctl);
 180
 181int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
 182                   const unsigned char *buf, int count)
 183{
 184        struct usb_wwan_port_private *portdata;
 185        struct usb_wwan_intf_private *intfdata;
 186        int i;
 187        int left, todo;
 188        struct urb *this_urb = NULL;    /* spurious */
 189        int err;
 190        unsigned long flags;
 191
 192        portdata = usb_get_serial_port_data(port);
 193        intfdata = usb_get_serial_data(port->serial);
 194
 195        dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count);
 196
 197        i = 0;
 198        left = count;
 199        for (i = 0; left > 0 && i < N_OUT_URB; i++) {
 200                todo = left;
 201                if (todo > OUT_BUFLEN)
 202                        todo = OUT_BUFLEN;
 203
 204                this_urb = portdata->out_urbs[i];
 205                if (test_and_set_bit(i, &portdata->out_busy)) {
 206                        if (time_before(jiffies,
 207                                        portdata->tx_start_time[i] + 10 * HZ))
 208                                continue;
 209                        usb_unlink_urb(this_urb);
 210                        continue;
 211                }
 212                dev_dbg(&port->dev, "%s: endpoint %d buf %d\n", __func__,
 213                        usb_pipeendpoint(this_urb->pipe), i);
 214
 215                err = usb_autopm_get_interface_async(port->serial->interface);
 216                if (err < 0) {
 217                        clear_bit(i, &portdata->out_busy);
 218                        break;
 219                }
 220
 221                /* send the data */
 222                memcpy(this_urb->transfer_buffer, buf, todo);
 223                this_urb->transfer_buffer_length = todo;
 224
 225                spin_lock_irqsave(&intfdata->susp_lock, flags);
 226                if (intfdata->suspended) {
 227                        usb_anchor_urb(this_urb, &portdata->delayed);
 228                        spin_unlock_irqrestore(&intfdata->susp_lock, flags);
 229                } else {
 230                        intfdata->in_flight++;
 231                        spin_unlock_irqrestore(&intfdata->susp_lock, flags);
 232                        err = usb_submit_urb(this_urb, GFP_ATOMIC);
 233                        if (err) {
 234                                dev_err(&port->dev,
 235                                        "%s: submit urb %d failed: %d\n",
 236                                        __func__, i, err);
 237                                clear_bit(i, &portdata->out_busy);
 238                                spin_lock_irqsave(&intfdata->susp_lock, flags);
 239                                intfdata->in_flight--;
 240                                spin_unlock_irqrestore(&intfdata->susp_lock,
 241                                                       flags);
 242                                usb_autopm_put_interface_async(port->serial->interface);
 243                                break;
 244                        }
 245                }
 246
 247                portdata->tx_start_time[i] = jiffies;
 248                buf += todo;
 249                left -= todo;
 250        }
 251
 252        count -= left;
 253        dev_dbg(&port->dev, "%s: wrote (did %d)\n", __func__, count);
 254        return count;
 255}
 256EXPORT_SYMBOL(usb_wwan_write);
 257
 258static void usb_wwan_indat_callback(struct urb *urb)
 259{
 260        int err;
 261        int endpoint;
 262        struct usb_serial_port *port;
 263        struct device *dev;
 264        unsigned char *data = urb->transfer_buffer;
 265        int status = urb->status;
 266
 267        endpoint = usb_pipeendpoint(urb->pipe);
 268        port = urb->context;
 269        dev = &port->dev;
 270
 271        if (status) {
 272                dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n",
 273                        __func__, status, endpoint);
 274        } else {
 275                if (urb->actual_length) {
 276                        tty_insert_flip_string(&port->port, data,
 277                                        urb->actual_length);
 278                        tty_flip_buffer_push(&port->port);
 279                } else
 280                        dev_dbg(dev, "%s: empty read urb received\n", __func__);
 281        }
 282        /* Resubmit urb so we continue receiving */
 283        err = usb_submit_urb(urb, GFP_ATOMIC);
 284        if (err) {
 285                if (err != -EPERM) {
 286                        dev_err(dev, "%s: resubmit read urb failed. (%d)\n",
 287                                __func__, err);
 288                        /* busy also in error unless we are killed */
 289                        usb_mark_last_busy(port->serial->dev);
 290                }
 291        } else {
 292                usb_mark_last_busy(port->serial->dev);
 293        }
 294}
 295
 296static void usb_wwan_outdat_callback(struct urb *urb)
 297{
 298        struct usb_serial_port *port;
 299        struct usb_wwan_port_private *portdata;
 300        struct usb_wwan_intf_private *intfdata;
 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(&intfdata->susp_lock);
 310        intfdata->in_flight--;
 311        spin_unlock(&intfdata->susp_lock);
 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 ASYNC_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 (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
 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");
 696