ep0.c 16 KB

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