stmf0: Do not send more data than requested for GET_DESCRIPTOR
[fw/altos] / src / stmf0 / ao_usb_stm.c
index e68da8eb2adea8f5fe8faad28cec367641635931..63b35b249b55217074033b557d72867db422997d 100644 (file)
@@ -437,6 +437,17 @@ ao_usb_set_ep0(void)
        ao_usb_set_address(0);
 
        ao_usb_running = 0;
+
+       /* Reset our internal state
+        */
+
+       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+
+       ao_usb_ep0_in_data = NULL;
+       ao_usb_ep0_in_len = 0;
+
+       ao_usb_ep0_out_data = 0;
+       ao_usb_ep0_out_len = 0;
 }
 
 static void
@@ -493,6 +504,20 @@ ao_usb_set_configuration(void)
                       STM_USB_EPR_STAT_TX_NAK);
 #endif
 
+       ao_usb_in_flushed = 0;
+       ao_usb_in_pending = 0;
+       ao_wakeup(&ao_usb_in_pending);
+#if AO_USB_HAS_IN2
+       ao_usb_in2_flushed = 0;
+       ao_usb_in2_pending = 0;
+       ao_wakeup(&ao_usb_in2_pending);
+#endif
+
+       ao_usb_out_avail = 0;
+       ao_usb_configuration = 0;
+
+       ao_wakeup(AO_USB_OUT_SLEEP_ADDR);
+
        ao_usb_running = 1;
 #if AO_USB_DIRECTIO
        ao_wakeup(&ao_usb_running);
@@ -658,7 +683,7 @@ ao_usb_serial_init(void)
 /* Walk through the list of descriptors and find a match
  */
 static void
-ao_usb_get_descriptor(uint16_t value)
+ao_usb_get_descriptor(uint16_t value, uint16_t length)
 {
        const uint8_t           *descriptor;
        uint8_t         type = value >> 8;
@@ -679,6 +704,8 @@ ao_usb_get_descriptor(uint16_t value)
                                len = sizeof (ao_usb_serial);
                        }
 #endif
+                       if (len > length)
+                               len = length;
                        ao_usb_ep0_in_set(descriptor, len);
                        break;
                }
@@ -723,7 +750,7 @@ ao_usb_ep0_setup(void)
                                break;
                        case AO_USB_REQ_GET_DESCRIPTOR:
                                debug ("get descriptor %d\n", ao_usb_setup.value);
-                               ao_usb_get_descriptor(ao_usb_setup.value);
+                               ao_usb_get_descriptor(ao_usb_setup.value, ao_usb_setup.length);
                                break;
                        case AO_USB_REQ_GET_CONFIGURATION:
                                debug ("get configuration %d\n", ao_usb_configuration);
@@ -1007,7 +1034,7 @@ ao_usb_putchar(char c)
 }
 #endif
 
-#if AO_USB_HAS_IN
+#if AO_USB_HAS_IN2
 /* Queue the current IN buffer for transmission */
 static void
 _ao_usb_in2_send(void)