public inbox for ecos-patches@sourceware.org
 help / color / mirror / Atom feed
* USB serial package
@ 2008-07-12 10:50 Andrew Lunn
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Lunn @ 2008-07-12 10:50 UTC (permalink / raw)
  To: pagliughi; +Cc: eCos Patches

Hi Frank

A while ago you contributed the USB Serial package.

I just committed this. I moved a few things around a bit, mostly the
examples which i turned into tests so that the normal test framework
would build them for you, when configured.

I also added some documentation, in SGML. It would be great if you
looked over it and let me know if there are any errors. Now that you
have a framework i think it should also be possible for you to extend
the documentation. SGML is not that bad to understand when you have
some examples to crib from. The html form of the documentation is only
in the docs-latest section.

I've not yet looked at getting the Linux driver to compile with
2.6.26. If it continues raining tomorrow like today i might take a
look.

Thanks for the contribution,

       Andrew

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-18 20:19         ` Andrew Lunn
@ 2008-06-18 21:11           ` Frank Pagliughi
  0 siblings, 0 replies; 11+ messages in thread
From: Frank Pagliughi @ 2008-06-18 21:11 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-patches

Andrew Lunn wrote:
>> The eCos library uses the 'usbs_enumeration_data' structure which calls  
>> out the different descriptor types, but makes no provision for class  
>> descriptors that I could find. Maybe we could add something to the  
>> structure? Like a catch-all void/byte pointer and length?  Could it be  
>> done without breaking the existing code?
>>     
>
> Do these class descriptors have a well defined structure? It would be
> better to define a class structure which is then added to the
> usbs_enumeration_data. We can define a CDL interface which is used to
> enable this structure and the necessary code in
> usbs_handle_standard_control() to return it to the host. Class drivers
> which need to use it then implement the CDL structure.
>
>   
For this specific (communications) class there are several little 
"functional" descriptors, each a few bytes long. They each follow the 
usual descriptor convention where the first byte is the length, the 
second byte is the descriptor type, and the third is the descriptor 
subtype. After that the remaining bytes are defined by the type/subtype.

For each different one, the class code/driver/package can create a C 
struct to declare and define them.

The problem is that for even this one class, I count 18 different 
functional descriptors!  The "Header Functional Descriptor", the "Call 
Management Functional Descriptor", the "Abstract Control Management 
Functional Descriptor", and so on.  The class has several subclasses - 
for serial ports, modems, telephones, ISDN devices, etc - so the 
possible combinations could add up.

For this specific driver we need one or two.

So, I'm not sure the best way to proceed.


Frank

P.S. This info is all in the "USB Serial Bus Class Definitions for 
Communications Devices" spec which you can download from the developer's 
section of www.usb.org.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-18 20:00       ` Frank Pagliughi
@ 2008-06-18 20:19         ` Andrew Lunn
  2008-06-18 21:11           ` Frank Pagliughi
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Lunn @ 2008-06-18 20:19 UTC (permalink / raw)
  To: Frank Pagliughi; +Cc: ecos-patches

> The eCos library uses the 'usbs_enumeration_data' structure which calls  
> out the different descriptor types, but makes no provision for class  
> descriptors that I could find. Maybe we could add something to the  
> structure? Like a catch-all void/byte pointer and length?  Could it be  
> done without breaking the existing code?

Do these class descriptors have a well defined structure? It would be
better to define a class structure which is then added to the
usbs_enumeration_data. We can define a CDL interface which is used to
enable this structure and the necessary code in
usbs_handle_standard_control() to return it to the host. Class drivers
which need to use it then implement the CDL structure.

      Andrew

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-18 19:29     ` Andrew Lunn
@ 2008-06-18 20:00       ` Frank Pagliughi
  2008-06-18 20:19         ` Andrew Lunn
  0 siblings, 1 reply; 11+ messages in thread
From: Frank Pagliughi @ 2008-06-18 20:00 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-patches


>> I also couldn't figure out any way to add class-specific descriptors  
>> (which would make the ACM configuration usable with a Linux host). Any  
>> help here would be appreciated.
>>     
>
> Sorry, no idea. I would have to take a look at my USB book to first
> figure out the encoding.
>   
I actually hadn't seen class-specific descriptors before doing this 
package. Apparently you just jam them into the response to the request 
for the configuration descriptor along with the interface and endpoint 
descriptors, etc. Most of the USB device libraries I've used (or 
written) just place the entire response into contiguous memory in ROM or 
RAM without worrying too much about the contents.

The eCos library uses the 'usbs_enumeration_data' structure which calls 
out the different descriptor types, but makes no provision for class 
descriptors that I could find. Maybe we could add something to the 
structure? Like a catch-all void/byte pointer and length?  Could it be 
done without breaking the existing code?
>   
>> I ask because I have the start of several other classes that could be  
>> submitted (Printer, Mass Storage, & HID), and would undoubtedly be  
>> modeled after this one.
>>     
>
> Such class drivers would be great. However do you need to get the
> class specific descriptors working first?
>   
Definitely not for printer classes; I already have that working.  I 
don't think for HID classes, either. I don't remember for mass storage 
devices.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-16 15:56   ` Frank Pagliughi
@ 2008-06-18 19:29     ` Andrew Lunn
  2008-06-18 20:00       ` Frank Pagliughi
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Lunn @ 2008-06-18 19:29 UTC (permalink / raw)
  To: Frank Pagliughi; +Cc: ecos-patches

On Mon, Jun 16, 2008 at 11:56:22AM -0400, Frank Pagliughi wrote:
> Andrew Lunn wrote:
>> Hi Frank
>> Which 2.6 kernel did you test this with? I just tried my slightly out
>> of date 2.6.26-rc5 and it does not compile. Looking at
>> http://lxr.linux.no/ there has been some reworking going on in this
>> area. It might compile with 2.6.25. It would be nice to document what
>> is know to work.
>>
>>     Thanks
>>         Andrew
>>
>>   
> BTW, please let me know if you have any thoughts, ideas, or suggestions  
> on the submission.

I got it running this evening. The eCos example works great. I'm now
working on documentation, writing some sgml. I will also look at the
kernel module. I used uses module parameters when loading the
usbserial module, but a specific kernel modules might be nicer in some
situation.

> I wasn't sure which way to go on a number of items, 
> like:
>    - Should it implement an API of its own or just expose the endpoints  
> for the standard USB API.

I think your API is O.K. Another option would be to make it look like
a serial port, so that you could open it with open("/dev/ttyUSB")
etc. That adds more overhead, but would allow select() to be used
etc. But that could be layered over the top of what you provide.

>    - How best to make it device/driver independent.

You have to configure the code with the endpoints somehow. What you
have done in CDL seems good to me. I did something very similar in my
own private code.

>    - Did I leave out any configuration options that would make it more  
> useful?

I don't think so, but i've not put it to serious use. 

> I also couldn't figure out any way to add class-specific descriptors  
> (which would make the ACM configuration usable with a Linux host). Any  
> help here would be appreciated.

Sorry, no idea. I would have to take a look at my USB book to first
figure out the encoding.

> I ask because I have the start of several other classes that could be  
> submitted (Printer, Mass Storage, & HID), and would undoubtedly be  
> modeled after this one.

Such class drivers would be great. However do you need to get the
class specific descriptors working first?

Thanks for the code.

       Andrew

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-15 10:56 ` Andrew Lunn
  2008-06-16 15:08   ` Frank Pagliughi
@ 2008-06-16 15:56   ` Frank Pagliughi
  2008-06-18 19:29     ` Andrew Lunn
  1 sibling, 1 reply; 11+ messages in thread
From: Frank Pagliughi @ 2008-06-16 15:56 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-patches

Andrew Lunn wrote:
> Hi Frank
> Which 2.6 kernel did you test this with? I just tried my slightly out
> of date 2.6.26-rc5 and it does not compile. Looking at
> http://lxr.linux.no/ there has been some reworking going on in this
> area. It might compile with 2.6.25. It would be nice to document what
> is know to work.
>
>     Thanks
>         Andrew
>
>   
BTW, please let me know if you have any thoughts, ideas, or suggestions 
on the submission. I wasn't sure which way to go on a number of items, like:
    - Should it implement an API of its own or just expose the endpoints 
for the standard USB API.
    - How best to make it device/driver independent.
    - Did I leave out any configuration options that would make it more 
useful?

I also couldn't figure out any way to add class-specific descriptors 
(which would make the ACM configuration usable with a Linux host). Any 
help here would be appreciated.

I ask because I have the start of several other classes that could be 
submitted (Printer, Mass Storage, & HID), and would undoubtedly be 
modeled after this one.

- Frank



  

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-15 10:56 ` Andrew Lunn
@ 2008-06-16 15:08   ` Frank Pagliughi
  2008-06-16 15:56   ` Frank Pagliughi
  1 sibling, 0 replies; 11+ messages in thread
