blob: c256cc31fbd2e0e56e335a35a7a6f7f1b13183f2 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenk29e7f5a2004-03-12 00:14:09 +00002/*
3 * (C) Copyright 2003
4 * Gerry Hamel, geh@ti.com, Texas Instruments
5 *
Wolfgang Denk3f0137b2006-06-14 17:45:53 +02006 * (C) Copyright 2006
7 * Bryan O'Donoghue, deckard@CodeHermit.ie
8 *
wdenk29e7f5a2004-03-12 00:14:09 +00009 * Based on
10 * linux/drivers/usbd/ep0.c
11 *
12 * Copyright (c) 2000, 2001, 2002 Lineo
13 * Copyright (c) 2001 Hewlett Packard
14 *
15 * By:
16 * Stuart Lynne <sl@lineo.com>,
17 * Tom Rushworth <tbr@lineo.com>,
18 * Bruce Balden <balden@lineo.com>
wdenk29e7f5a2004-03-12 00:14:09 +000019 */
20
21/*
22 * This is the builtin ep0 control function. It implements all required functionality
23 * for responding to control requests (SETUP packets).
24 *
25 * XXX
26 *
27 * Currently we do not pass any SETUP packets (or other) to the configured
28 * function driver. This may need to change.
29 *
30 * XXX
Wolfgang Denk3f0137b2006-06-14 17:45:53 +020031 *
32 * As alluded to above, a simple callback cdc_recv_setup has been implemented
Wolfgang Denke2601822006-06-14 18:14:56 +020033 * in the usb_device data structure to facilicate passing
Wolfgang Denk3f0137b2006-06-14 17:45:53 +020034 * Common Device Class packets to a function driver.
35 *
36 * XXX
wdenk29e7f5a2004-03-12 00:14:09 +000037 */
38
39#include <common.h>
Simon Glassbd7a59a2019-11-14 12:57:23 -070040#include <serial.h>
Jean-Christophe PLAGNIOL-VILLARD8f6bcf42009-04-03 12:46:58 +020041#include <usbdevice.h>
wdenk29e7f5a2004-03-12 00:14:09 +000042
43#if 0
44#define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
45#else
46#define dbg_ep0(lvl,fmt,args...)
47#endif
48
Pali Rohár2cecb462020-12-26 19:12:11 +010049__maybe_unused static char *usbd_device_descriptors[] = {
50 "UNKNOWN", /* 0 */
51 "DEVICE", /* 1 */
52 "CONFIG", /* 2 */
53 "STRING", /* 3 */
54 "INTERFACE", /* 4 */
55 "ENDPOINT", /* 5 */
56 "DEVICE QUALIFIER", /* 6 */
57 "OTHER SPEED", /* 7 */
58 "INTERFACE POWER", /* 8 */
59};
60
61#define USBD_DEVICE_DESCRIPTORS(x) (((unsigned int)x <= USB_DESCRIPTOR_TYPE_INTERFACE_POWER) ? \
62 usbd_device_descriptors[x] : "UNKNOWN")
63
64__maybe_unused static char *usbd_device_states[] = {
65 "STATE_INIT",
66 "STATE_CREATED",
67 "STATE_ATTACHED",
68 "STATE_POWERED",
69 "STATE_DEFAULT",
70 "STATE_ADDRESSED",
71 "STATE_CONFIGURED",
72 "STATE_UNKNOWN",
73};
74
75#define USBD_DEVICE_STATE(x) (((unsigned int)x <= STATE_UNKNOWN) ? usbd_device_states[x] : "UNKNOWN")
76
77__maybe_unused static char *usbd_device_requests[] = {
78 "GET STATUS", /* 0 */
79 "CLEAR FEATURE", /* 1 */
80 "RESERVED", /* 2 */
81 "SET FEATURE", /* 3 */
82 "RESERVED", /* 4 */
83 "SET ADDRESS", /* 5 */
84 "GET DESCRIPTOR", /* 6 */
85 "SET DESCRIPTOR", /* 7 */
86 "GET CONFIGURATION", /* 8 */
87 "SET CONFIGURATION", /* 9 */
88 "GET INTERFACE", /* 10 */
89 "SET INTERFACE", /* 11 */
90 "SYNC FRAME", /* 12 */
91};
92
93#define USBD_DEVICE_REQUESTS(x) (((unsigned int)x <= USB_REQ_SYNCH_FRAME) ? usbd_device_requests[x] : "UNKNOWN")
94
wdenk29e7f5a2004-03-12 00:14:09 +000095/* EP0 Configuration Set ********************************************************************* */
96
97
98/**
99 * ep0_get_status - fill in URB data with appropriate status
100 * @device:
101 * @urb:
102 * @index:
103 * @requesttype:
104 *
105 */
106static int ep0_get_status (struct usb_device_instance *device,
107 struct urb *urb, int index, int requesttype)
108{
109 char *cp;
110
111 urb->actual_length = 2;
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200112 cp = (char*)urb->buffer;
wdenk29e7f5a2004-03-12 00:14:09 +0000113 cp[0] = cp[1] = 0;
114
115 switch (requesttype) {
116 case USB_REQ_RECIPIENT_DEVICE:
117 cp[0] = USB_STATUS_SELFPOWERED;
118 break;
119 case USB_REQ_RECIPIENT_INTERFACE:
120 break;
121 case USB_REQ_RECIPIENT_ENDPOINT:
122 cp[0] = usbd_endpoint_halted (device, index);
123 break;
124 case USB_REQ_RECIPIENT_OTHER:
125 urb->actual_length = 0;
126 default:
127 break;
128 }
129 dbg_ep0 (2, "%02x %02x", cp[0], cp[1]);
130 return 0;
131}
132
133/**
134 * ep0_get_one
135 * @device:
136 * @urb:
137 * @result:
138 *
139 * Set a single byte value in the urb send buffer. Return non-zero to signal
140 * a request error.
141 */
142static int ep0_get_one (struct usb_device_instance *device, struct urb *urb,
143 __u8 result)
144{
145 urb->actual_length = 1; /* XXX 2? */
146 ((char *) urb->buffer)[0] = result;
147 return 0;
148}
149
150/**
151 * copy_config
152 * @urb: pointer to urb
153 * @data: pointer to configuration data
154 * @length: length of data
155 *
156 * Copy configuration data to urb transfer buffer if there is room for it.
157 */
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200158void copy_config (struct urb *urb, void *data, int max_length,
wdenk29e7f5a2004-03-12 00:14:09 +0000159 int max_buf)
160{
161 int available;
162 int length;
163
164 /*dbg_ep0(3, "-> actual: %d buf: %d max_buf: %d max_length: %d data: %p", */
165 /* urb->actual_length, urb->buffer_length, max_buf, max_length, data); */
166
167 if (!data) {
168 dbg_ep0 (1, "data is NULL");
169 return;
170 }
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200171 length = max_length;
wdenk29e7f5a2004-03-12 00:14:09 +0000172
173 if (length > max_length) {
174 dbg_ep0 (1, "length: %d >= max_length: %d", length,
175 max_length);
176 return;
177 }
178 /*dbg_ep0(1, " actual: %d buf: %d max_buf: %d max_length: %d length: %d", */
179 /* urb->actual_length, urb->buffer_length, max_buf, max_length, length); */
180
181 if ((available =
182 /*urb->buffer_length */ max_buf - urb->actual_length) <= 0) {
183 return;
184 }
185 /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
186 /* urb->actual_length, urb->buffer_length, max_buf, length, available); */
187
188 if (length > available) {
189 length = available;
190 }
191 /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
192 /* urb->actual_length, urb->buffer_length, max_buf, length, available); */
193
194 memcpy (urb->buffer + urb->actual_length, data, length);
195 urb->actual_length += length;
196
197 dbg_ep0 (3,
198 "copy_config: <- actual: %d buf: %d max_buf: %d max_length: %d available: %d",
199 urb->actual_length, urb->buffer_length, max_buf, max_length,
200 available);
201}
202
203/**
204 * ep0_get_descriptor
205 * @device:
206 * @urb:
207 * @max:
208 * @descriptor_type:
209 * @index:
210 *
211 * Called by ep0_rx_process for a get descriptor device command. Determine what
212 * descriptor is being requested, copy to send buffer. Return zero if ok to send,
213 * return non-zero to signal a request error.
214 */
215static int ep0_get_descriptor (struct usb_device_instance *device,
216 struct urb *urb, int max, int descriptor_type,
217 int index)
218{
219 int port = 0; /* XXX compound device */
wdenk29e7f5a2004-03-12 00:14:09 +0000220
221 /*dbg_ep0(3, "max: %x type: %x index: %x", max, descriptor_type, index); */
222
223 if (!urb || !urb->buffer || !urb->buffer_length
224 || (urb->buffer_length < 255)) {
225 dbg_ep0 (2, "invalid urb %p", urb);
226 return -1L;
227 }
228
229 /* setup tx urb */
230 urb->actual_length = 0;
wdenk29e7f5a2004-03-12 00:14:09 +0000231
232 dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type));
233
234 switch (descriptor_type) {
235 case USB_DESCRIPTOR_TYPE_DEVICE:
236 {
237 struct usb_device_descriptor *device_descriptor;
wdenk29e7f5a2004-03-12 00:14:09 +0000238 if (!
239 (device_descriptor =
240 usbd_device_device_descriptor (device, port))) {
241 return -1;
242 }
243 /* copy descriptor for this device */
244 copy_config (urb, device_descriptor,
245 sizeof (struct usb_device_descriptor),
246 max);
247
248 /* correct the correct control endpoint 0 max packet size into the descriptor */
249 device_descriptor =
250 (struct usb_device_descriptor *) urb->buffer;
wdenk29e7f5a2004-03-12 00:14:09 +0000251
252 }
Wolfgang Denke2601822006-06-14 18:14:56 +0200253 dbg_ep0(3, "copied device configuration, actual_length: 0x%x", urb->actual_length);
wdenk29e7f5a2004-03-12 00:14:09 +0000254 break;
255
256 case USB_DESCRIPTOR_TYPE_CONFIGURATION:
257 {
wdenk29e7f5a2004-03-12 00:14:09 +0000258 struct usb_configuration_descriptor
259 *configuration_descriptor;
260 struct usb_device_descriptor *device_descriptor;
wdenk29e7f5a2004-03-12 00:14:09 +0000261 if (!
262 (device_descriptor =
263 usbd_device_device_descriptor (device, port))) {
264 return -1;
265 }
266 /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
Harald Welteed1c3f02008-07-07 00:58:05 +0800267 if (index >= device_descriptor->bNumConfigurations) {
268 dbg_ep0 (0, "index too large: %d >= %d", index,
wdenk29e7f5a2004-03-12 00:14:09 +0000269 device_descriptor->
270 bNumConfigurations);
271 return -1;
272 }
273
274 if (!
275 (configuration_descriptor =
276 usbd_device_configuration_descriptor (device,
277 port,
278 index))) {
279 dbg_ep0 (0,
280 "usbd_device_configuration_descriptor failed: %d",
281 index);
282 return -1;
283 }
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200284 dbg_ep0(0, "attempt to copy %d bytes to urb\n",cpu_to_le16(configuration_descriptor->wTotalLength));
wdenk29e7f5a2004-03-12 00:14:09 +0000285 copy_config (urb, configuration_descriptor,
wdenk29e7f5a2004-03-12 00:14:09 +0000286
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200287 cpu_to_le16(configuration_descriptor->wTotalLength),
288 max);
wdenk29e7f5a2004-03-12 00:14:09 +0000289 }
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200290
wdenk29e7f5a2004-03-12 00:14:09 +0000291 break;
292
293 case USB_DESCRIPTOR_TYPE_STRING:
294 {
295 struct usb_string_descriptor *string_descriptor;
wdenk29e7f5a2004-03-12 00:14:09 +0000296 if (!(string_descriptor = usbd_get_string (index))) {
Pali Roháre4670002021-02-07 14:50:11 +0100297 dbg_ep0(0, "Invalid string index %d\n", index);
wdenk29e7f5a2004-03-12 00:14:09 +0000298 return -1;
299 }
Wolfgang Denke2601822006-06-14 18:14:56 +0200300 dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength);
wdenk29e7f5a2004-03-12 00:14:09 +0000301 copy_config (urb, string_descriptor, string_descriptor->bLength, max);
302 }
303 break;
304 case USB_DESCRIPTOR_TYPE_INTERFACE:
Pali Roháre4670002021-02-07 14:50:11 +0100305 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000306 return -1;
307 case USB_DESCRIPTOR_TYPE_ENDPOINT:
Pali Roháre4670002021-02-07 14:50:11 +0100308 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000309 return -1;
310 case USB_DESCRIPTOR_TYPE_HID:
311 {
Pali Roháre4670002021-02-07 14:50:11 +0100312 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000313 return -1; /* unsupported at this time */
314#if 0
315 int bNumInterface =
316 le16_to_cpu (urb->device_request.wIndex);
317 int bAlternateSetting = 0;
318 int class = 0;
319 struct usb_class_descriptor *class_descriptor;
320
321 if (!(class_descriptor =
322 usbd_device_class_descriptor_index (device,
323 port, 0,
324 bNumInterface,
325 bAlternateSetting,
326 class))
327 || class_descriptor->descriptor.hid.bDescriptorType != USB_DT_HID) {
328 dbg_ep0 (3, "[%d] interface is not HID",
329 bNumInterface);
330 return -1;
331 }
332 /* copy descriptor for this class */
333 copy_config (urb, class_descriptor,
334 class_descriptor->descriptor.hid.bLength,
335 max);
336#endif
337 }
338 break;
339 case USB_DESCRIPTOR_TYPE_REPORT:
340 {
Pali Roháre4670002021-02-07 14:50:11 +0100341 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000342 return -1; /* unsupported at this time */
343#if 0
344 int bNumInterface =
345 le16_to_cpu (urb->device_request.wIndex);
346 int bAlternateSetting = 0;
347 int class = 0;
348 struct usb_class_report_descriptor *report_descriptor;
349
350 if (!(report_descriptor =
351 usbd_device_class_report_descriptor_index
352 (device, port, 0, bNumInterface,
353 bAlternateSetting, class))
354 || report_descriptor->bDescriptorType !=
355 USB_DT_REPORT) {
356 dbg_ep0 (3, "[%d] descriptor is not REPORT",
357 bNumInterface);
358 return -1;
359 }
360 /* copy report descriptor for this class */
361 /*copy_config(urb, &report_descriptor->bData[0], report_descriptor->wLength, max); */
362 if (max - urb->actual_length > 0) {
363 int length =
Masahiro Yamadab62b39b2014-09-18 13:28:06 +0900364 min(report_descriptor->wLength,
wdenk29e7f5a2004-03-12 00:14:09 +0000365 max - urb->actual_length);
366 memcpy (urb->buffer + urb->actual_length,
367 &report_descriptor->bData[0], length);
368 urb->actual_length += length;
369 }
370#endif
371 }
372 break;
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200373 case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
Vipin KUMARbdb17702012-03-26 15:38:06 +0530374 return -1;
Vipin KUMARbdb17702012-03-26 15:38:06 +0530375
wdenk29e7f5a2004-03-12 00:14:09 +0000376 default:
377 return -1;
378 }
379
380
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200381 dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d tx_packetSize: %2d",
wdenk29e7f5a2004-03-12 00:14:09 +0000382 urb->buffer, urb->buffer_length, urb->actual_length,
383 device->bus->endpoint_array[0].tx_packetSize);
384/*
385 if ((urb->actual_length < max) && !(urb->actual_length % device->bus->endpoint_array[0].tx_packetSize)) {
386 dbg_ep0(0, "adding null byte");
387 urb->buffer[urb->actual_length++] = 0;
388 dbg_ep0(0, "urb: buffer_length: %2d actual_length: %2d packet size: %2d",
389 urb->buffer_length, urb->actual_length device->bus->endpoint_array[0].tx_packetSize);
390 }
391*/
392 return 0;
393
394}
395
396/**
397 * ep0_recv_setup - called to indicate URB has been received
398 * @urb: pointer to struct urb
399 *
400 * Check if this is a setup packet, process the device request, put results
401 * back into the urb and return zero or non-zero to indicate success (DATA)
402 * or failure (STALL).
403 *
404 */
405int ep0_recv_setup (struct urb *urb)
406{
407 /*struct usb_device_request *request = urb->buffer; */
408 /*struct usb_device_instance *device = urb->device; */
409
410 struct usb_device_request *request;
411 struct usb_device_instance *device;
412 int address;
413
414 dbg_ep0 (0, "entering ep0_recv_setup()");
415 if (!urb || !urb->device) {
416 dbg_ep0 (3, "invalid URB %p", urb);
417 return -1;
418 }
419
420 request = &urb->device_request;
421 device = urb->device;
422
423 dbg_ep0 (3, "urb: %p device: %p", urb, urb->device);
424
425
426 /*dbg_ep0(2, "- - - - - - - - - -"); */
427
428 dbg_ep0 (2,
429 "bmRequestType:%02x bRequest:%02x wValue:%04x wIndex:%04x wLength:%04x %s",
430 request->bmRequestType, request->bRequest,
431 le16_to_cpu (request->wValue), le16_to_cpu (request->wIndex),
432 le16_to_cpu (request->wLength),
433 USBD_DEVICE_REQUESTS (request->bRequest));
434
435 /* handle USB Standard Request (c.f. USB Spec table 9-2) */
436 if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200437 if(device->device_state <= STATE_CONFIGURED){
438 /* Attempt to handle a CDC specific request if we are
439 * in the configured state.
440 */
441 return device->cdc_recv_setup(request,urb);
442 }
wdenk29e7f5a2004-03-12 00:14:09 +0000443 dbg_ep0 (1, "non standard request: %x",
444 request->bmRequestType & USB_REQ_TYPE_MASK);
445 return -1; /* Stall here */
446 }
447
448 switch (device->device_state) {
449 case STATE_CREATED:
450 case STATE_ATTACHED:
451 case STATE_POWERED:
452 /* It actually is important to allow requests in these states,
453 * Windows will request descriptors before assigning an
454 * address to the client.
455 */
456
457 /*dbg_ep0 (1, "request %s not allowed in this state: %s", */
458 /* USBD_DEVICE_REQUESTS(request->bRequest), */
459 /* usbd_device_states[device->device_state]); */
460 /*return -1; */
461 break;
462
463 case STATE_INIT:
464 case STATE_DEFAULT:
465 switch (request->bRequest) {
466 case USB_REQ_GET_STATUS:
467 case USB_REQ_GET_INTERFACE:
468 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
469 case USB_REQ_CLEAR_FEATURE:
470 case USB_REQ_SET_FEATURE:
471 case USB_REQ_SET_DESCRIPTOR:
472 /* case USB_REQ_SET_CONFIGURATION: */
473 case USB_REQ_SET_INTERFACE:
474 dbg_ep0 (1,
475 "request %s not allowed in DEFAULT state: %s",
476 USBD_DEVICE_REQUESTS (request->bRequest),
477 usbd_device_states[device->device_state]);
478 return -1;
479
480 case USB_REQ_SET_CONFIGURATION:
481 case USB_REQ_SET_ADDRESS:
482 case USB_REQ_GET_DESCRIPTOR:
483 case USB_REQ_GET_CONFIGURATION:
484 break;
485 }
486 case STATE_ADDRESSED:
487 case STATE_CONFIGURED:
488 break;
489 case STATE_UNKNOWN:
490 dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s",
491 USBD_DEVICE_REQUESTS (request->bRequest),
492 usbd_device_states[device->device_state]);
493 return -1;
494 }
495
496 /* handle all requests that return data (direction bit set on bm RequestType) */
497 if ((request->bmRequestType & USB_REQ_DIRECTION_MASK)) {
498
499 dbg_ep0 (3, "Device-to-Host");
500
501 switch (request->bRequest) {
502
503 case USB_REQ_GET_STATUS:
504 return ep0_get_status (device, urb, request->wIndex,
505 request->bmRequestType &
506 USB_REQ_RECIPIENT_MASK);
507
508 case USB_REQ_GET_DESCRIPTOR:
509 return ep0_get_descriptor (device, urb,
510 le16_to_cpu (request->wLength),
511 le16_to_cpu (request->wValue) >> 8,
512 le16_to_cpu (request->wValue) & 0xff);
513
514 case USB_REQ_GET_CONFIGURATION:
Pali Roháre4670002021-02-07 14:50:11 +0100515 dbg_ep0(2, "get config %d\n", device->configuration);
wdenk29e7f5a2004-03-12 00:14:09 +0000516 return ep0_get_one (device, urb,
517 device->configuration);
518
519 case USB_REQ_GET_INTERFACE:
520 return ep0_get_one (device, urb, device->alternate);
521
522 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
523 return -1;
524
525 case USB_REQ_CLEAR_FEATURE:
526 case USB_REQ_SET_FEATURE:
527 case USB_REQ_SET_ADDRESS:
528 case USB_REQ_SET_DESCRIPTOR:
529 case USB_REQ_SET_CONFIGURATION:
530 case USB_REQ_SET_INTERFACE:
531 return -1;
532 }
533 }
534 /* handle the requests that do not return data */
535 else {
536
537
538 /*dbg_ep0(3, "Host-to-Device"); */
539 switch (request->bRequest) {
540
541 case USB_REQ_CLEAR_FEATURE:
542 case USB_REQ_SET_FEATURE:
543 dbg_ep0 (0, "Host-to-Device");
544 switch (request->
545 bmRequestType & USB_REQ_RECIPIENT_MASK) {
546 case USB_REQ_RECIPIENT_DEVICE:
547 /* XXX DEVICE_REMOTE_WAKEUP or TEST_MODE would be added here */
548 /* XXX fall through for now as we do not support either */
549 case USB_REQ_RECIPIENT_INTERFACE:
550 case USB_REQ_RECIPIENT_OTHER:
551 dbg_ep0 (0, "request %s not",
552 USBD_DEVICE_REQUESTS (request->bRequest));
553 default:
554 return -1;
555
556 case USB_REQ_RECIPIENT_ENDPOINT:
557 dbg_ep0 (0, "ENDPOINT: %x", le16_to_cpu (request->wValue));
558 if (le16_to_cpu (request->wValue) == USB_ENDPOINT_HALT) {
559 /*return usbd_device_feature (device, le16_to_cpu (request->wIndex), */
560 /* request->bRequest == USB_REQ_SET_FEATURE); */
561 /* NEED TO IMPLEMENT THIS!!! */
562 return -1;
563 } else {
564 dbg_ep0 (1, "request %s bad wValue: %04x",
565 USBD_DEVICE_REQUESTS
566 (request->bRequest),
567 le16_to_cpu (request->wValue));
568 return -1;
569 }
570 }
571
572 case USB_REQ_SET_ADDRESS:
573 /* check if this is a re-address, reset first if it is (this shouldn't be possible) */
574 if (device->device_state != STATE_DEFAULT) {
575 dbg_ep0 (1, "set_address: %02x state: %s",
576 le16_to_cpu (request->wValue),
577 usbd_device_states[device->device_state]);
578 return -1;
579 }
580 address = le16_to_cpu (request->wValue);
581 if ((address & 0x7f) != address) {
582 dbg_ep0 (1, "invalid address %04x %04x",
583 address, address & 0x7f);
584 return -1;
585 }
586 device->address = address;
587
588 /*dbg_ep0(2, "address: %d %d %d", */
589 /* request->wValue, le16_to_cpu(request->wValue), device->address); */
590
wdenk29e7f5a2004-03-12 00:14:09 +0000591 return 0;
592
593 case USB_REQ_SET_DESCRIPTOR: /* XXX should we support this? */
594 dbg_ep0 (0, "set descriptor: NOT SUPPORTED");
595 return -1;
596
597 case USB_REQ_SET_CONFIGURATION:
598 /* c.f. 9.4.7 - the top half of wValue is reserved */
Harald Welteed1c3f02008-07-07 00:58:05 +0800599 device->configuration = le16_to_cpu(request->wValue) & 0xff;
600
wdenk29e7f5a2004-03-12 00:14:09 +0000601 /* reset interface and alternate settings */
602 device->interface = device->alternate = 0;
603
604 /*dbg_ep0(2, "set configuration: %d", device->configuration); */
Pali Roháre4670002021-02-07 14:50:11 +0100605 /*dbg_ep0(2, "DEVICE_CONFIGURED.. event?\n"); */
wdenk29e7f5a2004-03-12 00:14:09 +0000606 return 0;
607
608 case USB_REQ_SET_INTERFACE:
609 device->interface = le16_to_cpu (request->wIndex);
610 device->alternate = le16_to_cpu (request->wValue);
611 /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
Pali Roháre4670002021-02-07 14:50:11 +0100612 dbg_ep0(2, "DEVICE_SET_INTERFACE.. event?\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000613 return 0;
614
615 case USB_REQ_GET_STATUS:
616 case USB_REQ_GET_DESCRIPTOR:
617 case USB_REQ_GET_CONFIGURATION:
618 case USB_REQ_GET_INTERFACE:
619 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
620 return -1;
621 }
622 }
623 return -1;
624}