X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fnet%2Fusbnet.c;h=9c8d8c25d60c011482bfc02eab45484764c277d9;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=cca6e72cf2fab8e90998bc8108bda9bfd68bbf99;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index cca6e72cf..9c8d8c25d 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -31,6 +31,7 @@ * - GeneSys GL620USB-A * - NetChip 1080 (interoperates with NetChip Win32 drivers) * - Prolific PL-2301/2302 (replaces "plusb" driver) + * - KC Technology KC2190 * * + Smart USB devices can support such links directly, using Internet * standard protocols instead of proprietary host-to-device links. @@ -106,6 +107,7 @@ * 22-aug-2003 AX8817X support (Dave Hollis). * 14-jun-2004 Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan * (Neil Bortnak) + * 03-nov-2004 Trivial patch for KC2190 (KC-190) chip. (Jonathan McDowell) * *-------------------------------------------------------------------------*/ @@ -134,7 +136,7 @@ #include #include -#define DRIVER_VERSION "25-Aug-2003" +#define DRIVER_VERSION "03-Nov-2004" /*-------------------------------------------------------------------------*/ @@ -525,7 +527,7 @@ static void ax8817x_interrupt_complete(struct urb *urb, struct pt_regs *regs) devdbg(dev, "ax8817x - Link Status is: %d", link); } } - usb_submit_urb(data->int_urb, GFP_KERNEL); + usb_submit_urb(data->int_urb, GFP_ATOMIC); } } @@ -567,7 +569,7 @@ static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 i static void ax8817x_set_multicast(struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); struct ax8817x_data *data = (struct ax8817x_data *)&dev->data; u8 rx_ctl = 0x8c; @@ -610,7 +612,7 @@ static void ax8817x_set_multicast(struct net_device *net) static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) { - struct usbnet *dev = netdev->priv; + struct usbnet *dev = netdev_priv(netdev); u16 res; u8 buf[1]; @@ -623,7 +625,7 @@ static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) { - struct usbnet *dev = netdev->priv; + struct usbnet *dev = netdev_priv(netdev); u16 res = val; u8 buf[1]; @@ -634,7 +636,7 @@ static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, i static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); u8 opt; if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { @@ -654,7 +656,7 @@ static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *woli static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); u8 opt = 0; u8 buf[1]; @@ -675,7 +677,7 @@ static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolin static int ax8817x_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, u8 *data) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); u16 *ebuf = (u16 *)data; int i; @@ -704,14 +706,14 @@ static void ax8817x_get_drvinfo (struct net_device *net, static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); return mii_ethtool_gset(&dev->mii,cmd); } static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); return mii_ethtool_sset(&dev->mii,cmd); } @@ -743,7 +745,7 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) dev->out = usb_sndbulkpipe(dev->udev, 2); // allocate irq urb - if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) { + if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == NULL) { dbg ("%s: cannot allocate interrupt URB", dev->net->name); return -ENOMEM; @@ -825,7 +827,7 @@ static void ax8817x_unbind(struct usbnet *dev, struct usb_interface *intf) { struct ax8817x_data *data = (struct ax8817x_data *)dev->data; - usb_unlink_urb(data->int_urb); + usb_kill_urb(data->int_urb); usb_free_urb(data->int_urb); kfree(data->int_buf); } @@ -1296,7 +1298,7 @@ struct gl_header { struct gl_packet packets; }; -#ifdef GENLINK_ACK +#ifdef GENELINK_ACK // FIXME: this code is incomplete, not debugged; it doesn't // handle interrupts correctly. interrupts should be generic @@ -1437,7 +1439,7 @@ static int genelink_free (struct usbnet *dev) // handling needs to be generic) // cancel irq urb first - usb_unlink_urb (priv->irq_urb); + usb_kill_urb (priv->irq_urb); // free irq urb usb_free_urb (priv->irq_urb); @@ -2159,6 +2161,13 @@ static const struct driver_info prolific_info = { #endif /* CONFIG_USB_PL2301 */ + +#ifdef CONFIG_USB_KC2190 +#define HAVE_HARDWARE +static const struct driver_info kc2190_info = { + .description = "KC Technology KC-190", +}; +#endif /* CONFIG_USB_KC2190 */ #ifdef CONFIG_USB_ARMLINUX @@ -2256,14 +2265,34 @@ static const struct driver_info zaurus_sl5x00_info = { .unbind = cdc_unbind, .tx_fixup = zaurus_tx_fixup, }; +#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info) + static const struct driver_info zaurus_pxa_info = { .description = "Sharp Zaurus, PXA-2xx based", .flags = FLAG_FRAMING_Z, .check_connect = always_connected, + .bind = generic_cdc_bind, + .unbind = cdc_unbind, .tx_fixup = zaurus_tx_fixup, +}; +#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info) - .in = 1, .out = 2, +static const struct driver_info olympus_mxl_info = { + .description = "Olympus R1000", + .flags = FLAG_FRAMING_Z, + .check_connect = always_connected, + .bind = generic_cdc_bind, + .unbind = cdc_unbind, + .tx_fixup = zaurus_tx_fixup, }; +#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info) + +#else + +/* blacklist all those devices */ +#define ZAURUS_STRONGARM_INFO 0 +#define ZAURUS_PXA_INFO 0 +#define OLYMPUS_MXL_INFO 0 #endif @@ -2276,7 +2305,7 @@ static const struct driver_info zaurus_pxa_info = { static int usbnet_change_mtu (struct net_device *net, int new_mtu) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET) return -EINVAL; @@ -2302,7 +2331,8 @@ static int usbnet_change_mtu (struct net_device *net, int new_mtu) static struct net_device_stats *usbnet_get_stats (struct net_device *net) { - return &((struct usbnet *) net->priv)->stats; + struct usbnet *dev = netdev_priv(net); + return &dev->stats; } /*-------------------------------------------------------------------------*/ @@ -2374,7 +2404,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) #endif size = (sizeof (struct ethhdr) + dev->net->mtu); - if ((skb = alloc_skb (size, flags)) == 0) { + if ((skb = alloc_skb (size, flags)) == NULL) { devdbg (dev, "no rx skb"); defer_kevent (dev, EVENT_RX_MEMORY); usb_free_urb (urb); @@ -2569,7 +2599,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) static int usbnet_stop (struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); int temp; DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); DECLARE_WAITQUEUE (wait, current); @@ -2616,7 +2646,7 @@ static int usbnet_stop (struct net_device *net) static int usbnet_open (struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); int retval = 0; struct driver_info *info = dev->driver_info; @@ -2666,7 +2696,7 @@ done: static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); strncpy (info->driver, driver_name, sizeof info->driver); strncpy (info->version, DRIVER_VERSION, sizeof info->version); @@ -2677,7 +2707,7 @@ static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo * static u32 usbnet_get_link (struct net_device *net) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); /* If a check_connect is defined, return it's results */ if (dev->driver_info->check_connect) @@ -2689,14 +2719,14 @@ static u32 usbnet_get_link (struct net_device *net) static u32 usbnet_get_msglevel (struct net_device *net) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); return dev->msg_level; } static void usbnet_set_msglevel (struct net_device *net, u32 level) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); dev->msg_level = level; } @@ -2705,7 +2735,7 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd) { #ifdef NEED_MII { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); @@ -2731,7 +2761,7 @@ kevent (void *data) if (test_bit (EVENT_TX_HALT, &dev->flags)) { unlink_urbs (dev, &dev->txq); status = usb_clear_halt (dev->udev, dev->out); - if (status < 0) + if (status < 0 && status != -EPIPE) deverr (dev, "can't clear tx halt, status %d", status); else { @@ -2742,7 +2772,7 @@ kevent (void *data) if (test_bit (EVENT_RX_HALT, &dev->flags)) { unlink_urbs (dev, &dev->rxq); status = usb_clear_halt (dev->udev, dev->in); - if (status < 0) + if (status < 0 && status != -EPIPE) deverr (dev, "can't clear rx halt, status %d", status); else { @@ -2759,7 +2789,7 @@ kevent (void *data) urb = usb_alloc_urb (0, GFP_KERNEL); else clear_bit (EVENT_RX_MEMORY, &dev->flags); - if (urb != 0) { + if (urb != NULL) { clear_bit (EVENT_RX_MEMORY, &dev->flags); rx_submit (dev, urb, GFP_KERNEL); tasklet_schedule (&dev->bh); @@ -2817,7 +2847,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs) static void usbnet_tx_timeout (struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); unlink_urbs (dev, &dev->txq); tasklet_schedule (&dev->bh); @@ -2829,7 +2859,7 @@ static void usbnet_tx_timeout (struct net_device *net) static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); int length; int retval = NET_XMIT_SUCCESS; struct urb *urb = NULL; @@ -2986,7 +3016,8 @@ static void usbnet_bh (unsigned long param) // don't refill the queue all at once for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) { - if ((urb = usb_alloc_urb (0, GFP_ATOMIC)) != 0) + urb = usb_alloc_urb (0, GFP_ATOMIC); + if (urb != NULL) rx_submit (dev, urb, GFP_ATOMIC); } if (temp != dev->rxq.qlen) @@ -3014,6 +3045,7 @@ static void usbnet_disconnect (struct usb_interface *intf) { struct usbnet *dev; struct usb_device *xdev; + struct net_device *net; dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); @@ -3026,7 +3058,8 @@ static void usbnet_disconnect (struct usb_interface *intf) xdev->bus->bus_name, xdev->devpath, dev->driver_info->description); - unregister_netdev (dev->net); + net = dev->net; + unregister_netdev (net); /* we don't hold rtnl here ... */ flush_scheduled_work (); @@ -3034,8 +3067,7 @@ static void usbnet_disconnect (struct usb_interface *intf) if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); - free_netdev(dev->net); - kfree (dev); + free_netdev(net); usb_put_dev (xdev); } @@ -3069,12 +3101,13 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) status = -ENOMEM; // set up our own records - if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) { + net = alloc_etherdev(sizeof(*dev)); + if (!net) { dbg ("can't kmalloc dev"); goto out; } - memset (dev, 0, sizeof *dev); + dev = netdev_priv(net); dev->udev = xdev; dev->driver_info = info; dev->msg_level = msg_level; @@ -3088,14 +3121,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); - // set up network interface records - net = alloc_etherdev(0); - if (!net) - goto out1; - SET_MODULE_OWNER (net); dev->net = net; - net->priv = dev; strcpy (net->name, "usb%d"); memcpy (net->dev_addr, node_id, sizeof node_id); @@ -3144,8 +3171,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); - SET_NETDEV_DEV(dev->net, &udev->dev); - status = register_netdev (dev->net); + SET_NETDEV_DEV(net, &udev->dev); + status = register_netdev (net); if (status) goto out3; devinfo (dev, "register usbnet at usb-%s-%s, %s", @@ -3156,16 +3183,15 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) usb_set_intfdata (udev, dev); // start as if the link is up - netif_device_attach (dev->net); + netif_device_attach (net); return 0; out3: if (info->unbind) info->unbind (dev, udev); - free_netdev(net); out1: - kfree(dev); + free_netdev(net); out: usb_put_dev(xdev); return status; @@ -3252,6 +3278,18 @@ static const struct usb_device_id products [] = { // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" USB_DEVICE (0x6189, 0x182d), .driver_info = (unsigned long) &ax8817x_info, +}, { + // corega FEther USB2-TX + USB_DEVICE (0x07aa, 0x0017), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // Surecom EP-1427X-2 + USB_DEVICE (0x1189, 0x0893), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // goodway corp usb gwusb2e + USB_DEVICE (0x1631, 0x6200), + .driver_info = (unsigned long) &ax8817x_info, }, #endif @@ -3292,6 +3330,13 @@ static const struct usb_device_id products [] = { }, #endif +#ifdef CONFIG_USB_KC2190 +{ + USB_DEVICE (0x050f, 0x0190), // KC-190 + .driver_info = (unsigned long) &kc2190_info, +}, +#endif + #ifdef CONFIG_USB_RNDIS { /* RNDIS is MSFT's un-official variant of CDC ACM */ @@ -3308,11 +3353,18 @@ static const struct usb_device_id products [] = { * * PXA25x or PXA210 ... these use a "usb-eth" driver much like * the sa1100 one, but hardware uses different endpoint numbers. + * + * Or the Linux "Ethernet" gadget on hardware that can't talk + * CDC Ethernet (e.g., no altsettings), in either of two modes: + * - acting just like the old "usb-eth" firmware, though + * the implementation is different + * - supporting RNDIS as the first/default configuration for + * MS-Windows interop; Linux needs to use the other config */ { // 1183 = 0x049F, both used as hex values? // Compaq "Itsy" vendor/product id - USB_DEVICE (0x049F, 0x505A), + USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible .driver_info = (unsigned long) &linuxdev_info, }, { USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy" @@ -3320,15 +3372,22 @@ static const struct usb_device_id products [] = { }, { USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader .driver_info = (unsigned long) &blob_info, +}, { + // Linux Ethernet/RNDIS gadget on pxa210/25x/26x + USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203), + .driver_info = (unsigned long) &linuxdev_info, }, #endif -#ifdef CONFIG_USB_ZAURUS +#if defined(CONFIG_USB_ZAURUS) || defined(CONFIG_USB_CDCETHER) /* * SA-1100 based Sharp Zaurus ("collie"), or compatible. * Same idea as above, but different framing. * * PXA-2xx based models are also lying-about-cdc. + * + * NOTE: These entries do double-duty, serving as blacklist entries + * whenever Zaurus support isn't enabled, but CDC Ethernet is. */ { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO @@ -3339,82 +3398,79 @@ static const struct usb_device_id products [] = { .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = 6 /* Ethernet model */, .bInterfaceProtocol = 0, - .driver_info = (unsigned long) &zaurus_sl5x00_info, + .driver_info = ZAURUS_STRONGARM_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x8005, /* A-300 */ - .bInterfaceClass = 0x02, - .bInterfaceSubClass = 0x0a, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = 6 /* Ethernet model */, .bInterfaceProtocol = 0x00, - .driver_info = (unsigned long) &zaurus_pxa_info, + .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x8006, /* B-500/SL-5600 */ - .bInterfaceClass = 0x02, - .bInterfaceSubClass = 0x0a, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = 6 /* Ethernet model */, .bInterfaceProtocol = 0x00, - .driver_info = (unsigned long) &zaurus_pxa_info, + .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x8007, /* C-700 */ - .bInterfaceClass = 0x02, - .bInterfaceSubClass = 0x0a, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = 6 /* Ethernet model */, .bInterfaceProtocol = 0x00, - .driver_info = (unsigned long) &zaurus_pxa_info, + .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x9031, /* C-750 C-760 */ - .bInterfaceClass = 0x02, - .bInterfaceSubClass = 0x0a, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = 6 /* Ethernet model */, .bInterfaceProtocol = 0x00, - .driver_info = (unsigned long) &zaurus_pxa_info, + .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x9032, /* SL-6000 */ - .bInterfaceClass = 0x02, - .bInterfaceSubClass = 0x0a, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = 6 /* Ethernet model */, .bInterfaceProtocol = 0x00, - .driver_info = (unsigned long) &zaurus_pxa_info, + .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x9050, /* C-860 */ - .bInterfaceClass = 0x02, - .bInterfaceSubClass = 0x0a, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = 6 /* Ethernet model */, .bInterfaceProtocol = 0x00, - .driver_info = (unsigned long) &zaurus_pxa_info, + .driver_info = ZAURUS_PXA_INFO, }, -#endif - -#ifdef CONFIG_USB_CDCETHER -#ifndef CONFIG_USB_ZAURUS - /* if we couldn't whitelist Zaurus, we must blacklist it */ +/* Olympus has some models with a Zaurus-compatible option. + * R-1000 uses a FreeScale i.MXL cpu (ARMv4T) + */ { - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, - .idVendor = 0x04DD, - .idProduct = 0x8004, - /* match the master interface */ + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x07B4, + .idProduct = 0x0F02, /* R-1000 */ .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = 6 /* Ethernet model */, - .bInterfaceProtocol = 0, - .driver_info = 0, /* BLACKLIST */ + .bInterfaceProtocol = 0x00, + .driver_info = OLYMPUS_MXL_INFO, }, - // FIXME blacklist the other Zaurus models too, sigh #endif +#ifdef CONFIG_USB_CDCETHER { /* CDC Ether uses two interfaces, not necessarily consecutive. * We match the main interface, ignoring the optional device