ep0.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2003
  4. * Gerry Hamel, geh@ti.com, Texas Instruments
  5. *
  6. * (C) Copyright 2006
  7. * Bryan O'Donoghue, deckard@CodeHermit.ie
  8. *
  9. * 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>
  19. */
  20. /*
  21. * This is the builtin ep0 control function. It implements all required functionality
  22. * for responding to control requests (SETUP packets).
  23. *
  24. * XXX
  25. *
  26. * Currently we do not pass any SETUP packets (or other) to the configured
  27. * function driver. This may need to change.
  28. *
  29. * XXX
  30. *
  31. * As alluded to above, a simple callback cdc_recv_setup has been implemented
  32. * in the usb_device data structure to facilicate passing
  33. * Common Device Class packets to a function driver.
  34. *
  35. * XXX
  36. */
  37. #include <common.h>
  38. #include <serial.h>
  39. #include <usbdevice.h>
  40. #if 0
  41. #define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
  42. #else
  43. #define dbg_ep0(lvl,fmt,args...)
  44. #endif
  45. __maybe_unused static char *usbd_device_descriptors[] = {
  46. "UNKNOWN", /* 0 */
  47. "DEVICE", /* 1 */
  48. "CONFIG", /* 2 */
  49. "STRING", /* 3 */
  50. "INTERFACE", /* 4 */
  51. "ENDPOINT", /* 5 */
  52. "DEVICE QUALIFIER", /* 6 */
  53. "OTHER SPEED", /* 7 */
  54. "INTERFACE POWER", /* 8 */
  55. };
  56. #define USBD_DEVICE_DESCRIPTORS(x) (((unsigned int)x <= USB_DESCRIPTOR_TYPE_INTERFACE_POWER) ? \
  57. usbd_device_descriptors[x] : "UNKNOWN")
  58. __maybe_unused static char *usbd_device_states[] = {
  59. "STATE_INIT",
  60. "STATE_CREATED",
  61. "STATE_ATTACHED",
  62. "STATE_POWERED",
  63. "STATE_DEFAULT",
  64. "STATE_ADDRESSED",
  65. "STATE_CONFIGURED",
  66. "STATE_UNKNOWN",
  67. };
  68. #define USBD_DEVICE_STATE(x) (((unsigned int)x <= STATE_UNKNOWN) ? usbd_device_states[x] : "UNKNOWN")
  69. __maybe_unused static char *usbd_device_requests[] = {
  70. "GET STATUS", /* 0 */
  71. "CLEAR FEATURE", /* 1 */
  72. "RESERVED", /* 2 */
  73. "SET FEATURE", /* 3 */
  74. "RESERVED", /* 4 */
  75. "SET ADDRESS", /* 5 */
  76. "GET DESCRIPTOR", /* 6 */
  77. "SET DESCRIPTOR", /* 7 */
  78. "GET CONFIGURATION", /* 8 */
  79. "SET CONFIGURATION", /* 9 */
  80. "GET INTERFACE", /* 10 */
  81. "SET INTERFACE", /* 11 */
  82. "SYNC FRAME", /* 12 */
  83. };
  84. #define USBD_DEVICE_REQUESTS(x) (((unsigned int)x <= USB_REQ_SYNCH_FRAME) ? usbd_device_requests[x] : "UNKNOWN")
  85. /* EP0 Configuration Set ********************************************************************* */
  86. /**
  87. * ep0_get_status - fill in URB data with appropriate status
  88. * @device:
  89. * @urb:
  90. * @index:
  91. * @requesttype:
  92. *
  93. */
  94. static int ep0_get_status (struct usb_device_instance *device,
  95. struct urb *urb, int index, int requesttype)
  96. {
  97. char *cp;
  98. urb->actual_length = 2;
  99. cp = (char*)urb->buffer;
  100. cp[0] = cp[1] = 0;
  101. switch (requesttype) {
  102. case USB_REQ_RECIPIENT_DEVICE:
  103. cp[0] = USB_STATUS_SELFPOWERED;
  104. break;
  105. case USB_REQ_RECIPIENT_INTERFACE:
  106. break;
  107. case USB_REQ_RECIPIENT_ENDPOINT:
  108. cp[0] = usbd_endpoint_halted (device, index);
  109. break;
  110. case USB_REQ_RECIPIENT_OTHER:
  111. urb->actual_length = 0;
  112. default:
  113. break;
  114. }
  115. dbg_ep0 (2, "%02x %02x", cp[0], cp[1]);
  116. return 0;
  117. }
  118. /**
  119. * ep0_get_one
  120. * @device:
  121. * @urb:
  122. * @result:
  123. *
  124. * Set a single byte value in the urb send buffer. Return non-zero to signal
  125. * a request error.
  126. */
  127. static int ep0_get_one (struct usb_device_instance *device, struct urb *urb,
  128. __u8 result)
  129. {
  130. urb->actual_length = 1; /* XXX 2? */
  131. ((char *) urb->buffer)[0] = result;
  132. return 0;
  133. }
  134. /**
  135. * copy_config
  136. * @urb: pointer to urb
  137. * @data: pointer to configuration data
  138. * @length: length of data
  139. *
  140. * Copy configuration data to urb transfer buffer if there is room for it.
  141. */
  142. void copy_config (struct urb *urb, void *data, int max_length,
  143. int max_buf)
  144. {
  145. int available;
  146. int length;
  147. /*dbg_ep0(3, "-> actual: %d buf: %d max_buf: %d max_length: %d data: %p", */
  148. /* urb->actual_length, urb->buffer_length, max_buf, max_length, data); */
  149. if (!data) {
  150. dbg_ep0 (1, "data is NULL");
  151. return;
  152. }
  153. length = max_length;
  154. if (length > max_length) {
  155. dbg_ep0 (1, "length: %d >= max_length: %d", length,
  156. max_length);
  157. return;
  158. }
  159. /*dbg_ep0(1, " actual: %d buf: %d max_buf: %d max_length: %d length: %d", */
  160. /* urb->actual_length, urb->buffer_length, max_buf, max_length, length); */
  161. if ((available =
  162. /*urb->buffer_length */ max_buf - urb->actual_length) <= 0) {
  163. return;
  164. }
  165. /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
  166. /* urb->actual_length, urb->buffer_length, max_buf, length, available); */
  167. if (length > available) {
  168. length = available;
  169. }
  170. /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
  171. /* urb->actual_length, urb->buffer_length, max_buf, length, available); */
  172. memcpy (urb->buffer + urb->actual_length, data, length);
  173. urb->actual_length += length;
  174. dbg_ep0 (3,
  175. "copy_config: <- actual: %d buf: %d max_buf: %d max_length: %d available: %d",
  176. urb->actual_length, urb->buffer_length, max_buf, max_length,
  177. available);
  178. }
  179. /**
  180. * ep0_get_descriptor
  181. * @device:
  182. * @urb:
  183. * @max:
  184. * @descriptor_type:
  185. * @index:
  186. *
  187. * Called by ep0_rx_process for a get descriptor device command. Determine what
  188. * descriptor is being requested, copy to send buffer. Return zero if ok to send,
  189. * return non-zero to signal a request error.
  190. */
  191. static int ep0_get_descriptor (struct usb_device_instance *device,
  192. struct urb *urb, int max, int descriptor_type,
  193. int index)
  194. {
  195. int port = 0; /* XXX compound device */
  196. /*dbg_ep0(3, "max: %x type: %x index: %x", max, descriptor_type, index); */
  197. if (!urb || !urb->buffer || !urb->buffer_length
  198. || (urb->buffer_length < 255)) {
  199. dbg_ep0 (2, "invalid urb %p", urb);
  200. return -1L;
  201. }
  202. /* setup tx urb */
  203. urb->actual_length = 0;
  204. dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type));
  205. switch (descriptor_type) {
  206. case USB_DESCRIPTOR_TYPE_DEVICE:
  207. {
  208. struct usb_device_descriptor *device_descriptor;
  209. if (!
  210. (device_descriptor =
  211. usbd_device_device_descriptor (device, port))) {
  212. return -1;
  213. }
  214. /* copy descriptor for this device */
  215. copy_config (urb, device_descriptor,
  216. sizeof (struct usb_device_descriptor),
  217. max);
  218. /* correct the correct control endpoint 0 max packet size into the descriptor */
  219. device_descriptor =
  220. (struct usb_device_descriptor *) urb->buffer;
  221. }
  222. dbg_ep0(3, "copied device configuration, actual_length: 0x%x", urb->actual_length);
  223. break;
  224. case USB_DESCRIPTOR_TYPE_CONFIGURATION:
  225. {
  226. struct usb_configuration_descriptor
  227. *configuration_descriptor;
  228. struct usb_device_descriptor *device_descriptor;
  229. if (!
  230. (device_descriptor =
  231. usbd_device_device_descriptor (device, port))) {
  232. return -1;
  233. }
  234. /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
  235. if (index >= device_descriptor->bNumConfigurations) {
  236. dbg_ep0 (0, "index too large: %d >= %d", index,
  237. device_descriptor->
  238. bNumConfigurations);
  239. return -1;
  240. }
  241. if (!
  242. (configuration_descriptor =
  243. usbd_device_configuration_descriptor (device,
  244. port,
  245. index))) {
  246. dbg_ep0 (0,
  247. "usbd_device_configuration_descriptor failed: %d",
  248. index);
  249. return -1;
  250. }
  251. dbg_ep0(0, "attempt to copy %d bytes to urb\n",cpu_to_le16(configuration_descriptor->wTotalLength));
  252. copy_config (urb, configuration_descriptor,
  253. cpu_to_le16(configuration_descriptor->wTotalLength),
  254. max);
  255. }
  256. break;
  257. case USB_DESCRIPTOR_TYPE_STRING:
  258. {
  259. struct usb_string_descriptor *string_descriptor;
  260. if (!(string_descriptor = usbd_get_string (index))) {
  261. serial_printf("Invalid string index %d\n", index);
  262. return -1;
  263. }
  264. dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength);
  265. copy_config (urb, string_descriptor, string_descriptor->bLength, max);
  266. }
  267. break;
  268. case USB_DESCRIPTOR_TYPE_INTERFACE:
  269. serial_printf("USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
  270. return -1;
  271. case USB_DESCRIPTOR_TYPE_ENDPOINT:
  272. serial_printf("USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
  273. return -1;
  274. case USB_DESCRIPTOR_TYPE_HID:
  275. {
  276. serial_printf("USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
  277. return -1; /* unsupported at this time */
  278. #if 0
  279. int bNumInterface =
  280. le16_to_cpu (urb->device_request.wIndex);
  281. int bAlternateSetting = 0;
  282. int class = 0;
  283. struct usb_class_descriptor *class_descriptor;
  284. if (!(class_descriptor =
  285. usbd_device_class_descriptor_index (device,
  286. port, 0,
  287. bNumInterface,
  288. bAlternateSetting,
  289. class))
  290. || class_descriptor->descriptor.hid.bDescriptorType != USB_DT_HID) {
  291. dbg_ep0 (3, "[%d] interface is not HID",
  292. bNumInterface);
  293. return -1;
  294. }
  295. /* copy descriptor for this class */
  296. copy_config (urb, class_descriptor,
  297. class_descriptor->descriptor.hid.bLength,
  298. max);
  299. #endif
  300. }
  301. break;
  302. case USB_DESCRIPTOR_TYPE_REPORT:
  303. {
  304. serial_printf("USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
  305. return -1; /* unsupported at this time */
  306. #if 0
  307. int bNumInterface =
  308. le16_to_cpu (urb->device_request.wIndex);
  309. int bAlternateSetting = 0;
  310. int class = 0;
  311. struct usb_class_report_descriptor *report_descriptor;
  312. if (!(report_descriptor =
  313. usbd_device_class_report_descriptor_index
  314. (device, port, 0, bNumInterface,
  315. bAlternateSetting, class))
  316. || report_descriptor->bDescriptorType !=
  317. USB_DT_REPORT) {
  318. dbg_ep0 (3, "[%d] descriptor is not REPORT",
  319. bNumInterface);
  320. return -1;
  321. }
  322. /* copy report descriptor for this class */
  323. /*copy_config(urb, &report_descriptor->bData[0], report_descriptor->wLength, max); */
  324. if (max - urb->actual_length > 0) {
  325. int length =
  326. min(report_descriptor->wLength,
  327. max - urb->actual_length);
  328. memcpy (urb->buffer + urb->actual_length,
  329. &report_descriptor->bData[0], length);
  330. urb->actual_length += length;
  331. }
  332. #endif
  333. }
  334. break;
  335. case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
  336. #if defined(CONFIG_USBD_HS)
  337. {
  338. struct usb_qualifier_descriptor *qualifier_descriptor =
  339. device->qualifier_descriptor;
  340. if (!qualifier_descriptor)
  341. return -1;
  342. /* copy descriptor for this device */
  343. copy_config(urb, qualifier_descriptor,
  344. sizeof(struct usb_qualifier_descriptor),
  345. max);
  346. }
  347. dbg_ep0(3, "copied qualifier descriptor, actual_length: 0x%x",
  348. urb->actual_length);
  349. #else
  350. return -1;
  351. #endif
  352. break;
  353. default:
  354. return -1;
  355. }
  356. dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d tx_packetSize: %2d",
  357. urb->buffer, urb->buffer_length, urb->actual_length,
  358. device->bus->endpoint_array[0].tx_packetSize);
  359. /*
  360. if ((urb->actual_length < max) && !(urb->actual_length % device->bus->endpoint_array[0].tx_packetSize)) {
  361. dbg_ep0(0, "adding null byte");
  362. urb->buffer[urb->actual_length++] = 0;
  363. dbg_ep0(0, "urb: buffer_length: %2d actual_length: %2d packet size: %2d",
  364. urb->buffer_length, urb->actual_length device->bus->endpoint_array[0].tx_packetSize);
  365. }
  366. */
  367. return 0;
  368. }
  369. /**
  370. * ep0_recv_setup - called to indicate URB has been received
  371. * @urb: pointer to struct urb
  372. *
  373. * Check if this is a setup packet, process the device request, put results
  374. * back into the urb and return zero or non-zero to indicate success (DATA)
  375. * or failure (STALL).
  376. *
  377. */
  378. int ep0_recv_setup (struct urb *urb)
  379. {
  380. /*struct usb_device_request *request = urb->buffer; */
  381. /*struct usb_device_instance *device = urb->device; */
  382. struct usb_device_request *request;
  383. struct usb_device_instance *device;
  384. int address;
  385. dbg_ep0 (0, "entering ep0_recv_setup()");
  386. if (!urb || !urb->device) {
  387. dbg_ep0 (3, "invalid URB %p", urb);
  388. return -1;
  389. }
  390. request = &urb->device_request;
  391. device = urb->device;
  392. dbg_ep0 (3, "urb: %p device: %p", urb, urb->device);
  393. /*dbg_ep0(2, "- - - - - - - - - -"); */
  394. dbg_ep0 (2,
  395. "bmRequestType:%02x bRequest:%02x wValue:%04x wIndex:%04x wLength:%04x %s",
  396. request->bmRequestType, request->bRequest,
  397. le16_to_cpu (request->wValue), le16_to_cpu (request->wIndex),
  398. le16_to_cpu (request->wLength),
  399. USBD_DEVICE_REQUESTS (request->bRequest));
  400. /* handle USB Standard Request (c.f. USB Spec table 9-2) */
  401. if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
  402. if(device->device_state <= STATE_CONFIGURED){
  403. /* Attempt to handle a CDC specific request if we are
  404. * in the configured state.
  405. */
  406. return device->cdc_recv_setup(request,urb);
  407. }
  408. dbg_ep0 (1, "non standard request: %x",
  409. request->bmRequestType & USB_REQ_TYPE_MASK);
  410. return -1; /* Stall here */
  411. }
  412. switch (device->device_state) {
  413. case STATE_CREATED:
  414. case STATE_ATTACHED:
  415. case STATE_POWERED:
  416. /* It actually is important to allow requests in these states,
  417. * Windows will request descriptors before assigning an
  418. * address to the client.
  419. */
  420. /*dbg_ep0 (1, "request %s not allowed in this state: %s", */
  421. /* USBD_DEVICE_REQUESTS(request->bRequest), */
  422. /* usbd_device_states[device->device_state]); */
  423. /*return -1; */
  424. break;
  425. case STATE_INIT:
  426. case STATE_DEFAULT:
  427. switch (request->bRequest) {
  428. case USB_REQ_GET_STATUS:
  429. case USB_REQ_GET_INTERFACE:
  430. case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
  431. case USB_REQ_CLEAR_FEATURE:
  432. case USB_REQ_SET_FEATURE:
  433. case USB_REQ_SET_DESCRIPTOR:
  434. /* case USB_REQ_SET_CONFIGURATION: */
  435. case USB_REQ_SET_INTERFACE:
  436. dbg_ep0 (1,
  437. "request %s not allowed in DEFAULT state: %s",
  438. USBD_DEVICE_REQUESTS (request->bRequest),
  439. usbd_device_states[device->device_state]);
  440. return -1;
  441. case USB_REQ_SET_CONFIGURATION:
  442. case USB_REQ_SET_ADDRESS:
  443. case USB_REQ_GET_DESCRIPTOR:
  444. case USB_REQ_GET_CONFIGURATION:
  445. break;
  446. }
  447. case STATE_ADDRESSED:
  448. case STATE_CONFIGURED:
  449. break;
  450. case STATE_UNKNOWN:
  451. dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s",
  452. USBD_DEVICE_REQUESTS (request->bRequest),
  453. usbd_device_states[device->device_state]);
  454. return -1;
  455. }
  456. /* handle all requests that return data (direction bit set on bm RequestType) */
  457. if ((request->bmRequestType & USB_REQ_DIRECTION_MASK)) {
  458. dbg_ep0 (3, "Device-to-Host");
  459. switch (request->bRequest) {
  460. case USB_REQ_GET_STATUS:
  461. return ep0_get_status (device, urb, request->wIndex,
  462. request->bmRequestType &
  463. USB_REQ_RECIPIENT_MASK);
  464. case USB_REQ_GET_DESCRIPTOR:
  465. return ep0_get_descriptor (device, urb,
  466. le16_to_cpu (request->wLength),
  467. le16_to_cpu (request->wValue) >> 8,
  468. le16_to_cpu (request->wValue) & 0xff);
  469. case USB_REQ_GET_CONFIGURATION:
  470. serial_printf("get config %d\n", device->configuration);
  471. return ep0_get_one (device, urb,
  472. device->configuration);
  473. case USB_REQ_GET_INTERFACE:
  474. return ep0_get_one (device, urb, device->alternate);
  475. case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
  476. return -1;
  477. case USB_REQ_CLEAR_FEATURE:
  478. case USB_REQ_SET_FEATURE:
  479. case USB_REQ_SET_ADDRESS:
  480. case USB_REQ_SET_DESCRIPTOR:
  481. case USB_REQ_SET_CONFIGURATION:
  482. case USB_REQ_SET_INTERFACE:
  483. return -1;
  484. }
  485. }
  486. /* handle the requests that do not return data */
  487. else {
  488. /*dbg_ep0(3, "Host-to-Device"); */
  489. switch (request->bRequest) {
  490. case USB_REQ_CLEAR_FEATURE:
  491. case USB_REQ_SET_FEATURE:
  492. dbg_ep0 (0, "Host-to-Device");
  493. switch (request->
  494. bmRequestType & USB_REQ_RECIPIENT_MASK) {
  495. case USB_REQ_RECIPIENT_DEVICE:
  496. /* XXX DEVICE_REMOTE_WAKEUP or TEST_MODE would be added here */
  497. /* XXX fall through for now as we do not support either */
  498. case USB_REQ_RECIPIENT_INTERFACE:
  499. case USB_REQ_RECIPIENT_OTHER:
  500. dbg_ep0 (0, "request %s not",
  501. USBD_DEVICE_REQUESTS (request->bRequest));
  502. default:
  503. return -1;
  504. case USB_REQ_RECIPIENT_ENDPOINT:
  505. dbg_ep0 (0, "ENDPOINT: %x", le16_to_cpu (request->wValue));
  506. if (le16_to_cpu (request->wValue) == USB_ENDPOINT_HALT) {
  507. /*return usbd_device_feature (device, le16_to_cpu (request->wIndex), */
  508. /* request->bRequest == USB_REQ_SET_FEATURE); */
  509. /* NEED TO IMPLEMENT THIS!!! */
  510. return -1;
  511. } else {
  512. dbg_ep0 (1, "request %s bad wValue: %04x",
  513. USBD_DEVICE_REQUESTS
  514. (request->bRequest),
  515. le16_to_cpu (request->wValue));
  516. return -1;
  517. }
  518. }
  519. case USB_REQ_SET_ADDRESS:
  520. /* check if this is a re-address, reset first if it is (this shouldn't be possible) */
  521. if (device->device_state != STATE_DEFAULT) {
  522. dbg_ep0 (1, "set_address: %02x state: %s",
  523. le16_to_cpu (request->wValue),
  524. usbd_device_states[device->device_state]);
  525. return -1;
  526. }
  527. address = le16_to_cpu (request->wValue);
  528. if ((address & 0x7f) != address) {
  529. dbg_ep0 (1, "invalid address %04x %04x",
  530. address, address & 0x7f);
  531. return -1;
  532. }
  533. device->address = address;
  534. /*dbg_ep0(2, "address: %d %d %d", */
  535. /* request->wValue, le16_to_cpu(request->wValue), device->address); */
  536. return 0;
  537. case USB_REQ_SET_DESCRIPTOR: /* XXX should we support this? */
  538. dbg_ep0 (0, "set descriptor: NOT SUPPORTED");
  539. return -1;
  540. case USB_REQ_SET_CONFIGURATION:
  541. /* c.f. 9.4.7 - the top half of wValue is reserved */
  542. device->configuration = le16_to_cpu(request->wValue) & 0xff;
  543. /* reset interface and alternate settings */
  544. device->interface = device->alternate = 0;
  545. /*dbg_ep0(2, "set configuration: %d", device->configuration); */
  546. /*serial_printf("DEVICE_CONFIGURED.. event?\n"); */
  547. return 0;
  548. case USB_REQ_SET_INTERFACE:
  549. device->interface = le16_to_cpu (request->wIndex);
  550. device->alternate = le16_to_cpu (request->wValue);
  551. /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
  552. serial_printf("DEVICE_SET_INTERFACE.. event?\n");
  553. return 0;
  554. case USB_REQ_GET_STATUS:
  555. case USB_REQ_GET_DESCRIPTOR:
  556. case USB_REQ_GET_CONFIGURATION:
  557. case USB_REQ_GET_INTERFACE:
  558. case USB_REQ_SYNCH_FRAME: /* XXX should never see this (?) */
  559. return -1;
  560. }
  561. }
  562. return -1;
  563. }