2005-04-17 06:20:36 +08:00
|
|
|
|
/*
|
|
|
|
|
* USB Networking Links
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
* Copyright (C) 2000-2005 by David Brownell
|
2005-04-17 06:20:36 +08:00
|
|
|
|
* Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This is a generic "USB networking" framework that works with several
|
|
|
|
|
* kinds of full and high speed networking devices:
|
|
|
|
|
*
|
|
|
|
|
* + USB host-to-host "network cables", used for IP-over-USB links.
|
|
|
|
|
* These are often used for Laplink style connectivity products.
|
|
|
|
|
* - AnchorChip 2720
|
|
|
|
|
* - Belkin, eTEK (interops with Win32 drivers)
|
|
|
|
|
* - 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.
|
|
|
|
|
* - Linux PDAs like iPaq, Yopy, and Zaurus
|
|
|
|
|
* - The BLOB boot loader (for diskless booting)
|
|
|
|
|
* - Linux "gadgets", perhaps using PXA-2xx or Net2280 controllers
|
|
|
|
|
* - Devices using EPSON's sample USB firmware
|
|
|
|
|
* - CDC-Ethernet class devices, such as many cable modems
|
|
|
|
|
*
|
|
|
|
|
* + Adapters to networks such as Ethernet.
|
|
|
|
|
* - AX8817X based USB 2.0 products
|
|
|
|
|
*
|
|
|
|
|
* Links to these devices can be bridged using Linux Ethernet bridging.
|
|
|
|
|
* With minor exceptions, these all use similar USB framing for network
|
|
|
|
|
* traffic, but need different protocols for control traffic.
|
|
|
|
|
*
|
|
|
|
|
* USB devices can implement their side of this protocol at the cost
|
|
|
|
|
* of two bulk endpoints; it's not restricted to "cable" applications.
|
|
|
|
|
* See the SA1110, Zaurus, or EPSON device/client support in this driver;
|
|
|
|
|
* slave/target drivers such as "usb-eth" (on most SA-1100 PDAs) or
|
|
|
|
|
* "g_ether" (in the Linux "gadget" framework) implement that behavior
|
|
|
|
|
* within devices.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* CHANGELOG:
|
|
|
|
|
*
|
|
|
|
|
* 13-sep-2000 experimental, new
|
|
|
|
|
* 10-oct-2000 usb_device_id table created.
|
|
|
|
|
* 28-oct-2000 misc fixes; mostly, discard more TTL-mangled rx packets.
|
|
|
|
|
* 01-nov-2000 usb_device_id table and probing api update by
|
|
|
|
|
* Adam J. Richter <adam@yggdrasil.com>.
|
|
|
|
|
* 18-dec-2000 (db) tx watchdog, "net1080" renaming to "usbnet", device_info
|
|
|
|
|
* and prolific support, isolate net1080-specific bits, cleanup.
|
|
|
|
|
* fix unlink_urbs oops in D3 PM resume code path.
|
|
|
|
|
*
|
|
|
|
|
* 02-feb-2001 (db) fix tx skb sharing, packet length, match_flags, ...
|
|
|
|
|
* 08-feb-2001 stubbed in "linuxdev", maybe the SA-1100 folk can use it;
|
|
|
|
|
* AnchorChips 2720 support (from spec) for testing;
|
|
|
|
|
* fix bit-ordering problem with ethernet multicast addr
|
|
|
|
|
* 19-feb-2001 Support for clearing halt conditions. SA1100 UDC support
|
|
|
|
|
* updates. Oleg Drokin (green@iXcelerator.com)
|
|
|
|
|
* 25-mar-2001 More SA-1100 updates, including workaround for ip problem
|
|
|
|
|
* expecting cleared skb->cb and framing change to match latest
|
|
|
|
|
* handhelds.org version (Oleg). Enable device IDs from the
|
|
|
|
|
* Win32 Belkin driver; other cleanups (db).
|
|
|
|
|
* 16-jul-2001 Bugfixes for uhci oops-on-unplug, Belkin support, various
|
|
|
|
|
* cleanups for problems not yet seen in the field. (db)
|
|
|
|
|
* 17-oct-2001 Handle "Advance USBNET" product, like Belkin/eTEK devices,
|
|
|
|
|
* from Ioannis Mavroukakis <i.mavroukakis@btinternet.com>;
|
|
|
|
|
* rx unlinks somehow weren't async; minor cleanup.
|
|
|
|
|
* 03-nov-2001 Merged GeneSys driver; original code from Jiun-Jie Huang
|
|
|
|
|
* <huangjj@genesyslogic.com.tw>, updated by Stanislav Brabec
|
|
|
|
|
* <utx@penguin.cz>. Made framing options (NetChip/GeneSys)
|
|
|
|
|
* tie mostly to (sub)driver info. Workaround some PL-2302
|
|
|
|
|
* chips that seem to reject SET_INTERFACE requests.
|
|
|
|
|
*
|
|
|
|
|
* 06-apr-2002 Added ethtool support, based on a patch from Brad Hards.
|
|
|
|
|
* Level of diagnostics is more configurable; they use device
|
|
|
|
|
* location (usb_device->devpath) instead of address (2.5).
|
|
|
|
|
* For tx_fixup, memflags can't be NOIO.
|
|
|
|
|
* 07-may-2002 Generalize/cleanup keventd support, handling rx stalls (mostly
|
|
|
|
|
* for USB 2.0 TTs) and memory shortages (potential) too. (db)
|
|
|
|
|
* Use "locally assigned" IEEE802 address space. (Brad Hards)
|
|
|
|
|
* 18-oct-2002 Support for Zaurus (Pavel Machek), related cleanup (db).
|
|
|
|
|
* 14-dec-2002 Remove Zaurus-private crc32 code (Pavel); 2.5 oops fix,
|
|
|
|
|
* cleanups and stubbed PXA-250 support (db), fix for framing
|
|
|
|
|
* issues on Z, net1080, and gl620a (Toby Milne)
|
|
|
|
|
*
|
|
|
|
|
* 31-mar-2003 Use endpoint descriptors: high speed support, simpler sa1100
|
|
|
|
|
* vs pxa25x, and CDC Ethernet. Throttle down log floods on
|
|
|
|
|
* disconnect; other cleanups. (db) Flush net1080 fifos
|
|
|
|
|
* after several sequential framing errors. (Johannes Erdfelt)
|
|
|
|
|
* 22-aug-2003 AX8817X support (Dave Hollis).
|
2005-09-01 00:54:36 +08:00
|
|
|
|
*
|
2005-04-17 06:20:36 +08:00
|
|
|
|
* 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)
|
|
|
|
|
*
|
|
|
|
|
* 01-feb-2005 AX88772 support (Phil Chang & Dave Hollis)
|
|
|
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// #define DEBUG // error path messages, extra info
|
|
|
|
|
// #define VERBOSE // more; success messages
|
|
|
|
|
|
|
|
|
|
#include <linux/config.h>
|
|
|
|
|
#ifdef CONFIG_USB_DEBUG
|
|
|
|
|
# define DEBUG
|
|
|
|
|
#endif
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
|
#include <linux/sched.h>
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
|
#include <linux/etherdevice.h>
|
|
|
|
|
#include <linux/ethtool.h>
|
|
|
|
|
#include <linux/workqueue.h>
|
|
|
|
|
#include <linux/mii.h>
|
|
|
|
|
#include <linux/usb.h>
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
|
|
|
|
|
#include "usbnet.h"
|
|
|
|
|
|
|
|
|
|
#define DRIVER_VERSION "22-Aug-2005"
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Nineteen USB 1.1 max size bulk transactions per frame (ms), max.
|
|
|
|
|
* Several dozen bytes of IPv4 data can fit in two such transactions.
|
|
|
|
|
* One maximum size Ethernet packet takes twenty four of them.
|
|
|
|
|
* For high speed, each frame comfortably fits almost 36 max size
|
|
|
|
|
* Ethernet packets (so queues should be bigger).
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
*
|
|
|
|
|
* REVISIT qlens should be members of 'struct usbnet'; the goal is to
|
|
|
|
|
* let the USB host controller be busy for 5msec or more before an irq
|
|
|
|
|
* is required, under load. Jumbograms change the equation.
|
2005-04-17 06:20:36 +08:00
|
|
|
|
*/
|
|
|
|
|
#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
|
|
|
|
|
#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
|
|
|
|
|
|
|
|
|
|
// reawaken network queue this soon after stopping; else watchdog barks
|
|
|
|
|
#define TX_TIMEOUT_JIFFIES (5*HZ)
|
|
|
|
|
|
|
|
|
|
// throttle rx/tx briefly after some faults, so khubd might disconnect()
|
|
|
|
|
// us (it polls at HZ/4 usually) before we report too many false errors.
|
|
|
|
|
#define THROTTLE_JIFFIES (HZ/8)
|
|
|
|
|
|
|
|
|
|
// between wakeups
|
|
|
|
|
#define UNLINK_TIMEOUT_MS 3
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// randomly generated ethernet address
|
|
|
|
|
static u8 node_id [ETH_ALEN];
|
|
|
|
|
|
|
|
|
|
static const char driver_name [] = "usbnet";
|
|
|
|
|
|
|
|
|
|
/* use ethtool to change the level for any given device */
|
|
|
|
|
static int msg_level = -1;
|
|
|
|
|
module_param (msg_level, int, 0);
|
|
|
|
|
MODULE_PARM_DESC (msg_level, "Override default message level");
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/* handles CDC Ethernet and many other network "bulk data" interfaces */
|
2005-09-01 00:53:10 +08:00
|
|
|
|
int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
int tmp;
|
|
|
|
|
struct usb_host_interface *alt = NULL;
|
|
|
|
|
struct usb_host_endpoint *in = NULL, *out = NULL;
|
|
|
|
|
struct usb_host_endpoint *status = NULL;
|
|
|
|
|
|
|
|
|
|
for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
|
|
|
|
|
unsigned ep;
|
|
|
|
|
|
|
|
|
|
in = out = status = NULL;
|
|
|
|
|
alt = intf->altsetting + tmp;
|
|
|
|
|
|
|
|
|
|
/* take the first altsetting with in-bulk + out-bulk;
|
|
|
|
|
* remember any status endpoint, just in case;
|
|
|
|
|
* ignore other endpoints and altsetttings.
|
|
|
|
|
*/
|
|
|
|
|
for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
|
|
|
|
|
struct usb_host_endpoint *e;
|
|
|
|
|
int intr = 0;
|
|
|
|
|
|
|
|
|
|
e = alt->endpoint + ep;
|
|
|
|
|
switch (e->desc.bmAttributes) {
|
|
|
|
|
case USB_ENDPOINT_XFER_INT:
|
|
|
|
|
if (!(e->desc.bEndpointAddress & USB_DIR_IN))
|
|
|
|
|
continue;
|
|
|
|
|
intr = 1;
|
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
case USB_ENDPOINT_XFER_BULK:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (e->desc.bEndpointAddress & USB_DIR_IN) {
|
|
|
|
|
if (!intr && !in)
|
|
|
|
|
in = e;
|
|
|
|
|
else if (intr && !status)
|
|
|
|
|
status = e;
|
|
|
|
|
} else {
|
|
|
|
|
if (!out)
|
|
|
|
|
out = e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (in && out)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!alt || !in || !out)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
if (alt->desc.bAlternateSetting != 0
|
|
|
|
|
|| !(dev->driver_info->flags & FLAG_NO_SETINT)) {
|
|
|
|
|
tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber,
|
|
|
|
|
alt->desc.bAlternateSetting);
|
|
|
|
|
if (tmp < 0)
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev->in = usb_rcvbulkpipe (dev->udev,
|
|
|
|
|
in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
|
|
|
|
|
dev->out = usb_sndbulkpipe (dev->udev,
|
|
|
|
|
out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
|
|
|
|
|
dev->status = status;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2005-09-01 00:53:10 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
static void intr_complete (struct urb *urb, struct pt_regs *regs);
|
|
|
|
|
|
|
|
|
|
static int init_status (struct usbnet *dev, struct usb_interface *intf)
|
|
|
|
|
{
|
|
|
|
|
char *buf = NULL;
|
|
|
|
|
unsigned pipe = 0;
|
|
|
|
|
unsigned maxp;
|
|
|
|
|
unsigned period;
|
|
|
|
|
|
|
|
|
|
if (!dev->driver_info->status)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
pipe = usb_rcvintpipe (dev->udev,
|
|
|
|
|
dev->status->desc.bEndpointAddress
|
|
|
|
|
& USB_ENDPOINT_NUMBER_MASK);
|
|
|
|
|
maxp = usb_maxpacket (dev->udev, pipe, 0);
|
|
|
|
|
|
|
|
|
|
/* avoid 1 msec chatter: min 8 msec poll rate */
|
|
|
|
|
period = max ((int) dev->status->desc.bInterval,
|
|
|
|
|
(dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
|
|
|
|
|
|
|
|
|
|
buf = kmalloc (maxp, SLAB_KERNEL);
|
|
|
|
|
if (buf) {
|
|
|
|
|
dev->interrupt = usb_alloc_urb (0, SLAB_KERNEL);
|
|
|
|
|
if (!dev->interrupt) {
|
|
|
|
|
kfree (buf);
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
} else {
|
|
|
|
|
usb_fill_int_urb(dev->interrupt, dev->udev, pipe,
|
|
|
|
|
buf, maxp, intr_complete, dev, period);
|
|
|
|
|
dev_dbg(&intf->dev,
|
|
|
|
|
"status ep%din, %d bytes period %d\n",
|
|
|
|
|
usb_pipeendpoint(pipe), maxp, period);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
/* Passes this packet up the stack, updating its accounting.
|
|
|
|
|
* Some link protocols batch packets, so their rx_fixup paths
|
|
|
|
|
* can return clones as well as just modify the original skb.
|
|
|
|
|
*/
|
|
|
|
|
void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
skb->dev = dev->net;
|
|
|
|
|
skb->protocol = eth_type_trans (skb, dev->net);
|
|
|
|
|
dev->stats.rx_packets++;
|
|
|
|
|
dev->stats.rx_bytes += skb->len;
|
|
|
|
|
|
|
|
|
|
if (netif_msg_rx_status (dev))
|
2005-04-27 02:26:53 +08:00
|
|
|
|
devdbg (dev, "< rx, len %zu, type 0x%x",
|
2005-04-17 06:20:36 +08:00
|
|
|
|
skb->len + sizeof (struct ethhdr), skb->protocol);
|
|
|
|
|
memset (skb->cb, 0, sizeof (struct skb_data));
|
|
|
|
|
status = netif_rx (skb);
|
|
|
|
|
if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev))
|
|
|
|
|
devdbg (dev, "netif_rx status %d", status);
|
|
|
|
|
}
|
2005-09-01 00:53:10 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_skb_return);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_USB_PL2301
|
|
|
|
|
#define HAVE_HARDWARE
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* Prolific PL-2301/PL-2302 driver ... http://www.prolifictech.com
|
|
|
|
|
*
|
|
|
|
|
* The protocol and handshaking used here should be bug-compatible
|
|
|
|
|
* with the Linux 2.2 "plusb" driver, by Deti Fliegl.
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Bits 0-4 can be used for software handshaking; they're set from
|
|
|
|
|
* one end, cleared from the other, "read" with the interrupt byte.
|
|
|
|
|
*/
|
|
|
|
|
#define PL_S_EN (1<<7) /* (feature only) suspend enable */
|
|
|
|
|
/* reserved bit -- rx ready (6) ? */
|
|
|
|
|
#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */
|
|
|
|
|
#define PL_RESET_OUT (1<<4) /* reset output pipe */
|
|
|
|
|
#define PL_RESET_IN (1<<3) /* reset input pipe */
|
|
|
|
|
#define PL_TX_C (1<<2) /* transmission complete */
|
|
|
|
|
#define PL_TX_REQ (1<<1) /* transmission received */
|
|
|
|
|
#define PL_PEER_E (1<<0) /* peer exists */
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
|
pl_vendor_req (struct usbnet *dev, u8 req, u8 val, u8 index)
|
|
|
|
|
{
|
|
|
|
|
return usb_control_msg (dev->udev,
|
|
|
|
|
usb_rcvctrlpipe (dev->udev, 0),
|
|
|
|
|
req,
|
|
|
|
|
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
|
|
|
|
val, index,
|
|
|
|
|
NULL, 0,
|
2005-09-01 00:53:42 +08:00
|
|
|
|
USB_CTRL_GET_TIMEOUT);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
|
pl_clear_QuickLink_features (struct usbnet *dev, int val)
|
|
|
|
|
{
|
|
|
|
|
return pl_vendor_req (dev, 1, (u8) val, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
|
pl_set_QuickLink_features (struct usbnet *dev, int val)
|
|
|
|
|
{
|
|
|
|
|
return pl_vendor_req (dev, 3, (u8) val, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static int pl_reset (struct usbnet *dev)
|
|
|
|
|
{
|
|
|
|
|
/* some units seem to need this reset, others reject it utterly.
|
|
|
|
|
* FIXME be more like "naplink" or windows drivers.
|
|
|
|
|
*/
|
|
|
|
|
(void) pl_set_QuickLink_features (dev,
|
|
|
|
|
PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct driver_info prolific_info = {
|
|
|
|
|
.description = "Prolific PL-2301/PL-2302",
|
|
|
|
|
.flags = FLAG_NO_SETINT,
|
|
|
|
|
/* some PL-2302 versions seem to fail usb_set_interface() */
|
|
|
|
|
.reset = pl_reset,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif /* CONFIG_USB_PL2301 */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* Network Device Driver (peer link to "Host Device", from USB host)
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static int usbnet_change_mtu (struct net_device *net, int new_mtu)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
int ll_mtu = new_mtu + net->hard_header_len;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
if (new_mtu <= 0 || ll_mtu > dev->hard_mtu)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
return -EINVAL;
|
|
|
|
|
// no second zero-length packet read wanted after mtu-sized packets
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
if ((ll_mtu % dev->maxpacket) == 0)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
return -EDOM;
|
|
|
|
|
net->mtu = new_mtu;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static struct net_device_stats *usbnet_get_stats (struct net_device *net)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
return &dev->stats;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from
|
|
|
|
|
* completion callbacks. 2.5 should have fixed those bugs...
|
|
|
|
|
*/
|
|
|
|
|
|
2005-08-10 10:25:21 +08:00
|
|
|
|
static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
2005-08-10 10:25:21 +08:00
|
|
|
|
spin_lock_irqsave(&list->lock, flags);
|
|
|
|
|
__skb_unlink(skb, list);
|
|
|
|
|
spin_unlock(&list->lock);
|
|
|
|
|
spin_lock(&dev->done.lock);
|
|
|
|
|
__skb_queue_tail(&dev->done, skb);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
if (dev->done.qlen == 1)
|
2005-08-10 10:25:21 +08:00
|
|
|
|
tasklet_schedule(&dev->bh);
|
|
|
|
|
spin_unlock_irqrestore(&dev->done.lock, flags);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* some work can't be done in tasklets, so we use keventd
|
|
|
|
|
*
|
|
|
|
|
* NOTE: annoying asymmetry: if it's active, schedule_work() fails,
|
|
|
|
|
* but tasklet_schedule() doesn't. hope the failure is rare.
|
|
|
|
|
*/
|
2005-09-01 00:53:10 +08:00
|
|
|
|
void usbnet_defer_kevent (struct usbnet *dev, int work)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
set_bit (work, &dev->flags);
|
|
|
|
|
if (!schedule_work (&dev->kevent))
|
|
|
|
|
deverr (dev, "kevent %d may have been dropped", work);
|
|
|
|
|
else
|
|
|
|
|
devdbg (dev, "kevent %d scheduled", work);
|
|
|
|
|
}
|
2005-09-01 00:53:10 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static void rx_complete (struct urb *urb, struct pt_regs *regs);
|
|
|
|
|
|
2005-07-29 11:46:32 +08:00
|
|
|
|
static void rx_submit (struct usbnet *dev, struct urb *urb, unsigned flags)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
struct sk_buff *skb;
|
|
|
|
|
struct skb_data *entry;
|
|
|
|
|
int retval = 0;
|
|
|
|
|
unsigned long lockflags;
|
2005-09-01 00:53:10 +08:00
|
|
|
|
size_t size = dev->rx_urb_size;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) {
|
|
|
|
|
if (netif_msg_rx_err (dev))
|
|
|
|
|
devdbg (dev, "no rx skb");
|
2005-09-01 00:53:10 +08:00
|
|
|
|
usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
usb_free_urb (urb);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
skb_reserve (skb, NET_IP_ALIGN);
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
skb->data, size, rx_complete, skb);
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave (&dev->rxq.lock, lockflags);
|
|
|
|
|
|
|
|
|
|
if (netif_running (dev->net)
|
|
|
|
|
&& netif_device_present (dev->net)
|
|
|
|
|
&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
|
|
|
|
|
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
|
|
|
|
|
case -EPIPE:
|
2005-09-01 00:53:10 +08:00
|
|
|
|
usbnet_defer_kevent (dev, EVENT_RX_HALT);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
break;
|
|
|
|
|
case -ENOMEM:
|
2005-09-01 00:53:10 +08:00
|
|
|
|
usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
break;
|
|
|
|
|
case -ENODEV:
|
|
|
|
|
if (netif_msg_ifdown (dev))
|
|
|
|
|
devdbg (dev, "device gone");
|
|
|
|
|
netif_device_detach (dev->net);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (netif_msg_rx_err (dev))
|
|
|
|
|
devdbg (dev, "rx submit, %d", retval);
|
|
|
|
|
tasklet_schedule (&dev->bh);
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
__skb_queue_tail (&dev->rxq, skb);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (netif_msg_ifdown (dev))
|
|
|
|
|
devdbg (dev, "rx: stopped");
|
|
|
|
|
retval = -ENOLINK;
|
|
|
|
|
}
|
|
|
|
|
spin_unlock_irqrestore (&dev->rxq.lock, lockflags);
|
|
|
|
|
if (retval) {
|
|
|
|
|
dev_kfree_skb_any (skb);
|
|
|
|
|
usb_free_urb (urb);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
|
|
|
|
|
{
|
|
|
|
|
if (dev->driver_info->rx_fixup
|
|
|
|
|
&& !dev->driver_info->rx_fixup (dev, skb))
|
|
|
|
|
goto error;
|
|
|
|
|
// else network stack removes extra byte if we forced a short packet
|
|
|
|
|
|
|
|
|
|
if (skb->len)
|
2005-09-01 00:53:10 +08:00
|
|
|
|
usbnet_skb_return (dev, skb);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
else {
|
|
|
|
|
if (netif_msg_rx_err (dev))
|
|
|
|
|
devdbg (dev, "drop");
|
|
|
|
|
error:
|
|
|
|
|
dev->stats.rx_errors++;
|
|
|
|
|
skb_queue_tail (&dev->done, skb);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static void rx_complete (struct urb *urb, struct pt_regs *regs)
|
|
|
|
|
{
|
|
|
|
|
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
|
|
|
|
struct skb_data *entry = (struct skb_data *) skb->cb;
|
|
|
|
|
struct usbnet *dev = entry->dev;
|
|
|
|
|
int urb_status = urb->status;
|
|
|
|
|
|
|
|
|
|
skb_put (skb, urb->actual_length);
|
|
|
|
|
entry->state = rx_done;
|
|
|
|
|
entry->urb = NULL;
|
|
|
|
|
|
|
|
|
|
switch (urb_status) {
|
|
|
|
|
// success
|
|
|
|
|
case 0:
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
if (skb->len < dev->net->hard_header_len) {
|
2005-04-17 06:20:36 +08:00
|
|
|
|
entry->state = rx_cleanup;
|
|
|
|
|
dev->stats.rx_errors++;
|
|
|
|
|
dev->stats.rx_length_errors++;
|
|
|
|
|
if (netif_msg_rx_err (dev))
|
|
|
|
|
devdbg (dev, "rx length %d", skb->len);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// stalls need manual reset. this is rare ... except that
|
|
|
|
|
// when going through USB 2.0 TTs, unplug appears this way.
|
|
|
|
|
// we avoid the highspeed version of the ETIMEOUT/EILSEQ
|
|
|
|
|
// storm, recovering as needed.
|
|
|
|
|
case -EPIPE:
|
|
|
|
|
dev->stats.rx_errors++;
|
2005-09-01 00:53:10 +08:00
|
|
|
|
usbnet_defer_kevent (dev, EVENT_RX_HALT);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
// FALLTHROUGH
|
|
|
|
|
|
|
|
|
|
// software-driven interface shutdown
|
|
|
|
|
case -ECONNRESET: // async unlink
|
|
|
|
|
case -ESHUTDOWN: // hardware gone
|
|
|
|
|
if (netif_msg_ifdown (dev))
|
|
|
|
|
devdbg (dev, "rx shutdown, code %d", urb_status);
|
|
|
|
|
goto block;
|
|
|
|
|
|
|
|
|
|
// we get controller i/o faults during khubd disconnect() delays.
|
|
|
|
|
// throttle down resubmits, to avoid log floods; just temporarily,
|
|
|
|
|
// so we still recover when the fault isn't a khubd delay.
|
|
|
|
|
case -EPROTO: // ehci
|
|
|
|
|
case -ETIMEDOUT: // ohci
|
|
|
|
|
case -EILSEQ: // uhci
|
|
|
|
|
dev->stats.rx_errors++;
|
|
|
|
|
if (!timer_pending (&dev->delay)) {
|
|
|
|
|
mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES);
|
|
|
|
|
if (netif_msg_link (dev))
|
|
|
|
|
devdbg (dev, "rx throttle %d", urb_status);
|
|
|
|
|
}
|
|
|
|
|
block:
|
|
|
|
|
entry->state = rx_cleanup;
|
|
|
|
|
entry->urb = urb;
|
|
|
|
|
urb = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// data overrun ... flush fifo?
|
|
|
|
|
case -EOVERFLOW:
|
|
|
|
|
dev->stats.rx_over_errors++;
|
|
|
|
|
// FALLTHROUGH
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
entry->state = rx_cleanup;
|
|
|
|
|
dev->stats.rx_errors++;
|
|
|
|
|
if (netif_msg_rx_err (dev))
|
|
|
|
|
devdbg (dev, "rx status %d", urb_status);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-10 10:25:21 +08:00
|
|
|
|
defer_bh(dev, skb, &dev->rxq);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
if (urb) {
|
|
|
|
|
if (netif_running (dev->net)
|
|
|
|
|
&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
|
|
|
|
|
rx_submit (dev, urb, GFP_ATOMIC);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
usb_free_urb (urb);
|
|
|
|
|
}
|
|
|
|
|
if (netif_msg_rx_err (dev))
|
|
|
|
|
devdbg (dev, "no read resubmitted");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intr_complete (struct urb *urb, struct pt_regs *regs)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = urb->context;
|
|
|
|
|
int status = urb->status;
|
|
|
|
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
/* success */
|
|
|
|
|
case 0:
|
|
|
|
|
dev->driver_info->status(dev, urb);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* software-driven interface shutdown */
|
|
|
|
|
case -ENOENT: // urb killed
|
|
|
|
|
case -ESHUTDOWN: // hardware gone
|
|
|
|
|
if (netif_msg_ifdown (dev))
|
|
|
|
|
devdbg (dev, "intr shutdown, code %d", status);
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* NOTE: not throttling like RX/TX, since this endpoint
|
|
|
|
|
* already polls infrequently
|
|
|
|
|
*/
|
|
|
|
|
default:
|
|
|
|
|
devdbg (dev, "intr status %d", status);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!netif_running (dev->net))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
|
|
|
|
|
status = usb_submit_urb (urb, GFP_ATOMIC);
|
|
|
|
|
if (status != 0 && netif_msg_timer (dev))
|
|
|
|
|
deverr(dev, "intr resubmit --> %d", status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// unlink pending rx/tx; completion handlers do all other cleanup
|
|
|
|
|
|
|
|
|
|
static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
|
|
|
|
|
{
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
struct sk_buff *skb, *skbnext;
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave (&q->lock, flags);
|
|
|
|
|
for (skb = q->next; skb != (struct sk_buff *) q; skb = skbnext) {
|
|
|
|
|
struct skb_data *entry;
|
|
|
|
|
struct urb *urb;
|
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
|
|
entry = (struct skb_data *) skb->cb;
|
|
|
|
|
urb = entry->urb;
|
|
|
|
|
skbnext = skb->next;
|
|
|
|
|
|
|
|
|
|
// during some PM-driven resume scenarios,
|
|
|
|
|
// these (async) unlinks complete immediately
|
|
|
|
|
retval = usb_unlink_urb (urb);
|
|
|
|
|
if (retval != -EINPROGRESS && retval != 0)
|
|
|
|
|
devdbg (dev, "unlink urb err, %d", retval);
|
|
|
|
|
else
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
spin_unlock_irqrestore (&q->lock, flags);
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// precondition: never called in_interrupt
|
|
|
|
|
|
|
|
|
|
static int usbnet_stop (struct net_device *net)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
int temp;
|
|
|
|
|
DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
|
|
|
|
|
DECLARE_WAITQUEUE (wait, current);
|
|
|
|
|
|
|
|
|
|
netif_stop_queue (net);
|
|
|
|
|
|
|
|
|
|
if (netif_msg_ifdown (dev))
|
|
|
|
|
devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
|
|
|
|
|
dev->stats.rx_packets, dev->stats.tx_packets,
|
|
|
|
|
dev->stats.rx_errors, dev->stats.tx_errors
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ensure there are no more active urbs
|
|
|
|
|
add_wait_queue (&unlink_wakeup, &wait);
|
|
|
|
|
dev->wait = &unlink_wakeup;
|
|
|
|
|
temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
|
|
|
|
|
|
|
|
|
|
// maybe wait for deletions to finish.
|
2005-07-09 05:57:23 +08:00
|
|
|
|
while (!skb_queue_empty(&dev->rxq) &&
|
|
|
|
|
!skb_queue_empty(&dev->txq) &&
|
|
|
|
|
!skb_queue_empty(&dev->done)) {
|
2005-04-17 06:20:36 +08:00
|
|
|
|
msleep(UNLINK_TIMEOUT_MS);
|
|
|
|
|
if (netif_msg_ifdown (dev))
|
|
|
|
|
devdbg (dev, "waited for %d urb completions", temp);
|
|
|
|
|
}
|
|
|
|
|
dev->wait = NULL;
|
|
|
|
|
remove_wait_queue (&unlink_wakeup, &wait);
|
|
|
|
|
|
|
|
|
|
usb_kill_urb(dev->interrupt);
|
|
|
|
|
|
|
|
|
|
/* deferred work (task, timer, softirq) must also stop.
|
|
|
|
|
* can't flush_scheduled_work() until we drop rtnl (later),
|
|
|
|
|
* else workers could deadlock; so make workers a NOP.
|
|
|
|
|
*/
|
|
|
|
|
dev->flags = 0;
|
|
|
|
|
del_timer_sync (&dev->delay);
|
|
|
|
|
tasklet_kill (&dev->bh);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// posts reads, and enables write queuing
|
|
|
|
|
|
|
|
|
|
// precondition: never called in_interrupt
|
|
|
|
|
|
|
|
|
|
static int usbnet_open (struct net_device *net)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
int retval = 0;
|
|
|
|
|
struct driver_info *info = dev->driver_info;
|
|
|
|
|
|
|
|
|
|
// put into "known safe" state
|
|
|
|
|
if (info->reset && (retval = info->reset (dev)) < 0) {
|
|
|
|
|
if (netif_msg_ifup (dev))
|
|
|
|
|
devinfo (dev,
|
|
|
|
|
"open reset fail (%d) usbnet usb-%s-%s, %s",
|
|
|
|
|
retval,
|
|
|
|
|
dev->udev->bus->bus_name, dev->udev->devpath,
|
|
|
|
|
info->description);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// insist peer be connected
|
|
|
|
|
if (info->check_connect && (retval = info->check_connect (dev)) < 0) {
|
|
|
|
|
if (netif_msg_ifup (dev))
|
|
|
|
|
devdbg (dev, "can't open; %d", retval);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* start any status interrupt transfer */
|
|
|
|
|
if (dev->interrupt) {
|
|
|
|
|
retval = usb_submit_urb (dev->interrupt, GFP_KERNEL);
|
|
|
|
|
if (retval < 0) {
|
|
|
|
|
if (netif_msg_ifup (dev))
|
|
|
|
|
deverr (dev, "intr submit %d", retval);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
netif_start_queue (net);
|
|
|
|
|
if (netif_msg_ifup (dev)) {
|
|
|
|
|
char *framing;
|
|
|
|
|
|
|
|
|
|
if (dev->driver_info->flags & FLAG_FRAMING_NC)
|
|
|
|
|
framing = "NetChip";
|
|
|
|
|
else if (dev->driver_info->flags & FLAG_FRAMING_GL)
|
|
|
|
|
framing = "GeneSys";
|
|
|
|
|
else if (dev->driver_info->flags & FLAG_FRAMING_Z)
|
|
|
|
|
framing = "Zaurus";
|
|
|
|
|
else if (dev->driver_info->flags & FLAG_FRAMING_RN)
|
|
|
|
|
framing = "RNDIS";
|
|
|
|
|
else if (dev->driver_info->flags & FLAG_FRAMING_AX)
|
|
|
|
|
framing = "ASIX";
|
|
|
|
|
else
|
|
|
|
|
framing = "simple";
|
|
|
|
|
|
|
|
|
|
devinfo (dev, "open: enable queueing "
|
|
|
|
|
"(rx %d, tx %d) mtu %d %s framing",
|
|
|
|
|
RX_QLEN (dev), TX_QLEN (dev), dev->net->mtu,
|
|
|
|
|
framing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// delay posting reads until we're fully open
|
|
|
|
|
tasklet_schedule (&dev->bh);
|
|
|
|
|
done:
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
/* ethtool methods; minidrivers may need to add some more, but
|
|
|
|
|
* they'll probably want to use this base set.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
/* REVISIT don't always return "usbnet" */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
strncpy (info->driver, driver_name, sizeof info->driver);
|
|
|
|
|
strncpy (info->version, DRIVER_VERSION, sizeof info->version);
|
|
|
|
|
strncpy (info->fw_version, dev->driver_info->description,
|
|
|
|
|
sizeof info->fw_version);
|
|
|
|
|
usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
|
|
|
|
|
}
|
2005-09-01 00:53:10 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
static u32 usbnet_get_link (struct net_device *net)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
/* If a check_connect is defined, return its result */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
if (dev->driver_info->check_connect)
|
|
|
|
|
return dev->driver_info->check_connect (dev) == 0;
|
|
|
|
|
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
/* Otherwise, say we're up (to avoid breaking scripts) */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
u32 usbnet_get_msglevel (struct net_device *net)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
|
|
|
|
|
return dev->msg_enable;
|
|
|
|
|
}
|
2005-09-01 00:53:10 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_get_msglevel);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
void usbnet_set_msglevel (struct net_device *net, u32 level)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
|
|
|
|
|
dev->msg_enable = level;
|
|
|
|
|
}
|
2005-09-01 00:53:10 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
/* drivers may override default ethtool_ops in their bind() routine */
|
|
|
|
|
static struct ethtool_ops usbnet_ethtool_ops = {
|
|
|
|
|
.get_drvinfo = usbnet_get_drvinfo,
|
|
|
|
|
.get_link = usbnet_get_link,
|
|
|
|
|
.get_msglevel = usbnet_get_msglevel,
|
|
|
|
|
.set_msglevel = usbnet_set_msglevel,
|
|
|
|
|
};
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/* work that cannot be done in interrupt context uses keventd.
|
|
|
|
|
*
|
|
|
|
|
* NOTE: with 2.5 we could do more of this using completion callbacks,
|
|
|
|
|
* especially now that control transfers can be queued.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
kevent (void *data)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = data;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
/* usb_clear_halt() needs a thread context */
|
|
|
|
|
if (test_bit (EVENT_TX_HALT, &dev->flags)) {
|
|
|
|
|
unlink_urbs (dev, &dev->txq);
|
|
|
|
|
status = usb_clear_halt (dev->udev, dev->out);
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
if (status < 0
|
|
|
|
|
&& status != -EPIPE
|
|
|
|
|
&& status != -ESHUTDOWN) {
|
2005-04-17 06:20:36 +08:00
|
|
|
|
if (netif_msg_tx_err (dev))
|
|
|
|
|
deverr (dev, "can't clear tx halt, status %d",
|
|
|
|
|
status);
|
|
|
|
|
} else {
|
|
|
|
|
clear_bit (EVENT_TX_HALT, &dev->flags);
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
if (status != -ESHUTDOWN)
|
|
|
|
|
netif_wake_queue (dev->net);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (test_bit (EVENT_RX_HALT, &dev->flags)) {
|
|
|
|
|
unlink_urbs (dev, &dev->rxq);
|
|
|
|
|
status = usb_clear_halt (dev->udev, dev->in);
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
if (status < 0
|
|
|
|
|
&& status != -EPIPE
|
|
|
|
|
&& status != -ESHUTDOWN) {
|
2005-04-17 06:20:36 +08:00
|
|
|
|
if (netif_msg_rx_err (dev))
|
|
|
|
|
deverr (dev, "can't clear rx halt, status %d",
|
|
|
|
|
status);
|
|
|
|
|
} else {
|
|
|
|
|
clear_bit (EVENT_RX_HALT, &dev->flags);
|
|
|
|
|
tasklet_schedule (&dev->bh);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* tasklet could resubmit itself forever if memory is tight */
|
|
|
|
|
if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
|
|
|
|
|
struct urb *urb = NULL;
|
|
|
|
|
|
|
|
|
|
if (netif_running (dev->net))
|
|
|
|
|
urb = usb_alloc_urb (0, GFP_KERNEL);
|
|
|
|
|
else
|
|
|
|
|
clear_bit (EVENT_RX_MEMORY, &dev->flags);
|
|
|
|
|
if (urb != NULL) {
|
|
|
|
|
clear_bit (EVENT_RX_MEMORY, &dev->flags);
|
|
|
|
|
rx_submit (dev, urb, GFP_KERNEL);
|
|
|
|
|
tasklet_schedule (&dev->bh);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-23 06:07:02 +08:00
|
|
|
|
if (test_bit (EVENT_LINK_RESET, &dev->flags)) {
|
|
|
|
|
struct driver_info *info = dev->driver_info;
|
|
|
|
|
int retval = 0;
|
|
|
|
|
|
|
|
|
|
clear_bit (EVENT_LINK_RESET, &dev->flags);
|
|
|
|
|
if(info->link_reset && (retval = info->link_reset(dev)) < 0) {
|
|
|
|
|
devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s",
|
|
|
|
|
retval,
|
|
|
|
|
dev->udev->bus->bus_name, dev->udev->devpath,
|
|
|
|
|
info->description);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
|
if (dev->flags)
|
|
|
|
|
devdbg (dev, "kevent done, flags = 0x%lx",
|
|
|
|
|
dev->flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static void tx_complete (struct urb *urb, struct pt_regs *regs)
|
|
|
|
|
{
|
|
|
|
|
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
|
|
|
|
struct skb_data *entry = (struct skb_data *) skb->cb;
|
|
|
|
|
struct usbnet *dev = entry->dev;
|
|
|
|
|
|
|
|
|
|
if (urb->status == 0) {
|
|
|
|
|
dev->stats.tx_packets++;
|
|
|
|
|
dev->stats.tx_bytes += entry->length;
|
|
|
|
|
} else {
|
|
|
|
|
dev->stats.tx_errors++;
|
|
|
|
|
|
|
|
|
|
switch (urb->status) {
|
|
|
|
|
case -EPIPE:
|
2005-09-01 00:53:10 +08:00
|
|
|
|
usbnet_defer_kevent (dev, EVENT_TX_HALT);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* software-driven interface shutdown */
|
|
|
|
|
case -ECONNRESET: // async unlink
|
|
|
|
|
case -ESHUTDOWN: // hardware gone
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// like rx, tx gets controller i/o faults during khubd delays
|
|
|
|
|
// and so it uses the same throttling mechanism.
|
|
|
|
|
case -EPROTO: // ehci
|
|
|
|
|
case -ETIMEDOUT: // ohci
|
|
|
|
|
case -EILSEQ: // uhci
|
|
|
|
|
if (!timer_pending (&dev->delay)) {
|
|
|
|
|
mod_timer (&dev->delay,
|
|
|
|
|
jiffies + THROTTLE_JIFFIES);
|
|
|
|
|
if (netif_msg_link (dev))
|
|
|
|
|
devdbg (dev, "tx throttle %d",
|
|
|
|
|
urb->status);
|
|
|
|
|
}
|
|
|
|
|
netif_stop_queue (dev->net);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (netif_msg_tx_err (dev))
|
|
|
|
|
devdbg (dev, "tx err %d", entry->urb->status);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
urb->dev = NULL;
|
|
|
|
|
entry->state = tx_done;
|
2005-08-10 10:25:21 +08:00
|
|
|
|
defer_bh(dev, skb, &dev->txq);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static void usbnet_tx_timeout (struct net_device *net)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
|
|
|
|
|
unlink_urbs (dev, &dev->txq);
|
|
|
|
|
tasklet_schedule (&dev->bh);
|
|
|
|
|
|
|
|
|
|
// FIXME: device recovery -- reset?
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = netdev_priv(net);
|
|
|
|
|
int length;
|
|
|
|
|
int retval = NET_XMIT_SUCCESS;
|
|
|
|
|
struct urb *urb = NULL;
|
|
|
|
|
struct skb_data *entry;
|
|
|
|
|
struct driver_info *info = dev->driver_info;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
|
|
// some devices want funky USB-level framing, for
|
|
|
|
|
// win32 driver (usually) and/or hardware quirks
|
|
|
|
|
if (info->tx_fixup) {
|
|
|
|
|
skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
|
|
|
|
|
if (!skb) {
|
|
|
|
|
if (netif_msg_tx_err (dev))
|
|
|
|
|
devdbg (dev, "can't tx_fixup skb");
|
|
|
|
|
goto drop;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
length = skb->len;
|
|
|
|
|
|
|
|
|
|
if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) {
|
|
|
|
|
if (netif_msg_tx_err (dev))
|
|
|
|
|
devdbg (dev, "no urb");
|
|
|
|
|
goto drop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
skb->data, skb->len, tx_complete, skb);
|
|
|
|
|
|
|
|
|
|
/* don't assume the hardware handles USB_ZERO_PACKET
|
|
|
|
|
* NOTE: strictly conforming cdc-ether devices should expect
|
|
|
|
|
* the ZLP here, but ignore the one-byte packet.
|
|
|
|
|
*
|
|
|
|
|
* FIXME zero that byte, if it doesn't require a new skb.
|
|
|
|
|
*/
|
|
|
|
|
if ((length % dev->maxpacket) == 0)
|
|
|
|
|
urb->transfer_buffer_length++;
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave (&dev->txq.lock, flags);
|
|
|
|
|
|
|
|
|
|
switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) {
|
|
|
|
|
case -EPIPE:
|
|
|
|
|
netif_stop_queue (net);
|
2005-09-01 00:53:10 +08:00
|
|
|
|
usbnet_defer_kevent (dev, EVENT_TX_HALT);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (netif_msg_tx_err (dev))
|
|
|
|
|
devdbg (dev, "tx: submit urb err %d", retval);
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
net->trans_start = jiffies;
|
|
|
|
|
__skb_queue_tail (&dev->txq, skb);
|
|
|
|
|
if (dev->txq.qlen >= TX_QLEN (dev))
|
|
|
|
|
netif_stop_queue (net);
|
|
|
|
|
}
|
|
|
|
|
spin_unlock_irqrestore (&dev->txq.lock, flags);
|
|
|
|
|
|
|
|
|
|
if (retval) {
|
|
|
|
|
if (netif_msg_tx_err (dev))
|
|
|
|
|
devdbg (dev, "drop, code %d", retval);
|
|
|
|
|
drop:
|
|
|
|
|
retval = NET_XMIT_SUCCESS;
|
|
|
|
|
dev->stats.tx_dropped++;
|
|
|
|
|
if (skb)
|
|
|
|
|
dev_kfree_skb_any (skb);
|
|
|
|
|
usb_free_urb (urb);
|
|
|
|
|
} else if (netif_msg_tx_queued (dev)) {
|
|
|
|
|
devdbg (dev, "> tx, len %d, type 0x%x",
|
|
|
|
|
length, skb->protocol);
|
|
|
|
|
}
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// tasklet (work deferred from completions, in_irq) or timer
|
|
|
|
|
|
|
|
|
|
static void usbnet_bh (unsigned long param)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = (struct usbnet *) param;
|
|
|
|
|
struct sk_buff *skb;
|
|
|
|
|
struct skb_data *entry;
|
|
|
|
|
|
|
|
|
|
while ((skb = skb_dequeue (&dev->done))) {
|
|
|
|
|
entry = (struct skb_data *) skb->cb;
|
|
|
|
|
switch (entry->state) {
|
|
|
|
|
case rx_done:
|
|
|
|
|
entry->state = rx_cleanup;
|
|
|
|
|
rx_process (dev, skb);
|
|
|
|
|
continue;
|
|
|
|
|
case tx_done:
|
|
|
|
|
case rx_cleanup:
|
|
|
|
|
usb_free_urb (entry->urb);
|
|
|
|
|
dev_kfree_skb (skb);
|
|
|
|
|
continue;
|
|
|
|
|
default:
|
|
|
|
|
devdbg (dev, "bogus skb state %d", entry->state);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// waiting for all pending urbs to complete?
|
|
|
|
|
if (dev->wait) {
|
|
|
|
|
if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {
|
|
|
|
|
wake_up (dev->wait);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// or are we maybe short a few urbs?
|
|
|
|
|
} else if (netif_running (dev->net)
|
|
|
|
|
&& netif_device_present (dev->net)
|
|
|
|
|
&& !timer_pending (&dev->delay)
|
|
|
|
|
&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
|
|
|
|
|
int temp = dev->rxq.qlen;
|
|
|
|
|
int qlen = RX_QLEN (dev);
|
|
|
|
|
|
|
|
|
|
if (temp < qlen) {
|
|
|
|
|
struct urb *urb;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
// don't refill the queue all at once
|
|
|
|
|
for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) {
|
|
|
|
|
urb = usb_alloc_urb (0, GFP_ATOMIC);
|
|
|
|
|
if (urb != NULL)
|
|
|
|
|
rx_submit (dev, urb, GFP_ATOMIC);
|
|
|
|
|
}
|
|
|
|
|
if (temp != dev->rxq.qlen && netif_msg_link (dev))
|
|
|
|
|
devdbg (dev, "rxqlen %d --> %d",
|
|
|
|
|
temp, dev->rxq.qlen);
|
|
|
|
|
if (dev->rxq.qlen < qlen)
|
|
|
|
|
tasklet_schedule (&dev->bh);
|
|
|
|
|
}
|
|
|
|
|
if (dev->txq.qlen < TX_QLEN (dev))
|
|
|
|
|
netif_wake_queue (dev->net);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* USB Device Driver support
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// precondition: never called in_interrupt
|
|
|
|
|
|
2005-09-01 00:52:45 +08:00
|
|
|
|
void usbnet_disconnect (struct usb_interface *intf)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev;
|
|
|
|
|
struct usb_device *xdev;
|
|
|
|
|
struct net_device *net;
|
|
|
|
|
|
|
|
|
|
dev = usb_get_intfdata(intf);
|
|
|
|
|
usb_set_intfdata(intf, NULL);
|
|
|
|
|
if (!dev)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
xdev = interface_to_usbdev (intf);
|
|
|
|
|
|
|
|
|
|
if (netif_msg_probe (dev))
|
2005-09-01 00:52:45 +08:00
|
|
|
|
devinfo (dev, "unregister '%s' usb-%s-%s, %s",
|
|
|
|
|
intf->dev.driver->name,
|
2005-04-17 06:20:36 +08:00
|
|
|
|
xdev->bus->bus_name, xdev->devpath,
|
|
|
|
|
dev->driver_info->description);
|
|
|
|
|
|
|
|
|
|
net = dev->net;
|
|
|
|
|
unregister_netdev (net);
|
|
|
|
|
|
|
|
|
|
/* we don't hold rtnl here ... */
|
|
|
|
|
flush_scheduled_work ();
|
|
|
|
|
|
|
|
|
|
if (dev->driver_info->unbind)
|
|
|
|
|
dev->driver_info->unbind (dev, intf);
|
|
|
|
|
|
|
|
|
|
free_netdev(net);
|
|
|
|
|
usb_put_dev (xdev);
|
|
|
|
|
}
|
2005-09-01 00:52:45 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_disconnect);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
// precondition: never called in_interrupt
|
|
|
|
|
|
2005-09-01 00:52:45 +08:00
|
|
|
|
int
|
2005-04-17 06:20:36 +08:00
|
|
|
|
usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
|
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev;
|
|
|
|
|
struct net_device *net;
|
|
|
|
|
struct usb_host_interface *interface;
|
|
|
|
|
struct driver_info *info;
|
|
|
|
|
struct usb_device *xdev;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
info = (struct driver_info *) prod->driver_info;
|
|
|
|
|
if (!info) {
|
|
|
|
|
dev_dbg (&udev->dev, "blacklisted by %s\n", driver_name);
|
|
|
|
|
return -ENODEV;
|
|
|
|
|
}
|
|
|
|
|
xdev = interface_to_usbdev (udev);
|
|
|
|
|
interface = udev->cur_altsetting;
|
|
|
|
|
|
|
|
|
|
usb_get_dev (xdev);
|
|
|
|
|
|
|
|
|
|
status = -ENOMEM;
|
|
|
|
|
|
|
|
|
|
// set up our own records
|
|
|
|
|
net = alloc_etherdev(sizeof(*dev));
|
|
|
|
|
if (!net) {
|
|
|
|
|
dbg ("can't kmalloc dev");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev = netdev_priv(net);
|
|
|
|
|
dev->udev = xdev;
|
|
|
|
|
dev->driver_info = info;
|
|
|
|
|
dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
|
|
|
|
|
| NETIF_MSG_PROBE | NETIF_MSG_LINK);
|
|
|
|
|
skb_queue_head_init (&dev->rxq);
|
|
|
|
|
skb_queue_head_init (&dev->txq);
|
|
|
|
|
skb_queue_head_init (&dev->done);
|
|
|
|
|
dev->bh.func = usbnet_bh;
|
|
|
|
|
dev->bh.data = (unsigned long) dev;
|
|
|
|
|
INIT_WORK (&dev->kevent, kevent, dev);
|
|
|
|
|
dev->delay.function = usbnet_bh;
|
|
|
|
|
dev->delay.data = (unsigned long) dev;
|
|
|
|
|
init_timer (&dev->delay);
|
|
|
|
|
|
|
|
|
|
SET_MODULE_OWNER (net);
|
|
|
|
|
dev->net = net;
|
|
|
|
|
strcpy (net->name, "usb%d");
|
|
|
|
|
memcpy (net->dev_addr, node_id, sizeof node_id);
|
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
/* rx and tx sides can use different message sizes;
|
|
|
|
|
* bind() should set rx_urb_size in that case.
|
|
|
|
|
*/
|
|
|
|
|
dev->hard_mtu = net->mtu + net->hard_header_len;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
#if 0
|
|
|
|
|
// dma_supported() is deeply broken on almost all architectures
|
|
|
|
|
// possible with some EHCI controllers
|
|
|
|
|
if (dma_supported (&udev->dev, DMA_64BIT_MASK))
|
|
|
|
|
net->features |= NETIF_F_HIGHDMA;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
net->change_mtu = usbnet_change_mtu;
|
|
|
|
|
net->get_stats = usbnet_get_stats;
|
|
|
|
|
net->hard_start_xmit = usbnet_start_xmit;
|
|
|
|
|
net->open = usbnet_open;
|
|
|
|
|
net->stop = usbnet_stop;
|
|
|
|
|
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
|
|
|
|
|
net->tx_timeout = usbnet_tx_timeout;
|
|
|
|
|
net->ethtool_ops = &usbnet_ethtool_ops;
|
|
|
|
|
|
|
|
|
|
// allow device-specific bind/init procedures
|
|
|
|
|
// NOTE net->name still not usable ...
|
|
|
|
|
if (info->bind) {
|
|
|
|
|
status = info->bind (dev, udev);
|
|
|
|
|
// heuristic: "usb%d" for links we know are two-host,
|
|
|
|
|
// else "eth%d" when there's reasonable doubt. userspace
|
|
|
|
|
// can rename the link if it knows better.
|
|
|
|
|
if ((dev->driver_info->flags & FLAG_ETHER) != 0
|
|
|
|
|
&& (net->dev_addr [0] & 0x02) == 0)
|
|
|
|
|
strcpy (net->name, "eth%d");
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
|
|
|
|
|
/* maybe the remote can't receive an Ethernet MTU */
|
|
|
|
|
if (net->mtu > (dev->hard_mtu - net->hard_header_len))
|
|
|
|
|
net->mtu = dev->hard_mtu - net->hard_header_len;
|
2005-09-01 00:53:10 +08:00
|
|
|
|
} else if (!info->in || !info->out)
|
|
|
|
|
status = usbnet_get_endpoints (dev, udev);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
else {
|
|
|
|
|
dev->in = usb_rcvbulkpipe (xdev, info->in);
|
|
|
|
|
dev->out = usb_sndbulkpipe (xdev, info->out);
|
|
|
|
|
if (!(info->flags & FLAG_NO_SETINT))
|
|
|
|
|
status = usb_set_interface (xdev,
|
|
|
|
|
interface->desc.bInterfaceNumber,
|
|
|
|
|
interface->desc.bAlternateSetting);
|
|
|
|
|
else
|
|
|
|
|
status = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (status == 0 && dev->status)
|
|
|
|
|
status = init_status (dev, udev);
|
|
|
|
|
if (status < 0)
|
|
|
|
|
goto out1;
|
|
|
|
|
|
2005-09-01 00:53:10 +08:00
|
|
|
|
if (!dev->rx_urb_size)
|
|
|
|
|
dev->rx_urb_size = dev->hard_mtu;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
|
|
|
|
|
|
|
|
|
|
SET_NETDEV_DEV(net, &udev->dev);
|
|
|
|
|
status = register_netdev (net);
|
|
|
|
|
if (status)
|
|
|
|
|
goto out3;
|
|
|
|
|
if (netif_msg_probe (dev))
|
2005-09-01 00:52:45 +08:00
|
|
|
|
devinfo (dev, "register '%s' at usb-%s-%s, %s, "
|
2005-04-17 06:20:36 +08:00
|
|
|
|
"%02x:%02x:%02x:%02x:%02x:%02x",
|
2005-09-01 00:52:45 +08:00
|
|
|
|
udev->dev.driver->name,
|
2005-04-17 06:20:36 +08:00
|
|
|
|
xdev->bus->bus_name, xdev->devpath,
|
|
|
|
|
dev->driver_info->description,
|
|
|
|
|
net->dev_addr [0], net->dev_addr [1],
|
|
|
|
|
net->dev_addr [2], net->dev_addr [3],
|
|
|
|
|
net->dev_addr [4], net->dev_addr [5]);
|
|
|
|
|
|
|
|
|
|
// ok, it's ready to go.
|
|
|
|
|
usb_set_intfdata (udev, dev);
|
|
|
|
|
|
|
|
|
|
// start as if the link is up
|
|
|
|
|
netif_device_attach (net);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
out3:
|
|
|
|
|
if (info->unbind)
|
|
|
|
|
info->unbind (dev, udev);
|
|
|
|
|
out1:
|
|
|
|
|
free_netdev(net);
|
|
|
|
|
out:
|
|
|
|
|
usb_put_dev(xdev);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
2005-09-01 00:52:45 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_probe);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
2005-09-01 00:52:45 +08:00
|
|
|
|
/* FIXME these suspend/resume methods assume non-CDC style
|
|
|
|
|
* devices, with only one interface.
|
|
|
|
|
*/
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
2005-09-01 00:52:45 +08:00
|
|
|
|
int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = usb_get_intfdata(intf);
|
|
|
|
|
|
2005-04-19 08:39:22 +08:00
|
|
|
|
/* accelerate emptying of the rx and queues, to avoid
|
|
|
|
|
* having everything error out.
|
|
|
|
|
*/
|
2005-04-17 06:20:36 +08:00
|
|
|
|
netif_device_detach (dev->net);
|
2005-04-19 08:39:22 +08:00
|
|
|
|
(void) unlink_urbs (dev, &dev->rxq);
|
|
|
|
|
(void) unlink_urbs (dev, &dev->txq);
|
|
|
|
|
intf->dev.power.power_state = PMSG_SUSPEND;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2005-09-01 00:52:45 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_suspend);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
2005-09-01 00:52:45 +08:00
|
|
|
|
int usbnet_resume (struct usb_interface *intf)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
struct usbnet *dev = usb_get_intfdata(intf);
|
|
|
|
|
|
2005-04-19 08:39:22 +08:00
|
|
|
|
intf->dev.power.power_state = PMSG_ON;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
netif_device_attach (dev->net);
|
2005-04-19 08:39:22 +08:00
|
|
|
|
tasklet_schedule (&dev->bh);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2005-09-01 00:52:45 +08:00
|
|
|
|
EXPORT_SYMBOL_GPL(usbnet_resume);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_HARDWARE
|
|
|
|
|
#error You need to configure some hardware for this driver
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* chip vendor names won't normally be on the cables, and
|
|
|
|
|
* may not be on the device.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static const struct usb_device_id products [] = {
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_USB_PL2301
|
|
|
|
|
{
|
|
|
|
|
USB_DEVICE (0x067b, 0x0000), // PL-2301
|
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
|
|
|
|
}, {
|
|
|
|
|
USB_DEVICE (0x067b, 0x0001), // PL-2302
|
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{ }, // END
|
|
|
|
|
};
|
|
|
|
|
MODULE_DEVICE_TABLE (usb, products);
|
|
|
|
|
|
|
|
|
|
static struct usb_driver usbnet_driver = {
|
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
|
.name = driver_name,
|
|
|
|
|
.id_table = products,
|
|
|
|
|
.probe = usbnet_probe,
|
|
|
|
|
.disconnect = usbnet_disconnect,
|
|
|
|
|
.suspend = usbnet_suspend,
|
|
|
|
|
.resume = usbnet_resume,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
static int __init usbnet_init(void)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
|
|
|
|
// compiler should optimize these out
|
|
|
|
|
BUG_ON (sizeof (((struct sk_buff *)0)->cb)
|
|
|
|
|
< sizeof (struct skb_data));
|
|
|
|
|
|
|
|
|
|
random_ether_addr(node_id);
|
|
|
|
|
|
|
|
|
|
return usb_register(&usbnet_driver);
|
|
|
|
|
}
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
module_init(usbnet_init);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
static void __exit usbnet_exit(void)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
{
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
usb_deregister(&usbnet_driver);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
}
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
module_exit(usbnet_exit);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
[PATCH] USB: usbnet (1/9) clean up framing
This starts to prepare the core of "usbnet" to know less about various
framing protocols that map Ethernet packets onto USB, so "minidrivers"
can be modules that just plug into the core.
- Remove some framing-specific code that cluttered the core:
* net->hard_header_len records how much space to preallocate;
now drivers that add their own framing (Net1080, GeneLink,
Zaurus, and RNDIS) will have smoother TX paths. Even for
the drivers (Zaurus, Net1080) that need trailers.
* defines new dev->hard_mtu, using this "hardware" limit to
check changes to the link's settable "software" mtu.
* now net->hard_header_len and dev->hard_mtu are set up in the
driver bind() routines, if needed.
- Transaction ID is no longer specific to the Net1080 framing;
RNDIS needs one too.
- Creates a new "usbnet.h" header with declarations that are shared
between the core and what will be separate modules.
- Plus a couple other minor tweaks, like recognizing -ESHUTDOWN
means the keventd work should just shut itself down asap.
The core code is only about 1/3 of this large file. Splitting out the
minidrivers into separate modules (e.g. ones for ASIX adapters,
Zaurii and similar, CDC Ethernet, etc), in later patches, will
improve maintainability and shrink typical runtime footprints.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-09-01 00:52:31 +08:00
|
|
|
|
MODULE_AUTHOR("David Brownell");
|
|
|
|
|
MODULE_DESCRIPTION("USB Host-to-Host Link Drivers (numerous vendors)");
|
|
|
|
|
MODULE_LICENSE("GPL");
|