diff options
Diffstat (limited to 'drivers/net/usb')
29 files changed, 362 insertions, 187 deletions
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 42b5151aa78..71e2b0523bc 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1647,6 +1647,7 @@ static struct usb_driver asix_driver = { .resume = usbnet_resume, .disconnect = usbnet_disconnect, .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(asix_driver); diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 182cfb4aeb1..26c5bebd9ec 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -338,16 +338,18 @@ static void catc_irq_done(struct urb *urb) } else { catc->rx_urb->dev = catc->usbdev; if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) { - err("submit(rx_urb) status %d", res); + dev_err(&catc->usbdev->dev, + "submit(rx_urb) status %d\n", res); } } } resubmit: res = usb_submit_urb (urb, GFP_ATOMIC); if (res) - err ("can't resubmit intr, %s-%s, status %d", - catc->usbdev->bus->bus_name, - catc->usbdev->devpath, res); + dev_err(&catc->usbdev->dev, + "can't resubmit intr, %s-%s, status %d\n", + catc->usbdev->bus->bus_name, + catc->usbdev->devpath, res); } /* @@ -366,7 +368,8 @@ static int catc_tx_run(struct catc *catc) catc->tx_urb->dev = catc->usbdev; if ((status = usb_submit_urb(catc->tx_urb, GFP_ATOMIC)) < 0) - err("submit(tx_urb), status %d", status); + dev_err(&catc->usbdev->dev, "submit(tx_urb), status %d\n", + status); catc->tx_idx = !catc->tx_idx; catc->tx_ptr = 0; @@ -496,7 +499,8 @@ static void catc_ctrl_run(struct catc *catc) memcpy(catc->ctrl_buf, q->buf, q->len); if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC))) - err("submit(ctrl_urb) status %d", status); + dev_err(&catc->usbdev->dev, "submit(ctrl_urb) status %d\n", + status); } static void catc_ctrl_done(struct urb *urb) @@ -555,7 +559,7 @@ static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value, catc->ctrl_head = (catc->ctrl_head + 1) & (CTRL_QUEUE - 1); if (catc->ctrl_head == catc->ctrl_tail) { - err("ctrl queue full"); + dev_err(&catc->usbdev->dev, "ctrl queue full\n"); catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1); retval = -1; } @@ -714,7 +718,8 @@ static int catc_open(struct net_device *netdev) catc->irq_urb->dev = catc->usbdev; if ((status = usb_submit_urb(catc->irq_urb, GFP_KERNEL)) < 0) { - err("submit(irq_urb) status %d", status); + dev_err(&catc->usbdev->dev, "submit(irq_urb) status %d\n", + status); return -1; } @@ -769,7 +774,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id if (usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 1)) { - err("Can't set altsetting 1."); + dev_err(&intf->dev, "Can't set altsetting 1.\n"); return -EIO; } @@ -799,7 +804,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id catc->irq_urb = usb_alloc_urb(0, GFP_KERNEL); if ((!catc->ctrl_urb) || (!catc->tx_urb) || (!catc->rx_urb) || (!catc->irq_urb)) { - err("No free urbs available."); + dev_err(&intf->dev, "No free urbs available.\n"); usb_free_urb(catc->ctrl_urb); usb_free_urb(catc->tx_urb); usb_free_urb(catc->rx_urb); @@ -947,6 +952,7 @@ static struct usb_driver catc_driver = { .probe = catc_probe, .disconnect = catc_disconnect, .id_table = catc_id_table, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(catc_driver); diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 3e41b00c680..d848d4dd575 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -457,6 +457,7 @@ static struct usb_driver usbpn_driver = { .probe = usbpn_probe, .disconnect = usbpn_disconnect, .id_table = usbpn_ids, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(usbpn_driver); diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 685a4e22c76..434d5af8e6f 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -368,6 +368,7 @@ static struct usb_driver eem_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(eem_driver); diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 00880edba04..a03de719704 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -485,6 +485,8 @@ static const struct driver_info wwan_info = { /*-------------------------------------------------------------------------*/ #define HUAWEI_VENDOR_ID 0x12D1 +#define NOVATEL_VENDOR_ID 0x1410 +#define ZTE_VENDOR_ID 0x19D2 static const struct usb_device_id products [] = { /* @@ -602,6 +604,76 @@ static const struct usb_device_id products [] = { * because of bugs/quirks in a given product (like Zaurus, above). */ { + /* Novatel USB551L */ + /* This match must come *before* the generic CDC-ETHER match so that + * we get FLAG_WWAN set on the device, since it's descriptors are + * generic CDC-ETHER. + */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = NOVATEL_VENDOR_ID, + .idProduct = 0xB001, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3805-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1003, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3806-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1015, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K4510-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1173, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3770-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1177, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3772-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1181, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, @@ -633,6 +705,7 @@ static struct usb_driver cdc_driver = { .resume = usbnet_resume, .reset_resume = usbnet_resume, .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(cdc_driver); diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 7adc9f6b0ea..4b9513fcf27 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1212,6 +1212,7 @@ static struct usb_driver cdc_ncm_driver = { .resume = usbnet_resume, .reset_resume = usbnet_resume, .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, }; static const struct ethtool_ops cdc_ncm_ethtool_ops = { diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c index b403d934e4e..0d1fe89ae0b 100644 --- a/drivers/net/usb/cdc_subset.c +++ b/drivers/net/usb/cdc_subset.c @@ -336,6 +336,7 @@ static struct usb_driver cdc_subset_driver = { .resume = usbnet_resume, .disconnect = usbnet_disconnect, .id_table = products, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(cdc_subset_driver); diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c index 0e0531356e6..49ab45e17fe 100644 --- a/drivers/net/usb/cx82310_eth.c +++ b/drivers/net/usb/cx82310_eth.c @@ -327,6 +327,7 @@ static struct usb_driver cx82310_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(cx82310_driver); diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index b97226318ea..e0433ce6ced 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -670,6 +670,7 @@ static struct usb_driver dm9601_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(dm9601_driver); diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index 38266bdae26..db3c8021f2a 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c @@ -225,6 +225,7 @@ static struct usb_driver gl620a_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(gl620a_driver); diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 2d2a6882ba3..62f30b46fa4 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -106,13 +106,6 @@ #define MAX_RX_URBS 2 -static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty) -{ - if (tty) - return tty->driver_data; - return NULL; -} - /*****************************************************************************/ /* Debugging functions */ /*****************************************************************************/ @@ -255,9 +248,8 @@ struct hso_serial { u8 dtr_state; unsigned tx_urb_used:1; + struct tty_port port; /* from usb_serial_port */ - struct tty_struct *tty; - int open_count; spinlock_t serial_lock; int (*write_data) (struct hso_serial *serial); @@ -1114,7 +1106,7 @@ static void hso_init_termios(struct ktermios *termios) static void _hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) { - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; struct ktermios *termios; if (!serial) { @@ -1190,7 +1182,7 @@ static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial) struct urb *urb; urb = serial->rx_urb[0]; - if (serial->open_count > 0) { + if (serial->port.count > 0) { count = put_rxbuf_data(urb, serial); if (count == -1) return; @@ -1226,7 +1218,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) DUMP1(urb->transfer_buffer, urb->actual_length); /* Anyone listening? */ - if (serial->open_count == 0) + if (serial->port.count == 0) return; if (status == 0) { @@ -1268,7 +1260,7 @@ static void hso_unthrottle_tasklet(struct hso_serial *serial) static void hso_unthrottle(struct tty_struct *tty) { - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; tasklet_hi_schedule(&serial->unthrottle_tasklet); } @@ -1304,15 +1296,12 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) kref_get(&serial->parent->ref); /* setup */ - spin_lock_irq(&serial->serial_lock); tty->driver_data = serial; - tty_kref_put(serial->tty); - serial->tty = tty_kref_get(tty); - spin_unlock_irq(&serial->serial_lock); + tty_port_tty_set(&serial->port, tty); /* check for port already opened, if not set the termios */ - serial->open_count++; - if (serial->open_count == 1) { + serial->port.count++; + if (serial->port.count == 1) { serial->rx_state = RX_IDLE; /* Force default termio settings */ _hso_serial_set_termios(tty, NULL); @@ -1324,7 +1313,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) result = hso_start_serial_device(serial->parent, GFP_KERNEL); if (result) { hso_stop_serial_device(serial->parent); - serial->open_count--; + serial->port.count--; kref_put(&serial->parent->ref, hso_serial_ref_free); } } else { @@ -1361,17 +1350,11 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) /* reset the rts and dtr */ /* do the actual close */ - serial->open_count--; + serial->port.count--; - if (serial->open_count <= 0) { - serial->open_count = 0; - spin_lock_irq(&serial->serial_lock); - if (serial->tty == tty) { - serial->tty->driver_data = NULL; - serial->tty = NULL; - tty_kref_put(tty); - } - spin_unlock_irq(&serial->serial_lock); + if (serial->port.count <= 0) { + serial->port.count = 0; + tty_port_tty_set(&serial->port, NULL); if (!usb_gone) hso_stop_serial_device(serial->parent); tasklet_kill(&serial->unthrottle_tasklet); @@ -1390,7 +1373,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf, int count) { - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; int space, tx_bytes; unsigned long flags; @@ -1422,7 +1405,7 @@ out: /* how much room is there for writing */ static int hso_serial_write_room(struct tty_struct *tty) { - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; int room; unsigned long flags; @@ -1437,7 +1420,7 @@ static int hso_serial_write_room(struct tty_struct *tty) /* setup the term */ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) { - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; unsigned long flags; if (old) @@ -1446,7 +1429,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) /* the actual setup */ spin_lock_irqsave(&serial->serial_lock, flags); - if (serial->open_count) + if (serial->port.count) _hso_serial_set_termios(tty, old); else tty->termios = old; @@ -1458,7 +1441,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) /* how many characters in the buffer */ static int hso_serial_chars_in_buffer(struct tty_struct *tty) { - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; int chars; unsigned long flags; @@ -1629,7 +1612,7 @@ static int hso_get_count(struct tty_struct *tty, struct serial_icounter_struct *icount) { struct uart_icount cnow; - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; struct hso_tiocmget *tiocmget = serial->tiocmget; memset(icount, 0, sizeof(struct serial_icounter_struct)); @@ -1659,7 +1642,7 @@ static int hso_get_count(struct tty_struct *tty, static int hso_serial_tiocmget(struct tty_struct *tty) { int retval; - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; struct hso_tiocmget *tiocmget; u16 UART_state_bitmap; @@ -1693,7 +1676,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, int val = 0; unsigned long flags; int if_num; - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; /* sanity check */ if (!serial) { @@ -1733,7 +1716,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, static int hso_serial_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct hso_serial *serial = get_serial_by_tty(tty); + struct hso_serial *serial = tty->driver_data; int ret = 0; D4("IOCTL cmd: %d, arg: %ld", cmd, arg); @@ -1905,7 +1888,7 @@ static void intr_callback(struct urb *urb) D1("Pending read interrupt on port %d\n", i); spin_lock(&serial->serial_lock); if (serial->rx_state == RX_IDLE && - serial->open_count > 0) { + serial->port.count > 0) { /* Setup and send a ctrl req read on * port i */ if (!serial->rx_urb_filled[0]) { @@ -1954,14 +1937,13 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) spin_lock(&serial->serial_lock); serial->tx_urb_used = 0; - tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { handle_usb_error(status, __func__, serial->parent); - tty_kref_put(tty); return; } hso_put_activity(serial->parent); + tty = tty_port_tty_get(&serial->port); if (tty) { tty_wakeup(tty); tty_kref_put(tty); @@ -2001,7 +1983,6 @@ static void ctrl_callback(struct urb *urb) struct hso_serial *serial = urb->context; struct usb_ctrlrequest *req; int status = urb->status; - struct tty_struct *tty; /* sanity check */ if (!serial) @@ -2009,11 +1990,9 @@ static void ctrl_callback(struct urb *urb) spin_lock(&serial->serial_lock); serial->tx_urb_used = 0; - tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { handle_usb_error(status, __func__, serial->parent); - tty_kref_put(tty); return; } @@ -2031,13 +2010,15 @@ static void ctrl_callback(struct urb *urb) put_rxbuf_data_and_resubmit_ctrl_urb(serial); spin_unlock(&serial->serial_lock); } else { + struct tty_struct *tty = tty_port_tty_get(&serial->port); hso_put_activity(serial->parent); - if (tty) + if (tty) { tty_wakeup(tty); + tty_kref_put(tty); + } /* response to a write command */ hso_kick_transmit(serial); } - tty_kref_put(tty); } /* handle RX data for serial port */ @@ -2053,8 +2034,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) return -2; } - /* All callers to put_rxbuf_data hold serial_lock */ - tty = tty_kref_get(serial->tty); + tty = tty_port_tty_get(&serial->port); /* Push data to tty */ if (tty) { @@ -2074,12 +2054,12 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) write_length_remaining -= curr_write_len; tty_flip_buffer_push(tty); } + tty_kref_put(tty); } if (write_length_remaining == 0) { serial->curr_rx_urb_offset = 0; serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; } - tty_kref_put(tty); return write_length_remaining; } @@ -2320,6 +2300,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, serial->minor = minor; serial->magic = HSO_SERIAL_MAGIC; spin_lock_init(&serial->serial_lock); + tty_port_init(&serial->port); serial->num_rx_urbs = num_urbs; /* RX, allocate urb and initialize */ @@ -3098,7 +3079,7 @@ static int hso_resume(struct usb_interface *iface) /* Start all serial ports */ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { if (serial_table[i] && (serial_table[i]->interface == iface)) { - if (dev2ser(serial_table[i])->open_count) { + if (dev2ser(serial_table[i])->port.count) { result = hso_start_serial_device(serial_table[i], GFP_NOIO); hso_kick_transmit(dev2ser(serial_table[i])); @@ -3172,13 +3153,12 @@ static void hso_free_interface(struct usb_interface *interface) if (serial_table[i] && (serial_table[i]->interface == interface)) { hso_dev = dev2ser(serial_table[i]); - spin_lock_irq(&hso_dev->serial_lock); - tty = tty_kref_get(hso_dev->tty); - spin_unlock_irq(&hso_dev->serial_lock); - if (tty) + tty = tty_port_tty_get(&hso_dev->port); + if (tty) { tty_hangup(tty); + tty_kref_put(tty); + } mutex_lock(&hso_dev->parent->mutex); - tty_kref_put(tty); hso_dev->parent->usb_gone = 1; mutex_unlock(&hso_dev->parent->mutex); kref_put(&serial_table[i]->ref, hso_serial_ref_free); @@ -3291,6 +3271,7 @@ static struct usb_driver hso_driver = { .resume = hso_resume, .reset_resume = hso_resume, .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, }; static int __init hso_init(void) @@ -3312,7 +3293,6 @@ static int __init hso_init(void) return -ENOMEM; /* fill in all needed values */ - tty_drv->magic = TTY_DRIVER_MAGIC; tty_drv->driver_name = driver_name; tty_drv->name = tty_filename; @@ -3333,7 +3313,7 @@ static int __init hso_init(void) if (result) { printk(KERN_ERR "%s - tty_register_driver failed(%d)\n", __func__, result); - return result; + goto err_free_tty; } /* register this module as an usb driver */ @@ -3341,13 +3321,16 @@ static int __init hso_init(void) if (result) { printk(KERN_ERR "Could not register hso driver? error: %d\n", result); - /* cleanup serial interface */ - tty_unregister_driver(tty_drv); - return result; + goto err_unreg_tty; } /* done */ return 0; +err_unreg_tty: + tty_unregister_driver(tty_drv); +err_free_tty: + put_tty_driver(tty_drv); + return result; } static void __exit hso_exit(void) @@ -3355,6 +3338,7 @@ static void __exit hso_exit(void) printk(KERN_INFO "hso: unloaded\n"); tty_unregister_driver(tty_drv); + put_tty_driver(tty_drv); /* deregister the usb driver */ usb_deregister(&hso_driver); } diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c index 12a22a453ff..8de641713d5 100644 --- a/drivers/net/usb/int51x1.c +++ b/drivers/net/usb/int51x1.c @@ -236,6 +236,7 @@ static struct usb_driver int51x1_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(int51x1_driver); diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index dd78c4cbd45..964031e3da8 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -209,7 +209,8 @@ static void ipheth_rcvbulk_callback(struct urb *urb) case 0: break; default: - err("%s: urb status: %d", __func__, status); + dev_err(&dev->intf->dev, "%s: urb status: %d\n", + __func__, status); return; } @@ -222,7 +223,8 @@ static void ipheth_rcvbulk_callback(struct urb *urb) skb = dev_alloc_skb(len); if (!skb) { - err("%s: dev_alloc_skb: -ENOMEM", __func__); + dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n", + __func__); dev->net->stats.rx_dropped++; return; } @@ -251,7 +253,8 @@ static void ipheth_sndbulk_callback(struct urb *urb) status != -ENOENT && status != -ECONNRESET && status != -ESHUTDOWN) - err("%s: urb status: %d", __func__, status); + dev_err(&dev->intf->dev, "%s: urb status: %d\n", + __func__, status); dev_kfree_skb_irq(dev->tx_skb); netif_wake_queue(dev->net); @@ -271,7 +274,8 @@ static int ipheth_carrier_set(struct ipheth_device *dev) dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE, IPHETH_CTRL_TIMEOUT); if (retval < 0) { - err("%s: usb_control_msg: %d", __func__, retval); + dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n", + __func__, retval); return retval; } @@ -308,9 +312,11 @@ static int ipheth_get_macaddr(struct ipheth_device *dev) IPHETH_CTRL_BUF_SIZE, IPHETH_CTRL_TIMEOUT); if (retval < 0) { - err("%s: usb_control_msg: %d", __func__, retval); + dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n", + __func__, retval); } else if (retval < ETH_ALEN) { - err("%s: usb_control_msg: short packet: %d bytes", + dev_err(&dev->intf->dev, + "%s: usb_control_msg: short packet: %d bytes\n", __func__, retval); retval = -EINVAL; } else { @@ -335,7 +341,8 @@ static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) retval = usb_submit_urb(dev->rx_urb, mem_flags); if (retval) - err("%s: usb_submit_urb: %d", __func__, retval); + dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", + __func__, retval); return retval; } @@ -396,7 +403,8 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net) retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC); if (retval) { - err("%s: usb_submit_urb: %d", __func__, retval); + dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", + __func__, retval); dev->net->stats.tx_errors++; dev_kfree_skb_irq(skb); } else { @@ -414,7 +422,7 @@ static void ipheth_tx_timeout(struct net_device *net) { struct ipheth_device *dev = netdev_priv(net); - err("%s: TX timeout", __func__); + dev_err(&dev->intf->dev, "%s: TX timeout\n", __func__); dev->net->stats.tx_errors++; usb_unlink_urb(dev->tx_urb); } @@ -464,7 +472,7 @@ static int ipheth_probe(struct usb_interface *intf, hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); if (hintf == NULL) { retval = -ENODEV; - err("Unable to find alternate settings interface"); + dev_err(&intf->dev, "Unable to find alternate settings interface\n"); goto err_endpoints; } @@ -477,7 +485,7 @@ static int ipheth_probe(struct usb_interface *intf, } if (!(dev->bulk_in && dev->bulk_out)) { retval = -ENODEV; - err("Unable to find endpoints"); + dev_err(&intf->dev, "Unable to find endpoints\n"); goto err_endpoints; } @@ -495,7 +503,7 @@ static int ipheth_probe(struct usb_interface *intf, retval = ipheth_alloc_urbs(dev); if (retval) { - err("error allocating urbs: %d", retval); + dev_err(&intf->dev, "error allocating urbs: %d\n", retval); goto err_alloc_urbs; } @@ -506,7 +514,7 @@ static int ipheth_probe(struct usb_interface *intf, retval = register_netdev(netdev); if (retval) { - err("error registering netdev: %d", retval); + dev_err(&intf->dev, "error registering netdev: %d\n", retval); retval = -EIO; goto err_register_netdev; } @@ -546,6 +554,7 @@ static struct usb_driver ipheth_driver = { .probe = ipheth_probe, .disconnect = ipheth_disconnect, .id_table = ipheth_table, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(ipheth_driver); diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index 7562649b3d6..92c49e0a59e 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -372,7 +372,8 @@ static struct usb_driver kalmia_driver = { .probe = usbnet_probe, .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, - .resume = usbnet_resume + .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(kalmia_driver); diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index df2a2cf35a9..d8ad5528438 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -179,6 +179,7 @@ static struct usb_driver kaweth_driver = { .resume = kaweth_resume, .id_table = usb_klsi_table, .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, }; typedef __u8 eth_addr_t[6]; @@ -400,12 +401,13 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth, ret = request_firmware(&fw, fwname, &kaweth->dev->dev); if (ret) { - err("Firmware request failed\n"); + dev_err(&kaweth->intf->dev, "Firmware request failed\n"); return ret; } if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { - err("Firmware too big: %zu", fw->size); + dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n", + fw->size); release_firmware(fw); return -ENOSPC; } @@ -501,9 +503,10 @@ static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf) } if (status) - err ("can't resubmit intr, %s-%s, status %d", - kaweth->dev->bus->bus_name, - kaweth->dev->devpath, status); + dev_err(&kaweth->intf->dev, + "can't resubmit intr, %s-%s, status %d\n", + kaweth->dev->bus->bus_name, + kaweth->dev->devpath, status); } static void int_callback(struct urb *u) @@ -576,7 +579,8 @@ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, kaweth->suspend_lowmem_rx = 1; schedule_delayed_work(&kaweth->lowmem_work, HZ/4); } - err("resubmitting rx_urb %d failed", result); + dev_err(&kaweth->intf->dev, "resubmitting rx_urb %d failed\n", + result); } else { kaweth->suspend_lowmem_rx = 0; } @@ -634,20 +638,21 @@ static void kaweth_usb_receive(struct urb *urb) spin_unlock(&kaweth->device_lock); if(status && status != -EREMOTEIO && count != 1) { - err("%s RX status: %d count: %d packet_len: %d", - net->name, - status, - count, - (int)pkt_len); + dev_err(&kaweth->intf->dev, + "%s RX status: %d count: %d packet_len: %d\n", + net->name, status, count, (int)pkt_len); kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); return; } if(kaweth->net && (count > 2)) { if(pkt_len > (count - 2)) { - err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count); - err("Packet len & 2047: %x", pkt_len & 2047); - err("Count 2: %x", count2); + dev_err(&kaweth->intf->dev, + "Packet length too long for USB frame (pkt_len: %x, count: %x)\n", + pkt_len, count); + dev_err(&kaweth->intf->dev, "Packet len & 2047: %x\n", + pkt_len & 2047); + dev_err(&kaweth->intf->dev, "Count 2: %x\n", count2); kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); return; } @@ -686,7 +691,7 @@ static int kaweth_open(struct net_device *net) res = usb_autopm_get_interface(kaweth->intf); if (res) { - err("Interface cannot be resumed."); + dev_err(&kaweth->intf->dev, "Interface cannot be resumed.\n"); return -EIO; } res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); @@ -907,7 +912,8 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth) KAWETH_CONTROL_TIMEOUT); if(result < 0) { - err("Failed to set Rx mode: %d", result); + dev_err(&kaweth->intf->dev, "Failed to set Rx mode: %d\n", + result); } else { dbg("Set Rx mode to %d", packet_filter_bitmap); @@ -1045,7 +1051,8 @@ static int kaweth_probe( "kaweth/new_code.bin", 100, 2)) < 0) { - err("Error downloading firmware (%d)", result); + dev_err(&intf->dev, "Error downloading firmware (%d)\n", + result); goto err_fw; } @@ -1053,7 +1060,9 @@ static int kaweth_probe( "kaweth/new_code_fix.bin", 100, 3)) < 0) { - err("Error downloading firmware fix (%d)", result); + dev_err(&intf->dev, + "Error downloading firmware fix (%d)\n", + result); goto err_fw; } @@ -1061,7 +1070,9 @@ static int kaweth_probe( "kaweth/trigger_code.bin", 126, 2)) < 0) { - err("Error downloading trigger code (%d)", result); + dev_err(&intf->dev, + "Error downloading trigger code (%d)\n", + result); goto err_fw; } @@ -1070,13 +1081,14 @@ static int kaweth_probe( "kaweth/trigger_code_fix.bin", 126, 3)) < 0) { - err("Error downloading trigger code fix (%d)", result); + dev_err(&intf->dev, "Error downloading trigger code fix (%d)\n", result); goto err_fw; } if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) { - err("Error triggering firmware (%d)", result); + dev_err(&intf->dev, "Error triggering firmware (%d)\n", + result); goto err_fw; } @@ -1091,7 +1103,7 @@ err_fw: result = kaweth_read_configuration(kaweth); if(result < 0) { - err("Error reading configuration (%d), no net device created", result); + dev_err(&intf->dev, "Error reading configuration (%d), no net device created\n", result); goto err_free_netdev; } @@ -1103,7 +1115,7 @@ err_fw: if(!memcmp(&kaweth->configuration.hw_addr, &bcast_addr, sizeof(bcast_addr))) { - err("Firmware not functioning properly, no net device created"); + dev_err(&intf->dev, "Firmware not functioning properly, no net device created\n"); goto err_free_netdev; } @@ -1113,7 +1125,7 @@ err_fw: } if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) { - err("Error setting SOFS wait"); + dev_err(&intf->dev, "Error setting SOFS wait\n"); goto err_free_netdev; } @@ -1123,7 +1135,7 @@ err_fw: KAWETH_PACKET_FILTER_MULTICAST); if(result < 0) { - err("Error setting receive filter"); + dev_err(&intf->dev, "Error setting receive filter\n"); goto err_free_netdev; } @@ -1175,7 +1187,7 @@ err_fw: SET_NETDEV_DEV(netdev, &intf->dev); if (register_netdev(netdev) != 0) { - err("Error registering netdev."); + dev_err(&intf->dev, "Error registering netdev.\n"); goto err_intfdata; } diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c index 45a981fde43..808d6506da4 100644 --- a/drivers/net/usb/lg-vl600.c +++ b/drivers/net/usb/lg-vl600.c @@ -344,6 +344,7 @@ static struct usb_driver lg_vl600_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(lg_vl600_driver); diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index c434b6ba033..add1064f755 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -690,6 +690,7 @@ static struct usb_driver mcs7830_driver = { .suspend = usbnet_suspend, .resume = usbnet_resume, .reset_resume = mcs7830_reset_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(mcs7830_driver); diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index 83f965cb69e..28c4d513ba8 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c @@ -587,6 +587,7 @@ static struct usb_driver net1080_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(net1080_driver); diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 75239309232..7023220456c 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1489,6 +1489,7 @@ static struct usb_driver pegasus_driver = { .id_table = pegasus_ids, .suspend = pegasus_suspend, .resume = pegasus_resume, + .disable_hub_initiated_lpm = 1, }; static void __init parse_id(char *id) diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c index b2b035e2997..4584b9a805b 100644 --- a/drivers/net/usb/plusb.c +++ b/drivers/net/usb/plusb.c @@ -152,6 +152,7 @@ static struct usb_driver plusb_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(plusb_driver); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index d316503b35d..380dbea6109 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -356,10 +356,19 @@ static const struct driver_info qmi_wwan_gobi = { }; /* ZTE suck at making USB descriptors */ +static const struct driver_info qmi_wwan_force_int1 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind_shared, + .manage_power = qmi_wwan_manage_power, + .data = BIT(1), /* interface whitelist bitmap */ +}; + static const struct driver_info qmi_wwan_force_int4 = { - .description = "Qualcomm Gobi wwan/QMI device", + .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, .data = BIT(4), /* interface whitelist bitmap */ @@ -401,6 +410,14 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */ .driver_info = (unsigned long)&qmi_wwan_info, }, + { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 56, /* NOTE: This is the *slave* interface of the CDC Union! */ + .driver_info = (unsigned long)&qmi_wwan_info, + }, { /* Huawei E392, E398 and possibly others in "Windows mode" * using a combined control and data interface without any CDC * functional descriptors @@ -430,6 +447,15 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, + { /* ZTE (Vodafone) K3520-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x0055, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int1, + }, { /* ZTE (Vodafone) K3565-Z */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x19d2, @@ -457,6 +483,15 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, + { /* ZTE (Vodafone) K3765-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x2002, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, { /* ZTE (Vodafone) K4505-Z */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x19d2, @@ -525,6 +560,7 @@ static struct usb_driver qmi_wwan_driver = { .resume = qmi_wwan_resume, .reset_resume = qmi_wwan_resume, .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, }; static int __init qmi_wwan_init(void) diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index c8f1b5b3aff..4a4335833c3 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -77,7 +77,9 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg, if (dev->driver_info->indication) { dev->driver_info->indication(dev, msg, buflen); } else { - switch (msg->status) { + u32 status = le32_to_cpu(msg->status); + + switch (status) { case RNDIS_STATUS_MEDIA_CONNECT: dev_info(udev, "rndis media connect\n"); break; @@ -85,8 +87,7 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg, dev_info(udev, "rndis media disconnect\n"); break; default: - dev_info(udev, "rndis indication: 0x%08x\n", - le32_to_cpu(msg->status)); + dev_info(udev, "rndis indication: 0x%08x\n", status); } } } @@ -109,16 +110,17 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) int retval; int partial; unsigned count; - __le32 rsp; - u32 xid = 0, msg_len, request_id; + u32 xid = 0, msg_len, request_id, msg_type, rsp, + status; /* REVISIT when this gets called from contexts other than probe() or * disconnect(): either serialize, or dispatch responses on xid */ + msg_type = le32_to_cpu(buf->msg_type); + /* Issue the request; xid is unique, don't bother byteswapping it */ - if (likely(buf->msg_type != RNDIS_MSG_HALT && - buf->msg_type != RNDIS_MSG_RESET)) { + if (likely(msg_type != RNDIS_MSG_HALT && msg_type != RNDIS_MSG_RESET)) { xid = dev->xid++; if (!xid) xid = dev->xid++; @@ -149,7 +151,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) } /* Poll the control channel; the request probably completed immediately */ - rsp = buf->msg_type | RNDIS_MSG_COMPLETION; + rsp = le32_to_cpu(buf->msg_type) | RNDIS_MSG_COMPLETION; for (count = 0; count < 10; count++) { memset(buf, 0, CONTROL_BUFFER_SIZE); retval = usb_control_msg(dev->udev, @@ -160,35 +162,36 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) buf, buflen, RNDIS_CONTROL_TIMEOUT_MS); if (likely(retval >= 8)) { + msg_type = le32_to_cpu(buf->msg_type); msg_len = le32_to_cpu(buf->msg_len); + status = le32_to_cpu(buf->status); request_id = (__force u32) buf->request_id; - if (likely(buf->msg_type == rsp)) { + if (likely(msg_type == rsp)) { if (likely(request_id == xid)) { if (unlikely(rsp == RNDIS_MSG_RESET_C)) return 0; - if (likely(RNDIS_STATUS_SUCCESS - == buf->status)) + if (likely(RNDIS_STATUS_SUCCESS == + status)) return 0; dev_dbg(&info->control->dev, "rndis reply status %08x\n", - le32_to_cpu(buf->status)); + status); return -EL3RST; } dev_dbg(&info->control->dev, "rndis reply id %d expected %d\n", request_id, xid); /* then likely retry */ - } else switch (buf->msg_type) { - case RNDIS_MSG_INDICATE: /* fault/event */ + } else switch (msg_type) { + case RNDIS_MSG_INDICATE: /* fault/event */ rndis_msg_indicate(dev, (void *)buf, buflen); - break; - case RNDIS_MSG_KEEPALIVE: { /* ping */ + case RNDIS_MSG_KEEPALIVE: { /* ping */ struct rndis_keepalive_c *msg = (void *)buf; - msg->msg_type = RNDIS_MSG_KEEPALIVE_C; + msg->msg_type = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C); msg->msg_len = cpu_to_le32(sizeof *msg); - msg->status = RNDIS_STATUS_SUCCESS; + msg->status = cpu_to_le32(RNDIS_STATUS_SUCCESS); retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), USB_CDC_SEND_ENCAPSULATED_COMMAND, @@ -236,7 +239,7 @@ EXPORT_SYMBOL_GPL(rndis_command); * ActiveSync 4.1 Windows driver. */ static int rndis_query(struct usbnet *dev, struct usb_interface *intf, - void *buf, __le32 oid, u32 in_len, + void *buf, u32 oid, u32 in_len, void **reply, int *reply_len) { int retval; @@ -251,9 +254,9 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf, u.buf = buf; memset(u.get, 0, sizeof *u.get + in_len); - u.get->msg_type = RNDIS_MSG_QUERY; + u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY); u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len); - u.get->oid = oid; + u.get->oid = cpu_to_le32(oid); u.get->len = cpu_to_le32(in_len); u.get->offset = cpu_to_le32(20); @@ -324,7 +327,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) if (retval < 0) goto fail; - u.init->msg_type = RNDIS_MSG_INIT; + u.init->msg_type = cpu_to_le32(RNDIS_MSG_INIT); u.init->msg_len = cpu_to_le32(sizeof *u.init); u.init->major_version = cpu_to_le32(1); u.init->minor_version = cpu_to_le32(0); @@ -395,22 +398,23 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) /* Check physical medium */ phym = NULL; reply_len = sizeof *phym; - retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, - 0, (void **) &phym, &reply_len); + retval = rndis_query(dev, intf, u.buf, + RNDIS_OID_GEN_PHYSICAL_MEDIUM, + 0, (void **) &phym, &reply_len); if (retval != 0 || !phym) { /* OID is optional so don't fail here. */ - phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; + phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED); phym = &phym_unspec; } if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && - *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { + le32_to_cpup(phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { netif_dbg(dev, probe, dev->net, "driver requires wireless physical medium, but device is not\n"); retval = -ENODEV; goto halt_fail_and_release; } if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && - *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { + le32_to_cpup(phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { netif_dbg(dev, probe, dev->net, "driver requires non-wireless physical medium, but device is wireless.\n"); retval = -ENODEV; @@ -419,8 +423,9 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) /* Get designated host ethernet address */ reply_len = ETH_ALEN; - retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, - 48, (void **) &bp, &reply_len); + retval = rndis_query(dev, intf, u.buf, + RNDIS_OID_802_3_PERMANENT_ADDRESS, + 48, (void **) &bp, &reply_len); if (unlikely(retval< 0)) { dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); goto halt_fail_and_release; @@ -430,12 +435,12 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) /* set a nonzero filter to enable data transfers */ memset(u.set, 0, sizeof *u.set); - u.set->msg_type = RNDIS_MSG_SET; + u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET); u.set->msg_len = cpu_to_le32(4 + sizeof *u.set); - u.set->oid = OID_GEN_CURRENT_PACKET_FILTER; + u.set->oid = cpu_to_le32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER); u.set->len = cpu_to_le32(4); u.set->offset = cpu_to_le32((sizeof *u.set) - 8); - *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER; + *(__le32 *)(u.buf + sizeof *u.set) = cpu_to_le32(RNDIS_DEFAULT_FILTER); retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); if (unlikely(retval < 0)) { @@ -450,7 +455,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) halt_fail_and_release: memset(u.halt, 0, sizeof *u.halt); - u.halt->msg_type = RNDIS_MSG_HALT; + u.halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT); u.halt->msg_len = cpu_to_le32(sizeof *u.halt); (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE); fail_and_release: @@ -475,7 +480,7 @@ void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) /* try to clear any rndis state/activity (no i/o from stack!) */ halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); if (halt) { - halt->msg_type = RNDIS_MSG_HALT; + halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT); halt->msg_len = cpu_to_le32(sizeof *halt); (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE); kfree(halt); @@ -494,16 +499,16 @@ int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) while (likely(skb->len)) { struct rndis_data_hdr *hdr = (void *)skb->data; struct sk_buff *skb2; - u32 msg_len, data_offset, data_len; + u32 msg_type, msg_len, data_offset, data_len; + msg_type = le32_to_cpu(hdr->msg_type); msg_len = le32_to_cpu(hdr->msg_len); data_offset = le32_to_cpu(hdr->data_offset); data_len = le32_to_cpu(hdr->data_len); /* don't choke if we see oob, per-packet data, etc */ - if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET || - skb->len < msg_len || - (data_offset + data_len + 8) > msg_len)) { + if (unlikely(msg_type != RNDIS_MSG_PACKET || skb->len < msg_len + || (data_offset + data_len + 8) > msg_len)) { dev->net->stats.rx_frame_errors++; netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n", le32_to_cpu(hdr->msg_type), @@ -569,7 +574,7 @@ rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) fill: hdr = (void *) __skb_push(skb, sizeof *hdr); memset(hdr, 0, sizeof *hdr); - hdr->msg_type = RNDIS_MSG_PACKET; + hdr->msg_type = cpu_to_le32(RNDIS_MSG_PACKET); hdr->msg_len = cpu_to_le32(skb->len); hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8); hdr->data_len = cpu_to_le32(len); @@ -633,6 +638,7 @@ static struct usb_driver rndis_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(rndis_driver); diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index d363b31053d..0e2c92e0e53 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -203,7 +203,8 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size) if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) { if (ret == -ENODEV) netif_device_detach(dev->netdev); - err("control request submission failed: %d", ret); + dev_err(&dev->udev->dev, + "control request submission failed: %d\n", ret); } else set_bit(RX_REG_SET, &dev->flags); @@ -516,9 +517,9 @@ resubmit: if (res == -ENODEV) netif_device_detach(dev->netdev); else if (res) - err ("can't resubmit intr, %s-%s/input0, status %d", - dev->udev->bus->bus_name, - dev->udev->devpath, res); + dev_err(&dev->udev->dev, + "can't resubmit intr, %s-%s/input0, status %d\n", + dev->udev->bus->bus_name, dev->udev->devpath, res); } static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message) @@ -890,11 +891,11 @@ static int rtl8150_probe(struct usb_interface *intf, dev->intr_interval = 100; /* 100ms */ if (!alloc_all_urbs(dev)) { - err("out of memory"); + dev_err(&intf->dev, "out of memory\n"); goto out; } if (!rtl8150_reset(dev)) { - err("couldn't reset the device"); + dev_err(&intf->dev, "couldn't reset the device\n"); goto out1; } fill_skb_pool(dev); @@ -903,7 +904,7 @@ static int rtl8150_probe(struct usb_interface *intf, usb_set_intfdata(intf, dev); SET_NETDEV_DEV(netdev, &intf->dev); if (register_netdev(netdev) != 0) { - err("couldn't register the device"); + dev_err(&intf->dev, "couldn't register the device\n"); goto out2; } @@ -947,7 +948,8 @@ static struct usb_driver rtl8150_driver = { .disconnect = rtl8150_disconnect, .id_table = rtl8150_table, .suspend = rtl8150_suspend, - .resume = rtl8150_resume + .resume = rtl8150_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(rtl8150_driver); diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index b59cf20c781..3faef5670d1 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -982,6 +982,7 @@ static struct usb_driver sierra_net_driver = { .suspend = usbnet_suspend, .resume = usbnet_resume, .no_dynamic_id = 1, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(sierra_net_driver); diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 00103a8c5e0..1c6e51588da 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -508,10 +508,9 @@ static int smsc75xx_link_reset(struct usbnet *dev) u16 lcladv, rmtadv; int ret; - /* read and write to clear phy interrupt status */ - ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); - check_warn_return(ret, "Error reading PHY_INT_SRC"); - smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff); + /* write to clear phy interrupt status */ + smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, + PHY_INT_SRC_CLEAR_ALL); ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); check_warn_return(ret, "Error writing INT_STS"); @@ -904,15 +903,20 @@ static int smsc75xx_reset(struct usbnet *dev) netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf); - /* Configure GPIO pins as LED outputs */ - ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf); - check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret); + ret = smsc75xx_read_reg(dev, E2P_CMD, &buf); + check_warn_return(ret, "Failed to read E2P_CMD: %d", ret); - buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL); - buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL; + /* only set default GPIO/LED settings if no EEPROM is detected */ + if (!(buf & E2P_CMD_LOADED)) { + ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf); + check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret); - ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf); - check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret); + buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL); + buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL; + + ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf); + check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret); + } ret = smsc75xx_write_reg(dev, FLOW, 0); check_warn_return(ret, "Failed to write FLOW: %d", ret); @@ -1250,6 +1254,7 @@ static struct usb_driver smsc75xx_driver = { .suspend = usbnet_suspend, .resume = usbnet_resume, .disconnect = usbnet_disconnect, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(smsc75xx_driver); diff --git a/drivers/net/usb/smsc75xx.h b/drivers/net/usb/smsc75xx.h index 16e98c77834..67eba39e6ee 100644 --- a/drivers/net/usb/smsc75xx.h +++ b/drivers/net/usb/smsc75xx.h @@ -388,6 +388,7 @@ #define PHY_INT_SRC_ANEG_COMP ((u16)0x0040) #define PHY_INT_SRC_REMOTE_FAULT ((u16)0x0020) #define PHY_INT_SRC_LINK_DOWN ((u16)0x0010) +#define PHY_INT_SRC_CLEAR_ALL ((u16)0xffff) #define PHY_INT_MASK (30) #define PHY_INT_MASK_ENERGY_ON ((u16)0x0080) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 94ae66999f5..b1112e75385 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1297,6 +1297,7 @@ static struct usb_driver smsc95xx_driver = { .suspend = usbnet_suspend, .resume = usbnet_resume, .disconnect = usbnet_disconnect, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(smsc95xx_driver); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 2d927fb4adf..9f58330f131 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -282,17 +282,32 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu) } EXPORT_SYMBOL_GPL(usbnet_change_mtu); +/* The caller must hold list->lock */ +static void __usbnet_queue_skb(struct sk_buff_head *list, + struct sk_buff *newsk, enum skb_state state) +{ + struct skb_data *entry = (struct skb_data *) newsk->cb; + + __skb_queue_tail(list, newsk); + entry->state = state; +} + /*-------------------------------------------------------------------------*/ /* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from * completion callbacks. 2.5 should have fixed those bugs... */ -static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list) +static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, + struct sk_buff_head *list, enum skb_state state) { unsigned long flags; + enum skb_state old_state; + struct skb_data *entry = (struct skb_data *) skb->cb; spin_lock_irqsave(&list->lock, flags); + old_state = entry->state; + entry->state = state; __skb_unlink(skb, list); spin_unlock(&list->lock); spin_lock(&dev->done.lock); @@ -300,6 +315,7 @@ static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_hea if (dev->done.qlen == 1) tasklet_schedule(&dev->bh); spin_unlock_irqrestore(&dev->done.lock, flags); + return old_state; } /* some work can't be done in tasklets, so we use keventd @@ -340,7 +356,6 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; - entry->state = rx_start; entry->length = 0; usb_fill_bulk_urb (urb, dev->udev, dev->in, @@ -372,7 +387,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) tasklet_schedule (&dev->bh); break; case 0: - __skb_queue_tail (&dev->rxq, skb); + __usbnet_queue_skb(&dev->rxq, skb, rx_start); } } else { netif_dbg(dev, ifdown, dev->net, "rx: stopped\n"); @@ -423,16 +438,17 @@ static void rx_complete (struct urb *urb) struct skb_data *entry = (struct skb_data *) skb->cb; struct usbnet *dev = entry->dev; int urb_status = urb->status; + enum skb_state state; skb_put (skb, urb->actual_length); - entry->state = rx_done; + state = rx_done; entry->urb = NULL; switch (urb_status) { /* success */ case 0: if (skb->len < dev->net->hard_header_len) { - entry->state = rx_cleanup; + state = rx_cleanup; dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; netif_dbg(dev, rx_err, dev->net, @@ -471,7 +487,7 @@ static void rx_complete (struct urb *urb) "rx throttle %d\n", urb_status); } block: - entry->state = rx_cleanup; + state = rx_cleanup; entry->urb = urb; urb = NULL; break; @@ -482,17 +498,18 @@ block: // FALLTHROUGH default: - entry->state = rx_cleanup; + state = rx_cleanup; dev->net->stats.rx_errors++; netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status); break; } - defer_bh(dev, skb, &dev->rxq); + state = defer_bh(dev, skb, &dev->rxq, state); if (urb) { if (netif_running (dev->net) && - !test_bit (EVENT_RX_HALT, &dev->flags)) { + !test_bit (EVENT_RX_HALT, &dev->flags) && + state != unlink_start) { rx_submit (dev, urb, GFP_ATOMIC); usb_mark_last_busy(dev->udev); return; @@ -579,16 +596,23 @@ EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq); static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) { unsigned long flags; - struct sk_buff *skb, *skbnext; + struct sk_buff *skb; int count = 0; spin_lock_irqsave (&q->lock, flags); - skb_queue_walk_safe(q, skb, skbnext) { + while (!skb_queue_empty(q)) { struct skb_data *entry; struct urb *urb; int retval; - entry = (struct skb_data *) skb->cb; + skb_queue_walk(q, skb) { + entry = (struct skb_data *) skb->cb; + if (entry->state != unlink_start) + goto found; + } + break; +found: + entry->state = unlink_start; urb = entry->urb; /* @@ -885,6 +909,7 @@ static const struct ethtool_ops usbnet_ethtool_ops = { .get_drvinfo = usbnet_get_drvinfo, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, + .get_ts_info = ethtool_op_get_ts_info, }; /*-------------------------------------------------------------------------*/ @@ -1039,8 +1064,7 @@ static void tx_complete (struct urb *urb) } usb_autopm_put_interface_async(dev->intf); - entry->state = tx_done; - defer_bh(dev, skb, &dev->txq); + (void) defer_bh(dev, skb, &dev->txq, tx_done); } /*-------------------------------------------------------------------------*/ @@ -1096,7 +1120,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; - entry->state = tx_start; entry->length = length; usb_fill_bulk_urb (urb, dev->udev, dev->out, @@ -1155,7 +1178,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, break; case 0: net->trans_start = jiffies; - __skb_queue_tail (&dev->txq, skb); + __usbnet_queue_skb(&dev->txq, skb, tx_start); if (dev->txq.qlen >= TX_QLEN (dev)) netif_stop_queue (net); } diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index 34db195fb8b..35c90307d47 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c @@ -377,6 +377,7 @@ static struct usb_driver zaurus_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; module_usb_driver(zaurus_driver); |