diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-02-22 20:38:31 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-02-22 20:38:31 +0000 |
commit | 9dbe7f2a8caaf7fb07f7b1d010562760bd62d185 (patch) | |
tree | 7f90f9038cd3eb347ce707cb4973f5c4b28b94f5 | |
parent | a0b5780e2d7731eb06c9882d103f87ae9064f2eb (diff) | |
download | rockbox-9dbe7f2a8caaf7fb07f7b1d010562760bd62d185.tar.gz rockbox-9dbe7f2a8caaf7fb07f7b1d010562760bd62d185.zip |
Improve usb descriptor handling. This should fix any cache and/or alignment related problem.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16371 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/export/usb_ch9.h | 6 | ||||
-rw-r--r-- | firmware/usbstack/usb_core.c | 346 |
2 files changed, 171 insertions, 181 deletions
diff --git a/firmware/export/usb_ch9.h b/firmware/export/usb_ch9.h index d5885ac9b8..4c272c338a 100644 --- a/firmware/export/usb_ch9.h +++ b/firmware/export/usb_ch9.h | |||
@@ -227,7 +227,7 @@ struct usb_config_descriptor { | |||
227 | uint8_t iConfiguration; | 227 | uint8_t iConfiguration; |
228 | uint8_t bmAttributes; | 228 | uint8_t bmAttributes; |
229 | uint8_t bMaxPower; | 229 | uint8_t bMaxPower; |
230 | } __attribute__ ((packed)); | 230 | } __attribute__ ((packed,aligned(2))); |
231 | 231 | ||
232 | #define USB_DT_CONFIG_SIZE 9 | 232 | #define USB_DT_CONFIG_SIZE 9 |
233 | 233 | ||
@@ -285,7 +285,7 @@ struct usb_endpoint_descriptor { | |||
285 | /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ | 285 | /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ |
286 | //uint8_t bRefresh; | 286 | //uint8_t bRefresh; |
287 | //uint8_t bSynchAddress; | 287 | //uint8_t bSynchAddress; |
288 | } __attribute__ ((packed)); | 288 | } __attribute__ ((packed,aligned(2))); |
289 | 289 | ||
290 | #define USB_DT_ENDPOINT_SIZE 7 | 290 | #define USB_DT_ENDPOINT_SIZE 7 |
291 | #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ | 291 | #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ |
@@ -304,7 +304,7 @@ struct usb_qualifier_descriptor { | |||
304 | uint8_t bMaxPacketSize0; | 304 | uint8_t bMaxPacketSize0; |
305 | uint8_t bNumConfigurations; | 305 | uint8_t bNumConfigurations; |
306 | uint8_t bRESERVED; | 306 | uint8_t bRESERVED; |
307 | } __attribute__ ((packed)); | 307 | } __attribute__ ((packed,aligned(2))); |
308 | 308 | ||
309 | /*-------------------------------------------------------------------------*/ | 309 | /*-------------------------------------------------------------------------*/ |
310 | 310 | ||
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index c68093b0d2..caada6c798 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c | |||
@@ -72,169 +72,138 @@ static const struct usb_device_descriptor device_descriptor= { | |||
72 | .bNumConfigurations = 1 | 72 | .bNumConfigurations = 1 |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static struct { | 75 | struct usb_config_descriptor config_descriptor = |
76 | struct usb_config_descriptor config_descriptor; | ||
77 | #ifdef USB_CHARGING_ONLY | ||
78 | struct usb_interface_descriptor charging_interface_descriptor; | ||
79 | struct usb_endpoint_descriptor charging_ep_in_descriptor; | ||
80 | struct usb_endpoint_descriptor charging_ep_out_descriptor; | ||
81 | #endif | ||
82 | #ifdef USB_STORAGE | ||
83 | struct usb_interface_descriptor mass_storage_interface_descriptor; | ||
84 | struct usb_endpoint_descriptor mass_storage_ep_in_descriptor; | ||
85 | struct usb_endpoint_descriptor mass_storage_ep_out_descriptor; | ||
86 | #endif | ||
87 | #ifdef USB_SERIAL | ||
88 | struct usb_interface_descriptor serial_interface_descriptor; | ||
89 | struct usb_endpoint_descriptor serial_ep_in_descriptor; | ||
90 | struct usb_endpoint_descriptor serial_ep_out_descriptor; | ||
91 | #endif | ||
92 | #ifdef USB_BENCHMARK | ||
93 | struct usb_interface_descriptor benchmark_interface_descriptor; | ||
94 | struct usb_endpoint_descriptor benchmark_ep_in_descriptor; | ||
95 | struct usb_endpoint_descriptor benchmark_ep_out_descriptor; | ||
96 | #endif | ||
97 | } __attribute__((packed)) *config_data, _config_data = | ||
98 | { | 76 | { |
99 | { | 77 | .bLength = sizeof(struct usb_config_descriptor), |
100 | .bLength = sizeof(struct usb_config_descriptor), | 78 | .bDescriptorType = USB_DT_CONFIG, |
101 | .bDescriptorType = USB_DT_CONFIG, | 79 | .wTotalLength = 0, /* will be filled in later */ |
102 | .wTotalLength = sizeof _config_data, | 80 | .bNumInterfaces = 1, |
103 | .bNumInterfaces = 1, | 81 | .bConfigurationValue = 1, |
104 | .bConfigurationValue = 1, | 82 | .iConfiguration = 0, |
105 | .iConfiguration = 0, | 83 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, |
106 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | 84 | .bMaxPower = 250, /* 500mA in 2mA units */ |
107 | .bMaxPower = 250, /* 500mA in 2mA units */ | 85 | }; |
108 | }, | ||
109 | 86 | ||
110 | #ifdef USB_CHARGING_ONLY | 87 | #ifdef USB_CHARGING_ONLY |
111 | /* dummy interface for charging-only */ | 88 | /* dummy interface for charging-only */ |
112 | { | 89 | struct usb_interface_descriptor charging_interface_descriptor = |
113 | .bLength = sizeof(struct usb_interface_descriptor), | 90 | { |
114 | .bDescriptorType = USB_DT_INTERFACE, | 91 | .bLength = sizeof(struct usb_interface_descriptor), |
115 | .bInterfaceNumber = 0, | 92 | .bDescriptorType = USB_DT_INTERFACE, |
116 | .bAlternateSetting = 0, | 93 | .bInterfaceNumber = 0, |
117 | .bNumEndpoints = 2, | 94 | .bAlternateSetting = 0, |
118 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | 95 | .bNumEndpoints = 0, |
119 | .bInterfaceSubClass = 0, | 96 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, |
120 | .bInterfaceProtocol = 0, | 97 | .bInterfaceSubClass = 0, |
121 | .iInterface = 5 | 98 | .bInterfaceProtocol = 0, |
122 | }, | 99 | .iInterface = 5 |
123 | /* TODO: try with zero endpoints */ | 100 | }; |
124 | { | ||
125 | .bLength = sizeof(struct usb_endpoint_descriptor), | ||
126 | .bDescriptorType = USB_DT_ENDPOINT, | ||
127 | .bEndpointAddress = EP_CHARGING_ONLY | USB_DIR_IN, | ||
128 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
129 | .wMaxPacketSize = 16, | ||
130 | .bInterval = 0 | ||
131 | }, | ||
132 | { | ||
133 | .bLength = sizeof(struct usb_endpoint_descriptor), | ||
134 | .bDescriptorType = USB_DT_ENDPOINT, | ||
135 | .bEndpointAddress = EP_CHARGING_ONLY | USB_DIR_OUT, | ||
136 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
137 | .wMaxPacketSize = 16, | ||
138 | .bInterval = 0 | ||
139 | }, | ||
140 | #endif | 101 | #endif |
141 | 102 | ||
142 | #ifdef USB_STORAGE | 103 | #ifdef USB_STORAGE |
143 | /* storage interface */ | 104 | /* storage interface */ |
144 | { | 105 | struct usb_interface_descriptor mass_storage_interface_descriptor = |
145 | .bLength = sizeof(struct usb_interface_descriptor), | 106 | { |
146 | .bDescriptorType = USB_DT_INTERFACE, | 107 | .bLength = sizeof(struct usb_interface_descriptor), |
147 | .bInterfaceNumber = 0, | 108 | .bDescriptorType = USB_DT_INTERFACE, |
148 | .bAlternateSetting = 0, | 109 | .bInterfaceNumber = 0, |
149 | .bNumEndpoints = 2, | 110 | .bAlternateSetting = 0, |
150 | .bInterfaceClass = USB_CLASS_MASS_STORAGE, | 111 | .bNumEndpoints = 2, |
151 | .bInterfaceSubClass = USB_SC_SCSI, | 112 | .bInterfaceClass = USB_CLASS_MASS_STORAGE, |
152 | .bInterfaceProtocol = USB_PROT_BULK, | 113 | .bInterfaceSubClass = USB_SC_SCSI, |
153 | .iInterface = 0 | 114 | .bInterfaceProtocol = USB_PROT_BULK, |
154 | }, | 115 | .iInterface = 0 |
116 | }; | ||
155 | 117 | ||
156 | { | 118 | struct usb_endpoint_descriptor mass_storage_ep_in_descriptor = |
157 | .bLength = sizeof(struct usb_endpoint_descriptor), | 119 | { |
158 | .bDescriptorType = USB_DT_ENDPOINT, | 120 | .bLength = sizeof(struct usb_endpoint_descriptor), |
159 | .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_IN, | 121 | .bDescriptorType = USB_DT_ENDPOINT, |
160 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 122 | .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_IN, |
161 | .wMaxPacketSize = 16, | 123 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
162 | .bInterval = 0 | 124 | .wMaxPacketSize = 16, |
163 | }, | 125 | .bInterval = 0 |
164 | { | 126 | }; |
165 | .bLength = sizeof(struct usb_endpoint_descriptor), | 127 | struct usb_endpoint_descriptor mass_storage_ep_out_descriptor = |
166 | .bDescriptorType = USB_DT_ENDPOINT, | 128 | { |
167 | .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_OUT, | 129 | .bLength = sizeof(struct usb_endpoint_descriptor), |
168 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 130 | .bDescriptorType = USB_DT_ENDPOINT, |
169 | .wMaxPacketSize = 16, | 131 | .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_OUT, |
170 | .bInterval = 0 | 132 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
171 | }, | 133 | .wMaxPacketSize = 16, |
134 | .bInterval = 0 | ||
135 | }; | ||
172 | #endif | 136 | #endif |
173 | 137 | ||
174 | #ifdef USB_SERIAL | 138 | #ifdef USB_SERIAL |
175 | /* serial interface */ | 139 | /* serial interface */ |
176 | { | 140 | struct usb_interface_descriptor serial_interface_descriptor = |
177 | .bLength = sizeof(struct usb_interface_descriptor), | 141 | { |
178 | .bDescriptorType = USB_DT_INTERFACE, | 142 | .bLength = sizeof(struct usb_interface_descriptor), |
179 | .bInterfaceNumber = 0, | 143 | .bDescriptorType = USB_DT_INTERFACE, |
180 | .bAlternateSetting = 0, | 144 | .bInterfaceNumber = 0, |
181 | .bNumEndpoints = 2, | 145 | .bAlternateSetting = 0, |
182 | .bInterfaceClass = USB_CLASS_CDC_DATA, | 146 | .bNumEndpoints = 2, |
183 | .bInterfaceSubClass = 0, | 147 | .bInterfaceClass = USB_CLASS_CDC_DATA, |
184 | .bInterfaceProtocol = 0, | 148 | .bInterfaceSubClass = 0, |
185 | .iInterface = 0 | 149 | .bInterfaceProtocol = 0, |
186 | }, | 150 | .iInterface = 0 |
151 | }; | ||
187 | 152 | ||
188 | { | 153 | struct usb_endpoint_descriptor serial_ep_in_descriptor = |
189 | .bLength = sizeof(struct usb_endpoint_descriptor), | 154 | { |
190 | .bDescriptorType = USB_DT_ENDPOINT, | 155 | .bLength = sizeof(struct usb_endpoint_descriptor), |
191 | .bEndpointAddress = EP_SERIAL | USB_DIR_IN, | 156 | .bDescriptorType = USB_DT_ENDPOINT, |
192 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 157 | .bEndpointAddress = EP_SERIAL | USB_DIR_IN, |
193 | .wMaxPacketSize = 16, | 158 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
194 | .bInterval = 0 | 159 | .wMaxPacketSize = 16, |
195 | }, | 160 | .bInterval = 0 |
196 | { | 161 | }; |
197 | .bLength = sizeof(struct usb_endpoint_descriptor), | 162 | struct usb_endpoint_descriptor serial_ep_out_descriptor = |
198 | .bDescriptorType = USB_DT_ENDPOINT, | 163 | { |
199 | .bEndpointAddress = EP_SERIAL | USB_DIR_OUT, | 164 | .bLength = sizeof(struct usb_endpoint_descriptor), |
200 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 165 | .bDescriptorType = USB_DT_ENDPOINT, |
201 | .wMaxPacketSize = 16, | 166 | .bEndpointAddress = EP_SERIAL | USB_DIR_OUT, |
202 | .bInterval = 0 | 167 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
203 | }, | 168 | .wMaxPacketSize = 16, |
169 | .bInterval = 0 | ||
170 | }; | ||
204 | #endif | 171 | #endif |
205 | 172 | ||
206 | #ifdef USB_BENCHMARK | 173 | #ifdef USB_BENCHMARK |
207 | /* bulk test interface */ | 174 | /* bulk test interface */ |
208 | { | 175 | struct usb_interface_descriptor benchmark_interface_descriptor = |
209 | .bLength = sizeof(struct usb_interface_descriptor), | 176 | { |
210 | .bDescriptorType = USB_DT_INTERFACE, | 177 | .bLength = sizeof(struct usb_interface_descriptor), |
211 | .bInterfaceNumber = 0, | 178 | .bDescriptorType = USB_DT_INTERFACE, |
212 | .bAlternateSetting = 0, | 179 | .bInterfaceNumber = 0, |
213 | .bNumEndpoints = 2, | 180 | .bAlternateSetting = 0, |
214 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | 181 | .bNumEndpoints = 2, |
215 | .bInterfaceSubClass = 255, | 182 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, |
216 | .bInterfaceProtocol = 255, | 183 | .bInterfaceSubClass = 255, |
217 | .iInterface = 4 | 184 | .bInterfaceProtocol = 255, |
218 | }, | 185 | .iInterface = 4 |
186 | }; | ||
219 | 187 | ||
220 | { | 188 | struct usb_endpoint_descriptor benchmark_ep_in_descriptor = |
221 | .bLength = sizeof(struct usb_endpoint_descriptor), | 189 | { |
222 | .bDescriptorType = USB_DT_ENDPOINT, | 190 | .bLength = sizeof(struct usb_endpoint_descriptor), |
223 | .bEndpointAddress = EP_BENCHMARK | USB_DIR_OUT, | 191 | .bDescriptorType = USB_DT_ENDPOINT, |
224 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 192 | .bEndpointAddress = EP_BENCHMARK | USB_DIR_OUT, |
225 | .wMaxPacketSize = 16, | 193 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
226 | .bInterval = 0 | 194 | .wMaxPacketSize = 16, |
227 | }, | 195 | .bInterval = 0 |
228 | { | ||
229 | .bLength = sizeof(struct usb_endpoint_descriptor), | ||
230 | .bDescriptorType = USB_DT_ENDPOINT, | ||
231 | .bEndpointAddress = EP_BENCHMARK | USB_DIR_IN, | ||
232 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
233 | .wMaxPacketSize = 16, | ||
234 | .bInterval = 0 | ||
235 | }, | ||
236 | #endif | ||
237 | }; | 196 | }; |
197 | struct usb_endpoint_descriptor benchmark_ep_out_descriptor = | ||
198 | { | ||
199 | .bLength = sizeof(struct usb_endpoint_descriptor), | ||
200 | .bDescriptorType = USB_DT_ENDPOINT, | ||
201 | .bEndpointAddress = EP_BENCHMARK | USB_DIR_IN, | ||
202 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
203 | .wMaxPacketSize = 16, | ||
204 | .bInterval = 0 | ||
205 | }; | ||
206 | #endif | ||
238 | 207 | ||
239 | static const struct usb_qualifier_descriptor qualifier_descriptor = | 208 | static const struct usb_qualifier_descriptor qualifier_descriptor = |
240 | { | 209 | { |
@@ -262,7 +231,6 @@ static struct usb_string_descriptor usb_string_iProduct = | |||
262 | {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'} | 231 | {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'} |
263 | }; | 232 | }; |
264 | 233 | ||
265 | #if defined(HAVE_AS3514) | ||
266 | static struct usb_string_descriptor usb_string_iSerial = | 234 | static struct usb_string_descriptor usb_string_iSerial = |
267 | { | 235 | { |
268 | 66, | 236 | 66, |
@@ -270,14 +238,6 @@ static struct usb_string_descriptor usb_string_iSerial = | |||
270 | {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', | 238 | {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', |
271 | '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} | 239 | '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} |
272 | }; | 240 | }; |
273 | #else | ||
274 | static struct usb_string_descriptor usb_string_iSerial = | ||
275 | { | ||
276 | 34, | ||
277 | USB_DT_STRING, | ||
278 | {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} | ||
279 | }; | ||
280 | #endif | ||
281 | 241 | ||
282 | /* Generic for all targets */ | 242 | /* Generic for all targets */ |
283 | 243 | ||
@@ -330,7 +290,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req); | |||
330 | static int ack_control(struct usb_ctrlrequest* req); | 290 | static int ack_control(struct usb_ctrlrequest* req); |
331 | 291 | ||
332 | static unsigned char *response_data; | 292 | static unsigned char *response_data; |
333 | static unsigned char __response_data[CACHEALIGN_UP(2)] CACHEALIGN_ATTR; | 293 | static unsigned char __response_data[CACHEALIGN_UP(256)] CACHEALIGN_ATTR; |
334 | 294 | ||
335 | struct usb_core_event | 295 | struct usb_core_event |
336 | { | 296 | { |
@@ -356,7 +316,8 @@ static void set_serial_descriptor(void) | |||
356 | 316 | ||
357 | /* We need to convert from a little-endian 64-bit int | 317 | /* We need to convert from a little-endian 64-bit int |
358 | into a utf-16 string of hex characters */ | 318 | into a utf-16 string of hex characters */ |
359 | short* p = &usb_string_iSerial.wString[15]; | 319 | /* Align at the right side of the 32-digit serial number */ |
320 | short* p = &usb_string_iSerial.wString[31]; | ||
360 | uint32_t x; | 321 | uint32_t x; |
361 | int i,j; | 322 | int i,j; |
362 | 323 | ||
@@ -394,7 +355,6 @@ void usb_core_init(void) | |||
394 | if (initialized) | 355 | if (initialized) |
395 | return; | 356 | return; |
396 | 357 | ||
397 | config_data = (void*)UNCACHED_ADDR(&_config_data); | ||
398 | response_data = (void*)UNCACHED_ADDR(&__response_data); | 358 | response_data = (void*)UNCACHED_ADDR(&__response_data); |
399 | 359 | ||
400 | queue_init(&usbcore_queue, false); | 360 | queue_init(&usbcore_queue, false); |
@@ -496,6 +456,12 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) | |||
496 | /* note: interrupt context */ | 456 | /* note: interrupt context */ |
497 | data_connection = true; | 457 | data_connection = true; |
498 | 458 | ||
459 | #if defined(IPOD_ARCH) || defined(HAVE_AS3514) | ||
460 | if(usb_state == DEFAULT) { | ||
461 | set_serial_descriptor(); | ||
462 | } | ||
463 | #endif | ||
464 | |||
499 | #ifdef USB_BENCHMARK | 465 | #ifdef USB_BENCHMARK |
500 | if ((req->bRequestType & 0x60) == USB_TYPE_VENDOR) { | 466 | if ((req->bRequestType & 0x60) == USB_TYPE_VENDOR) { |
501 | usb_benchmark_control_request(req); | 467 | usb_benchmark_control_request(req); |
@@ -617,7 +583,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) | |||
617 | else { | 583 | else { |
618 | max_packet_size=64; | 584 | max_packet_size=64; |
619 | } | 585 | } |
620 | config_data->config_descriptor.bDescriptorType=USB_DT_CONFIG; | 586 | config_descriptor.bDescriptorType=USB_DT_CONFIG; |
621 | } | 587 | } |
622 | else { | 588 | else { |
623 | if(usb_drv_port_speed()) { | 589 | if(usb_drv_port_speed()) { |
@@ -626,43 +592,67 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) | |||
626 | else { | 592 | else { |
627 | max_packet_size=512; | 593 | max_packet_size=512; |
628 | } | 594 | } |
629 | config_data->config_descriptor.bDescriptorType=USB_DT_OTHER_SPEED_CONFIG; | 595 | config_descriptor.bDescriptorType=USB_DT_OTHER_SPEED_CONFIG; |
630 | } | 596 | } |
597 | size = sizeof(config_descriptor); | ||
631 | 598 | ||
632 | #ifdef USB_CHARGING_ONLY | 599 | #ifdef USB_CHARGING_ONLY |
633 | memcpy(&config_data->charging_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | 600 | charging_interface_descriptor.bInterfaceNumber=interface_number; |
634 | memcpy(&config_data->charging_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | ||
635 | config_data->charging_interface_descriptor.bInterfaceNumber=interface_number; | ||
636 | interface_number++; | 601 | interface_number++; |
602 | memcpy(&response_data[size],&charging_interface_descriptor,sizeof(struct usb_interface_descriptor)); | ||
603 | size += sizeof(struct usb_interface_descriptor); | ||
637 | #endif | 604 | #endif |
638 | #ifdef USB_STORAGE | 605 | #ifdef USB_STORAGE |
639 | memcpy(&config_data->mass_storage_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | 606 | mass_storage_ep_in_descriptor.wMaxPacketSize=max_packet_size; |
640 | memcpy(&config_data->mass_storage_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | 607 | mass_storage_ep_out_descriptor.wMaxPacketSize=max_packet_size; |
641 | config_data->mass_storage_interface_descriptor.bInterfaceNumber=interface_number; | 608 | mass_storage_interface_descriptor.bInterfaceNumber=interface_number; |
642 | interface_number++; | 609 | interface_number++; |
610 | |||
611 | memcpy(&response_data[size],&mass_storage_interface_descriptor,sizeof(struct usb_interface_descriptor)); | ||
612 | size += sizeof(struct usb_interface_descriptor); | ||
613 | memcpy(&response_data[size],&mass_storage_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor)); | ||
614 | size += sizeof(struct usb_endpoint_descriptor); | ||
615 | memcpy(&response_data[size],&mass_storage_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor)); | ||
616 | size += sizeof(struct usb_endpoint_descriptor); | ||
643 | #endif | 617 | #endif |
644 | #ifdef USB_SERIAL | 618 | #ifdef USB_SERIAL |
645 | memcpy(&config_data->serial_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | 619 | serial_ep_in_descriptor.wMaxPacketSize=max_packet_size; |
646 | memcpy(&config_data->serial_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | 620 | serial_ep_out_descriptor.wMaxPacketSize=max_packet_size; |
647 | config_data->serial_interface_descriptor.bInterfaceNumber=interface_number; | 621 | serial_interface_descriptor.bInterfaceNumber=interface_number; |
648 | interface_number++; | 622 | interface_number++; |
623 | |||
624 | memcpy(&response_data[size],&serial_interface_descriptor,sizeof(struct usb_interface_descriptor)); | ||
625 | size += sizeof(struct usb_interface_descriptor); | ||
626 | memcpy(&response_data[size],&serial_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor)); | ||
627 | size += sizeof(struct usb_endpoint_descriptor); | ||
628 | memcpy(&response_data[size],&serial_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor)); | ||
629 | size += sizeof(struct usb_endpoint_descriptor); | ||
649 | #endif | 630 | #endif |
650 | #ifdef USB_BENCHMARK | 631 | #ifdef USB_BENCHMARK |
651 | memcpy(&config_data->benchmark_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | 632 | benchmark_ep_in_descriptor.wMaxPacketSize=max_packet_size; |
652 | memcpy(&config_data->benchmark_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); | 633 | benchmark_ep_out_descriptor.wMaxPacketSize=max_packet_size; |
653 | config_data.benchmark_interface_descriptor.bInterfaceNumber=interface_number; | 634 | config_descriptor.bNumInterfaces=interface_number; |
654 | interface_number++; | 635 | |
636 | memcpy(&response_data[size],&benchmark_interface_descriptor,sizeof(struct usb_interface_descriptor)); | ||
637 | size += sizeof(struct usb_interface_descriptor); | ||
638 | memcpy(&response_data[size],&benchmark_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor)); | ||
639 | size += sizeof(struct usb_endpoint_descriptor); | ||
640 | memcpy(&response_data[size],&benchmark_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor)); | ||
641 | size += sizeof(struct usb_endpoint_descriptor); | ||
655 | #endif | 642 | #endif |
656 | config_data->config_descriptor.bNumInterfaces=interface_number; | 643 | config_descriptor.wTotalLength = size; |
657 | ptr = config_data; | 644 | memcpy(&response_data[0],&config_descriptor,sizeof(struct usb_config_descriptor)); |
658 | size = sizeof _config_data; | 645 | |
646 | ptr = response_data; | ||
659 | break; | 647 | break; |
660 | } | 648 | } |
661 | 649 | ||
662 | case USB_DT_STRING: | 650 | case USB_DT_STRING: |
651 | logf("STRING %d",index); | ||
663 | if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) { | 652 | if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) { |
664 | ptr = usb_strings[index]; | ||
665 | size = usb_strings[index]->bLength; | 653 | size = usb_strings[index]->bLength; |
654 | memcpy(&response_data[0],&usb_strings[index],size); | ||
655 | ptr = response_data; | ||
666 | } | 656 | } |
667 | else { | 657 | else { |
668 | logf("bad string id %d", index); | 658 | logf("bad string id %d", index); |