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