From: Frank Pagliughi @ 2008-06-16 15:08 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-patches

Andrew Lunn wrote:
> Hi Frank
>
>   
>> The device can work with the standard USB serial device drivers on a  
>> Windows or Linux host, so there's no need for a custom host driver.  
>> Included are a micro Linux driver which just associates a USB VID/PID to  
>> the usbserial driver, and a Windows INF file to do the same for that  
>> host. The Linux driver requires a 2.6 kernel, while the Windows INF file  
>> should work with any version since Windows 2000.
>>     
>
> Which 2.6 kernel did you test this with? I just tried my slightly out
> of date 2.6.26-rc5 and it does not compile. Looking at
> http://lxr.linux.no/ there has been some reworking going on in this
> area. It might compile with 2.6.25. It would be nice to document what
> is know to work.
>
>     Thanks
>         Andrew
>
>   
My main development machine is running Fedora 6 (2.6.18-1.2798.fc6) with 
GCC 4.1.2
I can try to compile the code with a couple different machines and 
kernels later this week. Please send the failed output of your 
compilation. That might help.

Frank

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-06  1:26 Frank Pagliughi
  2008-06-06  7:33 ` Andrew Lunn
@ 2008-06-15 10:56 ` Andrew Lunn
  2008-06-16 15:08   ` Frank Pagliughi
  2008-06-16 15:56   ` Frank Pagliughi
  1 sibling, 2 replies; 11+ messages in thread
From: Andrew Lunn @ 2008-06-15 10:56 UTC (permalink / raw)
  To: Frank Pagliughi; +Cc: ecos-patches

Hi Frank

> The device can work with the standard USB serial device drivers on a  
> Windows or Linux host, so there's no need for a custom host driver.  
> Included are a micro Linux driver which just associates a USB VID/PID to  
> the usbserial driver, and a Windows INF file to do the same for that  
> host. The Linux driver requires a 2.6 kernel, while the Windows INF file  
> should work with any version since Windows 2000.

Which 2.6 kernel did you test this with? I just tried my slightly out
of date 2.6.26-rc5 and it does not compile. Looking at
http://lxr.linux.no/ there has been some reworking going on in this
area. It might compile with 2.6.25. It would be nice to document what
is know to work.

    Thanks
        Andrew

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-06  7:33 ` Andrew Lunn
@ 2008-06-06 14:25   ` Frank Pagliughi
  0 siblings, 0 replies; 11+ messages in thread
From: Frank Pagliughi @ 2008-06-06 14:25 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-patches

Andrew Lunn wrote:
>> I tested this with the AT91SAM7S-EK board as the device target, but it  
>> should work with any USB-enabled eCos board.
>>     
>
> Hi Frank
>
> Thanks for the code. I will take a look at it over the weekend.
>
> You said in a previous email that the AT91 USB driver was broken, its
> state transition indications pass the wrong values. Do you have a fix
> for that? Does this serial driver depend on the fix?
>
>     Thanks
>         Andrew
>
>   
Hello Andrew,

The submitted USB-serial driver works works with the existing AT91 USB 
driver and will also work with a "fixed" one.  It simply looks at the 
"state" values rather than the "state change values".

Sorry I haven't gotten to the AT91 USB driver yet. The main problem with 
the state change stuff is where the "state" enumerations differ from the 
"state change" enumerations. The "state change" has things like
    USBS_STATE_CHANGE_CONFIGURED   // Same as USBS_STATE_CONFIGURED
    USBS_STATE_CHANGE_DECONFIGURED   // No direct, equivalent state

The "deconfigured" change is a convenient trigger for these types of USB 
apps and modules, but this is easy enough to work around by looking at 
the new state (and maybe the old one) in the module.

I'm working on another USB driver at the moment (Philips/NXP ISP1181), 
and it will have the same issue of state/state change, so I was looking 
at perhaps making a common solution for them - which has caused the delay.

But again, the submitted USB-serial code will work with the existing USB 
driver(s).


- Frank

P.S. I'll be working this weekend, as well, so feel free to contact me 
with any questions.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: USB serial package
  2008-06-06  1:26 Frank Pagliughi
