Network Device -- USB-ethernet support 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.
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 -- eCos support for developing USB ethernet peripherals
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.
Example Host-side Device Driver -- Provide host-side support for the eCos USB-ethernet package
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:
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:
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.
\ No newline at end of file
Index: slave/v2_0/doc/simple.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: slave/v2_0/doc/simple.png
===================================================================
--- slave/v2_0/doc/simple.png (revision 174)
+++ slave/v2_0/doc/simple.png (nonexistent)
slave/v2_0/doc/simple.png
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: slave/v2_0/doc/makefile
===================================================================
--- slave/v2_0/doc/makefile (revision 174)
+++ slave/v2_0/doc/makefile (nonexistent)
@@ -1,55 +0,0 @@
-#=============================================================================
-#
-# makefile
-#
-# For building the USB-ethernet package documentation
-#
-#=============================================================================
-#####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
-# Date: 2001-01-11
-#####DESCRIPTIONEND####
-#=============================================================================
-
-TOPLEVEL := ../../../../../..
-MAIN_SGML := usbseth.sgml
-MAIN_HTML := io-usb-slave-eth.html
-MAIN_PDF := io-usb-slave-eth.pdf
-OTHER_SGML :=
-PICTURES := simple tcpip
-
-include $(TOPLEVEL)/pkgconf/rules.doc
Index: slave/v2_0/doc/simple.fig
===================================================================
--- slave/v2_0/doc/simple.fig (revision 174)
+++ slave/v2_0/doc/simple.fig (nonexistent)
@@ -1,23 +0,0 @@
-#FIG 3.2
-Portrait
-Center
-Inches
-Letter
-100.00
-Single
--2
-1200 2
-2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
- 600 600 2400 600 2400 2400 600 2400 600 600
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
- 2400 1500 4200 1500
-2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
- 4200 600 6000 600 6000 2400 4200 2400 4200 600
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
- 6000 1500 6600 1500
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
- 6600 300 6600 2700
-4 0 0 50 0 0 12 0.0000 4 135 675 3000 1425 USB bus\001
-4 0 0 50 0 0 12 0.0000 4 135 735 1200 1425 USB host\001
-4 0 0 50 0 0 12 0.0000 4 180 1155 4500 1425 USB peripheral\001
-4 0 0 50 0 0 12 0.0000 4 135 945 6150 2925 real network\001
Index: slave/v2_0/doc/usbseth-control.html
===================================================================
--- slave/v2_0/doc/usbseth-control.html (revision 174)
+++ slave/v2_0/doc/usbseth-control.html (nonexistent)
@@ -1,309 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-USB-ethernet State Handling
eCos Support for Developing USB-ethernet Peripherals
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.
\ No newline at end of file
Index: slave/v2_0/doc/usbseth.sgml
===================================================================
--- slave/v2_0/doc/usbseth.sgml (revision 174)
+++ slave/v2_0/doc/usbseth.sgml (nonexistent)
@@ -1,810 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- eCos Support for Developing USB-ethernet Peripherals
-
-
-
-
-
-Introduction
-
-
-Introduction
-eCos support for developing USB ethernet peripherals
-
-
-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.
-
-
-
-
-
-
-
-
-
-Initializing the USB-ethernet Package
-
-
-usbs_eth_init
-Initializing the USB-ethernet Package
-
-
-
-
-
-#include <cyg/io/usb/usbs_eth.h>
-
-
-void usbs_eth_init
-usbs_eth* usbeth
-usbs_control_endpoint* ep0
-usbs_rx_endpoint* ep1
-usbs_tx_endpoint* ep2
-unsigned char* mac_address
-
-
-
-
-Description
-
-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.
-
-
-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 usbs_eth_init function.
-
-
-The first argument identifies the specific
-usbs_eth 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
-usbs_eth0 to support this. If multiple
-usbs_eth 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
-usbs_eth_init().
-
-
-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
-usbs_eth_disable and
-usbs_eth_enable control functions. The package
-also assumes that no other code is interested in USB state changes or
-class control messages: it installs handlers
-usbs_eth_state_change_handler
-and
-usbs_eth_class_control_handler
-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
-usbs_eth_init, and those replacements should
-invoke the USB-ethernet ones when appropriate.
-
-
-The final argument to usbs_eth_init 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 scenario in which the
-USB-ethernet package is being used.
-
-
-The call to usbs_eth_init 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.
-
-
-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);
- …
-}
-
-
-
-
-
-
-
-
-
-
-USB-ethernet Data Transfers
-
-
-USB-ethernet Data Transfers
-Exchanging ethernet packets with the USB host
-
-
-
-
-
-#include <cyg/io/usb/usbs_eth.h>
-
-
-
-void usbs_eth_start_rx
-usbs_eth* usbseth
-unsigned char* buffer
-void (*)(usbs_eth*, void*, int) complete_fn
-void* complete_data
-
-
-
-void usbs_eth_start_tx
-usbs_eth* usbseth
-unsigned char* buffer
-void (*)(usbs_eth*, void*, int) complete_fn
-void* complete_data
-
-
-
-
-
-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.
-
-
-
-
-
-
-
-
-
-
-USB-ethernet State Handling
-
-
-USB-ethernet State Handling
-Maintaining the USB-ethernet connection with the host
-
-
-
-
-
-#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.
-
-
-
-
-
-
-
-
-
-
-Network Device for the eCos TCP/IP Stack
-
-
-Network Device
-USB-ethernet support 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.
-
-
-
-
-
-
-
-
-
-
-Example Host-side Device Driver
-
-
-Example Host-side Device Driver
-Provide host-side support for the eCos USB-ethernet package
-
-
-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.
-
-
-
-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.
-
-
-
-
-
-
-
-
-
-
-Communication Protocol
-
-
-Communication Protocol
-Protocol used between the host-side device driver and the eCos
-USB-ethernet package
-
-
-Description
-
-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.
-
-
-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.
-
-
-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 usbs_eth_init, e.g.
-0x405D90A9BC02. The remaining data is as specified by the appropriate
-IETF RFC's. The actual bulk
-USB transfer involves the following sequence of 44 bytes:
-
-
-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
-
-
-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
-usbs_eth_class_control_handler. 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.
-
-
-The first control message can be used by the host to obtain a MAC
-address:
-
-
-#define ECOS_USBETH_CONTROL_GET_MAC_ADDRESS 0x01
-
-
-The control message's type field should specify IN as the direction.
-The request field should be 0x01. 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
-usbs_eth_init.
-
-
-The second control message can be used by the host to enable or
-disable promiscuous mode.
-
-
-#define ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE 0x02
-
-
-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
-0x02. 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.
-
-
-
-
-
-
-
-
-
Index: slave/v2_0/ChangeLog
===================================================================
--- slave/v2_0/ChangeLog (revision 174)
+++ slave/v2_0/ChangeLog (nonexistent)
@@ -1,150 +0,0 @@
-2003-03-23 Iztok Zupet
-
- * doc/usbseth.sgml: Remove .eps and .gif and introduce .png for
- for PDF output.
- * doc/simple.gif, doc/tcpip.gif: Delete.
- * doc/simple.png, doc/tcpip.png: New files to replace GIFs.
-
-2003-02-25 Jonathan Larmour
-
- * doc/usbseth.sgml: Declare as not to get
- correct TOC numbering.
-
-2003-02-24 Jonathan Larmour
-
- * cdl/usbs_eth.cdl: Fix doc link.
-
- * doc/usbseth.sgml: Comment out DOCTYPE for now to allow building
- with standard doc build.
-
-2002-07-26 David Smith
-
- * host/ecos_usbeth.c (ecos_usbeth_probe):
- Two changes to the code that checks to see if this is the correct
- driver for the USB peripheral that was just loaded. Fixed a bug
- that was comparing the product id of the peripheral to the vendor
- id. Supports multiple implementations (vendor id/product id sets)
- so that the same driver could be used for several devices.
-
-2001-07-10 Bart Veer
-
- * doc/usbseth.sgml, doc/*.html:
- Document the below changes.
-
- * cdl/usbs_eth.cdl:
- The USB-ethernet device now registers itself as either eth0 or
- eth1 by default, depending on what else is present in the system.
- Also bootp/dhcp support is prohibited for this network device on
- the ground that it is rather unlikely that a host will provide
- a dhcp service for a network device that does not exist until the
- host-target connection has been fully established.
-
-
-2001-07-02 Bart Veer
-
- * host/ecos_usbeth.c (ecos_usbeth_probe):
- Determine the endpoints to use for transmits and receives
- from the descriptors supplied by the device.
-
-2001-06-28 Bart Veer
-
- * include/usbs_eth.h, src/usbsethdrv.c, src/usbseth.c:
- Align receive boundaries to cacheline boundaries, and
- always transfer a multiple of the cacheline size. This
- avoids problems with some USB device drivers.
-
-2001-05-21 Bart Veer
-
- * host/ecos_usbeth.c (ecos_usbeth_start_tx):
- Cope with targets that have problems receiving zero-byte
- packets.
-
-2001-02-02 Bart Veer
-
- * cdl/usbs_eth.cdl:
- Add doc property to point at the HTML
-
- * doc/usbseth.sgml, doc/*.html:
- Incorporate changes from docs department, regenerate HTML
-
-2001-01-26 Bart Veer
-
- * src/usbsethdrv.c (usbs_ethdrv_ioctl):
- Change chipset specification to null, since there is no real
- hardware involved, plus SNMP cleanup.
-
-2001-01-22 Bart Veer
-
- * doc/usbseth.sgml, doc/makefile, doc/simple.fig, doc/tcpip.fig:
- Added documentation.
-
-2000-12-15 Bart Veer
-
- * src/usbsethdrv.c:
- Enable poll functions.
-
-2000-11-29 Bart Veer
-
- * host/ecos_usbeth.c:
- Remove debugging and fix the MTU
-
-2000-11-28 Bart Veer
-
- * cdl/usbs_eth.cdl
- * include/usbs_eth.h
- * src/usbseth.c
- * src/usbsethdrv
- Clean-up, adding missing functionality such as SNMP support,
- update to current USB API.
-
-2000-11-24 Bart Veer
-
- * host/ecos_usbeth.c:
- Ignore runt packets, cope with the confusion between
- CRC errors and timeouts.
-
- * include/usbs_eth.h, src/usbseth.c
- Clean up alignments.
-
-2000-11-22 Bart Veer
-
- * include/usbs_eth.h: Fix nested #include protection
-
-2000-11-21 Bart Veer
-
- * First check-in of eCos USB 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####
-//===========================================================================
Index: slave/v2_0/src/usbsethdrv.c
===================================================================
--- slave/v2_0/src/usbsethdrv.c (revision 174)
+++ slave/v2_0/src/usbsethdrv.c (nonexistent)
@@ -1,616 +0,0 @@
-//==========================================================================
-//
-// usbethdrv.c
-//
-// Network device driver for USB-ethernet devices.
-//
-//==========================================================================
-//####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
-//
-//####DESCRIPTIONEND####
-//==========================================================================
-
-#include
-#include
-#include
-#include
-
-#define __ECOS 1
-#include
-#include
-#include
-
-#include
-#include
-
-// ----------------------------------------------------------------------------
-// The network driver data structure.
-ETH_DRV_SC(usbs_eth_sc0,
- (void*) &usbs_eth0,
- CYGDAT_USBS_ETHDRV_NAME,
- usbs_ethdrv_start,
- usbs_ethdrv_stop,
- usbs_ethdrv_ioctl,
- usbs_ethdrv_can_send,
- usbs_ethdrv_send,
- usbs_ethdrv_recv,
- usbs_ethdrv_deliver,
- usbs_ethdrv_poll,
- usbs_ethdrv_intvector);
-
-NETDEVTAB_ENTRY(usbs_eth_netdev0,
- "usbs_eth0",
- usbs_ethdrv_init,
- &usbs_eth_sc0);
-
-// ----------------------------------------------------------------------------
-// Statics gathering. The following macro can be used to increment a
-// statistic without having to use a #ifdef for the statistics
-// configuration option everywhere.
-#ifdef CYGFUN_USBS_ETHDRV_STATISTICS
-# define INCR_STAT(a) \
- CYG_MACRO_START \
- (a) += 1; \
- CYG_MACRO_END
-#else
-# define INCR_STAT(a) CYG_EMPTY_STATEMENT
-#endif
-
-// Various constants related to SNMP statistics. It is not clear
-// what these are all for.
-#ifdef CYGFUN_USBS_ETHDRV_STATISTICS
-# define CYGDAT_USBS_ETHDRV_DESCRIPTION "eCos USB ethernet device"
-#endif
-// ----------------------------------------------------------------------------
-// Utility functions.
-//
-// The TCP/IP stack works in terms of scatter/gather buffers. USB tends to
-// involve DMA operations so it is more convenient to work in terms of
-// 1514 byte flat buffers. Actually, the first two bytes of the buffer
-// are used to hold the ethernet frame size to work around restrictions
-// with certain hardware implementations of USB that may be unable to
-// transfer certain packet sizes.
-
-static bool
-scatter(unsigned char* buf, struct eth_drv_sg* sg, int sg_len)
-{
- unsigned int size;
-
- size = buf[0] | (buf[1] << 8);
- buf++; buf++;
-
- CYG_ASSERT((size >= CYGNUM_USBS_ETH_MIN_FRAME_SIZE) && (size <= CYGNUM_USBS_ETH_MAX_FRAME_SIZE),\
- "ethernet frame size limits must be observed");
-
- while ((size > 0) && (sg_len > 0)) {
- if (size > sg->len) {
- memcpy((void*) sg->buf, buf, sg->len);
- buf += sg->len;
- size -= sg->len;
- sg++;
- sg_len--;
- } else {
- memcpy((void*) sg->buf, buf, size);
- size = 0;
- }
- }
-
- return 0 == size;
-}
-
-static bool
-gather(unsigned char* buf, unsigned int size, struct eth_drv_sg* sg, int sg_len)
-{
- unsigned int left = size;
- unsigned char* base = buf;
-
- buf++; buf++;
- while ((left > 0) && (sg_len > 0)) {
- if (left > sg->len) {
- memcpy(buf, (void*) sg->buf, sg->len);
- buf += sg->len;
- left -= sg->len;
- sg++;
- sg_len--;
- } else {
- memcpy(buf, (void*) sg->buf, left);
- left = 0;
- }
- }
- size = size - left;
- base[0] = size & 0x00FF;
- base[1] = (size >> 8) & 0x00FF;
-
- return 0 == left;
-}
-
-
-// ----------------------------------------------------------------------------
-// usbs_ethdrv_init()
-//
-// This function is called during system initialization to decide
-// whether or not this particular network device is usable. For
-// USB-ethernet this is problematical, the device is only really
-// usable once both sides have come up. The typical sequence
-// of events is something like:
-//
-// 1) the eCos peripheral is powered up. Static constructors are
-// run resulting in basic initialization.
-//
-// 2) the eCos TCP/IP stack initialization happens. Roughly in
-// parallel the eCos USB slave side is initialized as well,
-// i.e. enumeration data is supplied to control endpoints,
-// endpoints are associated with application classes, and so
-// on. The relative order of TCP/IP and USB initialization is
-// not particularly important.
-//
-// It is the TCP/IP stack's initialization code that will
-// invoke usbs_eth_init().
-//
-// 3) host-side USB detects that the eCos peripheral has been
-// connected or powered up. It goes through the enumeration
-// process and will end up loading a host-side network driver.
-// This connects to the eCos-side USB ethernet code to
-// e.g. obtain the MAC address.
-//
-// 4) when the host-side is ready, the eCos side can be brought up.
-// The required call is (sc->funs->eth_drv->init)(sc, enaddr)
-//
-// In practice it is easier for now to invoke the init() function
-// immediately. There are not going to be any incoming packets
-// until the host is ready, and can_send() can just return false
-// for the time being.
-//
-// Invoked in: thread context only
-// ----------------------------------------------------------------------------
-
-static bool
-usbs_ethdrv_init(struct cyg_netdevtab_entry* ndp)
-{
- struct eth_drv_sc* sc = (struct eth_drv_sc*)(ndp->device_instance);
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
-
- (*sc->funs->eth_drv->init)(sc, eth->ecos_MAC);
- return true;
-}
-
-// ----------------------------------------------------------------------------
-// The receive process that is used to transfer a received ethernet
-// packet into the stack. The calling sequence is somewhat convoluted.
-// It started off as:
-//
-// 1) Ethernet hw ISR invoked by hardware, schedules its own
-// hw_dsr(), and blocks further interrupts in the ethernet chip
-// 2) hw_dsr() calls generic eth_drv_dsr() from io/eth common package
-// 3) eth_drv_dsr() interacts with the TCP/IP stack and allocates mbufs
-// (typically, the TCP/IP stack might not be in use)
-// 4) eth_drv_dsr() calls usbs_eth_recv() to transfer the data to mbufs
-// 5) eth_drv_dsr() returns to hw_dsr() which reenables interrupts
-// 6) hw_dsr() completes and everything can proceed.
-//
-// The problem with this is that the whole ethernet packet gets copied
-// inside a DSR, affecting dispatch latency (but not interrupt latency).
-// This is bad. Hence there is an alternative route involving a separate
-// thread in the TCP/IP stack.
-//
-// 1) Ethernet hw ISR runs as before, scheduling hw_dsr()
-// 2) hw_dsr() calls up into eth_drv_dsr()
-// 3) eth_drv_dsr() wakes up a thread inside the TCP/IP stack
-// 4) eth_drv_dsr() returns to hw_dsr(), which performs no further
-// processing. Ethernet chip interrupts remain disabled.
-// 5) The TCP/IP thread ends up calling hw_deliver(). This should take
-// care of any pending activity. For every buffered packet there should
-// be a call to a generic recv() function which then goes back into
-// the driver-specific recv() function.
-//
-// The advantage is that ethernet packet copying now happens at thread
-// level rather than DSR level so thread priorities can be used to
-// schedule things.
-//
-// USB-ethernet does not interact directly with any hardware, instead
-// it just passes information to lower levels of USB code. The reception
-// process is started by usbs_ethdrv_start() when the TCP/IP stack brings
-// up the interface.
-//
-// When the USB transfer has completed a callback will be invoked, at
-// DSR level. Assuming the transfer went ok, the callback will invoke
-// eth_drv_dsr() to inform the higher level code.
-//
-// The deliver function can check the state of the buffer
-// and go through the sc->funs->eth_drv->recv()/recv() sequence
-// to transfer the data into the stack.
-//
-// usbs_ethdrv_recv() does a scatter from the internal buffer into the
-// mbuf, thus freeing up the buffer. This allows it to start another
-// receive,
-//
-// Synchronisation involves the scheduler lock because the recv
-// callback is invoked inside a DSR.
-
-static void usbs_ethdrv_halted_callback(void*, int);
-
-static void
-usbs_ethdrv_recv_callback(usbs_eth* eth, void* callback_data, int size)
-{
- cyg_bool resubmit = true;
-
- struct eth_drv_sc* sc = (struct eth_drv_sc*) callback_data;
- CYG_ASSERT( eth == (usbs_eth*)(sc->driver_private), "USB and TCP/IP worlds need to be consistent");
-
- INCR_STAT(eth->interrupts);
- if (!eth->ecos_up) {
- // This message should just be discarded since the eCos TCP/IP
- // stack is not expecting anything from this interface.
- // Reception will resume when the interface comes back up.
- eth->rx_active = false;
- resubmit = false;
- } else if (size < 0) {
- // An error has occurred. The likely possibilities are:
- // -EPIPE: connection to the host has been broken
- // -EAGAIN: the endpoint is haltedn
- // -EMSGSIZE: bogus message from host
- // -EIO: other
-
- if (-EAGAIN == size) {
- // EAGAIN should be handled by waiting for the endpoint to be reset.
- resubmit = false;
- usbs_start_rx_endpoint_wait(eth->rx_endpoint, &usbs_ethdrv_halted_callback, (void*) sc);
- } else if (-EMSGSIZE == size) {
- // Do nothing for now
- } else {
- // EPIPE should be resubmitted, the usbseth.c will use the
- // pending rx support. EIO could mean anything.
- }
- } else if (0 == size) {
- // The endpoint is no longer halted. Just do the resubmit at
- // the end.
- } else {
- // A packet has been received. Now do a size sanity check
- // based on the first two bytes.
- int real_size = eth->rx_bufptr[0] + (eth->rx_bufptr[1] << 8);
- if (real_size < CYGNUM_USBS_ETH_MIN_FRAME_SIZE) {
- INCR_STAT(eth->rx_short_frames);
- } else if (real_size > CYGNUM_USBS_ETH_MAX_FRAME_SIZE) {
- INCR_STAT(eth->rx_too_long_frames);
- } else {
- // The packet appears to be valid. Inform higher level
- // code and mark the buffer as in use.
- resubmit = false;
- eth->rx_buffer_full = true;
- eth->rx_active = false;
- eth_drv_dsr(0, 0, (cyg_addrword_t) sc);
- }
- }
-
- if (resubmit) {
- eth->rx_active = true;
- usbs_eth_start_rx(eth, eth->rx_bufptr, &usbs_ethdrv_recv_callback, callback_data);
- }
-}
-
-// Another callback, used to wait while an endpoint is halted.
-static void
-usbs_ethdrv_halted_callback(void* callback_data, int size)
-{
- struct eth_drv_sc* sc = (struct eth_drv_sc*) callback_data;
- usbs_ethdrv_recv_callback((usbs_eth*) sc->driver_private, callback_data, 0);
-}
-
-// Start a receive operation. It is not possible to abort an existing
-// rx operation, so a valid sequence of events is: start, rx ongoing,
-// stop, restart. The rx_active field is used to keep track of whether
-// or not there is still a receive in progress. The receive callback
-// will just discard incoming data if the eCos stack is not currently
-// running.
-static void
-usbs_ethdrv_start_recv(struct eth_drv_sc* sc, usbs_eth* eth)
-{
- cyg_drv_dsr_lock();
- if (!eth->rx_active) {
- eth->rx_active = true;
- usbs_eth_start_rx(eth, eth->rx_bufptr, &usbs_ethdrv_recv_callback, (void*) sc);
- }
- cyg_drv_dsr_unlock();
-}
-
-// This is invoked from the delivery thread when a valid buffer
-// has been received. The buffer should be scattered into the
-// supplied list, then another receive should be started.
-
-static void
-usbs_ethdrv_recv(struct eth_drv_sc* sc,
- struct eth_drv_sg* sg_list, int sg_len)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
-
- CYG_ASSERT( eth->rx_buffer_full, "This function should only be called when there is a buffer available");
- (void) scatter(eth->rx_bufptr, sg_list, sg_len);
- eth->rx_buffer_full = false;
- eth->rx_active = true;
- usbs_eth_start_rx(eth, eth->rx_bufptr, &usbs_ethdrv_recv_callback, (void*) sc);
-}
-
-// ----------------------------------------------------------------------------
-// Now for the transmit process.
-//
-// When an application thread writes down a socket the data gets moved
-// into mbufs, and then passed to the appropriate device driver - which
-// may or may not be able to process it immediately. There is also a
-// timeout thread within the TCP/IP to handle retransmits etc.
-//
-// The stack will start by calling usbs_ethdrv_can_send() to determine
-// whether or not the driver can accept the packet. For the purposes
-// of the USB-ethernet driver this is true provided both host
-// and target are up and there is a spare buffer available.
-//
-// If the usbs_eth_can_send() returns true then there will be a call
-// to usbs_ethdrv_send(). This gathers the data into a single
-// buffer. If there is no transmit in progress yet then one is started.
-//
-// At some point the packet will have been transmitted and a callback
-// gets invoked. This needs to call eth_drv_dsr(), waking up the
-// delivery thread. The deliver() function can then check which
-// transmissions have completed and inform the higher level code
-// via sc->funs->eth_drv->tx_done(). The buffer can be re-used at
-// that point.
-
-static void
-usbs_ethdrv_send_callback(usbs_eth* eth, void* callback_data, int size)
-{
- struct eth_drv_sc* sc = (struct eth_drv_sc*) callback_data;
- CYG_ASSERT( eth == (usbs_eth*)(sc->driver_private), "USB and TCP/IP worlds need to be consistent");
-
- INCR_STAT(eth->interrupts);
-
- // There are a variety of possible error codes. -EAGAIN indicates
- // that the endpoint is stalled. -EPIPE indicates that the
- // connection to the host has been lost. These are not really
- // particularly interesting. Whatever happens the buffer
- // must be cleared and higher-level code informed so that
- // the mbufs can be released.
- if (size > 0) {
- INCR_STAT(eth->tx_count);
- }
- eth->tx_done = true;
- eth_drv_dsr(0, 0, (cyg_addrword_t) sc);
-}
-
-// Is it possible to send an ethernet frame? This requires
-// an empty buffer, i.e. there should be no existing
-// transmit in progress. It also requires that the host
-// is connected and that the endpoint is not currently halted.
-static int
-usbs_ethdrv_can_send(struct eth_drv_sc* sc)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
- return eth->host_up && !eth->tx_buffer_full && !eth->tx_endpoint->halted;
-}
-
-// Actually start a packet transmission. This means collecting
-// all the data into a single buffer and then invoking the
-// lower-level code. The latter may discard the packet immediately
-// if the MAC is not appropriate: it would be more efficient to
-// catch that here, especially for large packets, but the check
-// has to happen inside the lower-level code anyway in case
-// that is being invoked directly rather than via the driver.
-//
-// There is a possible recursion problem,
-// send->start_tx->tx_done->can_send->send, which is guarded
-// against using the tx_in_send flag.
-
-static void
-usbs_ethdrv_send(struct eth_drv_sc* sc,
- struct eth_drv_sg* sgl_list, int sg_len, int total_len,
- unsigned long key)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
-
- CYG_ASSERT( 0 == eth->tx_in_send, "send() should not be invoked recursively");
- CYG_ASSERT( total_len <= CYGNUM_USBS_ETH_MAX_FRAME_SIZE, "ethernet maximum frame size should be observed");
- CYG_ASSERT( CYGNUM_USBS_ETH_MIN_FRAME_SIZE <= total_len, "ethernet minimum frame size should be observed");
-
- eth->tx_in_send = true;
- CYG_ASSERT( !eth->tx_buffer_full, "the transmit buffer should be empty");
- gather(eth->tx_buffer, CYGNUM_USBS_ETH_MAX_FRAME_SIZE, sgl_list, sg_len);
- eth->tx_buffer_full = true;
- eth->tx_done = false;
- eth->tx_key = key;
- usbs_eth_start_tx(eth, eth->tx_buffer, &usbs_ethdrv_send_callback, (void*) sc);
- eth->tx_in_send = false;
-}
-
-// ----------------------------------------------------------------------------
-// Deliver needs to take into account both receive and transmit buffers.
-
-static void
-usbs_ethdrv_deliver(struct eth_drv_sc* sc)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
-
- if (eth->rx_buffer_full) {
- int size = eth->rx_bufptr[0] + (eth->rx_bufptr[1] << 8);
- (*sc->funs->eth_drv->recv)(sc, size);
- }
- if (eth->tx_done) {
- unsigned long key = eth->tx_key;
- eth->tx_buffer_full = false;
- eth->tx_done = false;
- (*sc->funs->eth_drv->tx_done)(sc, key, 1);
- }
-}
-
-// ----------------------------------------------------------------------------
-// usbs_ethdrv_start()
-//
-// This gets called by the TCP/IP stack later on during
-// initialization, when the stack is ready to send and receive
-// packets. It may get called multiple times while the stack
-// is running, with different flags values.
-//
-// As far as transmits are concerned, nothing needs to be done. If no
-// transmit is in progress then everything is fine anyway. If a
-// transmit is already in progress then it must be allowed to complete
-// via the usual route. Receives should however be restarted, the
-// start function has appropriate safeguards.
-//
-// Invoked in: thread context only
-// ----------------------------------------------------------------------------
-
-static void
-usbs_ethdrv_start(struct eth_drv_sc* sc, unsigned char* enaddr, int flags)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
- if (!eth->ecos_up) {
- eth->ecos_up = true;
- usbs_ethdrv_start_recv(sc, eth);
- }
-}
-
-// ----------------------------------------------------------------------------
-// usbs_ethdrv_stop()
-//
-// Similarly this gets called by the TCP/IP stack to bring the network
-// interface down. Nothing should happen for any packets currently
-// being transmitted or received, that would cause confusion everywhere.
-// The receive callback checks the ecos_up flag and does the right
-// thing. The TCP/IP stack should not call can_send() after taking
-// the interface down so no new transmits will be initiated.
-//
-// Invoked in: thread context only
-// ----------------------------------------------------------------------------
-
-static void
-usbs_ethdrv_stop(struct eth_drv_sc* sc)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
- eth->ecos_up = false;
-}
-
-// ----------------------------------------------------------------------------
-// usbs_eth_ioctl()
-//
-// The operations to worry about here are:
-//
-// SET_MAC_ADDRESS,via the SIOCSIFHWADDR ioctl
-//
-// GET_IF_STATS and GET_IF_STATS_UD, to report gathered statistics.
-//
-// Invoked in: thread context only
-// ----------------------------------------------------------------------------
-
-static int
-usbs_ethdrv_ioctl(struct eth_drv_sc* sc, unsigned long key, void* data, int data_length)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
- int result = EINVAL;
-
- switch(key) {
- case ETH_DRV_SET_MAC_ADDRESS:
- {
- if (6 == data_length) {
- memcpy(eth->ecos_MAC, data, 6);
- result = 0;
- }
- }
- break;
-#if defined(CYGFUN_USBS_ETHDRV_STATISTICS) && defined(ETH_DRV_GET_IF_STATS_UD)
- case ETH_DRV_GET_IF_STATS_UD:
- case ETH_DRV_GET_IF_STATS:
- {
- static unsigned char my_chipset[] = { 0, 0 };
- struct ether_drv_stats *p = (struct ether_drv_stats*) data;
- int i;
- strcpy(p->description, CYGDAT_USBS_ETHDRV_DESCRIPTION);
- for ( i = 0; i < SNMP_CHIPSET_LEN; i++ ) {
- if ( 0 == (p->snmp_chipset[i] = my_chipset[i]) ) {
- break;
- }
- }
- p->duplex = 3; // 3 == duplex
- p->operational = (eth->host_up && eth->ecos_up) ? 3 : 2; // 3 == up, 2 == down
- p->speed = 10 * 1000000;
- p->supports_dot3 = 1;
- p->rx_too_long_frames = eth->rx_too_long_frames;
- p->rx_short_frames = eth->rx_short_frames;
- p->interrupts = eth->interrupts;
- p->rx_count = eth->rx_count;
- p->tx_count = eth->tx_count;
- p->tx_queue_len = 1;
- }
- break;
-#endif
-
- default:
- break;
- }
-
- return result;
-}
-
-
-// ----------------------------------------------------------------------------
-// usbs_ethdrv_poll()
-//
-// On real ethernet hardware this is used by RedBoot once the
-// application has started running, so that the network device can be
-// used for debugging purposes as well as for the application's own
-// needs. The lower-level USB device may supply a poll function as well.
-// ----------------------------------------------------------------------------
-static void
-usbs_ethdrv_poll(struct eth_drv_sc* sc)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
- (*eth->control_endpoint->poll_fn)(eth->control_endpoint);
-}
-
-// ----------------------------------------------------------------------------
-// usbs_ethdrv_intvector()
-//
-// See usbs_eth_poll().
-// ----------------------------------------------------------------------------
-
-static int
-usbs_ethdrv_intvector(struct eth_drv_sc* sc)
-{
- usbs_eth* eth = (usbs_eth*)(sc->driver_private);
- return eth->control_endpoint->interrupt_vector;
-}
-
-
Index: slave/v2_0/src/usbseth.c
===================================================================
--- slave/v2_0/src/usbseth.c (revision 174)
+++ slave/v2_0/src/usbseth.c (nonexistent)
@@ -1,321 +0,0 @@
-//==========================================================================
-//
-// usbseth.c
-//
-// Support for USB-ethernet devices, slave-side.
-//
-//==========================================================================
-//####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
-//
-//####DESCRIPTIONEND####
-//
-//==========================================================================
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#define __ECOS 1
-#include
-
-#ifdef CYGPKG_USBS_ETHDRV
-#include
-#include
-#endif
-
-// ----------------------------------------------------------------------------
-// Static data.
-//
-// usbs_eth0 contains the per-device data, both the low-level data
-// such as which endpoints to use and the network-driver data such as
-// SNMP statistics. If this package is loaded then the assumption
-// is that there should be at least one USB-ethernet device. Additional
-// ones can be instantiated in application code if necessary. A call
-// to usbs_eth_init() is required for initialization.
-usbs_eth usbs_eth0;
-
-// ----------------------------------------------------------------------------
-// Initialization. This should be called explicitly by application code
-// at an appropriate point in the system startup.
-void
-usbs_eth_init(usbs_eth* eth, usbs_control_endpoint* ctrl, usbs_rx_endpoint* rx, usbs_tx_endpoint* tx, unsigned char* mac)
-{
- eth->control_endpoint = ctrl;
- eth->rx_endpoint = rx;
- eth->tx_endpoint = tx;
- eth->host_up = false;
- eth->host_promiscuous = false;
- memcpy(eth->host_MAC, mac, 6);
- eth->rx_pending_buf = (unsigned char*) 0;
-
- // Install default handlers for some messages. Higher level code
- // may override this.
- ctrl->state_change_fn = &usbs_eth_state_change_handler;
- ctrl->state_change_data = (void*) eth;
- ctrl->class_control_fn = &usbs_eth_class_control_handler;
- ctrl->class_control_data = (void*) eth;
-
-#ifdef CYGPKG_USBS_ETHDRV
- eth->ecos_up = false;
- eth->rx_active = false;
-# ifdef CYGFUN_USBS_ETHDRV_STATISTICS
- eth->interrupts = 0;
- eth->tx_count = 0;
- eth->rx_count = 0;
-# endif
-# ifndef HAL_DCACHE_LINE_SIZE
- eth->rx_bufptr = eth->rx_buffer;
-# else
-# endif
- eth->rx_bufptr = (unsigned char*) ((((cyg_uint32)eth->rx_buffer) + HAL_DCACHE_LINE_SIZE - 1)
- & ~(HAL_DCACHE_LINE_SIZE - 1));
- eth->rx_buffer_full = false;
- eth->tx_in_send = false;
- eth->tx_buffer_full = false;
- eth->tx_done = false;
-#endif
-}
-
-
-// ----------------------------------------------------------------------------
-// Generic transmit and receive operations. These can be called
-// explicitly by application code, or implicitly via the eCos ethernet
-// device driver code in usbsethdrv.c. These two modes of operation
-// should not be mixed since the routines do not perform any
-// synchronization themselves, instead they rely on higher level code.
-
-// Packet transmission. The exported function is usbs_eth_start_tx(),
-// which can be invoked from thread context or DSR context. The
-// supplied buffer must already be in a form that can be transmitted
-// directly out of the USB endpoint with no further processing
-// (although it is necessary to extract the size information from the
-// buffer).
-//
-// When the underlying USB transfer has completed the USB code will invoke
-// usbs_eth_tx_callback(), usually in DSR context although possibly in
-// thread context depending on the specific USB implementation. The
-// underlying USB driver may have had to do some padding so the amount
-// transferred may be slightly greater than requested.
-
-static void
-usbs_eth_tx_callback(void* usbs_callback_arg, int size)
-{
- usbs_eth* eth = (usbs_eth*) usbs_callback_arg;
- CYG_ASSERT( (size < 0) || (size >= CYGNUM_USBS_ETH_MINTU), "returned size must be valid.");
- (*eth->tx_callback_fn)(eth, eth->tx_callback_arg, size);
-}
-
-void
-usbs_eth_start_tx(usbs_eth* eth, unsigned char* buf, void (*callback_fn)(usbs_eth*, void*, int), void* callback_arg)
-{
- int size;
- cyg_bool address_ok = false;
- static const unsigned char broadcast_mac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-
- size = buf[0] + (buf[1] << 8);
- CYG_ASSERT( (size < 0) || ((size >= CYGNUM_USBS_ETH_MIN_FRAME_SIZE) && (size <= CYGNUM_USBS_ETH_MAX_FRAME_SIZE)), \
- "ethernet frame size constraints must be observed");
-
- if ((0 == memcmp(buf + 2, eth->host_MAC, 6)) ||
- (0 == memcmp(buf + 2, broadcast_mac, 6))) {
- address_ok = true;
- }
-
- // The following checks involve data that can change as a result
- // of control operations, so it is necessary to synchronize with
- // those. The control operations will typically run at DSR level
- // so a DSR lock has to be used.
-
- cyg_drv_dsr_lock();
- if (eth->host_up && (address_ok || eth->host_promiscuous)) {
-
- eth->tx_callback_fn = callback_fn;
- eth->tx_callback_arg = callback_arg;
- eth->tx_endpoint->buffer = buf;
- eth->tx_endpoint->buffer_size = size + 2;
- eth->tx_endpoint->complete_fn = &usbs_eth_tx_callback;
- eth->tx_endpoint->complete_data = (void*) eth;
- (*(eth->tx_endpoint->start_tx_fn))(eth->tx_endpoint);
-
- } else {
- // Packets not intended for the host can be discarded quietly.
- // A broken connection needs to be reported.
- (*callback_fn)(eth, callback_arg, eth->host_up ? size : -EPIPE);
- }
- cyg_drv_dsr_unlock();
-}
-
-// Packet reception. This simply involves starting a transfer for
-// up to the maximum ethernet frame size. The lower-level USB code
-// will detect the end of the transfer. The exported function is
-// usbs_eth_start_rx().
-static void
-usbs_eth_rx_callback(void* usbs_callback_arg, int size)
-{
- usbs_eth* eth = (usbs_eth*) usbs_callback_arg;
-
- CYG_ASSERT( (size <= 0) || ((size >= CYGNUM_USBS_ETH_MINTU) && (size <= CYGNUM_USBS_ETH_MAXTU)), \
- "ethernet frame size constraints must be observed");
-
- (*eth->rx_callback_fn)(eth, eth->rx_callback_arg, size);
-}
-
-void
-usbs_eth_start_rx(usbs_eth* eth, unsigned char* buf, void (*callback_fn)(usbs_eth*, void*, int), void* callback_arg)
-{
- eth->rx_callback_fn = callback_fn;
- eth->rx_callback_arg = callback_arg;
-
- cyg_drv_dsr_lock();
- if (eth->host_up) {
- eth->rx_endpoint->buffer = buf;
- eth->rx_endpoint->buffer_size = CYGNUM_USBS_ETH_RXSIZE;
- eth->rx_endpoint->complete_fn = &usbs_eth_rx_callback;
- eth->rx_endpoint->complete_data = (void*) eth;
- (*(eth->rx_endpoint->start_rx_fn))(eth->rx_endpoint);
- } else {
- CYG_ASSERT( (void*) 0 == eth->rx_pending_buf, "No RX operation should be in progress");
- eth->rx_pending_buf = buf;
- }
- cyg_drv_dsr_unlock();
-}
-
-// ----------------------------------------------------------------------------
-// Control operations. The host may send two types of application-specific
-// control messages, one to get the MAC address and one to enable/disable
-// promiscuous mode on the host side. This callback will typically be invoked
-// in DSR context.
-
-// These constants need to be shared somehow with the driver in ../host/,
-// but if some variant of that driver becomes part of the Linux kernel
-// then its sources must be self-contained with no dependencies on
-// eCos sources or headers. Hence a duplicate definition for now.
-#define USBS_ETH_CONTROL_GET_MAC_ADDRESS 0x01
-#define USBS_ETH_CONTROL_SET_PROMISCUOUS_MODE 0x02
-
-usbs_control_return
-usbs_eth_class_control_handler(usbs_control_endpoint* endpoint, void* callback_data)
-{
- usbs_control_return result = USBS_CONTROL_RETURN_STALL;
-
- usbs_eth* eth = (usbs_eth*) callback_data;
- usb_devreq* devreq = (usb_devreq*) endpoint->control_buffer;
- int size = (devreq->length_hi << 8) + devreq->length_lo;
-
- CYG_ASSERT(endpoint == eth->control_endpoint, "USB ethernet control messages correctly routed");
-
- if (USBS_ETH_CONTROL_GET_MAC_ADDRESS == devreq->request) {
- // This should be an IN operation for at least six bytes.
- if ((size >= 6) &&
- (USB_DEVREQ_DIRECTION_IN == (devreq->type & USB_DEVREQ_DIRECTION_MASK))) {
-
- endpoint->buffer = eth->host_MAC;
- endpoint->buffer_size = 6;
- result = USBS_CONTROL_RETURN_HANDLED;
- }
- // Otherwise drop through with a return value of STALL
-
- } else if (USBS_ETH_CONTROL_SET_PROMISCUOUS_MODE == devreq->request) {
- // The length should be 0, no more data is expected by either side.
- if (0 == size) {
- // The new promiscuity mode is encoded in value_lo;
- eth->host_promiscuous = devreq->value_lo;
- result = USBS_CONTROL_RETURN_HANDLED;
- }
- }
-
- return result;
-}
-
-// State changes. As far as the ethernet code is concerned, if there
-// is a change to CONFIGURED state then the device has come up,
-// otherwise if there is a change from CONFIGURED state it has gone
-// down. All other state changes are irrelevant.
-void
-usbs_eth_state_change_handler(usbs_control_endpoint* endpoint, void* callback_data, usbs_state_change change, int old_state)
-{
- usbs_eth* eth = (usbs_eth*) callback_data;
- CYG_ASSERT(endpoint == eth->control_endpoint, "USB ethernet state changes correctly routed");
-
- if (USBS_STATE_CHANGE_CONFIGURED == change) {
- if (USBS_STATE_CONFIGURED != old_state) {
- usbs_eth_enable(eth);
- }
- } else if ((USBS_STATE_CHANGE_RESUMED == change) && (USBS_STATE_CONFIGURED == (USBS_STATE_MASK & old_state))) {
- usbs_eth_enable(eth);
- } else if (eth->host_up) {
- usbs_eth_disable(eth);
- }
-}
-
-// Disabling the ethernet device means clearing the host_up flag.
-// This will block future transmits and receives but not any
-// that are currently underway.
-void
-usbs_eth_disable(usbs_eth* eth)
-{
- eth->host_up = false;
-}
-
-// Enabling the ethernet device means setting the host_up flag and
-// possibly activating a pending rx operation.
-void
-usbs_eth_enable(usbs_eth* eth)
-{
- if (!eth->host_up) {
- eth->host_up = true;
- eth->host_promiscuous = false;
- if ((void*) 0 != eth->rx_pending_buf) {
- eth->rx_endpoint->buffer = eth->rx_pending_buf;
- eth->rx_endpoint->buffer_size = CYGNUM_USBS_ETH_RXSIZE;
- eth->rx_endpoint->complete_fn = &usbs_eth_rx_callback;
- eth->rx_endpoint->complete_data = (void*) eth;
- eth->rx_pending_buf = (void*) 0;
- (*(eth->rx_endpoint->start_rx_fn))(eth->rx_endpoint);
- }
- }
-}
-
Index: slave/v2_0/host/ecos_usbeth.c
===================================================================
--- slave/v2_0/host/ecos_usbeth.c (revision 174)
+++ slave/v2_0/host/ecos_usbeth.c (nonexistent)
@@ -1,572 +0,0 @@
-//==========================================================================
-//
-// ecos_usbeth.c
-//
-// Linux device driver for eCos-based USB ethernet peripherals.
-//
-//==========================================================================
-//####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-11-12
-//
-//####DESCRIPTIONEND####
-//==========================================================================
-
-#include
-#include
-#include
-#include
-#include
-
-#ifdef MODULE
-MODULE_AUTHOR("Bart Veer ");
-MODULE_DESCRIPTION("USB ethernet driver for eCos-based peripherals");
-#endif
-
-// This array identifies specific implementations of eCos USB-ethernet
-// devices. All implementations should add their vendor and device
-// details.
-
-typedef struct ecos_usbeth_impl {
- const char* name;
- __u16 vendor;
- __u16 id;
-} ecos_usbeth_impl;
-
-const static ecos_usbeth_impl ecos_usbeth_implementations[] = {
- { "eCos ether", 0x4242, 0x4242 },
- { (const char*) 0, 0, 0 }
-};
-
-
-// Constants. These have to be kept in sync with the target-side
-// code.
-#define ECOS_USBETH_MAXTU 1516
-#define ECOS_USBETH_MAX_CONTROL_TU 8
-#define ECOS_USBETH_CONTROL_GET_MAC_ADDRESS 0x01
-#define ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE 0x02
-
-// The main data structure. It keeps track of both the USB
-// and network side of things, and provides buffers for
-// the various operations.
-//
-// NOTE: currently this driver only supports a single
-// plugged-in device. Theoretically multiple eCos-based
-// USB ethernet devices could be plugged in to a single
-// host and each one would require an ecos_usbeth
-// structure.
-typedef struct ecos_usbeth {
- spinlock_t usb_lock;
- int target_promiscuous;
- struct usb_device* usb_dev;
- struct net_device* net_dev;
- struct net_device_stats stats;
- struct urb rx_urb;
- struct urb tx_urb;
- unsigned char rx_buffer[ECOS_USBETH_MAXTU];
- unsigned char tx_buffer[ECOS_USBETH_MAXTU];
-} ecos_usbeth;
-
-
-// open()
-// Invoked by the TCP/IP stack when the interface is brought up.
-// This just starts a receive operation.
-static int
-ecos_usbeth_open(struct net_device* net)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) net->priv;
- int res;
-
- netif_start_queue(net);
- res = usb_submit_urb(&(usbeth->rx_urb));
- if (0 != res) {
- printk("ecos_usbeth: failed to start USB receives, %d\n", res);
- }
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-// close()
-// Invoked by the TCP/IP stack when the interface is taken down.
-// Any active USB operations need to be cancelled. During
-// a disconnect this may get called twice, once for the
-// disconnect and once for the network interface being
-// brought down.
-static int
-ecos_usbeth_close(struct net_device* net)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) net->priv;
-
- if (0 != netif_running(net)) {
- netif_stop_queue(net);
- net->start = 0;
-
- if (-EINPROGRESS == usbeth->rx_urb.status) {
- usb_unlink_urb(&(usbeth->rx_urb));
- }
- if (-EINPROGRESS == usbeth->tx_urb.status) {
- usb_unlink_urb(&(usbeth->tx_urb));
- }
- MOD_DEC_USE_COUNT;
- }
-
- return 0;
-}
-
-// Reception.
-// probe() fills in an rx_urb. When the net device is brought up
-// the urb is activated, and this callback gets run for incoming
-// data.
-static void
-ecos_usbeth_rx_callback(struct urb* urb)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) urb->context;
- struct net_device* net = usbeth->net_dev;
- struct sk_buff* skb;
- int len;
- int res;
-
- if (0 != urb->status) {
- // This happens numerous times during a disconnect. Do not
- // issue a warning, but do clear the status field or things
- // get confused when resubmitting.
- //
- // Some host hardware does not distinguish between CRC errors
- // (very rare) and timeouts (perfectly normal). Do not
- // increment the error count if it might have been a timeout.
- if (USB_ST_CRC != urb->status) {
- usbeth->stats.rx_errors++;
- }
- urb->status = 0;
- } else if (2 > urb->actual_length) {
- // With some hardware the target may have to send a bogus
- // first packet. Just ignore those.
-
- } else {
- len = usbeth->rx_buffer[0] + (usbeth->rx_buffer[1] << 8);
- if (len > (urb->actual_length - 2)) {
- usbeth->stats.rx_errors++;
- usbeth->stats.rx_length_errors++;
- printk("ecos_usbeth: warning, packet size mismatch, got %d bytes, expected %d\n",
- urb->actual_length, len);
- } else {
- skb = dev_alloc_skb(len + 2);
- if ((struct sk_buff*)0 == skb) {
- printk("ecos_usbeth: failed to alloc skb, dropping packet\n");
- usbeth->stats.rx_dropped++;
- } else {
-#if 0
- {
- int i;
- printk("--------------------------------------------------------------\n");
- printk("ecos_usbeth RX: total size %d\n", len);
- for (i = 0; (i < len) && (i < 128); i+= 8) {
- printk("rx %x %x %x %x %x %x %x %x\n",
- usbeth->rx_buffer[i+0], usbeth->rx_buffer[i+1], usbeth->rx_buffer[i+2], usbeth->rx_buffer[i+3],
- usbeth->rx_buffer[i+4], usbeth->rx_buffer[i+5], usbeth->rx_buffer[i+6], usbeth->rx_buffer[i+7]);
- }
- printk("--------------------------------------------------------------\n");
- }
-#endif
- skb->dev = net;
- eth_copy_and_sum(skb, &(usbeth->rx_buffer[2]), len, 0);
- skb_put(skb, len);
- skb->protocol = eth_type_trans(skb, net);
- netif_rx(skb);
- usbeth->stats.rx_packets++;
- usbeth->stats.rx_bytes += len;
- }
- }
- }
-
- if (0 != netif_running(net)) {
- res = usb_submit_urb(&(usbeth->rx_urb));
- if (0 != res) {
- printk("ecos_usbeth: failed to restart USB receives after packet, %d\n", res);
- }
- }
-}
-
-// start_tx().
-// Transmit a single packet. The relevant USB protocol requires a
-// 2-byte length field at the start, the incoming buffer has no space
-// for this, and the URB API does not support any form of
-// scatter/gather. Therefore unfortunately the whole packet has to be
-// copied. The callback function is specified when the URB is filled
-// in by probe().
-static void
-ecos_usbeth_tx_callback(struct urb* urb)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) urb->context;
- spin_lock(&usbeth->usb_lock);
- if (0 != netif_running(usbeth->net_dev)) {
- netif_wake_queue(usbeth->net_dev);
- }
- spin_unlock(&usbeth->usb_lock);
-}
-
-static int
-ecos_usbeth_start_tx(struct sk_buff* skb, struct net_device* net)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) net->priv;
- int res;
-
- if ((skb->len + 2) > ECOS_USBETH_MAXTU) {
- printk("ecos_usbeth: oversized packet of %d bytes\n", skb->len);
- return 0;
- }
-
- if (netif_queue_stopped(net)) {
- // Another transmission already in progress.
- // USB bulk operations should complete within 5s.
- int current_delay = jiffies - net->trans_start;
- if (current_delay < (5 * HZ)) {
- return 1;
- } else {
- // There has been a timeout. Discard this message.
- //printk("transmission timed out\n");
- usbeth->stats.tx_errors++;
- dev_kfree_skb(skb);
- return 0;
- }
- }
-
- spin_lock(&usbeth->usb_lock);
- usbeth->tx_buffer[0] = skb->len & 0x00FF;
- usbeth->tx_buffer[1] = (skb->len >> 8) & 0x00FF;
- memcpy(&(usbeth->tx_buffer[2]), skb->data, skb->len);
- usbeth->tx_urb.transfer_buffer_length = skb->len + 2;
-
- // Some targets are unhappy about receiving 0-length packets, not
- // just sending them.
- if (0 == (usbeth->tx_urb.transfer_buffer_length % 64)) {
- usbeth->tx_urb.transfer_buffer_length++;
- }
-#if 0
- {
- int i;
- printk("--------------------------------------------------------------\n");
- printk("ecos_usbeth start_tx: len %d\n", skb->len + 2);
- for (i = 0; (i < (skb->len + 2)) && (i < 128); i+= 8) {
- printk("tx %x %x %x %x %x %x %x %x\n",
- usbeth->tx_buffer[i], usbeth->tx_buffer[i+1], usbeth->tx_buffer[i+2], usbeth->tx_buffer[i+3],
- usbeth->tx_buffer[i+4], usbeth->tx_buffer[i+5], usbeth->tx_buffer[i+6], usbeth->tx_buffer[i+7]);
- }
- printk("--------------------------------------------------------------\n");
- }
-#endif
- res = usb_submit_urb(&(usbeth->tx_urb));
- if (0 == res) {
- netif_stop_queue(net);
- net->trans_start = jiffies;
- usbeth->stats.tx_packets++;
- usbeth->stats.tx_bytes += skb->len;
- } else {
- printk("ecos_usbeth: failed to start USB packet transmission, %d\n", res);
- usbeth->stats.tx_errors++;
- }
-
- spin_unlock(&usbeth->usb_lock);
- dev_kfree_skb(skb);
- return 0;
-}
-
-
-// set_rx_mode()
-// Invoked by the network stack to enable/disable promiscuous mode or
-// for multicasting. The latter is not yet supported on the target
-// side. The former involves a USB control message. The main call
-// is not allowed to block.
-static void
-ecos_usbeth_set_rx_mode_callback(struct urb* urb)
-{
- kfree(urb->setup_packet);
- usb_free_urb(urb);
-}
-
-static void
-ecos_usbeth_set_rx_mode(struct net_device* net)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) net->priv;
- __u16 promiscuous = net->flags & IFF_PROMISC;
- int res;
-
- if (promiscuous != usbeth->target_promiscuous) {
- devrequest* req;
- urb_t* urb;
-
- urb = usb_alloc_urb(0);
- if ((urb_t*)0 == urb) {
- return;
- }
- req = kmalloc(sizeof(devrequest), GFP_KERNEL);
- if ((devrequest*)0 == req) {
- usb_free_urb(urb);
- return;
- }
- req->requesttype = USB_TYPE_CLASS | USB_RECIP_DEVICE;
- req->request = ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE;
- req->value = cpu_to_le16p(&promiscuous);
- req->index = 0;
- req->length = 0;
-
- FILL_CONTROL_URB(urb,
- usbeth->usb_dev,
- usb_sndctrlpipe(usbeth->usb_dev, 0),
- (unsigned char*) req,
- (void*) 0,
- 0,
- &ecos_usbeth_set_rx_mode_callback,
- (void*) usbeth);
- res = usb_submit_urb(urb);
- if (0 != res) {
- kfree(req);
- usb_free_urb(urb);
- } else {
- usbeth->target_promiscuous = promiscuous;
- }
- }
-}
-
-// netdev_stats()
-// Supply the current network statistics. These are held in
-// the stats field of the ecos_usbeth structure
-static struct net_device_stats*
-ecos_usbeth_netdev_stats(struct net_device* net)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) net->priv;
- return &(usbeth->stats);
-}
-
-// ioctl()
-// Currently none of the network ioctl()'s are supported
-static int
-ecos_usbeth_ioctl(struct net_device* net, struct ifreq* request, int command)
-{
- return -EINVAL;
-}
-
-// probe().
-// This is invoked by the generic USB code when a new device has
-// been detected and its configuration details have been extracted
-// and stored in the usbdev structure. The interface_id specifies
-// a specific USB interface, to cope with multifunction peripherals.
-//
-// FIXME; right now this code only copes with simple enumeration data.
-// OK, to be really honest it just looks for the vendor and device ids
-// in the simple test cases and ignores everything else.
-//
-// On success it should return a non-NULL pointer, which happens to be
-// a newly allocated ecos_usbeth structure. This will get passed to
-// the disconnect function. Filling in the ecos_usbeth structure will,
-// amongst other things, register this as a network device driver.
-// The MAC address is obtained from the peripheral via a control
-// request.
-
-static void*
-ecos_usbeth_probe(struct usb_device* usbdev, unsigned int interface_id)
-{
- struct net_device* net;
- ecos_usbeth* usbeth;
- int res;
- unsigned char MAC[6];
- unsigned char dummy[1];
- int tx_endpoint = -1;
- int rx_endpoint = -1;
- const ecos_usbeth_impl* impl;
- int found_impl = 0;
-
- // See if this is the correct driver for this USB peripheral.
- impl = ecos_usbeth_implementations;
- while (impl->name != NULL) {
- if ((usbdev->descriptor.idVendor != impl->vendor) ||
- (usbdev->descriptor.idProduct != impl->id)) {
- found_impl = 1;
- break;
- }
- impl++;
- }
- if (! found_impl) {
- return (void*) 0;
- }
-
- // For now only support USB-ethernet peripherals consisting of a single
- // configuration, with a single interface, with two bulk endpoints.
- if ((1 != usbdev->descriptor.bNumConfigurations) ||
- (1 != usbdev->config[0].bNumInterfaces) ||
- (2 != usbdev->config[0].interface[0].altsetting->bNumEndpoints)) {
- return (void*) 0;
- }
- if ((0 == (usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress & USB_DIR_IN)) &&
- (0 != (usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress & USB_DIR_IN))) {
- tx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress;
- rx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress & ~USB_DIR_IN;
- }
- if ((0 != (usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress & USB_DIR_IN)) &&
- (0 == (usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress & USB_DIR_IN))) {
- tx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress;
- rx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress & ~USB_DIR_IN;
- }
- if (-1 == tx_endpoint) {
- return (void*) 0;
- }
-
- res = usb_set_configuration(usbdev, usbdev->config[0].bConfigurationValue);
- if (0 != res) {
- printk("ecos_usbeth: failed to set configuration, %d\n", res);
- return (void*) 0;
- }
- res = usb_control_msg(usbdev,
- usb_rcvctrlpipe(usbdev, 0),
- ECOS_USBETH_CONTROL_GET_MAC_ADDRESS,
- USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_DIR_IN,
- 0,
- 0,
- (void*) MAC,
- 6,
- 5 * HZ);
- if (6 != res) {
- printk("ecos_usbeth: failed to get MAC address, %d\n", res);
- return (void*) 0;
- }
-
- res = usb_control_msg(usbdev,
- usb_sndctrlpipe(usbdev, 0), // pipe
- ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE, // request
- USB_TYPE_CLASS | USB_RECIP_DEVICE, // requesttype
- 0, // value
- 0, // index
- (void*) dummy, // data
- 0, // size
- 5 * HZ); // timeout
- if (0 != res) {
- printk("ecos_usbeth: failed to disable promiscous mode, %d\n", res);
- }
-
- usbeth = (ecos_usbeth*) kmalloc(sizeof(ecos_usbeth), GFP_KERNEL);
- if ((ecos_usbeth*)0 == usbeth) {
- printk("ecos_usbeth: failed to allocate memory for usbeth data structure\n");
- return (void*) 0;
- }
- memset(usbeth, 0, sizeof(ecos_usbeth));
-
- net = init_etherdev(0, 0);
- if ((struct net_device*) 0 == net) {
- kfree(usbeth);
- printk("ecos_usbeth: failed to allocate memory for net data structure\n");
- return (void*) 0;
- }
-
- usbeth->usb_lock = SPIN_LOCK_UNLOCKED;
- usbeth->usb_dev = usbdev;
- FILL_BULK_URB(&(usbeth->tx_urb), usbdev, usb_sndbulkpipe(usbdev, tx_endpoint),
- usbeth->tx_buffer, ECOS_USBETH_MAXTU, &ecos_usbeth_tx_callback, (void*) usbeth);
- FILL_BULK_URB(&(usbeth->rx_urb), usbdev, usb_rcvbulkpipe(usbdev, rx_endpoint),
- usbeth->rx_buffer, ECOS_USBETH_MAXTU, &ecos_usbeth_rx_callback, (void*) usbeth);
-
- usbeth->net_dev = net;
- usbeth->target_promiscuous = 0;
-
- net->priv = (void*) usbeth;
- net->open = &ecos_usbeth_open;
- net->stop = &ecos_usbeth_close;
- net->do_ioctl = &ecos_usbeth_ioctl;
- net->hard_start_xmit = &ecos_usbeth_start_tx;
- net->set_multicast_list = &ecos_usbeth_set_rx_mode;
- net->get_stats = &ecos_usbeth_netdev_stats;
- net->mtu = 1500; // ECOS_USBETH_MAXTU - 2;
- memcpy(net->dev_addr, MAC, 6);
-
- printk("eCos-based USB ethernet peripheral active at %s\n", net->name);
- MOD_INC_USE_COUNT;
- return (void*) usbeth;
-}
-
-// disconnect().
-// Invoked after probe() has recognized a device but that device
-// has gone away.
-static void
-ecos_usbeth_disconnect(struct usb_device* usbdev, void* data)
-{
- ecos_usbeth* usbeth = (ecos_usbeth*) data;
- if (!usbeth) {
- printk("ecos_usbeth: warning, disconnecting unconnected device\n");
- return;
- }
- if (0 != netif_running(usbeth->net_dev)) {
- ecos_usbeth_close(usbeth->net_dev);
- }
- unregister_netdev(usbeth->net_dev);
- if (-EINPROGRESS == usbeth->rx_urb.status) {
- usb_unlink_urb(&(usbeth->rx_urb));
- }
- if (-EINPROGRESS == usbeth->tx_urb.status) {
- usb_unlink_urb(&(usbeth->tx_urb));
- }
- kfree(usbeth);
- MOD_DEC_USE_COUNT;
-}
-
-static struct usb_driver ecos_usbeth_driver = {
- name: "ecos_usbeth",
- probe: ecos_usbeth_probe,
- disconnect: ecos_usbeth_disconnect,
-};
-
-// init()
-// Called when the module is loaded. It just registers the device with
-// the generic USB code. Nothing else can really be done until
-// the USB code detects that a device has been attached.
-int __init
-ecos_usbeth_init(void)
-{
- printk("eCos USB-ethernet device driver\n");
- return usb_register(&ecos_usbeth_driver);
-}
-
-// exit()
-// Called when the module is unloaded. disconnect() will be
-// invoked if appropriate.
-void __exit
-ecos_usbeth_exit(void)
-{
- usb_deregister(&ecos_usbeth_driver);
-}
-
-module_init(ecos_usbeth_init);
-module_exit(ecos_usbeth_exit);
Index: slave/v2_0/host/COPYING
===================================================================
--- slave/v2_0/host/COPYING (revision 174)
+++ slave/v2_0/host/COPYING (nonexistent)
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C) 19yy
-
- 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
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
Index: slave/v2_0/host/Makefile
===================================================================
--- slave/v2_0/host/Makefile (revision 174)
+++ slave/v2_0/host/Makefile (nonexistent)
@@ -1,95 +0,0 @@
-#
-# Makefile for the Linux device driver for eCos USB-ethernet
-# devices. This makefile has been cloned from the one in
-# /usr/src/linux-2.2.16/drivers/usb
-#
-
-# This makefile will chain to the Linux makefile if appropriate.
-# The toplevel Linux makefile sets the variable KERNELRELEASE
-ifeq (,$(KERNELRELEASE))
-
-default:
- make -C /usr/src/linux SUBDIRS=$(shell pwd) modules
-
-modules: default
-
-modules_install:
- @echo Support for installing this module not yet implemented.
-
-else
-
-# A recursive invocation of this makefile from the Linux one.
-
-# Build this driver as a module.
-CONFIG_USB_ECOS_USBETH = m
-
-# Subdirs.
-
-SUB_DIRS :=
-MOD_SUB_DIRS := $(SUB_DIRS)
-MOD_IN_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS)
-
-# The target object and module list name.
-
-O_TARGET :=
-M_OBJS :=
-O_OBJS :=
-MOD_LIST_NAME := ECOS_USBETH_MODULE
-
-# Objects that export symbols.
-
-export-objs :=
-
-# Multipart objects.
-
-list-multi :=
-
-# Optional parts of multipart objects.
-
-# Object file lists.
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-# Object files in subdirectories
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_USB_ECOS_USBETH) += ecos_usbeth.o
-
-# Extract lists of the multi-part drivers.
-# The 'int-*' lists are the intermediate files used to build the multi's.
-
-multi-y := $(filter $(list-multi), $(obj-y))
-multi-m := $(filter $(list-multi), $(obj-m))
-int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
-int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
-
-# Files that are both resident and modular: remove from modular.
-
-obj-m := $(filter-out $(obj-y), $(obj-m))
-int-m := $(filter-out $(int-y), $(int-m))
-
-# Take multi-part drivers out of obj-y and put components in.
-
-obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)
-
-# Translate to Rules.make lists.
-
-O_OBJS := $(sort $(filter-out $(export-objs), $(obj-y)))
-OX_OBJS := $(sort $(filter $(export-objs), $(obj-y)))
-M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
-MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m)))
-MIX_OBJS := $(sort $(filter $(export-objs), $(int-m)))
-
-# The global Rules.make.
-
-include $(TOPDIR)/Rules.make
-
-# Link rules for multi-part drivers.
-
-endif