changeset 444:f00b7ea8ac0e

Add a new configuration option for the size of control packets. This option provides a partial workaround for a USB specification compliance issue.
author bartv
date Mon, 02 Dec 2002 20:48:15 +0000
parents b8b99761a77b
children 4bfb0d444b05
files packages/devs/usb/nec_upd985xx/current/ChangeLog packages/devs/usb/nec_upd985xx/current/cdl/usbs_upd985xx.cdl packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx.c
diffstat 3 files changed, 43 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/usb/nec_upd985xx/current/ChangeLog
+++ b/packages/devs/usb/nec_upd985xx/current/ChangeLog
@@ -1,3 +1,10 @@
+2002-12-01  Bart Veer  <bartv@ecoscentric.com>
+
+	* src/usbs_upd985xx.c, cdl/usbs_upd985xx.cdl:
+	Make the control packet size configurable, to work around a
+	problem detected by USB compliance testing. Based on work
+	by Clark Williams and Andrew Lunn.
+
 2002-10-26  Bart Veer  <bartv@ecoscentric.com>
 
 	* src/usbs_upd985xx.c (ep0_rx_dsr):
--- a/packages/devs/usb/nec_upd985xx/current/cdl/usbs_upd985xx.cdl
+++ b/packages/devs/usb/nec_upd985xx/current/cdl/usbs_upd985xx.cdl
@@ -8,6 +8,7 @@
 #####ECOSGPLCOPYRIGHTBEGIN####
 ## -------------------------------------------
 ## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2002 Bart Veer
 ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 ##
 ## eCos is free software; you can redistribute it and/or modify it under
@@ -88,10 +89,37 @@ cdl_package CYGPKG_DEVS_USB_UPD985XX {
             "
         }
 
+	cdl_option CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE {
+	    display	  "Size of endpoint 0 control packets"
+	    flavor        data
+	    default_value 8
+	    legal_values  { 8 16 32 64 }
+	    description "
+                Control messages on endpoint 0 are split into packets of
+                8, 16, 32 or 64 bytes - these are the values permitted by the
+                USB specification. The same packet size is used for both
+                receives and transmits. This value must also be used for the
+                max_packet_size field of the device descriptor in the
+                application's USB enumeration data.
+
+                According to section 5.5.5 of the USB specification, if a new
+                control message is received before the previous transaction
+                has completed then the previous transaction must be aborted.
+                If that transaction involved transferring data to the host
+                then there is a problem: that data may still be queued for
+                transmission and the NEC USB device appears to provide no way
+                of aborting that transmit. The problem is unlikely to arise
+                with normal usage, but may be detected by compliance
+                testsuites. Increasing the packet size to its maximum value
+                of 64 reduces the probability of failure.
+            "
+	}
+	
 	cdl_option CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE {
 	    display       "Size of statically-allocated endpoint 0 transmit buffer"
 	    flavor        data
 	    default_value 256
+	    requires      { CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE >= CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE }
 	    description "
 	        The implementation of the support for endpoint 0 uses
 	        a single static buffer to hold the response to the
@@ -109,7 +137,7 @@ cdl_package CYGPKG_DEVS_USB_UPD985XX {
 	    display       "Size of statically-allocated endpoint 0 transmit buffer"
 	    flavor        data
 	    default_value 64
-	    requires      { CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE >= 8 }
+	    requires      { CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE >= CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE }
 	    description "
 	        The implementation of the support for endpoint 0 uses
 	        a single static buffer to hold incoming control messages.
--- a/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx.c
+++ b/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx.c
@@ -8,6 +8,7 @@
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002 Bart Veer
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 //
 // eCos is free software; you can redistribute it and/or modify it under
@@ -1113,7 +1114,8 @@ ep0_start_tx(void)
 //
 // There is one special case. If the host asked for e.g. a string
 // descriptor and asked for 255 bytes, but the string was only
-// e.g. 32 bytes, then there is a problem. The data will be
+// e.g. 32 bytes, then there is a problem. With a default value
+// for CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE, the data will be
 // transferred as four 8-byte packets, but it is necessary to
 // terminate the transfer with a 0-byte packet. Endpoint 0 always
 // operates in NZLP mode so the hardware will never generate
@@ -1535,7 +1537,7 @@ ep0_rx_dsr(void)
                     if (actual_length > length) {
                         actual_length = length;
                     } 
-                    if ((length != actual_length) && (0 == (actual_length % 8))) {
+                    if ((length != actual_length) && (0 == (actual_length % CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE))) {
                         ep0.tx_needs_zero_transfer = true;
                     } else {
                         ep0.tx_needs_zero_transfer = false;
@@ -1662,10 +1664,10 @@ ep0_init(void)
     // Start a receive operation for a control message.
     ep0_start_rx(8);
     
-    // The endpoint 0 control register. Sticking with the default
-    // 8-byte packet size seems like a good idea. Setting the
+    // The endpoint 0 control register. The control packet size is
+    // configurable, with a default value of 8. Setting the
     // enabled bit here affects the state as seen by the host.
-    *EP0_CR                     = IBUS_SWAP32(EP0_CR_EP0EN | 8);                    FLUSH_IBUS();
+    *EP0_CR                     = IBUS_SWAP32(EP0_CR_EP0EN | CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE); FLUSH_IBUS();
     
     // The other endpoint registers will be initialized by the appropriate
     // _init() functions. Note that those other _init() functions should