blob: 9d08640ff23ac4972512046589ef8a240c719060 [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
Simon Glassbd7a59a2019-11-14 12:57:23 -070039#include <serial.h>
Jean-Christophe PLAGNIOL-VILLARD8f6bcf42009-04-03 12:46:58 +020040#include <usbdevice.h>
wdenk29e7f5a2004-03-12 00:14:09 +000041
42#if 0
43#define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
44#else
45#define dbg_ep0(lvl,fmt,args...)
46#endif
47
Pali Rohár2cecb462020-12-26 19:12:11 +010048__maybe_unused static char *usbd_device_descriptors[] = {
49 "UNKNOWN", /* 0 */
50 "DEVICE", /* 1 */
51 "CONFIG", /* 2 */
52 "STRING", /* 3 */
53 "INTERFACE", /* 4 */
54 "ENDPOINT", /* 5 */
55 "DEVICE QUALIFIER", /* 6 */
56 "OTHER SPEED", /* 7 */
57 "INTERFACE POWER", /* 8 */
58};
59
60#define USBD_DEVICE_DESCRIPTORS(x) (((unsigned int)x <= USB_DESCRIPTOR_TYPE_INTERFACE_POWER) ? \
61 usbd_device_descriptors[x] : "UNKNOWN")
62
63__maybe_unused static char *usbd_device_states[] = {
64 "STATE_INIT",
65 "STATE_CREATED",
66 "STATE_ATTACHED",
67 "STATE_POWERED",
68 "STATE_DEFAULT",
69 "STATE_ADDRESSED",
70 "STATE_CONFIGURED",
71 "STATE_UNKNOWN",
72};
73
74#define USBD_DEVICE_STATE(x) (((unsigned int)x <= STATE_UNKNOWN) ? usbd_device_states[x] : "UNKNOWN")
75
76__maybe_unused static char *usbd_device_requests[] = {
77 "GET STATUS", /* 0 */
78 "CLEAR FEATURE", /* 1 */
79 "RESERVED", /* 2 */
80 "SET FEATURE", /* 3 */
81 "RESERVED", /* 4 */
82 "SET ADDRESS", /* 5 */
83 "GET DESCRIPTOR", /* 6 */
84 "SET DESCRIPTOR", /* 7 */
85 "GET CONFIGURATION", /* 8 */
86 "SET CONFIGURATION", /* 9 */
87 "GET INTERFACE", /* 10 */
88 "SET INTERFACE", /* 11 */
89 "SYNC FRAME", /* 12 */
90};
91
92#define USBD_DEVICE_REQUESTS(x) (((unsigned int)x <= USB_REQ_SYNCH_FRAME) ? usbd_device_requests[x] : "UNKNOWN")
93
wdenk29e7f5a2004-03-12 00:14:09 +000094/* EP0 Configuration Set ********************************************************************* */
95
96
97/**
98 * ep0_get_status - fill in URB data with appropriate status
99 * @device:
100 * @urb:
101 * @index:
102 * @requesttype:
103 *
104 */
105static int ep0_get_status (struct usb_device_instance *device,
106 struct urb *urb, int index, int requesttype)
107{
108 char *cp;
109
110 urb->actual_length = 2;
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200111 cp = (char*)urb->buffer;
wdenk29e7f5a2004-03-12 00:14:09 +0000112 cp[0] = cp[1] = 0;
113
114 switch (requesttype) {
115 case USB_REQ_RECIPIENT_DEVICE:
116 cp[0] = USB_STATUS_SELFPOWERED;
117 break;
118 case USB_REQ_RECIPIENT_INTERFACE:
119 break;
120 case USB_REQ_RECIPIENT_ENDPOINT:
121 cp[0] = usbd_endpoint_halted (device, index);
122 break;
123 case USB_REQ_RECIPIENT_OTHER:
124 urb->actual_length = 0;
125 default:
126 break;
127 }
128 dbg_ep0 (2, "%02x %02x", cp[0], cp[1]);
129 return 0;
130}
131
132/**
133 * ep0_get_one
134 * @device:
135 * @urb:
136 * @result:
137 *
138 * Set a single byte value in the urb send buffer. Return non-zero to signal
139 * a request error.
140 */
141static int ep0_get_one (struct usb_device_instance *device, struct urb *urb,
142 __u8 result)
143{
144 urb->actual_length = 1; /* XXX 2? */
145 ((char *) urb->buffer)[0] = result;
146 return 0;
147}
148
149/**
150 * copy_config
151 * @urb: pointer to urb
152 * @data: pointer to configuration data
153 * @length: length of data
154 *
155 * Copy configuration data to urb transfer buffer if there is room for it.
156 */
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200157void copy_config (struct urb *urb, void *data, int max_length,
wdenk29e7f5a2004-03-12 00:14:09 +0000158 int max_buf)
159{
160 int available;
161 int length;
162
163 /*dbg_ep0(3, "-> actual: %d buf: %d max_buf: %d max_length: %d data: %p", */
164 /* urb->actual_length, urb->buffer_length, max_buf, max_length, data); */
165
166 if (!data) {
167 dbg_ep0 (1, "data is NULL");
168 return;
169 }
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200170 length = max_length;
wdenk29e7f5a2004-03-12 00:14:09 +0000171
172 if (length > max_length) {
173 dbg_ep0 (1, "length: %d >= max_length: %d", length,
174 max_length);
175 return;
176 }
177 /*dbg_ep0(1, " actual: %d buf: %d max_buf: %d max_length: %d length: %d", */
178 /* urb->actual_length, urb->buffer_length, max_buf, max_length, length); */
179
180 if ((available =
181 /*urb->buffer_length */ max_buf - urb->actual_length) <= 0) {
182 return;
183 }
184 /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
185 /* urb->actual_length, urb->buffer_length, max_buf, length, available); */
186
187 if (length > available) {
188 length = available;
189 }
190 /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
191 /* urb->actual_length, urb->buffer_length, max_buf, length, available); */
192
193 memcpy (urb->buffer + urb->actual_length, data, length);
194 urb->actual_length += length;
195
196 dbg_ep0 (3,
197 "copy_config: <- actual: %d buf: %d max_buf: %d max_length: %d available: %d",
198 urb->actual_length, urb->buffer_length, max_buf, max_length,
199 available);
200}
201
202/**
203 * ep0_get_descriptor
204 * @device:
205 * @urb:
206 * @max:
207 * @descriptor_type:
208 * @index:
209 *
210 * Called by ep0_rx_process for a get descriptor device command. Determine what
211 * descriptor is being requested, copy to send buffer. Return zero if ok to send,
212 * return non-zero to signal a request error.
213 */
214static int ep0_get_descriptor (struct usb_device_instance *device,
215 struct urb *urb, int max, int descriptor_type,
216 int index)
217{
218 int port = 0; /* XXX compound device */
wdenk29e7f5a2004-03-12 00:14:09 +0000219
220 /*dbg_ep0(3, "max: %x type: %x index: %x", max, descriptor_type, index); */
221
222 if (!urb || !urb->buffer || !urb->buffer_length
223 || (urb->buffer_length < 255)) {
224 dbg_ep0 (2, "invalid urb %p", urb);
225 return -1L;
226 }
227
228 /* setup tx urb */
229 urb->actual_length = 0;
wdenk29e7f5a2004-03-12 00:14:09 +0000230
231 dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type));
232
233 switch (descriptor_type) {
234 case USB_DESCRIPTOR_TYPE_DEVICE:
235 {
236 struct usb_device_descriptor *device_descriptor;
wdenk29e7f5a2004-03-12 00:14:09 +0000237 if (!
238 (device_descriptor =
239 usbd_device_device_descriptor (device, port))) {
240 return -1;
241 }
242 /* copy descriptor for this device */
243 copy_config (urb, device_descriptor,
244 sizeof (struct usb_device_descriptor),
245 max);
246
247 /* correct the correct control endpoint 0 max packet size into the descriptor */
248 device_descriptor =
249 (struct usb_device_descriptor *) urb->buffer;
wdenk29e7f5a2004-03-12 00:14:09 +0000250
251 }
Wolfgang Denke2601822006-06-14 18:14:56 +0200252 dbg_ep0(3, "copied device configuration, actual_length: 0x%x", urb->actual_length);
wdenk29e7f5a2004-03-12 00:14:09 +0000253 break;
254
255 case USB_DESCRIPTOR_TYPE_CONFIGURATION:
256 {
wdenk29e7f5a2004-03-12 00:14:09 +0000257 struct usb_configuration_descriptor
258 *configuration_descriptor;
259 struct usb_device_descriptor *device_descriptor;
wdenk29e7f5a2004-03-12 00:14:09 +0000260 if (!
261 (device_descriptor =
262 usbd_device_device_descriptor (device, port))) {
263 return -1;
264 }
265 /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
Harald Welteed1c3f02008-07-07 00:58:05 +0800266 if (index >= device_descriptor->bNumConfigurations) {
267 dbg_ep0 (0, "index too large: %d >= %d", index,
wdenk29e7f5a2004-03-12 00:14:09 +0000268 device_descriptor->
269 bNumConfigurations);
270 return -1;
271 }
272
273 if (!
274 (configuration_descriptor =
275 usbd_device_configuration_descriptor (device,
276 port,
277 index))) {
278 dbg_ep0 (0,
279 "usbd_device_configuration_descriptor failed: %d",
280 index);
281 return -1;
282 }
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200283 dbg_ep0(0, "attempt to copy %d bytes to urb\n",cpu_to_le16(configuration_descriptor->wTotalLength));
wdenk29e7f5a2004-03-12 00:14:09 +0000284 copy_config (urb, configuration_descriptor,
wdenk29e7f5a2004-03-12 00:14:09 +0000285
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200286 cpu_to_le16(configuration_descriptor->wTotalLength),
287 max);
wdenk29e7f5a2004-03-12 00:14:09 +0000288 }
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200289
wdenk29e7f5a2004-03-12 00:14:09 +0000290 break;
291
292 case USB_DESCRIPTOR_TYPE_STRING:
293 {
294 struct usb_string_descriptor *string_descriptor;
wdenk29e7f5a2004-03-12 00:14:09 +0000295 if (!(string_descriptor = usbd_get_string (index))) {
Pali Roháre4670002021-02-07 14:50:11 +0100296 dbg_ep0(0, "Invalid string index %d\n", index);
wdenk29e7f5a2004-03-12 00:14:09 +0000297 return -1;
298 }
Wolfgang Denke2601822006-06-14 18:14:56 +0200299 dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength);
wdenk29e7f5a2004-03-12 00:14:09 +0000300 copy_config (urb, string_descriptor, string_descriptor->bLength, max);
301 }
302 break;
303 case USB_DESCRIPTOR_TYPE_INTERFACE:
Pali Roháre4670002021-02-07 14:50:11 +0100304 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000305 return -1;
306 case USB_DESCRIPTOR_TYPE_ENDPOINT:
Pali Roháre4670002021-02-07 14:50:11 +0100307 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000308 return -1;
309 case USB_DESCRIPTOR_TYPE_HID:
310 {
Pali Roháre4670002021-02-07 14:50:11 +0100311 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000312 return -1; /* unsupported at this time */
313#if 0
314 int bNumInterface =
315 le16_to_cpu (urb->device_request.wIndex);
316 int bAlternateSetting = 0;
317 int class = 0;
318 struct usb_class_descriptor *class_descriptor;
319
320 if (!(class_descriptor =
321 usbd_device_class_descriptor_index (device,
322 port, 0,
323 bNumInterface,
324 bAlternateSetting,
325 class))
326 || class_descriptor->descriptor.hid.bDescriptorType != USB_DT_HID) {
327 dbg_ep0 (3, "[%d] interface is not HID",
328 bNumInterface);
329 return -1;
330 }
331 /* copy descriptor for this class */
332 copy_config (urb, class_descriptor,
333 class_descriptor->descriptor.hid.bLength,
334 max);
335#endif
336 }
337 break;
338 case USB_DESCRIPTOR_TYPE_REPORT:
339 {
Pali Roháre4670002021-02-07 14:50:11 +0100340 dbg_ep0(2, "USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000341 return -1; /* unsupported at this time */
342#if 0
343 int bNumInterface =
344 le16_to_cpu (urb->device_request.wIndex);
345 int bAlternateSetting = 0;
346 int class = 0;
347 struct usb_class_report_descriptor *report_descriptor;
348
349 if (!(report_descriptor =
350 usbd_device_class_report_descriptor_index
351 (device, port, 0, bNumInterface,
352 bAlternateSetting, class))
353 || report_descriptor->bDescriptorType !=
354 USB_DT_REPORT) {
355 dbg_ep0 (3, "[%d] descriptor is not REPORT",
356 bNumInterface);
357 return -1;
358 }
359 /* copy report descriptor for this class */
360 /*copy_config(urb, &report_descriptor->bData[0], report_descriptor->wLength, max); */
361 if (max - urb->actual_length > 0) {
362 int length =
Masahiro Yamadab62b39b2014-09-18 13:28:06 +0900363 min(report_descriptor->wLength,
wdenk29e7f5a2004-03-12 00:14:09 +0000364 max - urb->actual_length);
365 memcpy (urb->buffer + urb->actual_length,
366 &report_descriptor->bData[0], length);
367 urb->actual_length += length;
368 }
369#endif
370 }
371 break;
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200372 case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
Vipin KUMARbdb17702012-03-26 15:38:06 +0530373 return -1;
Vipin KUMARbdb17702012-03-26 15:38:06 +0530374
wdenk29e7f5a2004-03-12 00:14:09 +0000375 default:
376 return -1;
377 }
378
379
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200380 dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d tx_packetSize: %2d",
wdenk29e7f5a2004-03-12 00:14:09 +0000381 urb->buffer, urb->buffer_length, urb->actual_length,
382 device->bus->endpoint_array[0].tx_packetSize);
383/*
384 if ((urb->actual_length < max) && !(urb->actual_length % device->bus->endpoint_array[0].tx_packetSize)) {
385 dbg_ep0(0, "adding null byte");
386 urb->buffer[urb->actual_length++] = 0;
387 dbg_ep0(0, "urb: buffer_length: %2d actual_length: %2d packet size: %2d",
388 urb->buffer_length, urb->actual_length device->bus->endpoint_array[0].tx_packetSize);
389 }
390*/
391 return 0;
392
393}
394
395/**
396 * ep0_recv_setup - called to indicate URB has been received
397 * @urb: pointer to struct urb
398 *
399 * Check if this is a setup packet, process the device request, put results
400 * back into the urb and return zero or non-zero to indicate success (DATA)
401 * or failure (STALL).
402 *
403 */
404int ep0_recv_setup (struct urb *urb)
405{
406 /*struct usb_device_request *request = urb->buffer; */
407 /*struct usb_device_instance *device = urb->device; */
408
409 struct usb_device_request *request;
410 struct usb_device_instance *device;
411 int address;
412
413 dbg_ep0 (0, "entering ep0_recv_setup()");
414 if (!urb || !urb->device) {
415 dbg_ep0 (3, "invalid URB %p", urb);
416 return -1;
417 }
418
419 request = &urb->device_request;
420 device = urb->device;
421
422 dbg_ep0 (3, "urb: %p device: %p", urb, urb->device);
423
424
425 /*dbg_ep0(2, "- - - - - - - - - -"); */
426
427 dbg_ep0 (2,
428 "bmRequestType:%02x bRequest:%02x wValue:%04x wIndex:%04x wLength:%04x %s",
429 request->bmRequestType, request->bRequest,
430 le16_to_cpu (request->wValue), le16_to_cpu (request->wIndex),
431 le16_to_cpu (request->wLength),
432 USBD_DEVICE_REQUESTS (request->bRequest));
433
434 /* handle USB Standard Request (c.f. USB Spec table 9-2) */
435 if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
Wolfgang Denk3f0137b2006-06-14 17:45:53 +0200436 if(device->device_state <= STATE_CONFIGURED){
437 /* Attempt to handle a CDC specific request if we are
438 * in the configured state.
439 */
440 return device->cdc_recv_setup(request,urb);
441 }
wdenk29e7f5a2004-03-12 00:14:09 +0000442 dbg_ep0 (1, "non standard request: %x",
443 request->bmRequestType & USB_REQ_TYPE_MASK);
444 return -1; /* Stall here */
445 }
446
447 switch (device->device_state) {
448 case STATE_CREATED:
449 case STATE_ATTACHED:
450 case STATE_POWERED:
451 /* It actually is important to allow requests in these states,
452 * Windows will request descriptors before assigning an
453 * address to the client.
454 */
455
456 /*dbg_ep0 (1, "request %s not allowed in this state: %s", */
457 /* USBD_DEVICE_REQUESTS(request->bRequest), */
458 /* usbd_device_states[device->device_state]); */
459 /*return -1; */
460 break;
461
462 case STATE_INIT:
463 case STATE_DEFAULT:
464 switch (request->bRequest) {
465 case USB_REQ_GET_STATUS:
466 case USB_REQ_GET_INTERFACE:
467 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
468 case USB_REQ_CLEAR_FEATURE:
469 case USB_REQ_SET_FEATURE:
470 case USB_REQ_SET_DESCRIPTOR:
471 /* case USB_REQ_SET_CONFIGURATION: */
472 case USB_REQ_SET_INTERFACE:
473 dbg_ep0 (1,
474 "request %s not allowed in DEFAULT state: %s",
475 USBD_DEVICE_REQUESTS (request->bRequest),
476 usbd_device_states[device->device_state]);
477 return -1;
478
479 case USB_REQ_SET_CONFIGURATION:
480 case USB_REQ_SET_ADDRESS:
481 case USB_REQ_GET_DESCRIPTOR:
482 case USB_REQ_GET_CONFIGURATION:
483 break;
484 }
485 case STATE_ADDRESSED:
486 case STATE_CONFIGURED:
487 break;
488 case STATE_UNKNOWN:
489 dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s",
490 USBD_DEVICE_REQUESTS (request->bRequest),
491 usbd_device_states[device->device_state]);
492 return -1;
493 }
494
495 /* handle all requests that return data (direction bit set on bm RequestType) */
496 if ((request->bmRequestType & USB_REQ_DIRECTION_MASK)) {
497
498 dbg_ep0 (3, "Device-to-Host");
499
500 switch (request->bRequest) {
501
502 case USB_REQ_GET_STATUS:
503 return ep0_get_status (device, urb, request->wIndex,
504 request->bmRequestType &
505 USB_REQ_RECIPIENT_MASK);
506
507 case USB_REQ_GET_DESCRIPTOR:
508 return ep0_get_descriptor (device, urb,
509 le16_to_cpu (request->wLength),
510 le16_to_cpu (request->wValue) >> 8,
511 le16_to_cpu (request->wValue) & 0xff);
512
513 case USB_REQ_GET_CONFIGURATION:
Pali Roháre4670002021-02-07 14:50:11 +0100514 dbg_ep0(2, "get config %d\n", device->configuration);
wdenk29e7f5a2004-03-12 00:14:09 +0000515 return ep0_get_one (device, urb,
516 device->configuration);
517
518 case USB_REQ_GET_INTERFACE:
519 return ep0_get_one (device, urb, device->alternate);
520
521 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
522 return -1;
523
524 case USB_REQ_CLEAR_FEATURE:
525 case USB_REQ_SET_FEATURE:
526 case USB_REQ_SET_ADDRESS:
527 case USB_REQ_SET_DESCRIPTOR:
528 case USB_REQ_SET_CONFIGURATION:
529 case USB_REQ_SET_INTERFACE:
530 return -1;
531 }
532 }
533 /* handle the requests that do not return data */
534 else {
535
536
537 /*dbg_ep0(3, "Host-to-Device"); */
538 switch (request->bRequest) {
539
540 case USB_REQ_CLEAR_FEATURE:
541 case USB_REQ_SET_FEATURE:
542 dbg_ep0 (0, "Host-to-Device");
543 switch (request->
544 bmRequestType & USB_REQ_RECIPIENT_MASK) {
545 case USB_REQ_RECIPIENT_DEVICE:
546 /* XXX DEVICE_REMOTE_WAKEUP or TEST_MODE would be added here */
547 /* XXX fall through for now as we do not support either */
548 case USB_REQ_RECIPIENT_INTERFACE:
549 case USB_REQ_RECIPIENT_OTHER:
550 dbg_ep0 (0, "request %s not",
551 USBD_DEVICE_REQUESTS (request->bRequest));
552 default:
553 return -1;
554
555 case USB_REQ_RECIPIENT_ENDPOINT:
556 dbg_ep0 (0, "ENDPOINT: %x", le16_to_cpu (request->wValue));
557 if (le16_to_cpu (request->wValue) == USB_ENDPOINT_HALT) {
558 /*return usbd_device_feature (device, le16_to_cpu (request->wIndex), */
559 /* request->bRequest == USB_REQ_SET_FEATURE); */
560 /* NEED TO IMPLEMENT THIS!!! */
561 return -1;
562 } else {
563 dbg_ep0 (1, "request %s bad wValue: %04x",
564 USBD_DEVICE_REQUESTS
565 (request->bRequest),
566 le16_to_cpu (request->wValue));
567 return -1;
568 }
569 }
570
571 case USB_REQ_SET_ADDRESS:
572 /* check if this is a re-address, reset first if it is (this shouldn't be possible) */
573 if (device->device_state != STATE_DEFAULT) {
574 dbg_ep0 (1, "set_address: %02x state: %s",
575 le16_to_cpu (request->wValue),
576 usbd_device_states[device->device_state]);
577 return -1;
578 }
579 address = le16_to_cpu (request->wValue);
580 if ((address & 0x7f) != address) {
581 dbg_ep0 (1, "invalid address %04x %04x",
582 address, address & 0x7f);
583 return -1;
584 }
585 device->address = address;
586
587 /*dbg_ep0(2, "address: %d %d %d", */
588 /* request->wValue, le16_to_cpu(request->wValue), device->address); */
589
wdenk29e7f5a2004-03-12 00:14:09 +0000590 return 0;
591
592 case USB_REQ_SET_DESCRIPTOR: /* XXX should we support this? */
593 dbg_ep0 (0, "set descriptor: NOT SUPPORTED");
594 return -1;
595
596 case USB_REQ_SET_CONFIGURATION:
597 /* c.f. 9.4.7 - the top half of wValue is reserved */
Harald Welteed1c3f02008-07-07 00:58:05 +0800598 device->configuration = le16_to_cpu(request->wValue) & 0xff;
599
wdenk29e7f5a2004-03-12 00:14:09 +0000600 /* reset interface and alternate settings */
601 device->interface = device->alternate = 0;
602
603 /*dbg_ep0(2, "set configuration: %d", device->configuration); */
Pali Roháre4670002021-02-07 14:50:11 +0100604 /*dbg_ep0(2, "DEVICE_CONFIGURED.. event?\n"); */
wdenk29e7f5a2004-03-12 00:14:09 +0000605 return 0;
606
607 case USB_REQ_SET_INTERFACE:
608 device->interface = le16_to_cpu (request->wIndex);
609 device->alternate = le16_to_cpu (request->wValue);
610 /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
Pali Roháre4670002021-02-07 14:50:11 +0100611 dbg_ep0(2, "DEVICE_SET_INTERFACE.. event?\n");
wdenk29e7f5a2004-03-12 00:14:09 +0000612 return 0;
613
614 case USB_REQ_GET_STATUS:
615 case USB_REQ_GET_DESCRIPTOR:
616 case USB_REQ_GET_CONFIGURATION:
617 case USB_REQ_GET_INTERFACE:
618 case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
619 return -1;
620 }
621 }
622 return -1;
623}