@ 2008-06-06  7:33 ` Andrew Lunn
  2008-06-06 14:25   ` Frank Pagliughi
  2008-06-15 10:56 ` Andrew Lunn
  1 sibling, 1 reply; 11+ messages in thread
From: Andrew Lunn @ 2008-06-06  7:33 UTC (permalink / raw)
  To: Frank Pagliughi; +Cc: ecos-patches

> I tested this with the AT91SAM7S-EK board as the device target, but it  
> should work with any USB-enabled eCos board.

Hi Frank

Thanks for the code. I will take a look at it over the weekend.

You said in a previous email that the AT91 USB driver was broken, its
state transition indications pass the wrong values. Do you have a fix
for that? Does this serial driver depend on the fix?

    Thanks
        Andrew

^ permalink raw reply	[flat|nested] 11+ messages in thread

* USB serial package
@ 2008-06-06  1:26 Frank Pagliughi
  2008-06-06  7:33 ` Andrew Lunn
  2008-06-15 10:56 ` Andrew Lunn
  0 siblings, 2 replies; 11+ messages in thread
From: Frank Pagliughi @ 2008-06-06  1:26 UTC (permalink / raw)
  To: ecos-patches

[-- Attachment #1: Type: text/plain, Size: 2943 bytes --]

This attachment contains a slave package for USB-serial devices for 
eCos. It's the first of a couple device-side class modules that I hope 
to submit in the next few months.

This package is for USB devices that mimic a serial port connection to 
the host. The enclosed module provides the USB descriptors and callbacks 
necessary to handle the enumeration with the host and also provides a 
simple API for the device. Note, however the resulting device mimics a 
serial connection on the host side, but the device sees the connection 
as a normal USB connection with two bulk endpoints - an IN and an OUT.  
The eCos application can be programmed using the provided 
"usbs_serial_xxx" API, the standard eCos USB API, Unix-like File I/O, or 
C stdio.

The module can be used as a simple way for a USB device to communicate 
with a Windows or Linux host without the need for custom host device 
drivers, and without the limitations (and annoyance) of creating a HID 
device. It presents a pair of Bulk endpoints for host communications, 
and the actual data is free-form, just like any serial connection.  This 
can also be used as the basis for a real USB modem or a USB-serial 
converter.

The device can work with the standard USB serial device drivers on a 
Windows or Linux host, so there's no need for a custom host driver. 
Included are a micro Linux driver which just associates a USB VID/PID to 
the usbserial driver, and a Windows INF file to do the same for that 
host. The Linux driver requires a 2.6 kernel, while the Windows INF file 
should work with any version since Windows 2000.

The slave device can be configured as an ACM communications device or a 
'generic' device. A windows host requires an ACM device. A Linux host 
should also work with ACM devices, but the latest kernels are picky 
about requiring class-specific descriptors. I couldn't figure out how to 
add class descriptors to the configuration descriptors using the 
existing eCos USB API.

But, the generic configuration works well with Linux, and is probably 
preferable anyway. For Linux hosts, 'make' the driver, then:
    # modprobe usbserial
    # insmod ./ecos_usbserial.ko
then plug in the device. It should be recognized and assigned a tty 
device, like '/dev/ttyUSB0'

For windows, copy the INF file and the 'usbser.sys' driver from your 
version of Windows into a directory, plug in the device, and when 
prompted, navigate to the INF file.

In all cases, the eCos library module must be configured with a real 
Vendor ID and Product ID, and the Linux driver and INF file must be 
updated with those matching values.

I tested this with the AT91SAM7S-EK board as the device target, but it 
should work with any USB-enabled eCos board.

Sorry, I don't know how to write eCos documentation, so I added some 
example applications instead. Let me know if there's an easy way I can 
document this better.

Frank Pagliughi
President,
SoRo Systems, Inc.

[-- Attachment #2: ecos-usbserial.patch --]
[-- Type: text/x-patch, Size: 59980 bytes --]

diff -urN --exclude=.svn ecos/packages/ecos.db usbserial/packages/ecos.db
--- ecos/packages/ecos.db	2008-01-06 09:19:30.000000000 -0500
+++ usbserial/packages/ecos.db	2008-06-03 01:41:26.000000000 -0400
@@ -1409,6 +1409,14 @@
         description     "Support for USB peripherals that provide an ethernet-class function"
 }
 
+package CYGPKG_IO_USB_SLAVE_SERIAL {
+        alias		{ "USB slave-side serial drivers" usbs_serial }
+        directory       io/usb/serial/slave
+        script          usbs_serial.cdl
+        description     "Support for USB peripherals that present themselves as serial 
+                        devices to the host."
+}
+
 package CYGPKG_DEVS_USB_SA11X0 {
         alias           { "Device-driver for the SA11X0 on-chip USB support" usb_sa11x0 }
         hardware
@@ -4534,6 +4542,8 @@
                    CYGPKG_DEVS_FLASH_AT91
                    CYGPKG_DEVS_SPI_ARM_AT91
                    CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC
+                   CYGPKG_IO_USB
+                   CYGPKG_IO_USB_SLAVE
                    CYGPKG_DEVS_USB_AT91
         }
         description "
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/cdl/usbs_serial.cdl usbserial/packages/io/usb/serial/slave/current/cdl/usbs_serial.cdl
--- ecos/packages/io/usb/serial/slave/current/cdl/usbs_serial.cdl	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/cdl/usbs_serial.cdl	2008-06-05 12:18:17.000000000 -0400
@@ -0,0 +1,229 @@
+# ====================================================================
+#
+#      usbs_serial.cdl
+#
+#      USB slave-side serial package.
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+##
+## 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.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+# Contributors:
+# Date:           2008-06-04
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_IO_USB_SLAVE_SERIAL {
+    display     "USB slave serial support"
+    include_dir "cyg/io/usb"
+    parent      CYGPKG_IO_USB_SLAVE
+    requires    { CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS >= 1 }
+    requires    { CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS >= 1 }
+    compile     usbs_serial.c
+    implements  CYGINT_IO_USB_SLAVE_CLIENTS
+    doc         ref/io-usb-slave-eth.html
+    
+    description "
+        The USB slave serial package supports the development
+        of USB peripherals which mimic a serial connection to 
+        the host machine. Such a device creates a relatively
+        simple upgrade to USB from a legacy serial connection,
+        especially from the perspective of the host software and
+        device drivers."
+
+    cdl_option CYGDAT_IO_USB_SLAVE_CLASS_TYPE {
+        display         "Serial USB Class"
+        flavor          data
+        default_value   { "ACM" }
+        legal_values    { "ACM" "generic" }
+        description     "
+            The USB serial module can enumerate as either a generic 
+            (vendor-specific) usb device or a communications class ACM
+            device. The generic device requires a pair of Bulk endpoints,
+            while the ACM device also requires an Interupt IN endpoint.
+            For a Windows host, the ACM configuration is required to use 
+            the syandard 'usbser.sys' device driver, but for a Linux 
+            host, the generic configurarion works, and saves the additional
+            endpoint."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_EP0 {
+        display       "Name of EP0 structure"
+        flavor        data               
+        default_value { "usbs_at91_ep0" }
+        description   "
+            The name of the variable that contains the endpoint 0 structure.
+            This should be set to the EP0 structure for the desired USB device driver
+            such as usbs_at91_ep0, usbs_sa11x0_ep0, etc"
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_EP0_MAX_PACKET_SIZE {
+        display       "The size of EP0"
+        flavor        data
+        default_value 8
+        legal_values  { 8 16 64 } 
+        description   "
+            The size of the EP0 hardware buffer on the specific USB chip used."
+    } 
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM {
+        display       "Tx (USB IN) endpoint number"
+        flavor        data
+        default_value 1
+        description   "
+            The endpoint that should be used for the device-side transmitter, which
+            is the USB IN direction."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP {
+        display         "The Tx (USB IN) endpoint structure"
+         flavor         data               
+         default_value  { "usbs_at91_ep1" }
+         description    "
+             The endpoint structure that corresponds to the selected Tx endpoint
+             number. This is dependent on the USBS device driver selected, and 
+             could be usbs_at91_ep1, usbs_sa11x0_ep1, etc"
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM {
+        display         "Rx (USB OUT) endpoint number"
+        flavor          data
+        default_value   2
+        description     "
+            The endpoint that should be used for the device-side receiver, which
+            is the USB OUT direction."
+    } 
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP {
+        display         "The Rx (USB OUT) endpoint structure"
+         flavor         data               
+         default_value  { "usbs_at91_ep2" }
+         description    "
+             The endpoint structure that corresponds to the selected Rx endpoint
+             number. This is dependent on the USBS device driver selected, and 
+             could be usbs_at91_ep1, usbs_sa11x0_ep1, etc"
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM {
+        display         "Interrupt IN endpoint number"
+        flavor          data
+        default_value   3
+        active_if       { CYGDAT_IO_USB_SLAVE_CLASS_TYPE == "ACM" }
+        description     "
+            The endpoint that should be used for the ACM Interrupt IN"
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_INTR_EP {
+        display         "Interrupt IN endpoint structure"
+         flavor         data               
+         default_value  { "usbs_at91_ep3" }
+         active_if      { CYGDAT_IO_USB_SLAVE_CLASS_TYPE == "ACM" }
+         description    "
+             The endpoint structure that corresponds to the selected ACM
+             Interrupt IN endpoint."
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID {
+        display       "USB Forum Vendor ID"
+        flavor        data
+        default_value 0xFFFF
+        legal_values  1 to 0xFFFF
+        description   "
+            Each USB vendor has an Vendor ID allocated to it by the USB-IF organization.
+            Any arbitrary value can be selected for testing provided that it doesn't 
+            conflict with devices on the development host, but a device should NEVER be
+            released publicly without a valid Vendor ID"
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID {
+        display       "USB product ID"
+        flavor        data
+        default_value 1
+        legal_values  1 to 0xFFFF
+        description   "
+            You are free to select an arbitrary 16-bit Product ID for a device. The combination
+            of Vendor ID and Product ID uniquely identified a USB device."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_MFG_STR {
+        display       "The Device Vendor's Name (Manufacturer String)"
+        flavor        data
+        default_value { "\"eCos\"" }
+        description "
+                The standard USB enumeration allows for a manufacturer's name which is
+                normally reported to the user when the device is first plugged into
+                the host."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR {
+        display       "The Device Product Name"
+        flavor        data
+        default_value { "\"eCos USB Serial Device\"" }
+        description "
+                The standard USB enumeration allows for a product name which is
+                normally reported to the user when the device is first plugged into
+                the host."
+    }
+
+    cdl_option  CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG {
+        display       "Enable debug output from the driver"
+        default_value 0
+        flavor        bool
+        description   "
+            The driver may produce debug output which can be
+            useful to work out why it is not working as expected."
+    }
+    cdl_component CYGPKG_IO_USB_SLAVE_SERIAL_OPTIONS {
+    display     "Build options"
+    flavor      none
+
+    description "
+        Package-specific build options including control over compiler
+        flags used only in building this package."
+
+    cdl_option CYGPKG_IO_USB_SLAVE_SERIAL_CFLAGS_ADD {
+            display "Additional compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building this package. These flags are used in addition
+                to the set of global flags."
+    }
+        cdl_option CYGPKG_IO_USB_RUP_CFLAGS_REMOVE {
+            display "Suppressed compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building this package. These flags are removed from
+                the set of global flags if present."
+        }
+    }
+    cdl_option  CYGPKG_IO_USB_SLAVE_SERIAL_TESTS {
+        display       "Tests"
+        flavor        data
+        default_value { "tests/usb/serial" }
+    }
+}
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/examples/Makefile usbserial/packages/io/usb/serial/slave/current/examples/Makefile
--- ecos/packages/io/usb/serial/slave/current/examples/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/examples/Makefile	2008-06-05 11:09:57.000000000 -0400
@@ -0,0 +1,49 @@
+# Mostly written by Jonathan Larmour, Red Hat, Inc.
+# Reference to ecos.mak added by John Dallaway, eCosCentric Limited, 2003-01-20
+# This file is in the public domain and may be used for any purpose
+
+# Usage:   make INSTALL_DIR=/path/to/ecos/install
+
+INSTALL_DIR=$$(INSTALL_DIR) # override on make command line
+
+include $(INSTALL_DIR)/include/pkgconf/ecos.mak
+
+XCC           = $(ECOS_COMMAND_PREFIX)gcc
+XCXX          = $(XCC)
+XLD           = $(XCC)
+
+CFLAGS        = -I$(INSTALL_DIR)/include
+CXXFLAGS      = $(CFLAGS)
+LDFLAGS       = -nostartfiles -L$(INSTALL_DIR)/lib -Ttarget.ld
+
+# RULES
+
+.PHONY: all clean
+
+all: usbserial_echo usb2serial
+
+clean:
+	-rm -f usbserial_echo usb2serial
+	-rm -f usbserial_echo.o usb2serial.o
+
+%.o: %.c
+	$(XCC) -c -o $*.o $(CFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
+
+%.o: %.cpp
+	$(XCXX) -c -o $*.o $(CXXFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
+
+%.o: %.cxx
+	$(XCXX) -c -o $*.o $(CXXFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
+
+%.o: %.C
+	$(XCXX) -c -o $*.o $(CXXFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
+
+%.o: %.cc
+	$(XCXX) -c -o $*.o $(CXXFLAGS) $(ECOS_GLOBAL_CFLAGS) $<
+
+usbserial_echo: usbserial_echo.o
+	$(XLD) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o $@ $@.o
+
+usb2serial: usb2serial.o
+	$(XLD) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o $@ $@.o
+
Binary files ecos/packages/io/usb/serial/slave/current/examples/usb2serial.bin and usbserial/packages/io/usb/serial/slave/current/examples/usb2serial.bin differ
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/examples/usb2serial.c usbserial/packages/io/usb/serial/slave/current/examples/usb2serial.c
--- ecos/packages/io/usb/serial/slave/current/examples/usb2serial.c	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/examples/usb2serial.c	2008-06-05 20:05:19.000000000 -0400
@@ -0,0 +1,358 @@
+//==========================================================================
+//
+//      usb2serial.c
+//
+//      Example application for the USB serial layer in eCos.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Contributors: 
+// Date:         2008-06-02
+// Description:  USB serial example application.
+//
+//####DESCRIPTIONEND####
+//===========================================================================
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/kernel.h>
+#include <cyg/io/serialio.h>
+
+// Replace this with any other USB driver desired.
+#include <cyg/io/usb/usbs_at91.h>
+#include <cyg/io/usb/usbs_serial.h>
+#include <pkgconf/io_usb_slave_serial.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+// This application creates a USB-serial converter. To the host it will appear
+// as a single serial USB port, such as /dev/ttyUSB0 for a Linux host.
+// Any characters recieved from the USB host will be sent out the serial port
+// and visa-versa. It creates a separate, dedicated thread for each direction.
+// 
+// It uses the eCos USB-serial layer to enumerate with the USB host and monitor
+// the connection, but then uses standard C I/O functions to perform the 
+// communications.
+// 
+// The USB serial module can be configured as a generic adapter or an an ACM
+// communications class device. For the latter, the application handles the
+// USB communactions class requests which allows it to recieve requests from
+// the host to set serial parameters, like the baud rate. This actually turns
+// this example into a more realistic USB-serial adapter that can be configured
+// dynamically by the host.
+// 
+// The eCos library must be configured with the packages for USB slave, USB 
+// serial, and File I/O. It also requires the proper serial port driver for the
+// target platform.
+// 
+// This example was tested with the AT91SAM7S-EK board, but should work with any
+// board that has a USB slave and serial port, and the necessary drivers.
+
+
+// Comment this line out to remove debug output.
+#define DEBUG_OUTPUT
+
+#if defined(DEBUG_OUTPUT)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+// Set these to the USB devtab entries for the Tx and Rx Bulk endpoints 
+// selected in the configuration of the USB serial subsystem.
+#define USB_TX_DEV  "/dev/usbs1"
+#define USB_RX_DEV  "/dev/usbs2"
+
+// Set this for any available serial port on the target.
+#define SER_DEV     "/dev/ser0"
+
+// Buffer for incoming USB bulk data. The local USB driver can probably split
+// packets, but just in case, making this the page size of the host might be
+// helpful.
+#define BUF_SIZE 4096
+static char usb2ser_buf[BUF_SIZE];
+
+// The threads
+cyg_thread thread[2];
+
+// Space for two 4K stacks
+#define THREAD_STACK_SIZE 4096
+char stack[2][THREAD_STACK_SIZE];
+
+// The handles for the threads
+cyg_handle_t    usb2ser_thread, 
+                ser2usb_thread;
+
+// --------------------------------------------------------------------------
+// For an ACM serial device we can handle the USB class messages to deal with
+// requests from the host like setting the serial parameters (baud rate, 
+// etc).
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+static cyg_uint8    acm_buf[32];
+static cyg_uint32   baud = 34800;
+
+// --------------------------------------------------------------------------
+// Handler for the completion of a SetLineCoding request from the host.
+// The 'acm_buf' should contain the 7-byte request OUT packet from the
+// host. This contains a request to change the serial parameters.
+// In this example function, we will accept a few different baud rates.
+// To keep the example relatively simple, though, we keep the other serial
+// parameters to 1 stop bit, no parity, 8 data bits.
+
+static usbs_control_return
+acm_set_line_coding(usbs_control_endpoint* ep0, int n)
+{
+    int err;
+    cyg_uint32 req_baud;
+    cyg_io_handle_t handle;
+
+    // Get the requested baud rate from the received ctrl OUT packet
+    req_baud = (acm_buf[3] << 24) | (acm_buf[2] << 16) | 
+                (acm_buf[1] << 8) | acm_buf[0];
+
+    DBG("Set Baud: %u\n", (unsigned) baud);
+
+    // Look up the serial handle and attempt to set the baud rate.
+    if (cyg_io_lookup(SER_DEV, &handle) == 0) {
+        cyg_serial_info_t ser_info;
+        cyg_uint32 len = sizeof(ser_info);
+
+        switch (baud) {
+            case   9600 : ser_info.baud = CYGNUM_SERIAL_BAUD_9600;      break;
+            case  38400 : ser_info.baud = CYGNUM_SERIAL_BAUD_38400;     break;
+            case 115200 : ser_info.baud = CYGNUM_SERIAL_BAUD_115200;    break;
+            default:
+                DBG("Unsupported baud rate\n");
+                return USBS_CONTROL_RETURN_HANDLED;
+        }
+        ser_info.stop = CYGNUM_SERIAL_STOP_1;
+        ser_info.parity = CYGNUM_SERIAL_PARITY_NONE;
+        ser_info.word_length = CYGNUM_SERIAL_WORD_LENGTH_8;
+        ser_info.flags = 0;
+
+        err = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, 
+                                &ser_info, &len);
+        if (err == 0)
+            baud = req_baud;
+        else {
+            DBG("Error setting serial params\n");
+        }
+    }
+    else {
+        DBG("Error looking up serial device: %s\n", SER_DEV);
+    }
+    return USBS_CONTROL_RETURN_HANDLED;
+}
+
+// --------------------------------------------------------------------------
+// Handler for the ACM class messages.
+// 
+static usbs_control_return 
+acm_class_handler(usbs_control_endpoint* ep0, void* data)
+{
+    usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+    usb_devreq  *req = (usb_devreq *) ep0->control_buffer;
+
+    static cyg_uint8 rsp_buf[32];
+
+    DBG("ACM Class Handler\n");
+
+    switch (req->request) {
+
+        case USBS_SERIAL_SET_LINE_CODING :
+                DBG("Set Line Coding\n");
+                memset(acm_buf, 0, 32);
+                ep0->buffer = acm_buf;
+                ep0->buffer_size = 7;
+                ep0->complete_fn = acm_set_line_coding;
+                result = USBS_CONTROL_RETURN_HANDLED;
+                break;
+
+        case USBS_SERIAL_GET_LINE_CODING :
+                DBG("Get Line Coding\n");
+                rsp_buf[0] = baud & 0xFF;
+                rsp_buf[1] = (baud >>  8) & 0xFF;
+                rsp_buf[2] = (baud >> 16) & 0xFF;
+                rsp_buf[3] = (baud >> 24) & 0xFF;
+                rsp_buf[4] = 0; // One stop bit
+                rsp_buf[5] = 0; // No parity
+                rsp_buf[6] = 8; // 8 data bits
+                ep0->buffer = rsp_buf;
+                ep0->buffer_size = 7;
+                result = USBS_CONTROL_RETURN_HANDLED;
+                break;
+
+        default :
+                DBG("*** Unhandled ACM Request: 0x%02X ***\n",
+                    (unsigned) req->request);
+    }
+
+    return result;
+}
+
+#endif      // CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+// --------------------------------------------------------------------------
+// Thread recieves packets from the USB and sends them out the serial port
+// It uses a buffered stdio input, an un-buffered low-level file output.
+// This isn't terribly efficient, but rather an example of both methods.
+
+void usb2ser_func(cyg_addrword_t data)
+{
+    int  c;
+    FILE *rxf = fopen(USB_RX_DEV, "r");
+    int   txh = open(SER_DEV, O_WRONLY, 0);
+
+    DBG("Usb2Ser: Thread starting\n");
+
+    if (!rxf) {
+        DBG("Error opening USB rx port\n");
+        return;
+    }
+
+    if (txh < 0) {
+        DBG("Error opening serial tx port\n");
+        return;
+    }
+
+    // Give the USB receiver an adequate buffer.
+    setvbuf(rxf, usb2ser_buf, _IOFBF, BUF_SIZE);
+
+    while (1) {
+
+        // ----- Wait for the host to configure -----
+
+        DBG("Usb2Ser: Waiting for USB configuration\n");
+        usbs_serial_wait_until_configured();
+        cyg_thread_delay((cyg_tick_count_t) 10);
+
+        // ----- While configured read data & send out serial port -----
+
+        DBG("Usb2Ser: USB configured\n");
+        while (usbs_serial_is_configured()) {
+            if ((c = getc(rxf)) < 0) {
+                DBG("*** USB Read Error: %d ***\n", c);
+            }
+            else {
+                char ch = (char) c;
+                write(txh, &ch, 1);
+            }
+        }
+    }
+}
+
+// --------------------------------------------------------------------------
+// Thread recieves packets from the serial port and sends them out the USB
+// It uses a buffered stdio input, an un-buffered low-level file output.
+// This isn't terribly efficient, but rather an example of both methods.
+
+void ser2usb_func(cyg_addrword_t data)
+{
+    int  c;
+    FILE *rxf = fopen(SER_DEV, "r");
+    int  txh = open(USB_TX_DEV, O_WRONLY, 0);
+
+    DBG("Ser2Usb: Thread starting\n");
+
+    if (!rxf) {
+        DBG("Error opening serial rx port\n");
+        return;
+    }
+
+    if (txh < 0) {
+        DBG("Error opening USB tx port\n");
+        return;
+    }
+
+    while (1) {
+
+        // ----- Wait for the host to configure -----
+
+        DBG("Ser2Usb: Waiting for USB configuration\n");
+        usbs_serial_wait_until_configured();
+        cyg_thread_delay((cyg_tick_count_t) 10);
+
+        // ----- While configured read data & send out serial port -----
+
+        DBG("Ser2Usb: USB configured\n");
+        while (usbs_serial_is_configured()) {
+            if ((c = getc(rxf)) < 0) {
+                DBG("*** Console Read Error: %d ***\n", c);
+            }
+            else {
+                char ch = (char) c;
+                write(txh, &ch, 1);
+            }
+        }
+    }
+}
+
+// --------------------------------------------------------------------------
+//  Application Startup
+// --------------------------------------------------------------------------
+
+void cyg_user_start(void)
+{
+    DBG("Entering cyg_user_start() function\n");
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    // Override the class handler to use ours.
+    usbs_serial_ep0->class_control_fn = acm_class_handler;
+#endif
+
+    cyg_thread_create(4, usb2ser_func, (cyg_addrword_t) 0,
+                      "Usb2Serial", (void *) stack[0], THREAD_STACK_SIZE,
+                      &usb2ser_thread, &thread[0]);
+
+    cyg_thread_create(4, ser2usb_func, (cyg_addrword_t) 1,
+                      "Serial2Usb", (void *) stack[1], THREAD_STACK_SIZE,
+                      &ser2usb_thread, &thread[1]);
+
+    // Start USB subsystem
+    usbs_serial_start();
+
+    // Start the threads running.
+    cyg_thread_resume(usb2ser_thread);
+    cyg_thread_resume(ser2usb_thread);
+}
+
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/examples/usbserial_echo.c usbserial/packages/io/usb/serial/slave/current/examples/usbserial_echo.c
--- ecos/packages/io/usb/serial/slave/current/examples/usbserial_echo.c	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/examples/usbserial_echo.c	2008-06-05 12:29:38.000000000 -0400
@@ -0,0 +1,94 @@
+// usb_serial_echo.cpp
+// 
+// Device-side program to make a USB slave appear like a serial port
+// that echoes characters sent to it back to the host.
+//
+// AUTHOR:
+//		Frank Pagliughi
+//
+//		SoRo Systems, Inc.
+//		www.sorosys.com
+//
+// DATE:
+//		May 2008
+//
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/kernel.h>
+#include <cyg/io/usb/usbs_at91.h>
+#include <cyg/io/usb/usbs_serial.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEBUG_OUTPUT
+
+#if defined(DEBUG_OUTPUT)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+typedef unsigned char byte;
+
+// --------------------------------------------------------------------------
+//								Data & Callback(s)
+// --------------------------------------------------------------------------
+
+#define BUF_SIZE	4096
+
+static byte	rx_buf[2][BUF_SIZE],
+			tx_buf[BUF_SIZE];
+
+// --------------------------------------------------------------------------
+//								Main Routine
+// --------------------------------------------------------------------------
+
+int main(void)
+{
+	int			n;
+	unsigned	ibuf,
+				next_buf;
+
+	// ----- Start USB subsystem -----
+
+	usbs_serial_start();
+
+ 	// ----- Get data from host and send it back -----
+
+	while (1) {
+		ibuf = 0;
+
+		// ----- Wait for the host to configure -----
+
+		usbs_serial_wait_until_configured();
+		cyg_thread_delay((cyg_tick_count_t) 10);
+
+		// ----- While configured read data & print to screen -----
+
+		usbs_serial_start_rx(&usbs_ser0, rx_buf[ibuf], BUF_SIZE);
+
+		while (usbs_serial_is_configured()) {
+
+			n = usbs_serial_wait_for_rx(&usbs_ser0);
+			next_buf = ibuf ^ 1;
+
+			usbs_serial_start_rx(&usbs_ser0, rx_buf[next_buf], BUF_SIZE);
+
+			if (n < 0) {
+				DBG("*** I/O Error: %d ***\n", n);
+			}
+			else {
+				memcpy(tx_buf, rx_buf[ibuf], n);
+				usbs_serial_tx(&usbs_ser0, tx_buf, n);
+			}
+
+			ibuf = next_buf;
+		}
+	}
+
+	return 0;
+}
+
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/host/linux/ecos_usbserial.c usbserial/packages/io/usb/serial/slave/current/host/linux/ecos_usbserial.c
--- ecos/packages/io/usb/serial/slave/current/host/linux/ecos_usbserial.c	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/host/linux/ecos_usbserial.c	2008-06-03 01:39:37.000000000 -0400
@@ -0,0 +1,66 @@
+// ecos_usbserial.c
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+#define VENDOR_ID	0xFFFF
+#define PRODUCT_ID	1
+
+static struct usb_device_id id_table[] = {
+	{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver ecos_usbserial_driver = {
+	.name	 	= "ecos_usbserial",
+	.probe		= usb_serial_probe,
+	.disconnect	= usb_serial_disconnect,
+	.id_table	= id_table
+};
+
+static struct usb_serial_driver ecos_usbserial_device = {
+	.driver = {
+		.owner			= THIS_MODULE,
+		.name			= "ecos_usbserial",
+	},
+	.id_table			= id_table, 
+	.num_interrupt_in	= NUM_DONT_CARE,
+	.num_bulk_in		= NUM_DONT_CARE,
+	.num_bulk_out		= NUM_DONT_CARE,
+	.num_ports			= 1
+};
+
+static int __init ecos_usbserial_init(void)
+{
+	int retval;
+
+	retval = usb_serial_register(&ecos_usbserial_device);
+	if (retval)
+		return retval;
+
+	retval = usb_register(&ecos_usbserial_driver);
+	if (retval) {
+		usb_serial_deregister(&ecos_usbserial_device);
+		return retval;
+	}
+
+	return 0;
+}
+
+static void __exit ecos_usbserial_exit(void)
+{
+	usb_deregister(&ecos_usbserial_driver);
+	usb_serial_deregister(&ecos_usbserial_device);
+}
+
+module_init(ecos_usbserial_init);
+module_exit(ecos_usbserial_exit);
+
+MODULE_LICENSE("GPL");
+
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/host/linux/Makefile usbserial/packages/io/usb/serial/slave/current/host/linux/Makefile
--- ecos/packages/io/usb/serial/slave/current/host/linux/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/host/linux/Makefile	2008-06-03 01:39:37.000000000 -0400
@@ -0,0 +1,11 @@
+# Makefile for ecos_usbserial Linux kernel module
+
+ifneq ($(KERNELRELEASE),)
+	obj-m := ecos_usbserial.o
+else
+	KDIR ?= /lib/modules/$(shell uname -r)/build
+	PWD := $(shell pwd)
+default:
+	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+endif
+
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/host/windows/eCosUsbSerial.inf usbserial/packages/io/usb/serial/slave/current/host/windows/eCosUsbSerial.inf
--- ecos/packages/io/usb/serial/slave/current/host/windows/eCosUsbSerial.inf	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/host/windows/eCosUsbSerial.inf	2008-06-05 11:09:57.000000000 -0400
@@ -0,0 +1,49 @@
+; eCos USB Serial INF file for Windows
+; This can be used for any USB device that emulates a serial port connection.
+; Simply set the VID & PID numbers in this file to the proper values for the
+; device, copy this file and the 'usbser.sys' file from your version of Windows
+; into the same directory, and load these when prompted by the Windows device
+; manager.
+
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=eCosUsbSerial
+DriverVer=06/02/2008,0.0.0.1
+
+[DestinationDirs]
+DefaultDestDir=12	; %windir$\System32\drivers
+
+[Manufacturer]
+eCosUsbSerial=eCosDevices
+
+[eCosDevices]
+"eCosUsbSerial"=InstalleCosUsbSerial,USB\VID_FFFF&PID_0001
+
+[InstalleCosUsbSerial]
+CopyFiles=CopyeCosUsbFiles
+AddReg=eCosUsbReg
+
+[CopyeCosUsbFiles]
+usbser.sys			; The standard Windows USB serial driver
+
+[eCosUsbReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[InstalleCosUsbSerial.Services]
+AddService = usbser,2,eCosUsbSerialService
+
+[eCosUsbSerialService]
+DisplayName = ECOS_USB_SERIAL_NAME
+ServiceType = 1				; driver
+StartType = 3				; on-demand or manual
+ErrorControl = 1			; report errors
+ServiceBinary = %12%\usbser.sys		; Driver path: %windir%\System32\drivers
+LoadOrderGroup = Base
+
+[Strings]
+ECOS_USB_SERIAL_NAME = "eCos USB Serial Driver"
+
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/include/usbs_serial.h usbserial/packages/io/usb/serial/slave/current/include/usbs_serial.h
--- ecos/packages/io/usb/serial/slave/current/include/usbs_serial.h	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/include/usbs_serial.h	2008-06-05 17:57:43.000000000 -0400
@@ -0,0 +1,184 @@
+#ifndef CYGONCE_USBS_SERIAL_H
+#define CYGONCE_USBS_SERIAL_H
+//==========================================================================
+//
+//      include/usbs_serial.h
+//
+//      Description of the USB slave-side serial device support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Contributors: 
+// Date:         2008-06-02
+// Purpose:
+// Description:  USB slave-side serial support
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+//
+// The primary purpose of the USB slave-side serial code is to provide a 
+// simple USB connection to the host, especially for embedded systems that
+// are upgrading from RS-232 serial connections. The host would see the 
+// device as if through a serial port, and thus the host software would
+// remain unchanged. It would also eliminate the need for a new device
+// driver on the host.
+// 
+// On this side (the eCos USB slave side), the application sees the host
+// through a normal USB slave connection with two Bulk endpoints - one in 
+// the IN direction and one in the OUT direction. This module provides the
+// necessary USB descriptors to enumerate the device for a single serial
+// port, but then the application is free to communicate with the host
+// using any desired API:
+//  - The standard eCos USB slave API
+//  - The low-level File I/O layer (if USB devtab entries configured)
+//  - The C stdio functions (again, if USB devtab entries configured)
+//  - The USB serial API defined here.
+// 
+// The USB serial API is a thin layer over the standard eCos USB functions
+// to provide common synchronous and asynchronous transfers over the assigned
+// Bulk endpoints.
+//
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/usb/usbs.h>
+
+// ----------------------------------------------------------------------------
+// The ACM class requests
+// 
+
+#define USBS_SERIAL_SEND_ENCAPSULATED_COMMAND   0x00
+#define USBS_SERIAL_GET_ENCAPSULATED_RESPONSE   0x01
+#define USBS_SERIAL_SET_COMM_FEATURE            0x02
+#define USBS_SERIAL_GET_COMM_FEATURE            0x03
+#define USBS_SERIAL_CLEAR_COMM_FEATURE          0x04
+
+#define USBS_SERIAL_SET_LINE_CODING             0x20
+#define USBS_SERIAL_GET_LINE_CODING             0x21
+#define USBS_SERIAL_SET_CONTROL_LINE_STATE      0x22
+#define USBS_SERIAL_SEND_BREAK                  0x23
+
+// ----------------------------------------------------------------------------
+// Data structure to manage the pair of USB endpoints that comprise a single
+// serial port connection. Each "port" requires one Bulk IN endpoint and one
+// Bulk OUT endpoint.
+
+typedef struct usbs_serial {
+    // The communication endpoints. For the first (default) channel, these
+    // are normally set by the configuration, but can be changed by the
+    // application, if desired.
+    usbs_tx_endpoint*   tx_ep;
+    usbs_rx_endpoint*   rx_ep;
+
+    // The signal that a transmit operation is complete, and it's result.
+    cyg_sem_t   tx_ready;
+    int         tx_result;
+
+    // The signal that a receive operation is complete, and it's result.
+    cyg_sem_t   rx_ready;
+    int         rx_result;
+
+} usbs_serial;
+
+// The package constains one USB serial device.
+extern usbs_serial usbs_ser0;
+
+// It's assumed that there's a single USB slave chip in the system, with a
+// single control endpoint 0. The actual variable is contained in the device
+// driver, but the USB serial code keeps a pointer to it for driver 
+// independence. The application might find it useful for overriding low-level
+// code or callbacks.
+extern usbs_control_endpoint* usbs_serial_ep0;
+
+// ----------------------------------------------------------------------------
+// A C interface to the serial USB code.
+// The application can use this interface, the standard (low-level) USB slave
+// API, the standard Unix-like I/O API, or C stdio API.
+    
+// Initialize support for a particular USB serial "port"
+// This associates a usbs_serial structure with specific endpoints and 
+// initializes the structure for communications.
+void usbs_serial_init(usbs_serial*, usbs_tx_endpoint*, usbs_rx_endpoint*);
+
+// Block the calling thread until the host configures the USB device.
+void usbs_serial_wait_until_configured(void);
+
+// Determines if the USB substsrem is configured
+cyg_bool usbs_serial_is_configured(void);
+
+// Start an asynchronous transmit of a single buffer.
+void usbs_serial_start_tx(usbs_serial*, const void* buf, int n);
+
+// Block the calling thread until the transmit completes.
+// Returns the result code for the transfer
+int usbs_serial_wait_for_tx(usbs_serial*);
+
+// Blocking, synchronous transmit of a single buffer.
+int usbs_serial_tx(usbs_serial*, const void* buf, int n);
+
+// Start an asynchronous receive of a buffer.
+void usbs_serial_start_rx(usbs_serial*, void* buf, int n);
+
+// Block the calling thread until the receive completes.
+// Returns the result code for the transfer
+int usbs_serial_wait_for_rx(usbs_serial*);
+
+// Blocking, synchronous receive of a single buffer.
+int usbs_serial_rx(usbs_serial*, void* buf, int n);
+
+// The default USB-serial state change handler paces the functions
+// usbs_serial_wait_until_configured() and usbs_serial_is_configured().
+// The application can override the state chain handler, but chain to 
+// this function to keep the full USP-serial system working.
+void usbs_serial_state_change_handler(usbs_control_endpoint*, void*, 
+                                      usbs_state_change, int);
+
+// Starts the USB subsystem
+void usbs_serial_start(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // CYGONCE_USBS_SERIAL_H
+
diff -urN --exclude=.svn ecos/packages/io/usb/serial/slave/current/src/usbs_serial.c usbserial/packages/io/usb/serial/slave/current/src/usbs_serial.c
--- ecos/packages/io/usb/serial/slave/current/src/usbs_serial.c	1969-12-31 19:00:00.000000000 -0500
+++ usbserial/packages/io/usb/serial/slave/current/src/usbs_serial.c	2008-06-05 20:38:06.000000000 -0400
@@ -0,0 +1,544 @@
+//==========================================================================
+//
+//      usbs_serial.c
+//
+//      Support for slave-side USB serial devices.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Date:         2008-06-02
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/kernel/kapi.h>
+
+#include <pkgconf/io_usb_slave_serial.h>
+#include <cyg/io/usb/usbs_serial.h>
+#include <string.h>
+
+#if defined(CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+#define EP0_MAX_PACKET_SIZE     CYGNUM_IO_USB_SLAVE_SERIAL_EP0_MAX_PACKET_SIZE
+
+extern usbs_control_endpoint    CYGDAT_IO_USB_SLAVE_SERIAL_EP0;
+extern usbs_tx_endpoint         CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP;
+extern usbs_rx_endpoint         CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP;
+
+#define TX_EP_NUM               CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM
+#define RX_EP_NUM               CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM
+#define INTR_EP_NUM             CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM
+#define EP0                     (&CYGDAT_IO_USB_SLAVE_SERIAL_EP0)
+#define TX_EP                   (&CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP)
+#define RX_EP                   (&CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP)
+#define INTR_EP                 (&CYGDAT_IO_USB_SLAVE_SERIAL_INTR_EP)
+
+
+#define VENDOR_ID               CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID
+#define PRODUCT_ID              CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID
+
+#define USB_MAX_STR_LEN         256
+
+#define LO_BYTE_16(word16)      ((cyg_uint8) ((word16) & 0xFF))
+#define HI_BYTE_16(word16)      ((cyg_uint8) (((word16) >> 8) & 0xFF))
+
+#define BYTE0_32(word32)        ((cyg_uint8) ((word32) & 0xFF))
+#define BYTE1_32(word32)        ((cyg_uint8) (((word32) >>  8) & 0xFF))
+#define BYTE2_32(word32)        ((cyg_uint8) (((word32) >> 16) & 0xFF))
+#define BYTE3_32(word32)        ((cyg_uint8) (((word32) >> 24) & 0xFF))
+
+
+#define MFG_STR_INDEX           '\x01'
+#define PRODUCT_STR_INDEX       '\x02'
+
+#define USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH(interfaces, endpoints) \
+            (USB_CONFIGURATION_DESCRIPTOR_LENGTH +            \
+            ((interfaces) * USB_INTERFACE_DESCRIPTOR_LENGTH) +  \
+            ((endpoints)  * USB_ENDPOINT_DESCRIPTOR_LENGTH))
+
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    #define USBS_SERIAL_DEVICE_CLASS        2
+    #define USBS_SERIAL_NUM_IFACE           2
+    #define USBS_SERIAL_NUM_ENDP            3
+    #define USBS_SERIAL_DATA_IFACE_CLASS    0x0A    // Data
+#else
+    #define USBS_SERIAL_DEVICE_CLASS        0
+    #define USBS_SERIAL_NUM_IFACE           1
+    #define USBS_SERIAL_NUM_ENDP            2
+    #define USBS_SERIAL_DATA_IFACE_CLASS    0xFF    // Vendor
+#endif
+
+// ----- Configuration Descriptor -----
+
+static const usb_configuration_descriptor usb_configuration = {
+    length:             sizeof(usb_configuration_descriptor),
+    type:               USB_CONFIGURATION_DESCRIPTOR_TYPE,
+    total_length_lo:    
+        USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_LO(USBS_SERIAL_NUM_IFACE, USBS_SERIAL_NUM_ENDP),
+    total_length_hi:    
+        USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_HI(USBS_SERIAL_NUM_IFACE, USBS_SERIAL_NUM_ENDP),
+    number_interfaces:  USBS_SERIAL_NUM_IFACE,
+    configuration_id:   1,
+    configuration_str:  0,
+    attributes:         USB_CONFIGURATION_DESCRIPTOR_ATTR_REQUIRED |
+                                USB_CONFIGURATION_DESCRIPTOR_ATTR_SELF_POWERED,
+    max_power:          50
+};
+
+// ----- Interface Descriptor -----
+
+static const usb_interface_descriptor usb_interface[] = {
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    {
+        length:             sizeof(usb_interface_descriptor),
+        type:               USB_INTERFACE_DESCRIPTOR_TYPE,
+        interface_id:       0,
+        alternate_setting:  0,
+        number_endpoints:   1,
+        interface_class:    0x02,   // Comm class
+        interface_subclass: 0x02,
+        interface_protocol: 0x01,
+        interface_str:      0x00
+    },
+    {
+        length:             sizeof(usb_interface_descriptor),
+        type:               USB_INTERFACE_DESCRIPTOR_TYPE,
+        interface_id:       1,
+        alternate_setting:  0,
+        number_endpoints:   2,
+        interface_class:    USBS_SERIAL_DATA_IFACE_CLASS,
+        interface_subclass: 0x00,
+        interface_protocol: 0x00,
+        interface_str:      0x00
+    }
+#else
+    {
+        length:             sizeof(usb_interface_descriptor),
+        type:               USB_INTERFACE_DESCRIPTOR_TYPE,
+        interface_id:       0,
+        alternate_setting:  0,
+        number_endpoints:   2,
+        interface_class:    USBS_SERIAL_DATA_IFACE_CLASS,
+        interface_subclass: 0x00,
+        interface_protocol: 0x00,
+        interface_str:      0x00
+    }
+#endif
+};
+
+// ----- Endpoint Descriptors -----
+
+static const usb_endpoint_descriptor usb_endpoints[] =
+{ 
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    // Interrupt in endpoint
+    {
+        sizeof(usb_endpoint_descriptor),
+        USB_ENDPOINT_DESCRIPTOR_TYPE,
+        USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN | INTR_EP_NUM,
+        USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+        0x40,
+        0,
+        255
+    },
+#endif
+
+    // Tx (Bulk IN) Endpoint Descriptor
+    {
+        sizeof(usb_endpoint_descriptor),
+        USB_ENDPOINT_DESCRIPTOR_TYPE,
+        USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN | TX_EP_NUM,
+        USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+        0x40,
+        0,
+        0
+    },
+
+    // Rx (Bulk OUT) Endpoint Descriptor
+    {
+        sizeof(usb_endpoint_descriptor),
+        USB_ENDPOINT_DESCRIPTOR_TYPE,
+        USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT | RX_EP_NUM,
+        USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+        0x40,
+        0,
+        0
+    }
+};
+
+// ----- String Descriptors -----
+
+static char mfg_str_descr[USB_MAX_STR_LEN],
+            product_str_descr[USB_MAX_STR_LEN];
+
+
+static const char* usb_strings[] = {
+    "\x04\x03\x09\x04",
+    mfg_str_descr,
+    product_str_descr
+};
+
+// ----- Enumeration Data w/ Device Descriptor -----
+
+static usbs_enumeration_data usb_enum_data = {
+    {
+        length:                 sizeof(usb_device_descriptor),
+        type:                   USB_DEVICE_DESCRIPTOR_TYPE,
+        usb_spec_lo:            0x00, 
+        usb_spec_hi:            0x02,
+        device_class:           USBS_SERIAL_DEVICE_CLASS,
+        device_subclass:        0,
+        device_protocol:        0,
+        max_packet_size:        EP0_MAX_PACKET_SIZE,
+        vendor_lo:              LO_BYTE_16(VENDOR_ID),
+        vendor_hi:              HI_BYTE_16(VENDOR_ID),
+        product_lo:             LO_BYTE_16(PRODUCT_ID),
+        product_hi:             HI_BYTE_16(PRODUCT_ID),
+        device_lo:              0x00,
+        device_hi:              0x00,
+        manufacturer_str:       MFG_STR_INDEX,
+        product_str:            PRODUCT_STR_INDEX,
+        serial_number_str:      0,
+        number_configurations:  1
+    },
+
+    total_number_interfaces:    USBS_SERIAL_NUM_IFACE,
+    total_number_endpoints:     USBS_SERIAL_NUM_ENDP,
+    total_number_strings:       3,
+    configurations:             &usb_configuration,
+    interfaces:                 usb_interface,
+    endpoints:                  usb_endpoints,
+    strings:                    (const unsigned char **) usb_strings
+};
+
+// --------------------------------------------------------------------------
+// USBS Serial Data
+// --------------------------------------------------------------------------
+
+usbs_control_endpoint* usbs_serial_ep0 = EP0;
+
+// Lock for the state.
+cyg_mutex_t usbs_serial_lock;   
+
+// Condition variable for state changes
+cyg_cond_t  usbs_serial_state_cond;
+
+int usbs_serial_state;
+
+usbs_serial usbs_ser0 = {
+    tx_ep:      TX_EP,
+    rx_ep:      RX_EP,
+    tx_result:  0,    
+    rx_result:  0,    
+};
+
+static void (*usbs_serial_app_state_change_fn)(struct usbs_control_endpoint*, 
+                                               void*, usbs_state_change, int) = 0;
+
+// --------------------------------------------------------------------------
+// Create a USB String Descriptor from a C string.
+
+void
+usbs_serial_create_str_descriptor(char descr[], const char *str)
+{
+    int i, n = strlen(str);
+
+    if (n > (USB_MAX_STR_LEN/2 - 2))
+        n = USB_MAX_STR_LEN/2 - 2;
+
+    descr[0] = (cyg_uint8) (2*n + 2);
+    descr[1] = USB_DEVREQ_DESCRIPTOR_TYPE_STRING;
+
+    for (i=0; i<n; i++) {
+        descr[i*2+2] = str[i];
+        descr[i*2+3] = '\x00';
+    }
+}
+
+// --------------------------------------------------------------------------
+// ACM Class Handler
+//
+// For a Windows host, the device must, at least, respond to a SetLineCoding
+// request (0x20), otherwise Windows will report that it's unable to open the 
+// port. This request normally sets the standard serial parameters:
+//          baud rate, # stop bits, parity, and # data bits
+// If we're just making believe that we're a serial port to communicate with
+// the host via USB, then these values don't matter. So we ACK the request,
+// but ignore the parameters.
+// If we were actually creating a USB-serial converter, then we would need to
+// read these values and confire the serial port accordingly.
+// 
+// Similarly, the host can request the current settings through a 
+// GetLineCoding request (0x21). Since we're just faking it, we return some
+// arbitrary values: 38400,1,N,8
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+static usbs_control_return 
+usbs_serial_acm_class_handler(usbs_control_endpoint* ep0, void* data)
+{
+	usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+	DBG("USB Serial ACM Class Handler: ");
+
+	usb_devreq	*req = (usb_devreq *) ep0->control_buffer;
+
+    static cyg_uint8 rsp_buf[32];
+    cyg_uint32 baud = 38400;  // Arbitrary, fake value to return to the host.
+
+	switch (req->request) {
+
+        case USBS_SERIAL_SET_LINE_CODING :
+                DBG("ACM Request: Set Line Coding\n");
+                result = USBS_CONTROL_RETURN_HANDLED;
+                break;
+
+        case USBS_SERIAL_GET_LINE_CODING :
+                DBG("ACM Request: Get Line Coding\n");
+                rsp_buf[0] = BYTE0_32(baud);
+                rsp_buf[1] = BYTE1_32(baud);
+                rsp_buf[2] = BYTE2_32(baud);
+                rsp_buf[3] = BYTE3_32(baud);
+                rsp_buf[4] = 0; // One stop bit
+                rsp_buf[5] = 0; // No parity
+                rsp_buf[6] = 8; // 8 data bits
+				ep0->buffer = rsp_buf;
+				ep0->buffer_size = 7;
+                result = USBS_CONTROL_RETURN_HANDLED;
+                break;
+
+		default :
+				DBG("*** Unhandled ACM Request: 0x%02X ***\n",
+					(unsigned) req->request);
+	}
+
+	return result;
+}
+#endif      // CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+// --------------------------------------------------------------------------
+// Callback for a USB state change
+
+void
+usbs_serial_state_change_handler(usbs_control_endpoint* ep, void* data,
+                                 usbs_state_change change, int prev_state)
+{
+    #if defined(CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG)
+        const char *STATE_CHG_STR[] = { "Detached", "Attached", "Powered", "Reset",
+                                        "Addressed", "Configured", "Deconfigured",
+                                        "Suspended", "Resumed" };
+
+        if (change > 0) {
+            DBG("### %s ###\n", STATE_CHG_STR[(int) change-1]);
+        }
+    #endif
+
+    // Called from DSR, cond broadcast should be ok without mutex lock
+    usbs_serial_state = usbs_serial_ep0->state;
+    cyg_cond_broadcast(&usbs_serial_state_cond);
+
+    if (usbs_serial_app_state_change_fn)
+        (*usbs_serial_app_state_change_fn)(ep, data, change, prev_state);
+}
+
+// --------------------------------------------------------------------------
+// Block the calling thread until the USB is configured.
+ 
+void
+usbs_serial_wait_until_configured(void)
+{
+    cyg_mutex_lock(&usbs_serial_lock);
+    while (usbs_serial_state != USBS_STATE_CONFIGURED)
+      cyg_cond_wait(&usbs_serial_state_cond);
+    cyg_mutex_unlock(&usbs_serial_lock);
+}
+
+// --------------------------------------------------------------------------
+// Determine if the device is currently configured.
+
+cyg_bool
+usbs_serial_is_configured(void)
+{
+    return usbs_serial_state == USBS_STATE_CONFIGURED;
+}
+
+// --------------------------------------------------------------------------
+// Callback for when a transmit is complete
+
+static void 
+usbs_serial_tx_complete(void *p, int result)
+{
+    usbs_serial* ser = (usbs_serial*) p;
+    ser->tx_result = result;
+    cyg_semaphore_post(&ser->tx_ready);
+}
+
+// --------------------------------------------------------------------------
+// Callback for when a receive is complete
+
+static void 
+usbs_serial_rx_complete(void *p, int result)
+{
+    usbs_serial* ser = (usbs_serial*) p;
+    ser->rx_result = result;
+    cyg_semaphore_post(&ser->rx_ready);
+}
+
+// --------------------------------------------------------------------------
+// Start an asynchronous transmit of a buffer.
+// 
+ 
+void
+usbs_serial_start_tx(usbs_serial* ser, const void* buf, int n)
+{
+    usbs_start_tx_buffer(ser->tx_ep, (unsigned char*) buf, n,
+                          usbs_serial_tx_complete, ser);
+}
+
+// --------------------------------------------------------------------------
+// Block the caller until the transmit is complete
+
+int
+usbs_serial_wait_for_tx(usbs_serial* ser)
+{
+    cyg_semaphore_wait(&ser->tx_ready);
+    return ser->tx_result;
+}
+
+// --------------------------------------------------------------------------
+// Perform a synchronous transmit and wait for it to complete.
+
+int
+usbs_serial_tx(usbs_serial* ser, const void* buf, int n)
+{
+    usbs_serial_start_tx(ser, buf, n);
+    return usbs_serial_wait_for_tx(ser);
+}
+
+// --------------------------------------------------------------------------
+// Start an asynchronous receive of a buffer.
+
+void
+usbs_serial_start_rx(usbs_serial* ser, void* buf, int n)
+{
+    usbs_start_rx_buffer(ser->rx_ep, (unsigned char*) buf, n,
+                          usbs_serial_rx_complete, ser);
+}
+
+// --------------------------------------------------------------------------
+// Block the caller until the receive is complete
+
+int
+usbs_serial_wait_for_rx(usbs_serial* ser)
+{
+    cyg_semaphore_wait(&ser->rx_ready);
+    return ser->rx_result;
+}
+
+// --------------------------------------------------------------------------
+// Perform a synchronous receive and wait for it to complete.
+
+int
+usbs_serial_rx(usbs_serial* ser, void* buf, int n)
+{
+    usbs_serial_start_rx(ser, buf, n);
+    return usbs_serial_wait_for_rx(ser);
+}
+
+// --------------------------------------------------------------------------
+// Initialize a serial port structure.
+
+void
+usbs_serial_init(usbs_serial* ser, usbs_tx_endpoint* tx_ep, usbs_rx_endpoint* rx_ep)
+{
+    ser->tx_ep = tx_ep;
+    ser->rx_ep = rx_ep;
+
+    cyg_semaphore_init(&ser->tx_ready, 0);
+    cyg_semaphore_init(&ser->rx_ready, 0);
+}
+
+// --------------------------------------------------------------------------
+// Start the USB subsystem
+
+void
+usbs_serial_start(void)
+{
+    usbs_serial_init(&usbs_ser0, TX_EP, RX_EP);
+
+    cyg_mutex_init(&usbs_serial_lock);
+    cyg_cond_init(&usbs_serial_state_cond, &usbs_serial_lock);
+
+    // Make the mfg & product names into USB string descriptors
+
+    usbs_serial_create_str_descriptor(mfg_str_descr, 
+                                      CYGDAT_IO_USB_SLAVE_SERIAL_MFG_STR);
+    usbs_serial_create_str_descriptor(product_str_descr, 
+                                      CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR);
+
+    // ----- Set up enumeration & USB callbacks -----
+
+    usbs_serial_state = usbs_serial_ep0->state;
+
+    usbs_serial_ep0->enumeration_data   = &usb_enum_data;
+
+    if (usbs_serial_ep0->state_change_fn)
+        usbs_serial_app_state_change_fn = usbs_serial_ep0->state_change_fn;
+
+    usbs_serial_ep0->state_change_fn = usbs_serial_state_change_handler;
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    if (!usbs_serial_ep0->class_control_fn)
+        usbs_serial_ep0->class_control_fn = usbs_serial_acm_class_handler;
+#endif
+
+    // ----- Start USB subsystem -----
+
+    usbs_start(usbs_serial_ep0);
+}
+

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-07-12 10:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-12 10:50 USB serial package Andrew Lunn
  -- strict thread matches above, loose matches on Subject: below --
2008-06-06  1:26 Frank Pagliughi
2008-06-06  7:33 ` Andrew Lunn
2008-06-06 14:25   ` Frank Pagliughi
2008-06-15 10:56 ` Andrew Lunn
2008-06-16 15:08   ` Frank Pagliughi
2008-06-16 15:56   ` Frank Pagliughi
2008-06-18 19:29     ` Andrew Lunn
2008-06-18 20:00       ` Frank Pagliughi
2008-06-18 20:19         ` Andrew Lunn
2008-06-18 21:11           ` Frank Pagliughi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).