Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/io/usb/eth
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
# ==================================================================== |
# |
# usbs_eth.cdl |
# |
# USB slave-side ethernet package. |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos 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 or (at your option) any later version. |
## |
## eCos 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 eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): bartv |
# Original data: bartv |
# Contributors: |
# Date: 2000-10-04 |
# |
#####DESCRIPTIONEND#### |
# ==================================================================== |
|
cdl_package CYGPKG_IO_USB_SLAVE_ETH { |
display "USB slave ethernet support" |
include_dir "cyg/io/usb" |
parent CYGPKG_IO_USB_SLAVE |
requires { CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS >= 1 } |
requires { CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS >= 1 } |
compile usbseth.c |
implements CYGINT_IO_USB_SLAVE_CLIENTS |
doc ref/io-usb-slave-eth.html |
|
description " |
The USB slave ethernet package supports the development |
of USB peripherals which provide an ethernet service to |
the host machine. Such a peripheral could be a simple |
USB-ethernet converter, or it could be rather more |
complicated internally." |
|
cdl_component CYGPKG_USBS_ETHDRV { |
display "Provide a driver for a TCP/IP stack." |
requires CYGPKG_IO_ETH_DRIVERS |
implements CYGHWR_NET_DRIVERS |
default_value CYGPKG_NET |
compile -library=libextras.a usbsethdrv.c |
|
description " |
The primary purpose of USB slave ethernet support is to provide |
an ethernet service to the USB host. This is very different |
from a conventional network driver which provides a service |
to a TCP/IP stack running inside the peripheral. If this |
component is enabled then the USB-ethernet code will implement |
an eCos network driver, thus supporting both a host-side TCP/IP |
stack and an eCos stack. This raises issues such as enabling |
the bridge code in the stack, and the package documentation |
should be consulted for further information." |
|
cdl_option CYGFUN_USBS_ETHDRV_STATISTICS { |
display "Maintain traffic statistics" |
flavor bool |
default_value CYGPKG_SNMPAGENT |
description " |
The USB network device driver can maintain some statistics |
about traffic, for example the number of incoming and |
outgoing packets. These statistics are intended mainly |
for SNMP agent software." |
} |
|
cdl_option CYGDAT_USBS_ETHDRV_NAME { |
display "Name to use for this network device" |
flavor data |
default_value { (1 == CYGHWR_NET_DRIVERS) ? "\"eth0\"" : "\"eth1\"" } |
description " |
The name of this network device for control purposes. |
" |
} |
|
cdl_option CYGPRI_USBS_ETHDRV_ETH0 { |
display "Enable/disable generic eth0 configury" |
flavor bool |
calculated { "\"eth0\"" == CYGDAT_USBS_ETHDRV_NAME } |
implements CYGHWR_NET_DRIVER_ETH0 |
requires !CYGHWR_NET_DRIVER_ETH0_BOOTP |
} |
|
cdl_option CYGPRI_USBS_ETHDRV_ETH1 { |
display "Enable/disable generic eth1 configury" |
flavor bool |
calculated { "\"eth1\"" == CYGDAT_USBS_ETHDRV_NAME } |
implements CYGHWR_NET_DRIVER_ETH1 |
requires !CYGHWR_NET_DRIVER_ETH1_BOOTP |
} |
} |
} |
#ifndef CYGONCE_USBS_ETH_H |
#define CYGONCE_USBS_ETH_H_ |
//========================================================================== |
// |
// include/usbs_eth.h |
// |
// Description of the USB slave-side ethernet support |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos 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 or (at your option) any later version. |
// |
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): bartv |
// Contributors: bartv |
// Date: 2000-10-04 |
// Purpose: |
// Description: USB slave-side ethernet support |
// |
// |
//####DESCRIPTIONEND#### |
//========================================================================== |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
// |
// The primary purpose of the USB slave-side ethernet code is to |
// provide an ethernet service for the host. Essentially this means |
// the following: |
// |
// 1) the host can transmit an ethernet frame to the USB peripheral. |
// This frame is received by the code in this package and then |
// passed up to higher-level code for processing. Typically the |
// frame will originate from a TCP/IP stack running inside the |
// host, and the higher-level code will forward the frame via a |
// real ethernet chip or some other ethernet-style device. |
// |
// 2) higher-level code will provide ethernet frames to be sent to |
// the host, usually to a TCP/IP stack running on the host. The |
// exact source of the ethernet frame is not known. |
// |
// 3) the host may initiate a number of control operations, for |
// example it may request the MAC address or it may want to |
// control the filtering mode (e.g. enable promiscuous mode). |
// |
// 4) there are USB control-related operations, for example actions |
// to be taken when the peripheral is disconnected from the |
// bus or when the host wants to disable the ethernet interface. |
// |
// It is possible to develop a USB ethernet peripheral that does not |
// involve a TCP/IP stack inside the peripheral, in fact that is the |
// most common implementation. Instead a typical peripheral would |
// involve a USB port, an ethernet port, and a cheap microcontroller |
// just powerful enough to forward packets between the two. The eCos |
// USB code can be used in this way, and the primary external |
// interface provides enough functionality for this to work. |
// |
// +---------------+ ethernet |
// +----+ | | | |
// | | USB | app | | |
// |host|---------| / \ |-----o |
// | | | / \ | | |
// +----+ | USB-eth eth | | |
// +---------------+ | |
// USB peripheral |
// |
// Note that the USB-ethernet code does not know anything about the |
// real ethernet device or what the application gets up to, it just |
// provides an interface to the app. The above represents just one |
// possible use for a USB-ethernet device. |
// |
// Also worth mentioning: when the host TCP/IP stack requests the MAC |
// address USB-eth would normally respond with the MAC address for the |
// real ethernet device. That way things like host-side DHCP should |
// just work. |
// |
// Alternatively for some applications it is desirable to run a TCP/IP |
// stack inside the peripheral as well as on the host. This makes |
// things a fair bit more complicated, something like this. |
// |
// +---------------+ |
// | app | |
// | | | ethernet |
// +----+ | | | | |
// | | USB | TCP/IP | | |
// |host|---------| / \ |-----o |
// | | | / \ | | |
// +----+ | USB-eth eth | | |
// +---------------+ | |
// USB peripheral |
// |
// |
// Usually this will involve enabling the bridge code in the TCP/IP |
// stack, or possibly performing some sort of bridging below the |
// TCP/IP stack. One way of getting things to work is to view the |
// USB connection as a small ethernet segment with just two |
// attached machines, the host and the peripheral. The two will |
// need separate MAC addresses, in addition to the MAC address |
// for the real ethernet device. This way the bridge code |
// sees things the way it expects. |
// |
// There will still be some subtle differences between a setup like |
// this and a conventional ethernet bridge, mainly because there |
// is a host-side TCP/IP stack which can perform control operations. |
// For example the host stack may request that USB-eth go into |
// promiscuous mode. A conventional ethernet bridge just deals |
// with ethernet segments and does not need to worry about |
// control requests coming in from one of the segments. |
// |
// It is not absolutely essential that there is another network. |
// However without another network this setup would look to the host |
// like an ethernet segment with just two machines attached to it, the |
// host itself and the USB peripheral, yet it still involves all the |
// complexities of ethernet such as broadcast masks and IP subnets. |
// Anything along these lines is likely to prove somewhat confusing, |
// and the USB peripheral should probably act like some other class |
// of USB device instead. |
// |
// One special setup has the host acting as a bridge to another |
// network, rather than the peripheral. This might make sense for |
// mobile peripherals such as PDA's, as a way of connecting the |
// peripheral to an existing LAN without needing a LAN adapter. |
// Enabling bridging in the host may be a complex operation, limiting |
// the applicability of such a setup. |
// |
// This package will only implement the eCos network driver interface |
// if explicitly enabled. The package-specific interface is always |
// provided, although trying to mix and match the two may lead to |
// terrible confusion: once the network driver is active nothing else |
// should use the lower-level USB ethernet code. However application |
// code is responsible for initializing the package, and specifically |
// for providing details of the USB endpoints that should be used. |
// |
// The package assumes that it needs to provide just one |
// instantiation. Conceivably there may be applications where it makes |
// sense for a USB peripheral to supply two separate ethernet devices |
// to the host, but that would be an unusual setup. Also a peripheral |
// might provide two or more USB slave ports to allow multiple hosts |
// to be connected, with a separate USB-ethernet instantiation for |
// each port, but again that would be an unusual setup. Applications |
// which do require more than one instantiation are responsible |
// for doing this inside the application code. |
|
// The public interface depends on configuration options. |
#include <pkgconf/io_usb_slave_eth.h> |
|
// Define the interface in terms of eCos data types. |
#include <cyg/infra/cyg_type.h> |
|
// The generic USB support |
#include <cyg/io/usb/usbs.h> |
|
// Network driver definition, to support cloning of usbs_eth_netdev0 |
#ifdef CYGPKG_USBS_ETHDRV |
# include <cyg/io/eth/netdev.h> |
#endif |
|
// Cache details, to allow alignment to cache line boundaries etc. |
#include <cyg/hal/hal_cache.h> |
|
// ---------------------------------------------------------------------------- |
// Maximum transfer size. This is not specified by io/eth. It can be |
// determined from <netinet/if_ether.h> but the TCP/IP stack may not |
// be loaded so that header file cannot be used. |
// |
// Some (most?) USB implementations have implementation problems. For |
// example the SA11x0 family cannot support transfers that are exact |
// multiples of the 64-byte USB bulk packet size, instead it is |
// necessary to add explicit size information. This can be encoded |
// conveniently at the start of the buffer. |
// |
// So the actual MTU consists of: |
// 1) a 1500 byte payload |
// 2) the usual ethernet header with a six-byte source MAC |
// address, a six-byte destination MAC address, and a |
// two-byte protocol or length field, for a total header |
// size of 14 bytes. |
// 3) an extra two bytes of size info. |
// |
// For a total of 1516 bytes. |
#define CYGNUM_USBS_ETH_MAX_FRAME_SIZE 1514 |
#define CYGNUM_USBS_ETH_MAXTU (CYGNUM_USBS_ETH_MAX_FRAME_SIZE + 2) |
|
// Although the minimum ethernet frame size is 60 bytes, this includes |
// padding which is not needed when transferring over USB. Hence the |
// actual minimum is just the 14 byte ethernet header plus two bytes |
// for the length. |
#define CYGNUM_USBS_ETH_MIN_FRAME_SIZE 14 |
#define CYGNUM_USBS_ETH_MINTU (CYGNUM_USBS_ETH_MIN_FRAME_SIZE + 2) |
|
// Typical USB devices involve DMA operations and hence confusion |
// between cached and uncached memory. To make life easier for |
// the underlying USB device drivers, this package ensures that |
// receive operations always involve buffers that are aligned to |
// a cache-line boundary and that are a multiple of the cacheline |
// size. |
#ifndef HAL_DCACHE_LINE_SIZE |
# define CYGNUM_USBS_ETH_RXBUFSIZE CYGNUM_USBS_ETH_MAXTU |
# define CYGNUM_USBS_ETH_RXSIZE CYGNUM_USBS_ETH_MAXTU |
#else |
# define CYGNUM_USBS_ETH_RXBUFSIZE ((CYGNUM_USBS_ETH_MAXTU + HAL_DCACHE_LINE_SIZE + HAL_DCACHE_LINE_SIZE - 1) \ |
& ~(HAL_DCACHE_LINE_SIZE - 1)) |
# define CYGNUM_USBS_ETH_RXSIZE ((CYGNUM_USBS_ETH_MAXTU + HAL_DCACHE_LINE_SIZE - 1) & ~(HAL_DCACHE_LINE_SIZE - 1)) |
#endif |
|
// ---------------------------------------------------------------------------- |
// This data structure serves two purposes. First, it keeps track of |
// the information needed by the low-level USB ethernet code, for |
// example which endpoints should be used for incoming and outgoing |
// packets. Second, if the support for the TCP/IP stack is enabled |
// then there are additional fields to support that (e.g. for keeping |
// track of statistics). |
// |
// Arguably the two uses should be separated into distinct data |
// structures. That would make it possible to instantiate multiple |
// low-level USB-ethernet devices but only have a network driver for |
// one of them. Achieving that flexibility would require some extra |
// indirection, affecting performance and code-size, and it is not |
// clear that that flexibility would ever prove useful. For now having |
// a single data structure seems more appropriate. |
|
typedef struct usbs_eth { |
|
// What endpoints should be used for communication? |
usbs_control_endpoint* control_endpoint; |
usbs_rx_endpoint* rx_endpoint; |
usbs_tx_endpoint* tx_endpoint; |
|
// Is the host ready to receive packets? This state is determined |
// largely by control packets sent from the host. It can change at |
// DSR level. |
volatile cyg_bool host_up; |
|
// Has the host-side set promiscuous mode? This is relevant to the |
// network driver which may need to do filtering based on the MAC |
// address and host-side promiscuity. |
volatile cyg_bool host_promiscuous; |
|
// The host MAC address. This is the address supplied to the |
// host's TCP/IP stack and filled in by the init function. There |
// is no real hardware to extract the address from. |
unsigned char host_MAC[6]; |
|
// Needed for callback operations. |
void (*tx_callback_fn)(struct usbs_eth*, void*, int); |
void* tx_callback_arg; |
|
void (*rx_callback_fn)(struct usbs_eth*, void*, int); |
void* rx_callback_arg; |
|
// RX operations just block if the host is not connected, resuming |
// when a connection is established. This means saving the buffer |
// pointer so that when the host comes back up the rx operation |
// proper can start. This is not quite consistent because if the |
// connection breaks while an RX is in progress there will be a |
// callback with an error code whereas an RX on a broken |
// connection just blocks, but this does fit neatly into an |
// event-driven I/O model. |
unsigned char* rx_pending_buf; |
|
#ifdef CYGPKG_USBS_ETHDRV |
// Has the TCP/IP stack brought up this interface yet? |
cyg_bool ecos_up; |
|
// Is there an ongoing receive? Cancelling a receive operation |
// during a stop() may be difficult, and a stop() may be followed |
// immediately by a restart. |
cyg_bool rx_active; |
|
// The eCos-side MAC. If the host and the eCos stack are to |
// communicate then they must be able to address each other, i.e. |
// they need separate addresses. Again there is no real hardware |
// to extract the address from so it has to be supplied by higher |
// level code via e.g. an ioctl(). |
unsigned char ecos_MAC[6]; |
|
// SNMP statistics |
# ifdef CYGFUN_USBS_ETHDRV_STATISTICS |
unsigned int interrupts; |
unsigned int tx_count; |
unsigned int rx_count; |
unsigned int rx_short_frames; |
unsigned int rx_too_long_frames; |
# endif |
|
// The need for a receive buffer is unavoidable for now because |
// the network driver interface does not support pre-allocating an |
// mbuf and then passing it back to the stack later. Ideally the |
// rx operation would read a single USB packet, determine the |
// required mbuf size from the 2-byte header, copy the initial |
// data, and then read more USB packets. Alternatively, a |
// 1516 byte mbuf could be pre-allocated and then the whole |
// transfer could go there, potentially wasting some mbuf space. |
// None of this is possible at present. |
// |
// Also, typically there will be complications because of |
// dependencies on DMA, cached vs. uncached memory, etc. |
unsigned char rx_buffer[CYGNUM_USBS_ETH_RXBUFSIZE]; |
unsigned char* rx_bufptr; |
cyg_bool rx_buffer_full; |
|
// It should be possible to eliminate the tx buffer. The problem |
// is that the protocol requires 2 bytes to be prepended, and that |
// may not be possible with the buffer supplied by higher-level |
// code. Eliminating this buffer would either require USB |
// device drivers to implement gather functionality on transmits, |
// or it would impose a dependency on higher-level code. |
unsigned char tx_buffer[CYGNUM_USBS_ETH_MAXTU]; |
cyg_bool tx_buffer_full; |
cyg_bool tx_done; |
unsigned long tx_key; |
|
// Prevent recursion send()->tx_done()->can_send()/send() |
cyg_bool tx_in_send; |
#endif |
|
} usbs_eth; |
|
// The package automatically instantiates one USB ethernet device. |
extern usbs_eth usbs_eth0; |
|
// ---------------------------------------------------------------------------- |
// If the network driver option is enabled then the package also |
// provides a single cyg_netdevtab_entry. This is exported so that |
// application code can clone the entry. |
#ifdef CYGPKG_USBS_ETHDRV |
extern cyg_netdevtab_entry_t usbs_eth_netdev0; |
#endif |
|
// ---------------------------------------------------------------------------- |
// A C interface to the low-level USB code. |
|
// Initialize the USBS-eth support for a particular usbs_eth device. |
// This associates a usbs_eth structure with specific endpoints. |
extern void usbs_eth_init(usbs_eth*, usbs_control_endpoint*, usbs_rx_endpoint*, usbs_tx_endpoint*, unsigned char*); |
|
// Start an asynchronous transmit of a single buffer of up to |
// CYGNUM_USBS_ETH_MAXTU bytes. This buffer should contain a 2-byte |
// size field, a 14-byte ethernet header, and upto 1500 bytes of |
// payload. When the transmit has completed the callback function (if |
// any) will be invoked with the specified pointer. NOTE: figure out |
// what to do about error reporting |
extern void usbs_eth_start_tx(usbs_eth*, unsigned char*, void (*)(usbs_eth*, void*, int), void*); |
|
// Start an asynchronous receive of an ethernet packet. The supplied |
// buffer should be at least CYGNUM_USBS_ETH_MAXTU bytes. When a |
// complete ethernet frame has been received or when some sort of |
// error occurs the callback function will be invoked. The third |
// argument |
extern void usbs_eth_start_rx(usbs_eth*, unsigned char*, void (*)(usbs_eth*, void*, int), void*); |
|
// The handler for application class control messages. The init call |
// will install this in the control endpoint by default. However the |
// handler is fairly dumb: it assumes that all application control |
// messages are for the ethernet interface and does not bother to |
// check the control message's destination. This is fine for simple |
// USB ethernet devices, but for any kind of multi-function peripheral |
// higher-level code will have to perform multiplexing and invoke this |
// handler only when appropriate. |
extern usbs_control_return usbs_eth_class_control_handler(usbs_control_endpoint*, void*); |
|
// Similarly a handler for state change messages. Installing this |
// means that the ethernet code will have sufficient knowledge about |
// the state of the USB connection for simple ethernet-only |
// peripherals, but not for anything more complicated. In the latter |
// case higher-level code will need to keep track of which |
// configuration, interfaces, etc. are currently active and explicitly |
// enable or disable the ethernet device using the functions below. |
extern void usbs_eth_state_change_handler(usbs_control_endpoint*, void*, usbs_state_change, int); |
extern void usbs_eth_disable(usbs_eth*); |
extern void usbs_eth_enable(usbs_eth*); |
|
#ifdef __cplusplus |
} // extern "C" |
#endif |
|
#endif // CYGONCE_USBS_ETH_H_ |
<!-- Copyright (C) 2001 Red Hat, Inc. --> |
<!-- This material may be distributed only subject to the terms --> |
<!-- and conditions set forth in the Open Publication License, v1.0 --> |
<!-- or later (the latest version is presently available at --> |
<!-- http://www.opencontent.org/openpub/). --> |
<!-- Distribution of substantively modified versions of this --> |
<!-- document is prohibited without the explicit permission of the --> |
<!-- copyright holder. --> |
<!-- Distribution of the work or derivative of the work in any --> |
<!-- standard (paper) book form is prohibited unless prior --> |
<!-- permission is obtained from the copyright holder. --> |
<HTML |
><HEAD |
><TITLE |
>Communication Protocol</TITLE |
><META |
NAME="GENERATOR" |
CONTENT="Modular DocBook HTML Stylesheet Version 1.64 |
"><LINK |
REL="HOME" |
TITLE="eCos Support for Developing USB-ethernet Peripherals" |
HREF="io-usb-slave-eth.html"><LINK |
REL="PREVIOUS" |
TITLE="Example Host-side Device Driver" |
HREF="usbseth-host.html"></HEAD |
><BODY |
CLASS="REFENTRY" |
BGCOLOR="#FFFFFF" |
TEXT="#000000" |
LINK="#0000FF" |
VLINK="#840084" |
ALINK="#0000FF" |
><DIV |
CLASS="NAVHEADER" |
><TABLE |
WIDTH="100%" |
BORDER="0" |
CELLPADDING="0" |
CELLSPACING="0" |
><TR |
><TH |
COLSPAN="3" |
ALIGN="center" |
>eCos Support for Developing USB-ethernet Peripherals</TH |
></TR |
><TR |
><TD |
WIDTH="10%" |
ALIGN="left" |
VALIGN="bottom" |
><A |
HREF="usbseth-host.html" |
>Prev</A |
></TD |
><TD |
WIDTH="80%" |
ALIGN="center" |
VALIGN="bottom" |
></TD |
><TD |
WIDTH="10%" |
ALIGN="right" |
VALIGN="bottom" |
> </TD |
></TR |
></TABLE |
><HR |
ALIGN="LEFT" |
WIDTH="100%"></DIV |
><H1 |
><A |
NAME="USBSETH-PROTOCOL" |
>Communication Protocol</A |
></H1 |
><DIV |
CLASS="REFNAMEDIV" |
><A |
NAME="AEN281" |
></A |
><H2 |
>Name</H2 |
>Communication Protocol -- Protocol used between the host-side device driver and the eCos |
USB-ethernet package </DIV |
><DIV |
CLASS="REFSECT1" |
><A |
NAME="AEN284" |
></A |
><H2 |
>Description</H2 |
><P |
>There is a USB standard for the protocol to be used between the host |
and a class of communication devices, including ethernet. However, the |
eCos USB-ethernet package does not implement this protocol: the target |
hardware for which the package was first developed had certain |
limitations, and could not implement the standard. Instead, the package |
implements a simple new protocol.</P |
><P |
>A USB-ethernet peripheral involves bulk transfers on two endpoints: |
one endpoint will be used for packets from host to peripheral and the |
other will be used for the opposite direction. Transfers in both |
directions are variable length, with a lower limit of 16 bytes and an |
upper limit of 1516 bytes. The first two bytes of each transfer |
constitute a header specific to USB-ethernet. The next 14 bytes form |
the normal header for an ethernet frame: destination MAC address, |
source MAC address, and a protocol field. The remaining data, up to |
1500 bytes, are the payload. The first two bytes give the size of the |
ethernet frame, least significant byte first, with a value between 14 |
and 1514.</P |
><P |
>For example an ARP request from host to peripheral involves an |
ethernet frame of 42 bytes (0x002A), with the usual 14-byte header and |
a 28-byte payload. The destination is the broadcast address |
0xFFFFFFFFFFFF. The source depends on the MAC address specified for |
the host in the call to <A |
HREF="usbseth-init.html" |
><TT |
CLASS="FUNCTION" |
>usbs_eth_init</TT |
></A |
>, e.g. |
0x405D90A9BC02. The remaining data is as specified by the appropriate |
<A |
HREF="http://www.ietf.org" |
TARGET="_top" |
>IETF RFC's</A |
>. The actual bulk |
USB transfer involves the following sequence of 44 bytes:</P |
><TABLE |
BORDER="0" |
BGCOLOR="#E0E0E0" |
WIDTH="100%" |
><TR |
><TD |
><PRE |
CLASS="SCREEN" |
>2a 00 ff ff ff ff ff ff 40 5d 90 a9 bc 02 08 06 |
00 01 08 00 06 04 00 01 40 5d 90 a9 bc 02 0a 00 |
00 01 00 00 00 00 00 00 0a 00 00 02</PRE |
></TD |
></TR |
></TABLE |
><P |
>In addition there are two control messages. These will be sent by the |
host to endpoint 0, the control endpoint, and by default they will |
be handled by <A |
HREF="usbseth-control.html" |
><TT |
CLASS="FUNCTION" |
>usbs_eth_class_control_handler</TT |
></A |
>. If class-specific |
control messages are intercepted by other code then it is the |
responsibility of that code to invoke the USB-ethernet handler when |
appropriate.</P |
><P |
>The first control message can be used by the host to obtain a MAC |
address:</P |
><TABLE |
BORDER="0" |
BGCOLOR="#E0E0E0" |
WIDTH="100%" |
><TR |
><TD |
><PRE |
CLASS="PROGRAMLISTING" |
>#define ECOS_USBETH_CONTROL_GET_MAC_ADDRESS 0x01</PRE |
></TD |
></TR |
></TABLE |
><P |
>The control message's type field should specify IN as the direction. |
The request field should be <TT |
CLASS="LITERAL" |
>0x01</TT |
>. The length fields |
should specify a size of 6 bytes. The remaining fields of the control |
message will be ignored by the USB-ethernet package. The response |
consists of the 6-byte MAC address supplied by the initialization call |
<A |
HREF="usbseth-init.html" |
><TT |
CLASS="FUNCTION" |
>usbs_eth_init</TT |
></A |
>.</P |
><P |
>The second control message can be used by the host to enable or |
disable promiscuous mode.</P |
><TABLE |
BORDER="0" |
BGCOLOR="#E0E0E0" |
WIDTH="100%" |
><TR |
><TD |
><PRE |
CLASS="PROGRAMLISTING" |
>#define ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE 0x02</PRE |
></TD |
></TR |
></TABLE |
><P |
>This control message involves no further data so the length field |
should be set to 0. The value field should be non-zero to enable |
promiscuous mode, zero to disable it. The request field should be |
<TT |
CLASS="LITERAL" |
>0x02</TT |
>. The remaining fields in the control message |
will be ignored. It is the responsibility of the host-side device |
driver to keep track of whether or not promiscuous mode is currently |
enabled. It will be disabled when the peripheral changes to |
Configured state, typically at the point where the host-side device |
driver has been activated.</P |
></DIV |
><DIV |
CLASS="NAVFOOTER" |
><HR |
ALIGN="LEFT" |
WIDTH="100%"><TABLE |
WIDTH="100%" |
BORDER="0" |
CELLPADDING="0" |
CELLSPACING="0" |
><TR |
><TD |
WIDTH="33%" |
ALIGN="left" |
VALIGN="top" |
><A |
HREF="usbseth-host.html" |
>Prev</A |
></TD |
><TD |
WIDTH="34%" |
ALIGN="center" |
VALIGN="top" |
><A |
HREF="io-usb-slave-eth.html" |
>Home</A |
></TD |
><TD |
WIDTH="33%" |
ALIGN="right" |
VALIGN="top" |
> </TD |
></TR |
><TR |
><TD |
WIDTH="33%" |
ALIGN="left" |
VALIGN="top" |
>Example Host-side Device Driver</TD |
><TD |
WIDTH="34%" |
ALIGN="center" |
VALIGN="top" |
> </TD |
><TD |
WIDTH="33%" |
ALIGN="right" |
VALIGN="top" |
> </TD |
></TR |
></TABLE |
></DIV |
></BODY |
></HTML |
> |
<!-- Copyright (C) 2001 Red Hat, Inc. --> |
<!-- This material may be distributed only subject to the terms --> |
<!-- and conditions set forth in the Open Publication License, v1.0 --> |
<!-- or later (the latest version is presently available at --> |
<!-- http://www.opencontent.org/openpub/). --> |
<!-- Distribution of substantively modified versions of this --> |
<!-- document is prohibited without the explicit permission of the --> |
<!-- copyright holder. --> |
<!-- Distribution of the work or derivative of the work in any --> |
<!-- standard (paper) book form is prohibited unless prior --> |
<!-- permission is obtained from the copyright holder. --> |
<HTML |
><HEAD |
><TITLE |
>Initializing the USB-ethernet Package</TITLE |
><META |
NAME="GENERATOR" |
CONTENT="Modular DocBook HTML Stylesheet Version 1.64 |
"><LINK |
REL="HOME" |
TITLE="eCos Support for Developing USB-ethernet Peripherals" |
HREF="io-usb-slave-eth.html"><LINK |
REL="PREVIOUS" |
TITLE="Introduction" |
HREF="usbseth-intro.html"><LINK |
REL="NEXT" |
TITLE="USB-ethernet Data Transfers" |
HREF="usbseth-data.html"></HEAD |
><BODY |
CLASS="REFENTRY" |
BGCOLOR="#FFFFFF" |
TEXT="#000000" |
LINK="#0000FF" |
VLINK="#840084" |
ALINK="#0000FF" |
><DIV |
CLASS="NAVHEADER" |
><TABLE |
WIDTH="100%" |
BORDER="0" |
CELLPADDING="0" |
CELLSPACING="0" |
><TR |
><TH |
COLSPAN="3" |
ALIGN="center" |
>eCos Support for Developing USB-ethernet Peripherals</TH |
></TR |
><TR |
><TD |
WIDTH="10%" |
ALIGN="left" |
VALIGN="bottom" |
><A |
HREF="usbseth-intro.html" |
>Prev</A |
></TD |
><TD |
WIDTH="80%" |
ALIGN="center" |
VALIGN="bottom" |
></TD |
><TD |
WIDTH="10%" |
ALIGN="right" |
VALIGN="bottom" |
><A |
HREF="usbseth-data.html" |
>Next</A |
></TD |
></TR |
></TABLE |
><HR |
ALIGN="LEFT" |
WIDTH="100%"></DIV |
><H1 |
><A |
NAME="USBSETH-INIT" |
>Initializing the USB-ethernet Package</A |
></H1 |
><DIV |
CLASS="REFNAMEDIV" |
><A |
NAME="AEN47" |
></A |
><H2 |
>Name</H2 |
><TT |
CLASS="FUNCTION" |
>usbs_eth_init</TT |
> -- Initializing the USB-ethernet Package</DIV |
><DIV |
CLASS="REFSYNOPSISDIV" |
><A |
NAME="AEN51" |
></A |
><H2 |
>Synopsis</H2 |
><DIV |
CLASS="FUNCSYNOPSIS" |
><A |
NAME="AEN52" |
></A |
><P |
></P |
><TABLE |
BORDER="0" |
BGCOLOR="#E0E0E0" |
WIDTH="100%" |
><TR |
><TD |
><PRE |
CLASS="FUNCSYNOPSISINFO" |
>#include <cyg/io/usb/usbs_eth.h></PRE |
></TD |
></TR |
></TABLE |
><P |
><CODE |
><CODE |
CLASS="FUNCDEF" |
>void usbs_eth_init</CODE |
>(usbs_eth* usbeth, usbs_control_endpoint* ep0, usbs_rx_endpoint* ep1, usbs_tx_endpoint* ep2, unsigned char* mac_address);</CODE |
></P |
><P |
></P |
></DIV |
></DIV |
><DIV |
CLASS="REFSECT1" |
><A |
NAME="AEN67" |
></A |
><H2 |
>Description</H2 |
><P |
>The USB-ethernet package is not tied to any specific hardware. It |
requires certain functionality: there must be USB-slave hardware |
supported by a device driver; there must also be two endpoints for |
bulk transfers between host and peripheral, one for each direction; |
there must also be a control endpoint, although of course that is |
implicit with any USB hardware.</P |
><P |
>However, USB-slave hardware may well provide more endpoints than the |
minimum required for ethernet support. Some of those endpoints might |
be used by other packages, while other endpoints might be used |
directly by the application, or might not be needed for the peripheral |
being built. There is also the possibility of a USB peripheral that |
supports multiple configurations, with the ethernet support active in |
only some of those configurations. The USB-ethernet package has no |
knowledge about any of this, so it relies on higher-level code to tell |
it which endpoints should be used and other information. This is the |
purpose of the <TT |
CLASS="FUNCTION" |
>usbs_eth_init</TT |
> function.</P |
><P |
>The first argument identifies the specific |
<SPAN |
CLASS="STRUCTNAME" |
>usbs_eth</SPAN |
> data structure that is affected. It |
is expected that the vast majority of affected applications will only |
provide a single USB-ethernet device to a single host, and the package |
automatically provides a suitable data structure |
<TT |
CLASS="LITERAL" |
>usbs_eth0</TT |
> to support this. If multiple |
<SPAN |
CLASS="STRUCTNAME" |
>usbs_eth</SPAN |
> structures are needed for some |
reason then these need to be instantiated by other code, and each one |
needs to be initialised by a call to |
<TT |
CLASS="FUNCTION" |
>usbs_eth_init()</TT |
>. </P |
><P |
>The next three arguments identify the endpoints that should be used |
for USB communications: a control endpoint, a receive endpoint for |
ethernet packets coming from the host to the peripheral, and a |
transmit endpoint for ethernet packets going in the other direction. |
Obviously all three endpoints should be provided by the same USB |
hardware. The USB-ethernet package assumes that it has sole access to |
the receive and transmit endpoints, subject to the use of |
<TT |
CLASS="FUNCTION" |
>usbs_eth_disable</TT |
> and |
<TT |
CLASS="FUNCTION" |
>usbs_eth_enable</TT |
> control functions. The package |
also assumes that no other code is interested in USB state changes or |
class control messages: it installs handlers |
<A |
HREF="usbseth-control.html" |
><TT |
CLASS="FUNCTION" |
>usbs_eth_state_change_handler</TT |
></A |
> |
and |
<A |
HREF="usbseth-control.html" |
><TT |
CLASS="FUNCTION" |
>usbs_eth_class_control_handler</TT |
></A |
> |
in the control endpoint. If any other code does need to handle USB |
state changes or class control messages then replacement handlers |
should be installed after the call to |
<TT |
CLASS="FUNCTION" |
>usbs_eth_init</TT |
>, and those replacements should |
invoke the USB-ethernet ones when appropriate.</P |
><P |
>The final argument to <TT |
CLASS="FUNCTION" |
>usbs_eth_init</TT |
> specifies |
the MAC address (or Ethernet Station Address) that should be provided |
to the host-side device driver. Since the USB-ethernet package does not |
interact directly with a real ethernet device it cannot obtain the MAC |
address from any hardware. Instead, it must be supplied by higher-level |
code. The details depend on the <A |
HREF="usbseth-intro.html#AEN22" |
>scenario</A |
> in which the |
USB-ethernet package is being used.</P |
><P |
>The call to <TT |
CLASS="FUNCTION" |
>usbs_eth_init</TT |
> should normally happen |
after the enumeration data has been provided but before the underlying |
USB device driver has been started. If the USB device were to be |
started first then a connection between host and peripheral could be |
established immediately, and the host-side device driver would attempt |
to contact the USB-ethernet package for information such as the MAC |
address. </P |
><TABLE |
BORDER="0" |
BGCOLOR="#E0E0E0" |
WIDTH="100%" |
><TR |
><TD |
><PRE |
CLASS="PROGRAMLISTING" |
>int |
main(int argc, char** argv) |
{ |
unsigned char host_MAC[6] = { 0x40, 0x5d, 0x90, 0xa9, 0xbc, 0x02 }; |
|
usbs_sa11x0_ep0.enumeration_data = &usb_enum_data; |
… |
usbs_eth_init(&usbs_eth0, &usbs_sa11x0_ep0, &usbs_sa11x0_ep1, &usbs_sa11x0_ep2, host_MAC); |
… |
usbs_start(&usbs_sa11x0_ep0); |
… |
}</PRE |
></TD |
></TR |
></TABLE |
></DIV |
><DIV |
CLASS="NAVFOOTER" |
><HR |
ALIGN="LEFT" |
WIDTH="100%"><TABLE |
WIDTH="100%" |
BORDER="0" |
CELLPADDING="0" |
CELLSPACING="0" |
><TR |
><TD |
WIDTH="33%" |
ALIGN="left" |
VALIGN="top" |
><A |
HREF="usbseth-intro.html" |
>Prev</A |
></TD |
><TD |
WIDTH="34%" |
ALIGN="center" |
VALIGN="top" |
><A |
HREF="io-usb-slave-eth.html" |
>Home</A |
></TD |
><TD |
WIDTH="33%" |
ALIGN="right" |
VALIGN="top" |
><A |
HREF="usbseth-data.html" |
>Next</A |
></TD |
></TR |
><TR |
><TD |
WIDTH="33%" |
ALIGN="left" |
VALIGN="top" |
>Introduction</TD |
><TD |
WIDTH="34%" |
ALIGN="center" |
VALIGN="top" |
> </TD |
><TD |
WIDTH="33%" |
ALIGN="right" |
VALIGN="top" |
>USB-ethernet Data Transfers</TD |
></TR |
></TABLE |
></DIV |
></BODY |
></HTML |
> |
Network Device for the eCos TCP/IP Stack
Description
If the USB peripheral involves running the eCos TCP/IP stack and that +stack needs to use USB-ethernet as a transport layer (or as one of the +transports), then the USB-ethernet package can provide a suitable +network device driver. It is still necessary for higher-level code to +perform appropriate initialization by calling usbs_eth_init, but +after that it will be the TCP/IP stack rather than application code +that transmits or receives ethernet frames.
Not all peripherals involving the USB-ethernet package will require a +TCP/IP stack. Hence the provision of the network device is controlled +by a configuration option CYGPKG_USBS_ETHDRV. By +default this will be enabled if the TCP/IP package +CYGPKG_NET is loaded, and disabled otherwise.
There are a number of other configuration options related to the +network device. CYGFUN_USBS_ETHDRV_STATISTICS +determines whether or not the package will maintain statistics, mainly +intended for SNMP: by default this will be enabled if the SNMP support +package CYGPKG_SNMPAGENT is loaded, and disabled +otherwise. The name of the ethernet device is controlled by +CYGDATA_USBS_ETHDRV_NAME, and has a default value +of either eth0 or eth1 +depending on whether or not there is another network device driver +present in the configuration.
Usually eCos network device drivers default to using DHCP for +obtaining necessary information such as IP addresses. This is not +appropriate for USB-ethernet devices. On the host-side the +USB-ethernet network device will not exist until the USB peripheral +has been plugged in and communication has been established. Therefore +any DHCP daemon on the host would not be listening on that network +device at the point that eCos requests its IP and other information. A +related issue is that the use of DHCP would imply the presence of a +DHCP daemon on every affected host machine, as opposed to a single +daemon (plus backups) for the network as a whole. For these reasons +the USB-ethernet package precludes the use of DHCP as a way of setting +the IP address, instead requiring alternatives such as manual +configuration.
I. eCos Support for Developing USB-ethernet Peripherals
- Table of Contents
- Introduction — eCos support for developing USB ethernet peripherals
- Initializing the USB-ethernet Package — Initializing the USB-ethernet Package
- USB-ethernet Data Transfers — Exchanging ethernet packets with the USB host
- USB-ethernet State Handling — Maintaining the USB-ethernet connection with the host
- Network Device for the eCos TCP/IP Stack — USB-ethernet support for the eCos TCP/IP Stack
- Example Host-side Device Driver — Provide host-side support for the eCos USB-ethernet package
- Communication Protocol — Protocol used between the host-side device driver and the eCos +USB-ethernet package
Next | ||
Introduction |
USB-ethernet Data Transfers
Description
The USB-ethernet package provides two main modes of operation. In the +first mode it provides a network device +driver for use by a TCP/IP stack running inside the USB +peripheral. All incoming ethernet packages should be passed up the +TCP/IP stack, and only the stack will generate outgoing packets. Apart +from initialization and possibly +certain control operations, +higher-level code will not interact with the USB-ethernet package +directly.
In the second mode there is no TCP/IP stack running inside the USB +peripheral. For example, a simple USB-ethernet converter has an +ethernet chip and a USB port: ethernet packets received by the +ethernet chip need to be forwarded to the USB host, and ethernet +packets sent by the USB host need to be sent out of the ethernet chip. +usbs_eth_start_rx and +usbs_eth_start_tx allow for this lower-level +access to the USB-ethernet package.
The two modes of operation are mutually exclusive. If the network +device driver mode is enabled then application code should communicate +at the TCP/IP level, and not by using the lower-level functions. +Instead, it is the network device driver that will make use of these +functions, and it assumes that it has exclusive access. The package +does not perform any locking.
The transmit and receive functions work in much the same way. The +first argument identifies the usbs_eth +structure that should be used. For the majority of applications this +will be usbs_eth0. The second argument specifies +the location of the ethernet packet; outgoing for +usbs_eth_start_tx and incoming for +usbs_eth_start_rx. This buffer should correspond +to the protocol:
Outgoing packets can consist of up to 1516 bytes, consisting of a +two-byte header specific to USB-ethernet followed by a standard +ethernet frame (a header with 6-byte destination address, 6-byte +source address and a further two bytes, followed by a payload of +up to 1500 bytes). The two-byte USB-ethernet header consists simply of +the size of the ethernet frame, i.e. the size of the rest of the +packet not including the USB-ethernet header, with the least +significant byte first.
For incoming packets the supplied buffer should usually be at least +1516 bytes. There may be special circumstances in which a smaller +buffer might be safe; for example, if the host-side device driver is +modified to support only smaller packets. Once the packet has been +received the buffer will contain a two-byte header specific to +USB-ethernet, followed by a normal ethernet frame. The header +gives the size of the ethernet frame, excluding the header, with the +least significant byte first.
Both usbs_eth_start_tx and +usbs_eth_start_rx are asynchronous: the transfer +is started and, some time later, a completion function will be invoked. +The third and fourth arguments to both +usbs_eth_start_tx and +usbs_eth_start_rx supply the completion function +and an argument to that function respectively. The completion function +will be invoked with three arguments: a pointer to the +usbs_eth data structure, usually +usbs_eth0; the supplied completion data ; and a +return code field. A negative value indicates that an error occurred, +for example -EPIPE if the connection between USB +host and peripheral has been broken, or -EAGAIN if +an endpoint has been halted. A positive value indicates the total size +of the transfer, which should correspond to the size in the +USB-ethernet header plus an additional two bytes for the header +itself.
If the data transfer is succesful then the completion function will +typically be invoked in DSR context rather than in thread context, +although this depends on the implementation of the underlying USB +device driver. Therefore the completion function is restricted in what +it can do; in particular, it must not make any calls that will or may +block such as locking a mutex or allocating memory. The kernel +documentation should be consulted for more details of DSR's and +interrupt handling generally. Note that if the transfer finishes +quickly then the completion function may be invoked before +usbs_eth_start_rx or +usbs_eth_start_tx returns. This is especially +likely to happen if the current thread is descheduled after starting +the data transfer but before returning from these functions.
For transmit operations, it is possible for +usbs_eth_start_tx to invoke the completion +function immediately. If there is no current connection between host +and target then the transmit will fail immediately with +-EPIPE. In addition the USB-ethernet package will +check the destination MAC address and make sure that the ethernet +frame really is intended for the host: either it must be for the +address specified in the initialization call usbs_eth_init, or +it must be a broadcast packet, or the host must have enabled +promiscuous mode.
Introduction
Introduction
The eCos USB-ethernet package provides additional support for USB +peripherals that involve some sort of ethernet-style network. This can +be a traditional ethernet, or it can involve some other networking +technology that uses ethernet frames as a unit of transfer. It +provides functions to transfer ethernet frames over the USB bus, +handles certain control messages from the host, and optionally it can +provide a network device driver for use by the eCos TCP/IP stack. +The package comes with an example host-side device driver.
The USB-ethernet package is not tied to any specific hardware. It +requires the presence of USB hardware and a suitable device driver, +but not all USB peripherals involve ethernet communications. Hence the +configuration system cannot load the package automatically for +specific targets, in the way that a USB device driver or an ethernet +driver can be loaded automatically. Instead, the package has to be +added explicitly. When using the command line tools this will involve +an operation like the following:
$ ecosconfig add usbs_eth |
Typically, this will automatically cause the USB device driver to +become active. Loading the USB-ethernet package automatically provides +functionality for initialization, +data transfer, and the handling of +control messages and state +changes. If the current configuration includes the eCos TCP/IP stack +then the network device driver +support will be enabled as well by default, allowing the stack to +exchange ethernet frames over the USB bus.
There is a USB standard for a class of communication devices including +ethernet. The package does not implement this standard, due to +limitations in the hardware for which the package was first developed. +Instead, the package uses its own protocol between USB +host device driver and the +peripheral.
Usage Scenarios
The USB-ethernet package can be used several different scenarios. In +a simple scenario, the peripheral serves only to connect the USB host +to a suitable network:
After initialization, and once the USB connection between host and +peripheral has been established, higher-level code needs to detect +packets that are intended for the host, and to forward these. This can +be achieved by the low-level usbs_eth_start_tx +function. Similarly, higher-level code needs to detect packets coming +from the host, using usbs_eth_start_rx, and to +forward these using the real network. As far as the host is concerned +it is connected directly to the network. In this scenario there is no +confusion about addresses: there is a single MAC address for the +host/peripheral combination, corresponding to the connection to the +real network, and it is this address which should be supplied during +initialization.
In a more complicated scenario, there is a TCP/IP stack running inside +the peripheral.
This involves the USB-ethernet package providing a service both to the +host and to the eCos TCP/IP stack. It achieves the latter by acting as +an eCos network device. Typically, the TCP/IP stack will be configured +to act as a network bridge. The USB peripheral needs to examine the +packets arriving over the real network. Some of these packets will be +intended for the host, while others will be intended for the +peripheral itself. To distinguish between these two scenarios, two +distinct MAC addresses are needed: one for the host, and one for the +peripheral. Similarly, packets sent by the host may have to be +forwarded via the real network, or they may be intended for the TCP/IP +stack inside the peripheral. Packets generated inside the peripheral's +TCP/IP stack may need to be sent via the real network or over the USB +bus. The network bridge software will have to take care of all these +possibilities. Unusually for a network bridge, one of the network +segments being bridged will only ever have one machine attached.
There are other possible usage scenarios. For example, the peripheral +might not be attached to a real network at all. Instead it could be +the USB host that acts as a network bridge, allowing a TCP/IP stack +inside the peripheral to communicate with the outside world. The +various details will depend on the exact type of peripheral being +developed.
Prev | Home | Next |
eCos Support for Developing USB-ethernet Peripherals | Initializing the USB-ethernet Package |
Example Host-side Device Driver
Description
The USB-ethernet package is supplied with a single host-side device +driver. This driver has been developed against the Linux kernel +2.2.16-22, as shipped with Red Hat 7. The driver is provided as is and +should not be considered production quality: for example it only +checks for a bogus vendor id 0x4242 rather than an +official vendor id supplied by the USB Implementers Forum. Also, if the +peripheral involves multiple configurations or multiple interfaces, it +will fail to detect this. However, the driver can be used for simple +testing and as the basis of a full device driver. Details of the +protocol used between host and peripheral can be found in the Communication Protocol section.
The host-side device driver can be found in the host subdirectory of the USB-ethernet +package, specifically the file ecos_usbeth.c, and +comes with a Makefile. Both files may need +to be modified for specific applications. For example, the vendor id +table ecos_usbeth_implementations may need to be +updated for the specific USB peripheral being built. The +Makefile assumes that the Linux kernel sources +reside in /usr/src/linux, and +that the kernel has already been configured and built. Assuming this +is the case, the device driver can be built simply by invoking +make with no additional arguments. This will result +in a dynamically loadable kernel module, +ecos_usbeth.o, in the current directory.
Note: As normal for Linux kernel builds, the generated files such as +ecos_usbeth.o live in the same directory as the +source tree. This is very different from eCos where the source tree +(or component repository) is kept separate from any builds. There may +be problems if the component repository is kept read-only or if it is +put under source code control. Any such problems can be avoided by +making a copy of the host +subdirectory and building that copy.
Loading the kernel module into the current system requires root +privileges. If the generic USB support is also a loadable module and +has not been loaded already, this must happen first:
# insmod usb-uhci +Using /lib/modules/2.2.16-22/usb/usb-uhci.o |
Depending on the host hardware, the uhci or +usb-ohci modules may be more appropriate. Loading +the generic USB module will typically result in a number of messages +to the logfile /var/log/messages, giving details +of the specific host-side hardware that has been detected plus any +hubs. The next step is to load the USB-ethernet module:
# insmod ecos_usbeth.o |
This should result in a number of additional diagnostics in the +logfile:
Apr 1 18:01:08 grumpy kernel: eCos USB-ethernet device driver +Apr 1 18:01:08 grumpy kernel: usb.c: registered new driver ecos_usbeth |
If a suitable USB peripheral is now connected the host will detect +this, assign an address in the local USB network, obtain enumeration +data, and find a suitable device driver. Assuming the peripheral and +device driver agree on the supported vendor ids, the +ecos_usbeth.o module will be selected and this +will be reported in the system log:
Apr 1 18:04:12 grumpy kernel: usb.c: USB new device connect, assigned device number 3 +Apr 1 18:04:12 grumpy kernel: eCos-based USB ethernet peripheral active at eth1 |
What can happen next depends very much on the software that is running +on top of the USB-ethernet package inside the peripheral. For example, +if there is a TCP/IP stack then it should be possible to bring up a +network connection between host and peripheral using +ifconfig.
USB-ethernet State Handling
Synopsis
#include <cyg/io/usb/usbs_eth.h> |
usbs_control_return usbs_eth_class_control_handler
(usbs_control_endpoint* ep0, void* callback_data);
void usbs_eth_state_change_handler
(usbs_control_endpoint* ep0, void* callback_data, usbs_state_change change, int old_state);
void usbs_eth_disable
(usbs_eth* usbseth>);
void usbs_eth_enable
(usbs_eth* usbseth>);
Description
When the USB-ethernet package is initialized by a call to usbs_eth_init it +installs usbs_eth_state_change_handler to handle +USB state changes. This allows the package to detect when the +connection between the host and the peripheral is established or +broken, resulting in internal calls to +usbs_eth_enable and +usbs_eth_disable respectively. This is +appropriate if no other code needs to access the USB device. However, +if there is other code, either other USB-related packages or the +application itself, that needs to perform I/O over the USB bus, then +typically the USB-ethernet package should not have exclusive access to +state change events. Instead, the assumption is that higher-level +code, typically provided by the application, will install an +alternative state change handler in the control endpoint data +structure after the call to usbs_eth_init. This +alternative handler will either chain into +usbs_eth_state_change_handler when appropriate, +or else it will invoke usbs_eth_enable and +usbs_eth_disable directly. For further details of +state change handlers and control endpoints generally, see the +documentation for the common USB-slave package.
Similarly, usbs_eth_init will install +usbs_eth_class_control_handler in the control +endpoint data structure as the appropriate handler for class-specific +USB control messages. This code will handle the ethernet-specific +control messages , for example +requests by the host to enable or disable promiscuous mode or to +obtain the MAC address. If the USB device is not shared with any other +code then this is both necessary and sufficient. However, if other code +is involved and if that code also needs to process certain control +messages, higher-level code should install its own handler and chain +to the USB-ethernet one when appropriate. It should be noted that the +request code is encoded in just a single byte, so there is a real +possibility that exactly the same number will be used by different +protocols for different requests. Any such problems will have to be +identified and resolved by application developers, and may involve +modifying the source code for the USB-ethernet package.
As an alternative to chaining the state change handler, higher-level +code can instead call usbs_eth_disable and +usbs_eth_enable directly. These functions may +also be called if the USB-ethernet package should become inactive for +reasons not related directly to events on the USB bus. The main effect +of usbs_eth_enable is to restart receive +operations and to allow transmits. The main effect of +usbs_eth_disable is to block further transmits: +any current receive operations need to be aborted at the USB level, +for example by halting the appropriate endpoint.