]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/usbdcore_ep0.c
Remove obsolete mpc5xx linker scripts
[karo-tx-uboot.git] / drivers / usbdcore_ep0.c
1 /*
2  * (C) Copyright 2003
3  * Gerry Hamel, geh@ti.com, Texas Instruments
4  *
5  * Based on
6  * linux/drivers/usbd/ep0.c
7  *
8  * Copyright (c) 2000, 2001, 2002 Lineo
9  * Copyright (c) 2001 Hewlett Packard
10  *
11  * By:
12  *      Stuart Lynne <sl@lineo.com>,
13  *      Tom Rushworth <tbr@lineo.com>,
14  *      Bruce Balden <balden@lineo.com>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29  *
30  */
31
32 /*
33  * This is the builtin ep0 control function. It implements all required functionality
34  * for responding to control requests (SETUP packets).
35  *
36  * XXX
37  *
38  * Currently we do not pass any SETUP packets (or other) to the configured
39  * function driver. This may need to change.
40  *
41  * XXX
42  */
43
44 #include <common.h>
45
46 #if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE)
47 #include "usbdcore.h"
48
49 #if 0
50 #define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
51 #else
52 #define dbg_ep0(lvl,fmt,args...)
53 #endif
54
55 /* EP0 Configuration Set ********************************************************************* */
56
57
58 /**
59  * ep0_get_status - fill in URB data with appropriate status
60  * @device:
61  * @urb:
62  * @index:
63  * @requesttype:
64  *
65  */
66 static int ep0_get_status (struct usb_device_instance *device,
67                            struct urb *urb, int index, int requesttype)
68 {
69         char *cp;
70
71         urb->actual_length = 2;
72         cp = urb->buffer;
73         cp[0] = cp[1] = 0;
74
75         switch (requesttype) {
76         case USB_REQ_RECIPIENT_DEVICE:
77                 cp[0] = USB_STATUS_SELFPOWERED;
78                 break;
79         case USB_REQ_RECIPIENT_INTERFACE:
80                 break;
81         case USB_REQ_RECIPIENT_ENDPOINT:
82                 cp[0] = usbd_endpoint_halted (device, index);
83                 break;
84         case USB_REQ_RECIPIENT_OTHER:
85                 urb->actual_length = 0;
86         default:
87                 break;
88         }
89         dbg_ep0 (2, "%02x %02x", cp[0], cp[1]);
90         return 0;
91 }
92
93 /**
94  * ep0_get_one
95  * @device:
96  * @urb:
97  * @result:
98  *
99  * Set a single byte value in the urb send buffer. Return non-zero to signal
100  * a request error.
101  */
102 static int ep0_get_one (struct usb_device_instance *device, struct urb *urb,
103                         __u8 result)
104 {
105         urb->actual_length = 1; /* XXX 2? */
106         ((char *) urb->buffer)[0] = result;
107         return 0;
108 }
109
110 /**
111  * copy_config
112  * @urb: pointer to urb
113  * @data: pointer to configuration data
114  * @length: length of data
115  *
116  * Copy configuration data to urb transfer buffer if there is room for it.
117  */
118 static void copy_config (struct urb *urb, void *data, int max_length,
119                          int max_buf)
120 {
121         int available;
122         int length;
123
124         /*dbg_ep0(3, "-> actual: %d buf: %d max_buf: %d max_length: %d data: %p", */
125         /*        urb->actual_length, urb->buffer_length, max_buf, max_length, data); */
126
127         if (!data) {
128                 dbg_ep0 (1, "data is NULL");
129                 return;
130         }
131         if (!(length = *(unsigned char *) data)) {
132                 dbg_ep0 (1, "length is zero");
133                 return;
134         }
135
136         if (length > max_length) {
137                 dbg_ep0 (1, "length: %d >= max_length: %d", length,
138                          max_length);
139                 return;
140         }
141         /*dbg_ep0(1, "   actual: %d buf: %d max_buf: %d max_length: %d length: %d", */
142         /*        urb->actual_length, urb->buffer_length, max_buf, max_length, length); */
143
144         if ((available =
145              /*urb->buffer_length */ max_buf - urb->actual_length) <= 0) {
146                 return;
147         }
148         /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
149         /*        urb->actual_length, urb->buffer_length, max_buf, length, available); */
150
151         if (length > available) {
152                 length = available;
153         }
154         /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
155         /*        urb->actual_length, urb->buffer_length, max_buf, length, available); */
156
157         memcpy (urb->buffer + urb->actual_length, data, length);
158         urb->actual_length += length;
159
160         dbg_ep0 (3,
161                  "copy_config: <- actual: %d buf: %d max_buf: %d max_length: %d available: %d",
162                  urb->actual_length, urb->buffer_length, max_buf, max_length,
163                  available);
164 }
165
166 /**
167  * ep0_get_descriptor
168  * @device:
169  * @urb:
170  * @max:
171  * @descriptor_type:
172  * @index:
173  *
174  * Called by ep0_rx_process for a get descriptor device command. Determine what
175  * descriptor is being requested, copy to send buffer. Return zero if ok to send,
176  * return non-zero to signal a request error.
177  */
178 static int ep0_get_descriptor (struct usb_device_instance *device,
179                                struct urb *urb, int max, int descriptor_type,
180                                int index)
181 {
182         int port = 0;           /* XXX compound device */
183         char *cp;
184
185         /*dbg_ep0(3, "max: %x type: %x index: %x", max, descriptor_type, index); */
186
187         if (!urb || !urb->buffer || !urb->buffer_length
188             || (urb->buffer_length < 255)) {
189                 dbg_ep0 (2, "invalid urb %p", urb);
190                 return -1L;
191         }
192
193         /* setup tx urb */
194         urb->actual_length = 0;
195         cp = urb->buffer;
196
197         dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type));
198
199         switch (descriptor_type) {
200         case USB_DESCRIPTOR_TYPE_DEVICE:
201                 {
202                         struct usb_device_descriptor *device_descriptor;
203
204                         if (!
205                             (device_descriptor =
206                              usbd_device_device_descriptor (device, port))) {
207                                 return -1;
208                         }
209                         /* copy descriptor for this device */
210                         copy_config (urb, device_descriptor,
211                                      sizeof (struct usb_device_descriptor),
212                                      max);
213
214                         /* correct the correct control endpoint 0 max packet size into the descriptor */
215                         device_descriptor =
216                                 (struct usb_device_descriptor *) urb->buffer;
217                         device_descriptor->bMaxPacketSize0 =
218                                 urb->device->bus->maxpacketsize;
219
220                 }
221                 /*dbg_ep0(3, "copied device configuration, actual_length: %x", urb->actual_length); */
222                 break;
223
224         case USB_DESCRIPTOR_TYPE_CONFIGURATION:
225                 {
226                         int bNumInterface;
227                         struct usb_configuration_descriptor
228                                 *configuration_descriptor;
229                         struct usb_device_descriptor *device_descriptor;
230
231                         if (!
232                             (device_descriptor =
233                              usbd_device_device_descriptor (device, port))) {
234                                 return -1;
235                         }
236                         /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
237                         if (index > device_descriptor->bNumConfigurations) {
238                                 dbg_ep0 (0, "index too large: %d > %d", index,
239                                          device_descriptor->
240                                          bNumConfigurations);
241                                 return -1;
242                         }
243
244                         if (!
245                             (configuration_descriptor =
246                              usbd_device_configuration_descriptor (device,
247                                                                    port,
248                                                                    index))) {
249                                 dbg_ep0 (0,
250                                          "usbd_device_configuration_descriptor failed: %d",
251                                          index);
252                                 return -1;
253                         }
254                         copy_config (urb, configuration_descriptor,
255                                      sizeof (struct
256                                              usb_configuration_descriptor),
257                                      max);
258
259
260                         /* iterate across interfaces for specified configuration */
261                         dbg_ep0 (0, "bNumInterfaces: %d",
262                                  configuration_descriptor->bNumInterfaces);
263                         for (bNumInterface = 0;
264                              bNumInterface <
265                              configuration_descriptor->bNumInterfaces;
266                              bNumInterface++) {
267
268                                 int bAlternateSetting;
269                                 struct usb_interface_instance
270                                         *interface_instance;
271
272                                 dbg_ep0 (3, "[%d] bNumInterfaces: %d",
273                                          bNumInterface,
274                                          configuration_descriptor->bNumInterfaces);
275
276                                 if (! (interface_instance = usbd_device_interface_instance (device,
277                                                                      port, index, bNumInterface)))
278                                 {
279                                         dbg_ep0 (3, "[%d] interface_instance NULL",
280                                                  bNumInterface);
281                                         return -1;
282                                 }
283                                 /* iterate across interface alternates */
284                                 for (bAlternateSetting = 0;
285                                      bAlternateSetting < interface_instance->alternates;
286                                      bAlternateSetting++) {
287                                         /*int class; */
288                                         int bNumEndpoint;
289                                         struct usb_interface_descriptor *interface_descriptor;
290
291                                         struct usb_alternate_instance *alternate_instance;
292
293                                         dbg_ep0 (3, "[%d:%d] alternates: %d",
294                                                  bNumInterface,
295                                                  bAlternateSetting,
296                                                  interface_instance->alternates);
297
298                                         if (! (alternate_instance = usbd_device_alternate_instance (device, port, index, bNumInterface, bAlternateSetting))) {
299                                                 dbg_ep0 (3, "[%d] alternate_instance NULL",
300                                                          bNumInterface);
301                                                 return -1;
302                                         }
303                                         /* copy descriptor for this interface */
304                                         copy_config (urb, alternate_instance->interface_descriptor,
305                                                      sizeof (struct usb_interface_descriptor),
306                                                      max);
307
308                                         /*dbg_ep0(3, "[%d:%d] classes: %d endpoints: %d", bNumInterface, bAlternateSetting, */
309                                         /*        alternate_instance->classes, alternate_instance->endpoints); */
310
311                                         /* iterate across classes for this alternate interface */
312 #if 0
313                                         for (class = 0;
314                                              class < alternate_instance->classes;
315                                              class++) {
316                                                 struct usb_class_descriptor *class_descriptor;
317                                                 /*dbg_ep0(3, "[%d:%d:%d] classes: %d", bNumInterface, bAlternateSetting, */
318                                                 /*        class, alternate_instance->classes); */
319                                                 if (!(class_descriptor = usbd_device_class_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, class))) {
320                                                         dbg_ep0 (3, "[%d] class NULL",
321                                                                  class);
322                                                         return -1;
323                                                 }
324                                                 /* copy descriptor for this class */
325                                                 copy_config (urb, class_descriptor,
326                                                         sizeof (struct usb_class_descriptor),
327                                                         max);
328                                         }
329 #endif
330
331                                         /* iterate across endpoints for this alternate interface */
332                                         interface_descriptor = alternate_instance->interface_descriptor;
333                                         for (bNumEndpoint = 0;
334                                              bNumEndpoint < alternate_instance->endpoints;
335                                              bNumEndpoint++) {
336                                                 struct usb_endpoint_descriptor *endpoint_descriptor;
337                                                 dbg_ep0 (3, "[%d:%d:%d] endpoint: %d",
338                                                          bNumInterface,
339                                                          bAlternateSetting,
340                                                          bNumEndpoint,
341                                                          interface_descriptor->
342                                                          bNumEndpoints);
343                                                 if (!(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, bNumEndpoint))) {
344                                                         dbg_ep0 (3, "[%d] endpoint NULL",
345                                                                  bNumEndpoint);
346                                                         return -1;
347                                                 }
348                                                 /* copy descriptor for this endpoint */
349                                                 copy_config (urb, endpoint_descriptor,
350                                                              sizeof (struct usb_endpoint_descriptor),
351                                                              max);
352                                         }
353                                 }
354                         }
355                         dbg_ep0 (3, "lengths: %d %d",
356                                  le16_to_cpu (configuration_descriptor->wTotalLength),
357                                  urb->actual_length);
358                 }
359                 break;
360
361         case USB_DESCRIPTOR_TYPE_STRING:
362                 {
363                         struct usb_string_descriptor *string_descriptor;
364
365                         if (!(string_descriptor = usbd_get_string (index))) {
366                                 return -1;
367                         }
368                         /*dbg_ep0(3, "string_descriptor: %p", string_descriptor); */
369                         copy_config (urb, string_descriptor, string_descriptor->bLength, max);
370                 }
371                 break;
372         case USB_DESCRIPTOR_TYPE_INTERFACE:
373                 return -1;
374         case USB_DESCRIPTOR_TYPE_ENDPOINT:
375                 return -1;
376         case USB_DESCRIPTOR_TYPE_HID:
377                 {
378                         return -1;      /* unsupported at this time */
379 #if 0
380                         int bNumInterface =
381                                 le16_to_cpu (urb->device_request.wIndex);
382                         int bAlternateSetting = 0;
383                         int class = 0;
384                         struct usb_class_descriptor *class_descriptor;
385
386                         if (!(class_descriptor =
387                               usbd_device_class_descriptor_index (device,
388                                                                   port, 0,
389                                                                   bNumInterface,
390                                                                   bAlternateSetting,
391                                                                   class))
392                             || class_descriptor->descriptor.hid.bDescriptorType != USB_DT_HID) {
393                                 dbg_ep0 (3, "[%d] interface is not HID",
394                                          bNumInterface);
395                                 return -1;
396                         }
397                         /* copy descriptor for this class */
398                         copy_config (urb, class_descriptor,
399                                      class_descriptor->descriptor.hid.bLength,
400                                      max);
401 #endif
402                 }
403                 break;
404         case USB_DESCRIPTOR_TYPE_REPORT:
405                 {
406                         return -1;      /* unsupported at this time */
407 #if 0
408                         int bNumInterface =
409                                 le16_to_cpu (urb->device_request.wIndex);
410                         int bAlternateSetting = 0;
411                         int class = 0;
412                         struct usb_class_report_descriptor *report_descriptor;
413
414                         if (!(report_descriptor =
415                               usbd_device_class_report_descriptor_index
416                               (device, port, 0, bNumInterface,
417                                bAlternateSetting, class))
418                             || report_descriptor->bDescriptorType !=
419                             USB_DT_REPORT) {
420                                 dbg_ep0 (3, "[%d] descriptor is not REPORT",
421                                          bNumInterface);
422                                 return -1;
423                         }
424                         /* copy report descriptor for this class */
425                         /*copy_config(urb, &report_descriptor->bData[0], report_descriptor->wLength, max); */
426                         if (max - urb->actual_length > 0) {
427                                 int length =
428                                         MIN (report_descriptor->wLength,
429                                              max - urb->actual_length);
430                                 memcpy (urb->buffer + urb->actual_length,
431                                         &report_descriptor->bData[0], length);
432                                 urb->actual_length += length;
433                         }
434 #endif
435                 }
436                 break;
437         default:
438                 return -1;
439         }
440
441
442         dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d packet size: %2d",
443                  urb->buffer, urb->buffer_length, urb->actual_length,
444                  device->bus->endpoint_array[0].tx_packetSize);
445 /*
446     if ((urb->actual_length < max) && !(urb->actual_length % device->bus->endpoint_array[0].tx_packetSize)) {
447         dbg_ep0(0, "adding null byte");
448         urb->buffer[urb->actual_length++] = 0;
449         dbg_ep0(0, "urb: buffer_length: %2d actual_length: %2d packet size: %2d",
450                 urb->buffer_length, urb->actual_length device->bus->endpoint_array[0].tx_packetSize);
451     }
452 */
453         return 0;
454
455 }
456
457 /**
458  * ep0_recv_setup - called to indicate URB has been received
459  * @urb: pointer to struct urb
460  *
461  * Check if this is a setup packet, process the device request, put results
462  * back into the urb and return zero or non-zero to indicate success (DATA)
463  * or failure (STALL).
464  *
465  */
466 int ep0_recv_setup (struct urb *urb)
467 {
468         /*struct usb_device_request *request = urb->buffer; */
469         /*struct usb_device_instance *device = urb->device; */
470
471         struct usb_device_request *request;
472         struct usb_device_instance *device;
473         int address;
474
475         dbg_ep0 (0, "entering ep0_recv_setup()");
476         if (!urb || !urb->device) {
477                 dbg_ep0 (3, "invalid URB %p", urb);
478                 return -1;
479         }
480
481         request = &urb->device_request;
482         device = urb->device;
483
484         dbg_ep0 (3, "urb: %p device: %p", urb, urb->device);
485
486
487         /*dbg_ep0(2, "-       -       -       -       -       -       -       -       -       -"); */
488
489         dbg_ep0 (2,
490                  "bmRequestType:%02x bRequest:%02x wValue:%04x wIndex:%04x wLength:%04x %s",
491                  request->bmRequestType, request->bRequest,
492                  le16_to_cpu (request->wValue), le16_to_cpu (request->wIndex),
493                  le16_to_cpu (request->wLength),
494                  USBD_DEVICE_REQUESTS (request->bRequest));
495
496         /* handle USB Standard Request (c.f. USB Spec table 9-2) */
497         if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
498                 dbg_ep0 (1, "non standard request: %x",
499                          request->bmRequestType & USB_REQ_TYPE_MASK);
500                 return -1;      /* Stall here */
501         }
502
503         switch (device->device_state) {
504         case STATE_CREATED:
505         case STATE_ATTACHED:
506         case STATE_POWERED:
507                 /* It actually is important to allow requests in these states,
508                  * Windows will request descriptors before assigning an
509                  * address to the client.
510                  */
511
512                 /*dbg_ep0 (1, "request %s not allowed in this state: %s", */
513                 /*                USBD_DEVICE_REQUESTS(request->bRequest), */
514                 /*                usbd_device_states[device->device_state]); */
515                 /*return -1; */
516                 break;
517
518         case STATE_INIT:
519         case STATE_DEFAULT:
520                 switch (request->bRequest) {
521                 case USB_REQ_GET_STATUS:
522                 case USB_REQ_GET_INTERFACE:
523                 case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
524                 case USB_REQ_CLEAR_FEATURE:
525                 case USB_REQ_SET_FEATURE:
526                 case USB_REQ_SET_DESCRIPTOR:
527                         /* case USB_REQ_SET_CONFIGURATION: */
528                 case USB_REQ_SET_INTERFACE:
529                         dbg_ep0 (1,
530                                  "request %s not allowed in DEFAULT state: %s",
531                                  USBD_DEVICE_REQUESTS (request->bRequest),
532                                  usbd_device_states[device->device_state]);
533                         return -1;
534
535                 case USB_REQ_SET_CONFIGURATION:
536                 case USB_REQ_SET_ADDRESS:
537                 case USB_REQ_GET_DESCRIPTOR:
538                 case USB_REQ_GET_CONFIGURATION:
539                         break;
540                 }
541         case STATE_ADDRESSED:
542         case STATE_CONFIGURED:
543                 break;
544         case STATE_UNKNOWN:
545                 dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s",
546                          USBD_DEVICE_REQUESTS (request->bRequest),
547                          usbd_device_states[device->device_state]);
548                 return -1;
549         }
550
551         /* handle all requests that return data (direction bit set on bm RequestType) */
552         if ((request->bmRequestType & USB_REQ_DIRECTION_MASK)) {
553
554                 dbg_ep0 (3, "Device-to-Host");
555
556                 switch (request->bRequest) {
557
558                 case USB_REQ_GET_STATUS:
559                         return ep0_get_status (device, urb, request->wIndex,
560                                                request->bmRequestType &
561                                                USB_REQ_RECIPIENT_MASK);
562
563                 case USB_REQ_GET_DESCRIPTOR:
564                         return ep0_get_descriptor (device, urb,
565                                                    le16_to_cpu (request->wLength),
566                                                    le16_to_cpu (request->wValue) >> 8,
567                                                    le16_to_cpu (request->wValue) & 0xff);
568
569                 case USB_REQ_GET_CONFIGURATION:
570                         return ep0_get_one (device, urb,
571                                             device->configuration);
572
573                 case USB_REQ_GET_INTERFACE:
574                         return ep0_get_one (device, urb, device->alternate);
575
576                 case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
577                         return -1;
578
579                 case USB_REQ_CLEAR_FEATURE:
580                 case USB_REQ_SET_FEATURE:
581                 case USB_REQ_SET_ADDRESS:
582                 case USB_REQ_SET_DESCRIPTOR:
583                 case USB_REQ_SET_CONFIGURATION:
584                 case USB_REQ_SET_INTERFACE:
585                         return -1;
586                 }
587         }
588         /* handle the requests that do not return data */
589         else {
590
591
592                 /*dbg_ep0(3, "Host-to-Device"); */
593                 switch (request->bRequest) {
594
595                 case USB_REQ_CLEAR_FEATURE:
596                 case USB_REQ_SET_FEATURE:
597                         dbg_ep0 (0, "Host-to-Device");
598                         switch (request->
599                                 bmRequestType & USB_REQ_RECIPIENT_MASK) {
600                         case USB_REQ_RECIPIENT_DEVICE:
601                                 /* XXX DEVICE_REMOTE_WAKEUP or TEST_MODE would be added here */
602                                 /* XXX fall through for now as we do not support either */
603                         case USB_REQ_RECIPIENT_INTERFACE:
604                         case USB_REQ_RECIPIENT_OTHER:
605                                 dbg_ep0 (0, "request %s not",
606                                          USBD_DEVICE_REQUESTS (request->bRequest));
607                         default:
608                                 return -1;
609
610                         case USB_REQ_RECIPIENT_ENDPOINT:
611                                 dbg_ep0 (0, "ENDPOINT: %x", le16_to_cpu (request->wValue));
612                                 if (le16_to_cpu (request->wValue) == USB_ENDPOINT_HALT) {
613                                         /*return usbd_device_feature (device, le16_to_cpu (request->wIndex), */
614                                         /*                    request->bRequest == USB_REQ_SET_FEATURE); */
615                                         /* NEED TO IMPLEMENT THIS!!! */
616                                         return -1;
617                                 } else {
618                                         dbg_ep0 (1, "request %s bad wValue: %04x",
619                                                  USBD_DEVICE_REQUESTS
620                                                  (request->bRequest),
621                                                  le16_to_cpu (request->wValue));
622                                         return -1;
623                                 }
624                         }
625
626                 case USB_REQ_SET_ADDRESS:
627                         /* check if this is a re-address, reset first if it is (this shouldn't be possible) */
628                         if (device->device_state != STATE_DEFAULT) {
629                                 dbg_ep0 (1, "set_address: %02x state: %s",
630                                          le16_to_cpu (request->wValue),
631                                          usbd_device_states[device->device_state]);
632                                 return -1;
633                         }
634                         address = le16_to_cpu (request->wValue);
635                         if ((address & 0x7f) != address) {
636                                 dbg_ep0 (1, "invalid address %04x %04x",
637                                          address, address & 0x7f);
638                                 return -1;
639                         }
640                         device->address = address;
641
642                         /*dbg_ep0(2, "address: %d %d %d", */
643                         /*        request->wValue, le16_to_cpu(request->wValue), device->address); */
644
645                         serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
646                         return 0;
647
648                 case USB_REQ_SET_DESCRIPTOR:    /* XXX should we support this? */
649                         dbg_ep0 (0, "set descriptor: NOT SUPPORTED");
650                         return -1;
651
652                 case USB_REQ_SET_CONFIGURATION:
653                         /* c.f. 9.4.7 - the top half of wValue is reserved */
654                         /* */
655                         if ((device->configuration =
656                              le16_to_cpu (request->wValue) & 0x7f) != 0) {
657                                 /* c.f. 9.4.7 - zero is the default or addressed state, in our case this */
658                                 /* is the same is configuration zero */
659                                 device->configuration = 0;      /* TBR - ?????? */
660                         }
661                         /* reset interface and alternate settings */
662                         device->interface = device->alternate = 0;
663
664                         /*dbg_ep0(2, "set configuration: %d", device->configuration); */
665                         /*serial_printf("DEVICE_CONFIGURED.. event?\n"); */
666                         return 0;
667
668                 case USB_REQ_SET_INTERFACE:
669                         device->interface = le16_to_cpu (request->wIndex);
670                         device->alternate = le16_to_cpu (request->wValue);
671                         /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
672                         serial_printf ("DEVICE_SET_INTERFACE.. event?\n");
673                         return 0;
674
675                 case USB_REQ_GET_STATUS:
676                 case USB_REQ_GET_DESCRIPTOR:
677                 case USB_REQ_GET_CONFIGURATION:
678                 case USB_REQ_GET_INTERFACE:
679                 case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
680                         return -1;
681                 }
682         }
683         return -1;
684 }
685
686 #endif