usbd_composite.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /**
  2. ******************************************************************************
  3. * @attention
  4. *
  5. * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  6. *
  7. * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  8. * You may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at:
  10. *
  11. * http://www.st.com/software_license_agreement_liberty_v2
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. ******************************************************************************
  20. */
  21. /* Includes ------------------------------------------------------------------*/
  22. #include "usbd_composite.h"
  23. #include "usbd_hid.h"
  24. #include "usbd_msc.h"
  25. #include "usbd_desc.h"
  26. #include "usbd_ctlreq.h"
  27. #define MSC_MAX_FS_PACKET 64
  28. #define MSC_MAX_HS_PACKET 512
  29. // Support 2 USB devices.
  30. __ALIGN_BEGIN static USBD_CompositeClassData fsClassData __ALIGN_END;
  31. __ALIGN_BEGIN static USBD_CompositeClassData hsClassData __ALIGN_END;
  32. static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx);
  33. static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx);
  34. static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
  35. static uint8_t *USBD_Composite_GetHSCfgDesc (uint16_t *length);
  36. static uint8_t *USBD_Composite_GetFSCfgDesc (uint16_t *length);
  37. static uint8_t *USBD_Composite_GetDeviceQualifierDesc (uint16_t *length);
  38. static uint8_t USBD_Composite_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum);
  39. static uint8_t USBD_Composite_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum);
  40. USBD_ClassTypeDef USBD_Composite =
  41. {
  42. USBD_Composite_Init,
  43. USBD_Composite_DeInit,
  44. USBD_Composite_Setup,
  45. NULL, /*EP0_TxSent*/
  46. NULL, /*EP0_RxReady*/
  47. USBD_Composite_DataIn, /*DataIn*/
  48. USBD_Composite_DataOut, /*DataOut*/
  49. NULL, /*SOF */
  50. NULL,
  51. NULL,
  52. USBD_Composite_GetHSCfgDesc,
  53. USBD_Composite_GetFSCfgDesc,
  54. USBD_Composite_GetFSCfgDesc, // "Other" speed
  55. USBD_Composite_GetDeviceQualifierDesc,
  56. };
  57. __ALIGN_BEGIN static uint8_t USBD_Composite_CfgHSDesc[USB_COMPOSITE_CONFIG_DESC_SIZ] __ALIGN_END =
  58. {
  59. 0x09, /* bLength: Configuration Descriptor size */
  60. USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
  61. USB_COMPOSITE_CONFIG_DESC_SIZ,
  62. /* wTotalLength: Bytes returned */
  63. 0x00,
  64. 0x02, /*bNumInterfaces: 1 interface*/
  65. 0x01, /*bConfigurationValue: Configuration value*/
  66. 0x00, /*iConfiguration: Index of string descriptor describing
  67. the configuration*/
  68. 0x80, /*bmAttributes: bus powered */
  69. 0xFA, /*MaxPower 500 mA: this current is used for detecting Vbus*/
  70. /************** Descriptor of GENERIC interface ****************/
  71. /* 09 */
  72. 0x09, /*bLength: Interface Descriptor size*/
  73. USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
  74. 0x00, /*bInterfaceNumber: Number of Interface*/
  75. 0x00, /*bAlternateSetting: Alternate setting*/
  76. 0x02, /*bNumEndpoints*/
  77. 0x03, /*bInterfaceClass: HID*/
  78. 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
  79. 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
  80. 0, /*iInterface: Index of string descriptor*/
  81. /******************** Descriptor of GENERIC HID ********************/
  82. /* 18 */
  83. 0x09, /*bLength: HID Descriptor size*/
  84. HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
  85. 0x11, /*bcdHID: HID Class Spec release number*/
  86. 0x01,
  87. 0x00, /*bCountryCode: Hardware target country*/
  88. 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
  89. 0x22, /*bDescriptorType*/
  90. HID_GENERIC_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
  91. 0x00,
  92. /******************** Descriptor of Generic HID endpoint ********************/
  93. /* 27 */
  94. 0x07, /*bLength: Endpoint Descriptor size*/
  95. USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
  96. HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
  97. 0x03, /*bmAttributes: Interrupt endpoint*/
  98. HID_EPIN_SIZE, /*wMaxPacketSize: 64 Byte max */
  99. 0x00,
  100. HID_HS_BINTERVAL, /*bInterval*/
  101. /* 34 */
  102. /******************** Descriptor of GENERIC HID endpoint ********************/
  103. /* 34 */
  104. 0x07, /*bLength: Endpoint Descriptor size*/
  105. USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
  106. HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/
  107. 0x03, /*bmAttributes: Interrupt endpoint*/
  108. HID_EPOUT_SIZE, /*wMaxPacketSize */
  109. 0x00,
  110. HID_HS_BINTERVAL, /*bInterval*/
  111. /* 41 */
  112. /******************** Mass Storage interface ********************/
  113. 0x09, /* bLength: Interface Descriptor size */
  114. USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
  115. 0x01, /* bInterfaceNumber: Number of Interface */
  116. 0x00, /* bAlternateSetting: Alternate setting */
  117. 0x02, /* bNumEndpoints*/
  118. 0x08, /* bInterfaceClass: MSC Class */
  119. 0x06, /* bInterfaceSubClass : SCSI transparent*/
  120. 0x50, /* nInterfaceProtocol */
  121. 0x00, /* iInterface: */
  122. /******************** Mass Storage Endpoints ********************/
  123. 0x07, /*Endpoint descriptor length = 7*/
  124. 0x05, /*Endpoint descriptor type */
  125. MSC_EPIN_ADDR, /*Endpoint address */
  126. 0x02, /*Bulk endpoint type */
  127. LOBYTE(MSC_MAX_HS_PACKET),
  128. HIBYTE(MSC_MAX_HS_PACKET),
  129. 0x00, /*Polling interval in milliseconds */
  130. 0x07, /*Endpoint descriptor length = 7 */
  131. 0x05, /*Endpoint descriptor type */
  132. MSC_EPOUT_ADDR, /*Endpoint address */
  133. 0x02, /*Bulk endpoint type */
  134. LOBYTE(MSC_MAX_HS_PACKET),
  135. HIBYTE(MSC_MAX_HS_PACKET),
  136. 0x00 /*Polling interval in milliseconds*/
  137. };
  138. __ALIGN_BEGIN static uint8_t USBD_Composite_CfgFSDesc[USB_COMPOSITE_CONFIG_DESC_SIZ] __ALIGN_END =
  139. {
  140. 0x09, /* bLength: Configuration Descriptor size */
  141. USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
  142. USB_COMPOSITE_CONFIG_DESC_SIZ,
  143. /* wTotalLength: Bytes returned */
  144. 0x00,
  145. 0x02, /*bNumInterfaces: 1 interface*/
  146. 0x01, /*bConfigurationValue: Configuration value*/
  147. 0x00, /*iConfiguration: Index of string descriptor describing
  148. the configuration*/
  149. 0x80, /*bmAttributes: bus powered */
  150. 0xFA, /*MaxPower 500 mA: this current is used for detecting Vbus*/
  151. /************** Descriptor of GENERIC interface ****************/
  152. /* 09 */
  153. 0x09, /*bLength: Interface Descriptor size*/
  154. USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
  155. 0x00, /*bInterfaceNumber: Number of Interface*/
  156. 0x00, /*bAlternateSetting: Alternate setting*/
  157. 0x02, /*bNumEndpoints*/
  158. 0x03, /*bInterfaceClass: HID*/
  159. 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
  160. 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
  161. 0, /*iInterface: Index of string descriptor*/
  162. /******************** Descriptor of GENERIC HID ********************/
  163. /* 18 */
  164. 0x09, /*bLength: HID Descriptor size*/
  165. HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
  166. 0x11, /*bcdHID: HID Class Spec release number*/
  167. 0x01,
  168. 0x00, /*bCountryCode: Hardware target country*/
  169. 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
  170. 0x22, /*bDescriptorType*/
  171. HID_GENERIC_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
  172. 0x00,
  173. /******************** Descriptor of Generic HID endpoint ********************/
  174. /* 27 */
  175. 0x07, /*bLength: Endpoint Descriptor size*/
  176. USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
  177. HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
  178. 0x03, /*bmAttributes: Interrupt endpoint*/
  179. HID_EPIN_SIZE, /*wMaxPacketSize: 64 Byte max */
  180. 0x00,
  181. HID_FS_BINTERVAL, /*bInterval*/
  182. /* 34 */
  183. /******************** Descriptor of GENERIC HID endpoint ********************/
  184. /* 34 */
  185. 0x07, /*bLength: Endpoint Descriptor size*/
  186. USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
  187. HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/
  188. 0x03, /*bmAttributes: Interrupt endpoint*/
  189. HID_EPOUT_SIZE, /*wMaxPacketSize */
  190. 0x00,
  191. HID_FS_BINTERVAL, /*bInterval*/
  192. /* 41 */
  193. /******************** Mass Storage interface ********************/
  194. 0x09, /* bLength: Interface Descriptor size */
  195. USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
  196. 0x01, /* bInterfaceNumber: Number of Interface */
  197. 0x00, /* bAlternateSetting: Alternate setting */
  198. 0x02, /* bNumEndpoints*/
  199. 0x08, /* bInterfaceClass: MSC Class */
  200. 0x06, /* bInterfaceSubClass : SCSI transparent*/
  201. 0x50, /* nInterfaceProtocol */
  202. 0x00, /* iInterface: */
  203. /******************** Mass Storage Endpoints ********************/
  204. 0x07, /*Endpoint descriptor length = 7*/
  205. 0x05, /*Endpoint descriptor type */
  206. MSC_EPIN_ADDR, /*Endpoint address */
  207. 0x02, /*Bulk endpoint type */
  208. LOBYTE(MSC_MAX_FS_PACKET),
  209. HIBYTE(MSC_MAX_FS_PACKET),
  210. 0x00, /*Polling interval in milliseconds */
  211. 0x07, /*Endpoint descriptor length = 7 */
  212. 0x05, /*Endpoint descriptor type */
  213. MSC_EPOUT_ADDR, /*Endpoint address */
  214. 0x02, /*Bulk endpoint type */
  215. LOBYTE(MSC_MAX_FS_PACKET),
  216. HIBYTE(MSC_MAX_FS_PACKET),
  217. 0x00 /*Polling interval in milliseconds*/
  218. } ;
  219. /* USB Standard Device Descriptor */
  220. __ALIGN_BEGIN static uint8_t USBD_Composite_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
  221. {
  222. USB_LEN_DEV_QUALIFIER_DESC,
  223. USB_DESC_TYPE_DEVICE_QUALIFIER,
  224. 0x00,
  225. 0x02,
  226. 0x00,
  227. 0x00,
  228. 0x00,
  229. MSC_MAX_FS_PACKET,
  230. 0x01,
  231. 0x00,
  232. };
  233. static uint8_t USBD_Composite_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
  234. {
  235. uint8_t ret = 0;
  236. // HID Endpoints
  237. USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE);
  238. USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE);
  239. USBD_CompositeClassData* classData;
  240. if(pdev->dev_speed == USBD_SPEED_HIGH)
  241. {
  242. classData = &hsClassData;
  243. // MSC Endpoints
  244. USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
  245. USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
  246. }
  247. else
  248. {
  249. classData = &fsClassData;
  250. // MSC Endpoints
  251. USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
  252. USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
  253. }
  254. classData->hid.state = HID_IDLE;
  255. classData->hid.reportReady = 0;
  256. classData->DataInReady = 0;
  257. classData->DataOutReady = 0;
  258. pdev->pClassData = classData;
  259. MSC_BOT_Init(pdev);
  260. // Prepare Out endpoint to receive next HID packet
  261. USBD_LL_PrepareReceive(
  262. pdev,
  263. HID_EPOUT_ADDR,
  264. classData->hid.rxBuffer,
  265. sizeof(classData->hid.rxBuffer));
  266. return ret;
  267. }
  268. static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
  269. {
  270. USBD_LL_CloseEP(pdev, HID_EPIN_ADDR);
  271. USBD_LL_CloseEP(pdev, HID_EPOUT_ADDR);
  272. USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR);
  273. USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR);
  274. MSC_BOT_DeInit(pdev);
  275. pdev->pClassData = NULL;
  276. return USBD_OK;
  277. }
  278. static uint8_t USBD_Composite_Setup(
  279. USBD_HandleTypeDef *pdev,
  280. USBD_SetupReqTypedef *req)
  281. {
  282. uint16_t len = 0;
  283. uint8_t *pbuf = NULL;
  284. USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
  285. USBD_HID_HandleTypeDef *hhid = &(classData->hid);
  286. USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
  287. switch (req->bmRequest & USB_REQ_TYPE_MASK)
  288. {
  289. case USB_REQ_TYPE_CLASS :
  290. switch (req->bRequest)
  291. {
  292. case HID_REQ_SET_PROTOCOL:
  293. hhid->Protocol = (uint8_t)(req->wValue);
  294. break;
  295. case HID_REQ_GET_PROTOCOL:
  296. USBD_CtlSendData (pdev, (uint8_t *)&hhid->Protocol, 1);
  297. break;
  298. case HID_REQ_SET_IDLE:
  299. hhid->IdleState = (uint8_t)(req->wValue >> 8);
  300. break;
  301. case HID_REQ_GET_IDLE:
  302. USBD_CtlSendData (pdev, (uint8_t *)&hhid->IdleState, 1);
  303. break;
  304. case BOT_GET_MAX_LUN :
  305. if((req->wValue == 0) &&
  306. (req->wLength == 1) &&
  307. ((req->bmRequest & 0x80) == 0x80))
  308. {
  309. hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
  310. USBD_CtlSendData (pdev, (uint8_t *)&hmsc->max_lun, 1);
  311. }
  312. else
  313. {
  314. USBD_CtlError(pdev , req);
  315. return USBD_FAIL;
  316. }
  317. break;
  318. case BOT_RESET :
  319. if((req->wValue == 0) &&
  320. (req->wLength == 0) &&
  321. ((req->bmRequest & 0x80) != 0x80))
  322. {
  323. MSC_BOT_Reset(pdev);
  324. }
  325. else
  326. {
  327. USBD_CtlError(pdev , req);
  328. return USBD_FAIL;
  329. }
  330. break;
  331. default:
  332. USBD_CtlError (pdev, req);
  333. return USBD_FAIL;
  334. } break;
  335. case USB_REQ_TYPE_STANDARD:
  336. switch (req->bRequest)
  337. {
  338. case USB_REQ_GET_DESCRIPTOR:
  339. if( req->wValue >> 8 == HID_REPORT_DESC)
  340. {
  341. len = MIN(HID_GENERIC_REPORT_DESC_SIZE , req->wLength);
  342. pbuf = (uint8_t*) USBD_HID_GetReportDesc();
  343. }
  344. else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
  345. {
  346. pbuf = (uint8_t*) USBD_HID_GetDesc();
  347. len = MIN(USB_HID_DESC_SIZ , req->wLength);
  348. }
  349. USBD_CtlSendData (pdev, pbuf, len);
  350. break;
  351. case USB_REQ_GET_INTERFACE :
  352. if (req->wIndex == 0)
  353. {
  354. USBD_CtlSendData (pdev, (uint8_t *)&hhid->AltSetting, 1);
  355. }
  356. else
  357. {
  358. USBD_CtlSendData (pdev, (uint8_t *)&hmsc->interface, 1);
  359. }
  360. break;
  361. case USB_REQ_SET_INTERFACE :
  362. if (req->wIndex == 0)
  363. {
  364. hhid->AltSetting = (uint8_t)(req->wValue);
  365. }
  366. else
  367. {
  368. hmsc->interface = (uint8_t)(req->wValue);
  369. }
  370. break;
  371. case USB_REQ_CLEAR_FEATURE:
  372. /* Flush the FIFO and Clear the stall status */
  373. USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
  374. /* Reactivate the EP */
  375. USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
  376. switch ((uint8_t)req->wIndex)
  377. {
  378. case MSC_EPIN_ADDR:
  379. USBD_LL_OpenEP(
  380. pdev,
  381. MSC_EPIN_ADDR,
  382. USBD_EP_TYPE_BULK,
  383. pdev->dev_speed == USBD_SPEED_HIGH ? MSC_MAX_HS_PACKET : MSC_MAX_FS_PACKET);
  384. break;
  385. case MSC_EPOUT_ADDR:
  386. USBD_LL_OpenEP(
  387. pdev,
  388. MSC_EPOUT_ADDR,
  389. USBD_EP_TYPE_BULK,
  390. pdev->dev_speed == USBD_SPEED_HIGH ? MSC_MAX_HS_PACKET : MSC_MAX_FS_PACKET);
  391. break;
  392. case HID_EPIN_ADDR:
  393. USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE);
  394. break;
  395. case HID_EPOUT_ADDR:
  396. USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE);
  397. break;
  398. }
  399. /* Handle BOT error */
  400. MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
  401. break;
  402. } break;
  403. }
  404. return USBD_OK;
  405. }
  406. static uint8_t USBD_Composite_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
  407. {
  408. USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
  409. if (epnum == (HID_EPIN_ADDR & 0x7F))
  410. {
  411. USBD_HID_HandleTypeDef *hhid = &(classData->hid);
  412. /* Ensure that the FIFO is empty before a new transfer, this condition could
  413. be caused by a new transfer before the end of the previous transfer */
  414. hhid->state = HID_IDLE;
  415. }
  416. else if (epnum == (MSC_EPIN_ADDR & 0x7F))
  417. {
  418. classData->DataInReady = epnum;
  419. }
  420. return USBD_OK;
  421. }
  422. static uint8_t USBD_Composite_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
  423. {
  424. USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
  425. if (epnum == (HID_EPOUT_ADDR & 0x7F))
  426. {
  427. USBD_HID_HandleTypeDef *hhid = &(classData->hid);
  428. hhid->reportReady = 1;
  429. }
  430. else if (epnum == (MSC_EPOUT_ADDR & 0x7F))
  431. {
  432. classData->DataOutReady = epnum;
  433. }
  434. return USBD_OK;
  435. }
  436. void s2s_usbDevicePoll(USBD_HandleTypeDef *pdev) {
  437. USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
  438. if (classData->DataInReady)
  439. {
  440. int tmp = classData->DataInReady;
  441. classData->DataInReady = 0;
  442. MSC_BOT_DataIn(pdev, tmp);
  443. }
  444. if (classData->DataOutReady) {
  445. int tmp = classData->DataOutReady;
  446. classData->DataOutReady = 0;
  447. MSC_BOT_DataOut(pdev, tmp);
  448. }
  449. }
  450. static uint8_t *USBD_Composite_GetDeviceQualifierDesc (uint16_t *length)
  451. {
  452. *length = sizeof (USBD_Composite_DeviceQualifierDesc);
  453. return USBD_Composite_DeviceQualifierDesc;
  454. }
  455. uint8_t *USBD_Composite_GetHSCfgDesc (uint16_t *length)
  456. {
  457. *length = sizeof (USBD_Composite_CfgHSDesc);
  458. return USBD_Composite_CfgHSDesc;
  459. }
  460. uint8_t *USBD_Composite_GetFSCfgDesc (uint16_t *length)
  461. {
  462. *length = sizeof (USBD_Composite_CfgFSDesc);
  463. return USBD_Composite_CfgFSDesc;
  464. }