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
 135static int get_serial_info(struct usb_serial_port *port,
 136                           struct serial_struct __user *retinfo)
 137{
 138        struct serial_struct tmp;
 139
 140        memset(&tmp, 0, sizeof(tmp));
 141        tmp.line            = port->minor;
 142        tmp.port            = port->port_number;
 143        tmp.baud_base       = tty_get_baud_rate(port->port.tty);
 144        tmp.close_delay     = port->port.close_delay / 10;
 145        tmp.closing_wait    = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
 146                                 ASYNC_CLOSING_WAIT_NONE :
 147                                 port->port.closing_wait / 10;
 148
 149        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
 150                return -EFAULT;
 151        return 0;
 152}
 153
 154static int set_serial_info(struct usb_serial_port *port,
 155                           struct serial_struct __user *newinfo)
 156{
 157        struct serial_struct new_serial;
 158        unsigned int closing_wait, close_delay;
 159        int retval = 0;
 160
 161        if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
 162                return -EFAULT;
 163
 164        close_delay = new_serial.close_delay * 10;
 165        closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
 166                        ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
 167
 168        mutex_lock(&port->port.mutex);
 169
 170        if (!capable(CAP_SYS_ADMIN)) {
 171                if ((close_delay != port->port.close_delay) ||
 172                    (closing_wait != port->port.closing_wait))
 173                        retval = -EPERM;
 174                else
 175                        retval = -EOPNOTSUPP;
 176        } else {
 177                port->port.close_delay  = close_delay;
 178                port->port.closing_wait = closing_wait;
 179        }
 180
 181        mutex_unlock(&port->port.mutex);
 182        return retval;
 183}
 184
 185int usb_wwan_ioctl(struct tty_struct *tty,
 186                   unsigned int cmd, unsigned long arg)
 187{
 188        struct usb_serial_port *port = tty->driver_data;
 189
 190        dev_dbg(&port->dev, "%s cmd 0x%04x\n", __func__, cmd);
 191
 192        switch (cmd) {
 193        case TIOCGSERIAL:
 194                return get_serial_info(port,
 195                                       (struct serial_struct __user *) arg);
 196        case TIOCSSERIAL:
 197                return set_serial_info(port,
 198                                       (struct serial_struct __user *) arg);
 199        default:
 200                break;
 201        }
 202
 203        dev_dbg(&port->dev, "%s arg not supported\n", __func__);
 204
 205        return -ENOIOCTLCMD;
 206}
 207EXPORT_SYMBOL(usb_wwan_ioctl);
 208
 209int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
 210                   const unsigned char *buf, int count)
 211{
 212        struct usb_wwan_port_private *portdata;
 213        struct usb_wwan_intf_private *intfdata;
 214        int i;
 215        int left, todo;
 216        struct urb *this_urb = NULL;    /* spurious */
 217        int err;
 218        unsigned long flags;
 219
 220        portdata = usb_get_serial_port_data(port);
 221        intfdata = usb_get_serial_data(port->serial);
 222
 223        dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count);
 224
 225        i = 0;
 226        left = count;
 227        for (i = 0; left > 0 && i < N_OUT_URB; i++) {
 228                todo = left;
 229                if (todo > OUT_BUFLEN)
 230                        todo = OUT_BUFLEN;
 231
 232                this_urb = portdata->out_urbs[i];
 233                if (test_and_set_bit(i, &portdata->out_busy)) {
 234                        if (time_before(jiffies,
 235                                        portdata->tx_start_time[i] + 10 * HZ))
 236                                continue;
 237                        usb_unlink_urb(this_urb);
 238                        continue;
 239                }
 240                dev_dbg(&port->dev, "%s: endpoint %d buf %d\n", __func__,
 241                        usb_pipeendpoint(this_urb->pipe), i);
 242
 243                err = usb_autopm_get_interface_async(port->serial->interface);
 244                if (err < 0) {
 245                        clear_bit(i, &portdata->out_busy);
 246                        break;
 247                }
 248
 249                /* send the data */
 250                memcpy(this_urb->transfer_buffer, buf, todo);
 251                this_urb->transfer_buffer_length = todo;
 252
 253                spin_lock_irqsave(&intfdata->susp_lock, flags);
 254                if (intfdata->suspended) {
 255                        usb_anchor_urb(this_urb, &portdata->delayed);
 256                        spin_unlock_irqrestore(&intfdata->susp_lock, flags);
 257                } else {
 258                        intfdata->in_flight++;
 259                        spin_unlock_irqrestore(&intfdata->susp_lock, flags);
 260                        err = usb_submit_urb(this_urb, GFP_ATOMIC);
 261                        if (err) {
 262                                dev_err(&port->dev,
 263                                        "%s: submit urb %d failed: %d\n",
 264                                        __func__, i, err);
 265                                clear_bit(i, &portdata->out_busy);
 266                                spin_lock_irqsave(&intfdata->susp_lock, flags);
 267                                intfdata->in_flight--;
 268                                spin_unlock_irqrestore(&intfdata->susp_lock,
 269                                                       flags);
 270                                usb_autopm_put_interface_async(port->serial->interface);
 271                                break;
 272                        }
 273                }
 274
 275                portdata->tx_start_time[i] = jiffies;
 276                buf += todo;
 277                left -= todo;
 278        }
 279
 280        count -= left;
 281        dev_dbg(&port->dev, "%s: wrote (did %d)\n", __func__, count);
 282        return count;
 283}
 284EXPORT_SYMBOL(usb_wwan_write);
 285
 286static void usb_wwan_indat_callback(struct urb *urb)
 287{
 288        int err;
 289        int endpoint;
 290        struct usb_serial_port *port;
 291        struct device *dev;
 292        unsigned char *data = urb->transfer_buffer;
 293        int status = urb->status;
 294
 295        endpoint = usb_pipeendpoint(urb->pipe);
 296        port = urb->context;
 297        dev = &port->dev;
 298
 299        if (status) {
 300                dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n",
 301                        __func__, status, endpoint);
 302        } else {
 303                if (urb->actual_length) {
 304                        tty_insert_flip_string(&port->port, data,
 305                                        urb->actual_length);
 306                        tty_flip_buffer_push(&port->port);
 307                } else
 308                        dev_dbg(dev, "%s: empty read urb received\n", __func__);
 309        }
 310        /* Resubmit urb so we continue receiving */
 311        err = usb_submit_urb(urb, GFP_ATOMIC);
 312        if (err) {
 313                if (err != -EPERM && err != -ENODEV) {
 314                        dev_err(dev, "%s: resubmit read urb failed. (%d)\n",
 315                                __func__, err);
 316                        /* busy also in error unless we are killed */
 317                        usb_mark_last_busy(port->serial->dev);
 318                }
 319        } else {
 320                usb_mark_last_busy(port->serial->dev);
 321        }
 322}
 323
 324static void usb_wwan_outdat_callback(struct urb *urb)
 325{
 326        struct usb_serial_port *port;
 327        struct usb_wwan_port_private *portdata;
 328        struct usb_wwan_intf_private *intfdata;
 329        int i;
 330
 331        port = urb->context;
 332        intfdata = usb_get_serial_data(port->serial);
 333
 334        usb_serial_port_softint(port);
 335        usb_autopm_put_interface_async(port->serial->interface);
 336        portdata = usb_get_serial_port_data(port);
 337        spin_lock(&intfdata->susp_lock);
 338        intfdata->in_flight--;
 339        spin_unlock(&intfdata->susp_lock);
 340
 341        for (i = 0; i < N_OUT_URB; ++i) {
 342                if (portdata->out_urbs[i] == urb) {
 343                        smp_mb__before_atomic();
 344                        clear_bit(i, &portdata->out_busy);
 345                        break;
 346                }
 347        }
 348}
 349
 350int usb_wwan_write_room(struct tty_struct *tty)
 351{
 352        struct usb_serial_port *port = tty->driver_data;
 353        struct usb_wwan_port_private *portdata;
 354        int i;
 355        int data_len = 0;
 356        struct urb *this_urb;
 357
 358        portdata = usb_get_serial_port_data(port);
 359
 360        for (i = 0; i < N_OUT_URB; i++) {
 361                this_urb = portdata->out_urbs[i];
 362                if (this_urb && !test_bit(i, &portdata->out_busy))
 363                        data_len += OUT_BUFLEN;
 364        }
 365
 366        dev_dbg(&port->dev, "%s: %d\n", __func__, data_len);
 367        return data_len;
 368}
 369EXPORT_SYMBOL(usb_wwan_write_room);
 370
 371int usb_wwan_chars_in_buffer(struct tty_struct *tty)
 372{
 373        struct usb_serial_port *port = tty->driver_data;
 374        struct usb_wwan_port_private *portdata;
 375        int i;
 376        int data_len = 0;
 377        struct urb *this_urb;
 378
 379        portdata = usb_get_serial_port_data(port);
 380
 381        for (i = 0; i < N_OUT_URB; i++) {
 382                this_urb = portdata->out_urbs[i];
 383                /* FIXME: This locking is insufficient as this_urb may
 384                   go unused during the test */
 385                if (this_urb && test_bit(i, &portdata->out_busy))
 386                        data_len += this_urb->transfer_buffer_length;
 387        }
 388        dev_dbg(&port->dev, "%s: %d\n", __func__, data_len);
 389        return data_len;
 390}
 391EXPORT_SYMBOL(usb_wwan_chars_in_buffer);
 392
 393int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port)
 394{
 395        struct usb_wwan_port_private *portdata;
 396        struct usb_wwan_intf_private *intfdata;
 397        struct usb_serial *serial = port->serial;
 398        int i, err;
 399        struct urb *urb;
 400
 401        portdata = usb_get_serial_port_data(port);
 402        intfdata = usb_get_serial_data(serial);
 403
 404        if (port->interrupt_in_urb) {
 405                err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 406                if (err) {
 407                        dev_err(&port->dev, "%s: submit int urb failed: %d\n",
 408                                __func__, err);
 409                }
 410        }
 411
 412        /* Start reading from the IN endpoint */
 413        for (i = 0; i < N_IN_URB; i++) {
 414                urb = portdata->in_urbs[i];
 415                if (!urb)
 416                        continue;
 417                err = usb_submit_urb(urb, GFP_KERNEL);
 418                if (err) {
 419                        dev_err(&port->dev,
 420                                "%s: submit read urb %d failed: %d\n",
 421                                __func__, i, err);
 422                }
 423        }
 424
 425        spin_lock_irq(&intfdata->susp_lock);
 426        if (++intfdata->open_ports == 1)
 427                serial->interface->needs_remote_wakeup = 1;
 428        spin_unlock_irq(&intfdata->susp_lock);
 429        /* this balances a get in the generic USB serial code */
 430        usb_autopm_put_interface(serial->interface);
 431
 432        return 0;
 433}
 434EXPORT_SYMBOL(usb_wwan_open);
 435
 436static void unbusy_queued_urb(struct urb *urb,
 437                                        struct usb_wwan_port_private *portdata)
 438{
 439        int i;
 440
 441        for (i = 0; i < N_OUT_URB; i++) {
 442                if (urb == portdata->out_urbs[i]) {
 443                        clear_bit(i, &portdata->out_busy);
 444                        break;
 445                }
 446        }
 447}
 448
 449void usb_wwan_close(struct usb_serial_port *port)
 450{
 451        int i;
 452        struct usb_serial *serial = port->serial;
 453        struct usb_wwan_port_private *portdata;
 454        struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
 455        struct urb *urb;
 456
 457        portdata = usb_get_serial_port_data(port);
 458
 459        /*
 460         * Need to take susp_lock to make sure port is not already being
 461         * resumed, but no need to hold it due to initialized
 462         */
 463        spin_lock_irq(&intfdata->susp_lock);
 464        if (--intfdata->open_ports == 0)
 465                serial->interface->needs_remote_wakeup = 0;
 466        spin_unlock_irq(&intfdata->susp_lock);
 467
 468        for (;;) {
 469                urb = usb_get_from_anchor(&portdata->delayed);
 470                if (!urb)
 471                        break;
 472                unbusy_queued_urb(urb, portdata);
 473                usb_autopm_put_interface_async(serial->interface);
 474        }
 475
 476        for (i = 0; i < N_IN_URB; i++)
 477                usb_kill_urb(portdata->in_urbs[i]);
 478        for (i = 0; i < N_OUT_URB; i++)
 479                usb_kill_urb(portdata->out_urbs[i]);
 480        usb_kill_urb(port->interrupt_in_urb);
 481
 482        usb_autopm_get_interface_no_resume(serial->interface);
 483}
 484EXPORT_SYMBOL(usb_wwan_close);
 485
 486static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
 487                                      int endpoint,
 488                                      int dir, void *ctx, char *buf, int len,
 489                                      void (*callback) (struct urb *))
 490{
 491        struct usb_serial *serial = port->serial;
 492        struct urb *urb;
 493
 494        urb = usb_alloc_urb(0, GFP_KERNEL);     /* No ISO */
 495        if (!urb)
 496                return NULL;
 497
 498        usb_fill_bulk_urb(urb, serial->dev,
 499                          usb_sndbulkpipe(serial->dev, endpoint) | dir,
 500                          buf, len, callback, ctx);
 501
 502        return urb;
 503}
 504
 505int usb_wwan_port_probe(struct usb_serial_port *port)
 506{
 507        struct usb_wwan_port_private *portdata;
 508        struct urb *urb;
 509        u8 *buffer;
 510        int i;
 511
 512        if (!port->bulk_in_size || !port->bulk_out_size)
 513                return -ENODEV;
 514
 515        portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
 516        if (!portdata)
 517                return -ENOMEM;
 518
 519        init_usb_anchor(&portdata->delayed);
 520
 521        for (i = 0; i < N_IN_URB; i++) {
 522                buffer = (u8 *)__get_free_page(GFP_KERNEL);
 523                if (!buffer)
 524                        goto bail_out_error;
 525                portdata->in_buffer[i] = buffer;
 526
 527                urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress,
 528                                                USB_DIR_IN, port,
 529                                                buffer, IN_BUFLEN,
 530                                                usb_wwan_indat_callback);
 531                portdata->in_urbs[i] = urb;
 532        }
 533
 534        for (i = 0; i < N_OUT_URB; i++) {
 535                buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
 536                if (!buffer)
 537                        goto bail_out_error2;
 538                portdata->out_buffer[i] = buffer;
 539
 540                urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress,
 541                                                USB_DIR_OUT, port,
 542                                                buffer, OUT_BUFLEN,
 543                                                usb_wwan_outdat_callback);
 544                portdata->out_urbs[i] = urb;
 545        }
 546
 547        usb_set_serial_port_data(port, portdata);
 548
 549        return 0;
 550
 551bail_out_error2:
 552        for (i = 0; i < N_OUT_URB; i++) {
 553                usb_free_urb(portdata->out_urbs[i]);
 554                kfree(portdata->out_buffer[i]);
 555        }
 556bail_out_error:
 557        for (i = 0; i < N_IN_URB; i++) {
 558                usb_free_urb(portdata->in_urbs[i]);
 559                free_page((unsigned long)portdata->in_buffer[i]);
 560        }
 561        kfree(portdata);
 562
 563        return -ENOMEM;
 564}
 565EXPORT_SYMBOL_GPL(usb_wwan_port_probe);
 566
 567int usb_wwan_port_remove(struct usb_serial_port *port)
 568{
 569        int i;
 570        struct usb_wwan_port_private *portdata;
 571
 572        portdata = usb_get_serial_port_data(port);
 573        usb_set_serial_port_data(port, NULL);
 574
 575        for (i = 0; i < N_IN_URB; i++) {
 576                usb_free_urb(portdata->in_urbs[i]);
 577                free_page((unsigned long)portdata->in_buffer[i]);
 578        }
 579        for (i = 0; i < N_OUT_URB; i++) {
 580                usb_free_urb(portdata->out_urbs[i]);
 581                kfree(portdata->out_buffer[i]);
 582        }
 583
 584        kfree(portdata);
 585
 586        return 0;
 587}
 588EXPORT_SYMBOL(usb_wwan_port_remove);
 589
 590#ifdef CONFIG_PM
 591static void stop_urbs(struct usb_serial *serial)
 592{
 593        int i, j;
 594        struct usb_serial_port *port;
 595        struct usb_wwan_port_private *portdata;
 596
 597        for (i = 0; i < serial->num_ports; ++i) {
 598                port = serial->port[i];
 599                portdata = usb_get_serial_port_data(port);
 600                if (!portdata)
 601                        continue;
 602                for (j = 0; j < N_IN_URB; j++)
 603                        usb_kill_urb(portdata->in_urbs[j]);
 604                for (j = 0; j < N_OUT_URB; j++)
 605                        usb_kill_urb(portdata->out_urbs[j]);
 606                usb_kill_urb(port->interrupt_in_urb);
 607        }
 608}
 609
 610int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
 611{
 612        struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
 613
 614        spin_lock_irq(&intfdata->susp_lock);
 615        if (PMSG_IS_AUTO(message)) {
 616                if (intfdata->in_flight) {
 617                        spin_unlock_irq(&intfdata->susp_lock);
 618                        return -EBUSY;
 619                }
 620        }
 621        intfdata->suspended = 1;
 622        spin_unlock_irq(&intfdata->susp_lock);
 623
 624        stop_urbs(serial);
 625
 626        return 0;
 627}
 628EXPORT_SYMBOL(usb_wwan_suspend);
 629
 630/* Caller must hold susp_lock. */
 631static int usb_wwan_submit_delayed_urbs(struct usb_serial_port *port)
 632{
 633        struct usb_serial *serial = port->serial;
 634        struct usb_wwan_intf_private *data = usb_get_serial_data(serial);
 635        struct usb_wwan_port_private *portdata;
 636        struct urb *urb;
 637        int err_count = 0;
 638        int err;
 639
 640        portdata = usb_get_serial_port_data(port);
 641
 642        for (;;) {
 643                urb = usb_get_from_anchor(&portdata->delayed);
 644                if (!urb)
 645                        break;
 646
 647                err = usb_submit_urb(urb, GFP_ATOMIC);
 648                if (err) {
 649                        dev_err(&port->dev, "%s: submit urb failed: %d\n",
 650                                        __func__, err);
 651                        err_count++;
 652                        unbusy_queued_urb(urb, portdata);
 653                        usb_autopm_put_interface_async(serial->interface);
 654                        continue;
 655                }
 656                data->in_flight++;
 657        }
 658
 659        if (err_count)
 660                return -EIO;
 661
 662        return 0;
 663}
 664
 665int usb_wwan_resume(struct usb_serial *serial)
 666{
 667        int i, j;
 668        struct usb_serial_port *port;
 669        struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
 670        struct usb_wwan_port_private *portdata;
 671        struct urb *urb;
 672        int err;
 673        int err_count = 0;
 674
 675        spin_lock_irq(&intfdata->susp_lock);
 676        for (i = 0; i < serial->num_ports; i++) {
 677                port = serial->port[i];
 678
 679                if (!tty_port_initialized(&port->port))
 680                        continue;
 681
 682                portdata = usb_get_serial_port_data(port);
 683
 684                if (port->interrupt_in_urb) {
 685                        err = usb_submit_urb(port->interrupt_in_urb,
 686                                        GFP_ATOMIC);
 687                        if (err) {
 688                                dev_err(&port->dev,
 689                                        "%s: submit int urb failed: %d\n",
 690                                        __func__, err);
 691                                err_count++;
 692                        }
 693                }
 694
 695                err = usb_wwan_submit_delayed_urbs(port);
 696                if (err)
 697                        err_count++;
 698
 699                for (j = 0; j < N_IN_URB; j++) {
 700                        urb = portdata->in_urbs[j];
 701                        err = usb_submit_urb(urb, GFP_ATOMIC);
 702                        if (err < 0) {
 703                                dev_err(&port->dev,
 704                                        "%s: submit read urb %d failed: %d\n",
 705                                        __func__, i, err);
 706                                err_count++;
 707                        }
 708                }
 709        }
 710        intfdata->suspended = 0;
 711        spin_unlock_irq(&intfdata->susp_lock);
 712
 713        if (err_count)
 714                return -EIO;
 715
 716        return 0;
 717}
 718EXPORT_SYMBOL(usb_wwan_resume);
 719#endif
 720
 721MODULE_AUTHOR(DRIVER_AUTHOR);
 722MODULE_DESCRIPTION(DRIVER_DESC);
 723MODULE_LICENSE("GPL v2");
 724