⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbnet.c

📁 S3C2440ARM9开发板的USB驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * USB Host-to-Host Links * Copyright (C) 2000-2002 by David Brownell <dbrownell@users.sourceforge.net> *//* * This is used for "USB networking", connecting USB hosts as peers. * * It can be used with USB "network cables", for IP-over-USB communications; * Ethernet speeds without the Ethernet.  USB devices (including some PDAs) * can support such links directly, replacing device-specific protocols * with Internet standard ones. * * The links can be bridged using the Ethernet bridging (net/bridge) * support as appropriate.  Devices currently supported include: * *	- AnchorChip 2720 *	- Belkin, eTEK (interops with Win32 drivers) *	- EPSON USB clients *	- GeneSys GL620USB-A *	- "Linux Devices" (like iPaq and similar SA-1100 based PDAs) *	- NetChip 1080 (interoperates with NetChip Win32 drivers) *	- Prolific PL-2301/2302 (replaces "plusb" driver) * * 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 LINUXDEV or EPSON device/client support. * *  * Status: * * - AN2720 ... not widely available, but reportedly works well * * - Belkin/eTEK ... no known issues * * - Both GeneSys and PL-230x use interrupt transfers for driver-to-driver *   handshaking; it'd be worth implementing those as "carrier detect". *   Prefer generic hooks, not minidriver-specific hacks. * * - Linux devices ... the www.handhelds.org SA-1100 support works nicely, *   but the Sharp Zaurus uses an incompatible protocol (extra checksums). *   No reason not to merge the Zaurus protocol here too (got patch? :) * * - For Netchip, should use keventd to poll via control requests to detect *   hardware level "carrier detect".  * * - PL-230x ... the initialization protocol doesn't seem to match chip data *   sheets, sometimes it's not needed and sometimes it hangs.  Prolific has *   not responded to repeated support/information requests. * * Interop with more Win32 drivers may be a good thing. * * Seems like reporting "peer connected" (carrier present) events may end * up going through the netlink event system, not hotplug ... that may be * awkward in terms of automatic configuration though. * * There are reports that bridging gives lower-than-usual throughput. * * Need smarter hotplug policy scripts ... ones that know how to arrange * bridging with "brctl", and can handle static and dynamic ("pump") setups. * Use those eventual "peer connected" events, and zeroconf. * * * 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) * *-------------------------------------------------------------------------*/#include <linux/config.h>#include <linux/module.h>#include <linux/kmod.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/random.h>#include <linux/ethtool.h>#include <linux/tqueue.h>#include <asm/uaccess.h>#include <asm/unaligned.h>// #define	DEBUG			// error path messages, extra info// #define	VERBOSE			// more; success messages// #define	REALLY_QUEUE#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)#   define DEBUG#endif#include <linux/usb.h>/* in 2.5 these standard usb ops take mem_flags */#define ALLOC_URB(n,flags)	usb_alloc_urb(n)#define SUBMIT_URB(u,flags)	usb_submit_urb(u)/* and these got renamed (may move to usb.h) */#define usb_get_dev		usb_inc_dev_use#define usb_put_dev		usb_dec_dev_use/* minidrivers _could_ be individually configured */#define	CONFIG_USB_AN2720#define	CONFIG_USB_BELKIN#define	CONFIG_USB_EPSON2888#define	CONFIG_USB_GENESYS#define	CONFIG_USB_LINUXDEV#define	CONFIG_USB_NET1080#define	CONFIG_USB_PL2301#define DRIVER_VERSION		"17-Jul-2002"/*-------------------------------------------------------------------------*//* * 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. */#ifdef REALLY_QUEUE#define	RX_QLEN		4#define	TX_QLEN		4#else#define	RX_QLEN		1#define	TX_QLEN		1#endif// packets are always ethernet inside// ... except they can be bigger (limit of 64K with NetChip framing)#define MIN_PACKET	sizeof(struct ethhdr)#define MAX_PACKET	32768// reawaken network queue this soon after stopping; else watchdog barks#define TX_TIMEOUT_JIFFIES	(5*HZ)// for vendor-specific control operations#define	CONTROL_TIMEOUT_MS	(500)			/* msec */#define CONTROL_TIMEOUT_JIFFIES ((CONTROL_TIMEOUT_MS * HZ)/1000)// between wakeups#define UNLINK_TIMEOUT_JIFFIES ((3  /*ms*/ * HZ)/1000)/*-------------------------------------------------------------------------*/// list of all devices we managestatic DECLARE_MUTEX (usbnet_mutex);static LIST_HEAD (usbnet_list);// randomly generated ethernet addressstatic u8	node_id [ETH_ALEN];// state we keep for each device we handlestruct usbnet {	// housekeeping	struct usb_device	*udev;	struct driver_info	*driver_info;	struct semaphore	mutex;	struct list_head	dev_list;	wait_queue_head_t	*wait;	// protocol/interface state	struct net_device	net;	struct net_device_stats	stats;	int			msg_level;#ifdef CONFIG_USB_NET1080	u16			packet_id;#endif	// various kinds of pending driver work	struct sk_buff_head	rxq;	struct sk_buff_head	txq;	struct sk_buff_head	done;	struct tasklet_struct	bh;	struct tq_struct	kevent;	unsigned long		flags;#		define EVENT_TX_HALT	0#		define EVENT_RX_HALT	1#		define EVENT_RX_MEMORY	2};// device-specific info used by the driverstruct driver_info {	char		*description;	int		flags;#define FLAG_FRAMING_NC	0x0001		/* guard against device dropouts */ #define FLAG_FRAMING_GL	0x0002		/* genelink batches packets */#define FLAG_NO_SETINT	0x0010		/* device can't set_interface() */	/* reset device ... can sleep */	int	(*reset)(struct usbnet *);	/* see if peer is connected ... can sleep */	int	(*check_connect)(struct usbnet *);	/* fixup rx packet (strip framing) */	int	(*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);	/* fixup tx packet (add framing) */	struct sk_buff	*(*tx_fixup)(struct usbnet *dev,				struct sk_buff *skb, int flags);	// FIXME -- also an interrupt mechanism	// useful for at least PL2301/2302 and GL620USB-A	/* framework currently "knows" bulk EPs talk packets */	int		in;		/* rx endpoint */	int		out;		/* tx endpoint */	int		epsize;};#define EP_SIZE(usbnet)	((usbnet)->driver_info->epsize)// we record the state for each of our queued skbsenum skb_state {	illegal = 0,	tx_start, tx_done,	rx_start, rx_done, rx_cleanup};struct skb_data {	// skb->cb is one of these	struct urb		*urb;	struct usbnet		*dev;	enum skb_state		state;	size_t			length;};static const char driver_name [] = "usbnet";/* use ethtool to change the level for any given device */static int msg_level = 1;MODULE_PARM (msg_level, "i");MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)");#define	mutex_lock(x)	down(x)#define	mutex_unlock(x)	up(x)#define	RUN_CONTEXT (in_irq () ? "in_irq" \			: (in_interrupt () ? "in_interrupt" : "can sleep"))/*-------------------------------------------------------------------------*/#ifdef DEBUG#define devdbg(usbnet, fmt, arg...) \	printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net.name, ## arg)#else#define devdbg(usbnet, fmt, arg...) do {} while(0)#endif#define devinfo(usbnet, fmt, arg...) \	do { if ((usbnet)->msg_level >= 1) \	printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net.name, ## arg); \	} while (0)#ifdef	CONFIG_USB_AN2720/*------------------------------------------------------------------------- * * AnchorChips 2720 driver ... http://www.cypress.com * * This doesn't seem to have a way to detect whether the peer is * connected, or need any reset handshaking.  It's got pretty big * internal buffers (handles most of a frame's worth of data). * Chip data sheets don't describe any vendor control messages. * *-------------------------------------------------------------------------*/static const struct driver_info	an2720_info = {	.description =	"AnchorChips/Cypress 2720",	// no reset available!	// no check_connect available!	.in = 2, .out = 2,		// direction distinguishes these	.epsize =64,};#endif	/* CONFIG_USB_AN2720 */#ifdef	CONFIG_USB_BELKIN/*------------------------------------------------------------------------- * * Belkin F5U104 ... two NetChip 2280 devices + Atmel microcontroller * * ... also two eTEK designs, including one sold as "Advance USBNET" * *-------------------------------------------------------------------------*/static const struct driver_info	belkin_info = {	.description =	"Belkin, eTEK, or compatible",	.in = 1, .out = 1,		// direction distinguishes these	.epsize =64,};#endif	/* CONFIG_USB_BELKIN */#ifdef	CONFIG_USB_EPSON2888/*------------------------------------------------------------------------- * * EPSON USB clients * * This is the same idea as "linuxdev" (below) except the firmware in the * device might not be Tux-powered.  Epson provides reference firmware that * implements this interface.  Product developers can reuse or modify that * code, such as by using their own product and vendor codes. * *-------------------------------------------------------------------------*/static const struct driver_info	epson2888_info = {	.description =	"Epson USB Device",	.in = 4, .out = 3,	.epsize = 64,};#endif	/* CONFIG_USB_EPSON2888 */#ifdef CONFIG_USB_GENESYS/*------------------------------------------------------------------------- * * GeneSys GL620USB-A (www.genesyslogic.com.tw) * * ... should partially interop with the Win32 driver for this hardware * The GeneSys docs imply there's some NDIS issue motivating this framing. * * Some info from GeneSys: *  - GL620USB-A is full duplex; GL620USB is only half duplex for bulk. *    (Some cables, like the BAFO-100c, use the half duplex version.) *  - For the full duplex model, the low bit of the version code says *    which side is which ("left/right"). *  - For the half duplex type, a control/interrupt handshake settles *    the transfer direction.  (That's disabled here, partially coded.) *    A control URB would block until other side writes an interrupt. * *-------------------------------------------------------------------------*/// control msg write command#define GENELINK_CONNECT_WRITE			0xF0// interrupt pipe index#define GENELINK_INTERRUPT_PIPE			0x03// interrupt read buffer size#define INTERRUPT_BUFSIZE			0x08// interrupt pipe interval value#define GENELINK_INTERRUPT_INTERVAL		0x10// max transmit packet number per transmit#define GL_MAX_TRANSMIT_PACKETS			32// max packet length#define GL_MAX_PACKET_LEN			1514// max receive buffer size #define GL_RCV_BUF_SIZE		\	(((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)struct gl_packet {	u32		packet_length;	char		packet_data [1];};struct gl_header {	u32			packet_count;	struct gl_packet	packets;};#ifdef	GENLINK_ACK// FIXME:  this code is incomplete, not debugged; it doesn't// handle interrupts correctly.  interrupts should be generic// code like all other device I/O, anyway.struct gl_priv { 	struct urb	*irq_urb;	char		irq_buf [INTERRUPT_BUFSIZE];};static inline int gl_control_write (struct usbnet *dev, u8 request, u16 value){	int retval;	retval = usb_control_msg (dev->udev,		      usb_sndctrlpipe (dev->udev, 0),		      request,		      USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,		      value, 		      0,			// index		      0,			// data buffer		      0,			// size		      CONTROL_TIMEOUT_JIFFIES);	return retval;}static void gl_interrupt_complete (struct urb *urb){	int status = urb->status;		if (status)		dbg ("gl_interrupt_complete fail - %X", status);	else		dbg ("gl_interrupt_complete success...");}static int gl_interrupt_read (struct usbnet *dev){	struct gl_priv	*priv = dev->priv_data;	int		retval;	// issue usb interrupt read	if (priv && priv->irq_urb) {		// submit urb		if ((retval = SUBMIT_URB (priv->irq_urb, GFP_KERNEL)) != 0)			dbg ("gl_interrupt_read: submit fail - %X...", retval);		else			dbg ("gl_interrupt_read: submit success...");	}	return 0;}// check whether another side is connectedstatic int genelink_check_connect (struct usbnet *dev){	int			retval;	dbg ("genelink_check_connect...");	// detect whether another side is connected	if ((retval = gl_control_write (dev, GENELINK_CONNECT_WRITE, 0)) != 0) {		dbg ("%s: genelink_check_connect write fail - %X",			dev->net.name, retval);		return retval;	}	// usb interrupt read to ack another side 	if ((retval = gl_interrupt_read (dev)) != 0) {		dbg ("%s: genelink_check_connect read fail - %X",			dev->net.name, retval);		return retval;	}	dbg ("%s: genelink_check_connect read success", dev->net.name);	return 0;}// allocate and initialize the private data for genelinkstatic int genelink_init (struct usbnet *dev){	struct gl_priv *priv;	// allocate the private data structure	if ((priv = kmalloc (sizeof *priv, GFP_KERNEL)) == 0) {		dbg ("%s: cannot allocate private data per device",			dev->net.name);		return -ENOMEM;	}	// allocate irq urb	if ((priv->irq_urb = ALLOC_URB (0, GFP_KERNEL)) == 0) {		dbg ("%s: cannot allocate private irq urb per device",			dev->net.name);		kfree (priv);		return -ENOMEM;	}	// fill irq urb	FILL_INT_URB (priv->irq_urb, dev->udev,		usb_rcvintpipe (dev->udev, GENELINK_INTERRUPT_PIPE),		priv->irq_buf, INTERRUPT_BUFSIZE,		gl_interrupt_complete, 0,		GENELINK_INTERRUPT_INTERVAL);	// set private data pointer	dev->priv_data = priv;	return 0;}// release the private datastatic int genelink_free (struct usbnet *dev){	struct gl_priv	*priv = dev->priv_data;	if (!priv) 		return 0;// FIXME:  can't cancel here; it's synchronous, and// should have happened earlier in any case (interrupt// handling needs to be generic)	// cancel irq urb first	usb_unlink_urb (priv->irq_urb);	// free irq urb	usb_free_urb (priv->irq_urb);	// free the private data structure	kfree (priv);	return 0;}#endifstatic int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb){	struct gl_header	*header;	struct gl_packet	*packet;	struct sk_buff		*gl_skb;	int			status;	u32			size;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -