Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1765 lines
48 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. URB.C
  5. Abstract:
  6. This module contains the code to process URBs passed
  7. in by client drivers.
  8. Environment:
  9. kernel mode only
  10. Notes:
  11. ** URB handler routines
  12. Handler -- This function handles the specific USBD request, if the function passes
  13. the urb on to the port driver then it must return STATUS_PENDING. If any
  14. parameters are invalid then it returns the appropriate NT status code, and
  15. the IRP will completed by the deviceControl function.
  16. PostHandler -- This function is called when the Irp/Urb completes through the iocompletion
  17. routine. This routine is responsible for performing any cleanup and completing
  18. the request.
  19. Revision History:
  20. 09-29-95 : created
  21. 07-19-96 : removed device object
  22. --*/
  23. #include "wdm.h"
  24. #include "stdarg.h"
  25. #include "stdio.h"
  26. #include "usbdi.h" //public data structures
  27. #include "hcdi.h"
  28. #include "usbd.h" //private data strutures
  29. #ifdef USBD_DRIVER // USBPORT supercedes most of USBD, so we will remove
  30. // the obsolete code by compiling it only if
  31. // USBD_DRIVER is set.
  32. typedef NTSTATUS URB_HANDLER(PDEVICE_OBJECT DeviceObject, PIRP Irp, PURB Urb, BOOLEAN *IrpIsPending);
  33. typedef NTSTATUS URB_POSTHANDLER(PDEVICE_OBJECT DeviceObject, PIRP Irp, PURB Urb, PVOID Context);
  34. typedef struct _URB_DISPATCH_ENTRY {
  35. URB_HANDLER *UrbHandler; // API handler
  36. USHORT UrbRequestLength; // Length of the URB expected for this request
  37. USHORT RequestCode; // Request code for setup packet if standard command
  38. ULONG Flags;
  39. #if DBG
  40. ULONG ExpectedFunctionCode;
  41. #endif
  42. } URB_DISPATCH_ENTRY;
  43. URB_HANDLER USBD_SelectConfiguration;
  44. URB_HANDLER USBD_SelectInterface;
  45. URB_HANDLER USBD_AsyncTransfer;
  46. URB_HANDLER USBD_IsochTransfer;
  47. URB_HANDLER USBD_PassThru;
  48. URB_HANDLER USBD_AbortPipe;
  49. URB_HANDLER USBD_ResetPipe;
  50. URB_HANDLER USBD_SCT_GetSetDescriptor;
  51. URB_HANDLER USBD_SCT_SetClearFeature;
  52. URB_HANDLER USBD_SCT_GetStatus;
  53. URB_HANDLER USBD_SCT_VendorClassCommand;
  54. URB_HANDLER USBD_SCT_GetInterface;
  55. URB_HANDLER USBD_SCT_GetConfiguration;
  56. URB_HANDLER USBD_TakeFrameLengthControl;
  57. URB_HANDLER USBD_ReleaseFrameLengthControl;
  58. URB_HANDLER USBD_GetFrameLength;
  59. URB_HANDLER USBD_SetFrameLength;
  60. URB_HANDLER USBD_BulkTransfer;
  61. URB_DISPATCH_ENTRY UrbDispatchTable[URB_FUNCTION_LAST+1] =
  62. {
  63. //URB_FUNCTION_SELECT_CONFIGURATION
  64. USBD_SelectConfiguration,
  65. 0, // handler will validate length
  66. 0,
  67. 0,
  68. #if DBG
  69. URB_FUNCTION_SELECT_CONFIGURATION,
  70. #endif
  71. //URB_FUNCTION_SELECT_INTERFACE
  72. USBD_SelectInterface,
  73. 0,
  74. 0,
  75. 0,
  76. #if DBG
  77. URB_FUNCTION_SELECT_INTERFACE,
  78. #endif
  79. //URB_FUNCTION_ABORT_PIPE
  80. USBD_AbortPipe,
  81. sizeof(struct _URB_PIPE_REQUEST),
  82. 0,
  83. 0,
  84. #if DBG
  85. URB_FUNCTION_ABORT_PIPE,
  86. #endif
  87. //URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL
  88. USBD_TakeFrameLengthControl,
  89. sizeof(struct _URB_FRAME_LENGTH_CONTROL),
  90. 0,
  91. 0,
  92. #if DBG
  93. URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL,
  94. #endif
  95. //URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL
  96. USBD_ReleaseFrameLengthControl,
  97. sizeof(struct _URB_FRAME_LENGTH_CONTROL),
  98. 0,
  99. 0,
  100. #if DBG
  101. URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL,
  102. #endif
  103. //URB_FUNCTION_GET_FRAME_LENGTH
  104. USBD_GetFrameLength,
  105. sizeof(struct _URB_GET_FRAME_LENGTH),
  106. 0,
  107. 0,
  108. #if DBG
  109. URB_FUNCTION_GET_FRAME_LENGTH,
  110. #endif
  111. //URB_FUNCTION_SET_FRAME_LENGTH
  112. USBD_SetFrameLength,
  113. sizeof(struct _URB_SET_FRAME_LENGTH),
  114. 0,
  115. 0,
  116. #if DBG
  117. URB_FUNCTION_SET_FRAME_LENGTH,
  118. #endif
  119. //URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
  120. USBD_PassThru,
  121. 0,
  122. 0,
  123. 0,
  124. #if DBG
  125. URB_FUNCTION_GET_CURRENT_FRAME_NUMBER,
  126. #endif
  127. //URB_FUNCTION_CONTROL_TRANSFER
  128. USBD_AsyncTransfer,
  129. sizeof(struct _URB_CONTROL_TRANSFER),
  130. 0,
  131. USBD_REQUEST_IS_TRANSFER,
  132. #if DBG
  133. URB_FUNCTION_CONTROL_TRANSFER,
  134. #endif
  135. //URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
  136. USBD_AsyncTransfer,
  137. sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
  138. 0,
  139. USBD_REQUEST_IS_TRANSFER,
  140. #if DBG
  141. URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER,
  142. #endif
  143. //URB_FUNCTION_ISOCH_TRANSFER
  144. USBD_IsochTransfer,
  145. 0,
  146. 0,
  147. USBD_REQUEST_IS_TRANSFER,
  148. #if DBG
  149. URB_FUNCTION_ISOCH_TRANSFER,
  150. #endif
  151. //URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
  152. USBD_SCT_GetSetDescriptor,
  153. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  154. STANDARD_COMMAND_GET_DESCRIPTOR,
  155. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  156. #if DBG
  157. URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE,
  158. #endif
  159. //URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE
  160. USBD_SCT_GetSetDescriptor,
  161. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  162. STANDARD_COMMAND_SET_DESCRIPTOR,
  163. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  164. #if DBG
  165. URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE,
  166. #endif
  167. //URB_FUNCTION_SET_FEATURE_TO_DEVICE
  168. USBD_SCT_SetClearFeature,
  169. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  170. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_DEVICE) | (USB_REQUEST_SET_FEATURE<<8)),
  171. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  172. #if DBG
  173. URB_FUNCTION_SET_FEATURE_TO_DEVICE,
  174. #endif
  175. //URB_FUNCTION_SET_FEATURE_TO_INTERFACE
  176. USBD_SCT_SetClearFeature,
  177. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  178. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_INTERFACE) | (USB_REQUEST_SET_FEATURE<<8)),
  179. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  180. #if DBG
  181. URB_FUNCTION_SET_FEATURE_TO_INTERFACE,
  182. #endif
  183. //URB_FUNCTION_SET_FEATURE_TO_ENDPOINT
  184. USBD_SCT_SetClearFeature,
  185. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  186. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_ENDPOINT) | (USB_REQUEST_SET_FEATURE<<8)),
  187. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  188. #if DBG
  189. URB_FUNCTION_SET_FEATURE_TO_ENDPOINT,
  190. #endif
  191. //URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE
  192. USBD_SCT_SetClearFeature,
  193. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  194. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_DEVICE) | (USB_REQUEST_CLEAR_FEATURE<<8)),
  195. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  196. #if DBG
  197. URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE,
  198. #endif
  199. //URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE
  200. USBD_SCT_SetClearFeature,
  201. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  202. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_INTERFACE) | (USB_REQUEST_CLEAR_FEATURE<<8)),
  203. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  204. #if DBG
  205. URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE,
  206. #endif
  207. //URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT
  208. USBD_SCT_SetClearFeature,
  209. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  210. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_ENDPOINT) | (USB_REQUEST_CLEAR_FEATURE<<8)),
  211. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  212. #if DBG
  213. URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,
  214. #endif
  215. //URB_FUNCTION_GET_STATUS_FROMDEVICE
  216. USBD_SCT_GetStatus,
  217. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST),
  218. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_DEVICE) | (USB_REQUEST_GET_STATUS<<8)),
  219. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  220. #if DBG
  221. URB_FUNCTION_GET_STATUS_FROM_DEVICE,
  222. #endif
  223. //URB_FUNCTION_GET_STATUS_FROM_INTERFACE
  224. USBD_SCT_GetStatus,
  225. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST),
  226. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_INTERFACE) | (USB_REQUEST_GET_STATUS<<8)),
  227. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  228. #if DBG
  229. URB_FUNCTION_GET_STATUS_FROM_INTERFACE,
  230. #endif
  231. //URB_FUNCTION_GET_STATUS_FROMENDPOINT
  232. USBD_SCT_GetStatus,
  233. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST),
  234. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_ENDPOINT) | (USB_REQUEST_GET_STATUS<<8)),
  235. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  236. #if DBG
  237. URB_FUNCTION_GET_STATUS_FROM_ENDPOINT,
  238. #endif
  239. //URB_FUNCTION_SYNC_FRAME
  240. NULL,
  241. 0,
  242. 0,
  243. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  244. #if DBG
  245. 0, //URB_FUNCTION_SYNC_FRAME,
  246. #endif
  247. //URB_FUNCTION_VENDOR_DEVICE
  248. USBD_SCT_VendorClassCommand,
  249. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  250. (USB_COMMAND_TO_DEVICE | USB_VENDOR_COMMAND),
  251. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  252. #if DBG
  253. URB_FUNCTION_VENDOR_DEVICE,
  254. #endif
  255. //URB_FUNCTION_VENDOR_INTERFACE
  256. USBD_SCT_VendorClassCommand,
  257. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  258. (USB_COMMAND_TO_INTERFACE | USB_VENDOR_COMMAND),
  259. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  260. #if DBG
  261. URB_FUNCTION_VENDOR_INTERFACE,
  262. #endif
  263. //URB_FUNCTION_VENDOR_ENDPOINT
  264. USBD_SCT_VendorClassCommand,
  265. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  266. (USB_COMMAND_TO_ENDPOINT | USB_VENDOR_COMMAND),
  267. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  268. #if DBG
  269. URB_FUNCTION_VENDOR_ENDPOINT,
  270. #endif
  271. //URB_FUNCTION_CLASS_DEVICE
  272. USBD_SCT_VendorClassCommand,
  273. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  274. (USB_COMMAND_TO_DEVICE | USB_CLASS_COMMAND),
  275. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  276. #if DBG
  277. URB_FUNCTION_CLASS_DEVICE,
  278. #endif
  279. //URB_FUNCTION_CLASS_INTERFACE
  280. USBD_SCT_VendorClassCommand,
  281. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  282. (USB_COMMAND_TO_INTERFACE | USB_CLASS_COMMAND),
  283. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  284. #if DBG
  285. URB_FUNCTION_CLASS_INTERFACE,
  286. #endif
  287. //URB_FUNCTION_CLASS_ENDPOINT
  288. USBD_SCT_VendorClassCommand,
  289. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  290. (USB_COMMAND_TO_ENDPOINT | USB_CLASS_COMMAND),
  291. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  292. #if DBG
  293. URB_FUNCTION_CLASS_ENDPOINT,
  294. #endif
  295. //URB_FUNCTION_ NOT USED
  296. NULL,
  297. 0,
  298. 0,
  299. 0,
  300. #if DBG
  301. URB_FUNCTION_RESERVED,
  302. #endif
  303. //URB_FUNCTION_RESET_PIPE
  304. USBD_ResetPipe,
  305. sizeof(struct _URB_PIPE_REQUEST),
  306. (USB_COMMAND_TO_DEVICE),
  307. 0,
  308. #if DBG
  309. URB_FUNCTION_RESET_PIPE,
  310. #endif
  311. //URB_FUNCTION_CLASS_OTHER
  312. USBD_SCT_VendorClassCommand,
  313. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  314. (USB_COMMAND_TO_OTHER | USB_CLASS_COMMAND),
  315. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  316. #if DBG
  317. URB_FUNCTION_CLASS_OTHER,
  318. #endif
  319. //URB_FUNCTION_VENDOR_OTHER
  320. USBD_SCT_VendorClassCommand,
  321. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  322. (USB_COMMAND_TO_OTHER | USB_VENDOR_COMMAND),
  323. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  324. #if DBG
  325. URB_FUNCTION_VENDOR_OTHER,
  326. #endif
  327. //URB_FUNCTION_GET_STATUS_FROMOTHER
  328. USBD_SCT_GetStatus,
  329. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST),
  330. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_OTHER) | (USB_REQUEST_GET_STATUS<<8)),
  331. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  332. #if DBG
  333. URB_FUNCTION_GET_STATUS_FROM_OTHER,
  334. #endif
  335. //URB_FUNCTION_CLEAR_FEATURE_TO_OTHER
  336. USBD_SCT_SetClearFeature,
  337. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  338. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_OTHER) | (USB_REQUEST_CLEAR_FEATURE<<8)),
  339. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  340. #if DBG
  341. URB_FUNCTION_CLEAR_FEATURE_TO_OTHER,
  342. #endif
  343. //URB_FUNCTION_SET_FEATURE_TO_OTHER
  344. USBD_SCT_SetClearFeature,
  345. sizeof(struct _URB_CONTROL_FEATURE_REQUEST),
  346. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_OTHER) | (USB_REQUEST_SET_FEATURE<<8)),
  347. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE | USBD_REQUEST_NO_DATA_PHASE,
  348. #if DBG
  349. URB_FUNCTION_SET_FEATURE_TO_INTERFACE,
  350. #endif
  351. //URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT
  352. USBD_SCT_GetSetDescriptor,
  353. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  354. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_ENDPOINT) | (USB_REQUEST_GET_DESCRIPTOR<<8)),
  355. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  356. #if DBG
  357. URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT,
  358. #endif
  359. //URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT
  360. USBD_SCT_GetSetDescriptor,
  361. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  362. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_ENDPOINT) | (USB_REQUEST_SET_DESCRIPTOR<<8)),
  363. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  364. #if DBG
  365. URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT,
  366. #endif
  367. //URB_FUNCTION_GET_CONFIGURATION
  368. USBD_SCT_GetConfiguration,
  369. sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST),
  370. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_DEVICE) |
  371. (USB_REQUEST_GET_CONFIGURATION<<8)),
  372. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  373. #if DBG
  374. URB_FUNCTION_GET_CONFIGURATION,
  375. #endif
  376. //URB_FUNCTION_GET_INTERFACE
  377. USBD_SCT_GetInterface,
  378. sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST),
  379. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_INTERFACE) |
  380. (USB_REQUEST_GET_INTERFACE<<8)),
  381. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  382. #if DBG
  383. URB_FUNCTION_GET_INTERFACE,
  384. #endif
  385. //URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
  386. USBD_SCT_GetSetDescriptor,
  387. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  388. ((USB_DEVICE_TO_HOST | USB_COMMAND_TO_INTERFACE) | (USB_REQUEST_GET_DESCRIPTOR<<8)),
  389. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  390. #if DBG
  391. URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE,
  392. #endif
  393. //URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE
  394. USBD_SCT_GetSetDescriptor,
  395. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  396. ((USB_HOST_TO_DEVICE | USB_COMMAND_TO_INTERFACE) | (USB_REQUEST_SET_DESCRIPTOR<<8)),
  397. USBD_REQUEST_IS_TRANSFER | USBD_REQUEST_USES_DEFAULT_PIPE,
  398. #if DBG
  399. URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE,
  400. #endif
  401. };
  402. BOOLEAN
  403. USBD_ValidatePipe(
  404. PUSBD_PIPE PipeHandle
  405. )
  406. /*++
  407. Routine Description:
  408. Validates the pipe flags and anything else that we deem appropriate.
  409. Arguments:
  410. PipeHandle - PipeHandle associated with the URB in this IRP request
  411. Return Value:
  412. Boolean value indicating whether PipeHandle should be considered valid
  413. or not
  414. --*/
  415. {
  416. if (!PipeHandle ||
  417. (PipeHandle->Sig != SIG_PIPE) ||
  418. (PipeHandle->UsbdPipeFlags & ~(USBD_PF_VALID_MASK))) {
  419. return FALSE;
  420. }
  421. return TRUE;
  422. }
  423. NTSTATUS
  424. USBD_ProcessURB(
  425. IN PDEVICE_OBJECT DeviceObject,
  426. IN PIRP Irp,
  427. IN PURB Urb,
  428. OUT PBOOLEAN IrpIsPending
  429. )
  430. /*++
  431. Routine Description:
  432. Processes a URB from a client IRP, this does the guts of the
  433. processing.
  434. Two way to tell the caller not to pass the URB on
  435. 1) set IrpIsPending to FALSE or
  436. 2) return an error in
  437. Arguments:
  438. DeviceObject - Device object associated with this IRP request
  439. Irp - IO request block
  440. Urb - ptr to USB request block
  441. IrpIsPending - FALSE if USBD completes the IRP
  442. Return Value:
  443. --*/
  444. {
  445. NTSTATUS ntStatus = STATUS_SUCCESS;
  446. USHORT function;
  447. PHCD_URB hcdUrb = (PHCD_URB) Urb;
  448. PUSBD_PIPE pipeHandle;
  449. PUSBD_DEVICE_DATA device;
  450. USBD_KdPrint(3, ("'enter USBD_ProcessURB\n"));
  451. if (Urb == NULL) {
  452. return STATUS_INVALID_PARAMETER;
  453. }
  454. // initialize the error code to zero,
  455. // some drivers do not initailize on entry
  456. hcdUrb->HcdUrbCommonTransfer.Status = 0;
  457. if (Urb->UrbHeader.UsbdDeviceHandle == NULL) {
  458. PUSBD_EXTENSION deviceExtension;
  459. deviceExtension = GET_DEVICE_EXTENSION(DeviceObject);
  460. USBD_KdPrint(3, ("'USBD_ProcessURB -- URB for root hub\n"));
  461. Urb->UrbHeader.UsbdDeviceHandle =
  462. deviceExtension->RootHubDeviceData;
  463. }
  464. function = Urb->UrbHeader.Function;
  465. // Initialize flags field for this request
  466. hcdUrb->UrbHeader.UsbdFlags = 0;
  467. USBD_KdPrint(3, ("'USBD_ProcessURB, function = 0x%x\n", function));
  468. if (function > URB_FUNCTION_LAST) {
  469. ntStatus = STATUS_INVALID_PARAMETER;
  470. }
  471. #if DBG
  472. else {
  473. USBD_ASSERT(UrbDispatchTable[function].ExpectedFunctionCode == function);
  474. }
  475. #endif
  476. //
  477. // do some special transfer specific stuff
  478. //
  479. device = DEVICE_FROM_DEVICEHANDLEROBJECT(Urb->UrbHeader.UsbdDeviceHandle);
  480. if (!device) {
  481. hcdUrb->HcdUrbCommonTransfer.Status =
  482. SET_USBD_ERROR(USBD_STATUS_INVALID_PARAMETER);
  483. goto USBD_ProcessURB_Done;
  484. }
  485. ASSERT_DEVICE(device);
  486. if (UrbDispatchTable[function].Flags & USBD_REQUEST_IS_TRANSFER) {
  487. if (!device->AcceptingRequests) {
  488. //
  489. // Driver is attempting to transfer data when the device
  490. // is not in a state to accept requets or is not configured
  491. //
  492. USBD_Warning(device,
  493. "Failing driver transfer requests\n",
  494. FALSE);
  495. hcdUrb->HcdUrbCommonTransfer.Status =
  496. SET_USBD_ERROR(USBD_STATUS_INVALID_PARAMETER);
  497. goto USBD_ProcessURB_Done;
  498. }
  499. while (hcdUrb) {
  500. hcdUrb->UrbHeader.UsbdFlags |= USBD_REQUEST_IS_TRANSFER;
  501. if (UrbDispatchTable[function].Flags & USBD_REQUEST_NO_DATA_PHASE) {
  502. hcdUrb->HcdUrbCommonTransfer.TransferBuffer = NULL;
  503. hcdUrb->HcdUrbCommonTransfer.TransferBufferMDL = NULL;
  504. hcdUrb->HcdUrbCommonTransfer.TransferBufferLength = 0;
  505. }
  506. if (UrbDispatchTable[function].Flags & USBD_REQUEST_USES_DEFAULT_PIPE) {
  507. ASSERT_PIPE(&device->DefaultPipe);
  508. hcdUrb->HcdUrbCommonTransfer.UsbdPipeHandle = &device->DefaultPipe;
  509. } else if (function == URB_FUNCTION_CONTROL_TRANSFER &&
  510. hcdUrb->HcdUrbCommonTransfer.UsbdPipeHandle == 0) {
  511. PUSBD_EXTENSION deviceExtension;
  512. deviceExtension = GET_DEVICE_EXTENSION(DeviceObject);
  513. if ((deviceExtension->DiagnosticMode) &&
  514. !( (deviceExtension->DiagIgnoreHubs) &&
  515. (device->DeviceDescriptor.bDeviceClass == 0x09) ) )
  516. {
  517. // allow 0 to indicate default pipe in diag mode
  518. device = DEVICE_FROM_DEVICEHANDLEROBJECT(Urb->UrbHeader.UsbdDeviceHandle);
  519. ASSERT_PIPE(&device->DefaultPipe);
  520. hcdUrb->HcdUrbCommonTransfer.UsbdPipeHandle =
  521. &device->DefaultPipe;
  522. } else {
  523. hcdUrb->HcdUrbCommonTransfer.Status =
  524. SET_USBD_ERROR(USBD_STATUS_INVALID_PIPE_HANDLE);
  525. goto USBD_ProcessURB_Done;
  526. }
  527. }
  528. pipeHandle = hcdUrb->HcdUrbCommonTransfer.UsbdPipeHandle;
  529. ASSERT_PIPE(pipeHandle);
  530. // Validate the pipe flags.
  531. // BUGBUG: Need to use USBD_STATUS_INVALID_PIPE_FLAGS (usb.h).
  532. if (!USBD_ValidatePipe(pipeHandle)) {
  533. USBD_Warning(device,
  534. "Invalid PipeFlags passed to USBD_ProcessURB, fail!\n",
  535. TRUE);
  536. hcdUrb->HcdUrbCommonTransfer.Status =
  537. SET_USBD_ERROR(USBD_STATUS_INVALID_PIPE_HANDLE);
  538. goto USBD_ProcessURB_Done;
  539. }
  540. // make sure the pipe handle is still valid
  541. if (PIPE_CLOSED(pipeHandle)) {
  542. USBD_Warning(device,
  543. "PipeHandle closed in USBD_ProcessURB\n",
  544. FALSE);
  545. hcdUrb->HcdUrbCommonTransfer.Status =
  546. SET_USBD_ERROR(USBD_STATUS_INVALID_PIPE_HANDLE);
  547. goto USBD_ProcessURB_Done;
  548. }
  549. hcdUrb->HcdUrbCommonTransfer.hca.HcdIrp = Irp;
  550. hcdUrb->HcdUrbCommonTransfer.hca.HcdExtension = NULL;
  551. // if only a system buffer address is specified then
  552. // the caller has passed in a buffer allocated from the
  553. // non-paged pool -- we allocate an MDL for the request in
  554. // this case.
  555. if (hcdUrb->HcdUrbCommonTransfer.TransferBufferMDL == NULL &&
  556. hcdUrb->HcdUrbCommonTransfer.TransferBufferLength != 0) {
  557. if ((hcdUrb->HcdUrbCommonTransfer.TransferBufferMDL =
  558. IoAllocateMdl(hcdUrb->HcdUrbCommonTransfer.TransferBuffer,
  559. hcdUrb->HcdUrbCommonTransfer.TransferBufferLength,
  560. FALSE,
  561. FALSE,
  562. NULL)) == NULL)
  563. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  564. else {
  565. hcdUrb->UrbHeader.UsbdFlags |= USBD_REQUEST_MDL_ALLOCATED;
  566. MmBuildMdlForNonPagedPool(hcdUrb->HcdUrbCommonTransfer.TransferBufferMDL);
  567. }
  568. }
  569. if (hcdUrb->HcdUrbCommonTransfer.TransferBufferMDL != NULL &&
  570. hcdUrb->HcdUrbCommonTransfer.TransferBufferLength == 0) {
  571. ntStatus = STATUS_INVALID_PARAMETER;
  572. }
  573. // get next urb in the chain
  574. hcdUrb = hcdUrb->HcdUrbCommonTransfer.UrbLink;
  575. } /* end while hcd urb */
  576. } else {
  577. /* request is not a transfer, we will still attempt some validation */
  578. switch(function) {
  579. case URB_FUNCTION_ABORT_PIPE:
  580. case URB_FUNCTION_RESET_PIPE:
  581. /* not valid to attempt these after a remove */
  582. //
  583. // NOTE there is no gurantee that device will be valid
  584. // at this point but we will at least attempt to catch it
  585. //
  586. // in the case whwee the driver is attempting a reset of its
  587. // port this will prevent calls to the HCD with bogus endpoint
  588. // handles.
  589. //
  590. if (!device->AcceptingRequests) {
  591. USBD_Warning(NULL,
  592. "Failing ABORT/RESET request\n",
  593. FALSE);
  594. hcdUrb->HcdUrbCommonTransfer.Status =
  595. SET_USBD_ERROR(USBD_STATUS_INVALID_PARAMETER);
  596. goto USBD_ProcessURB_Done;
  597. }
  598. break;
  599. }
  600. }
  601. //
  602. // validate the length field based on the function
  603. //
  604. if (NT_SUCCESS(ntStatus) &&
  605. UrbDispatchTable[function].UrbRequestLength &&
  606. UrbDispatchTable[function].UrbRequestLength != Urb->UrbHeader.Length) {
  607. ntStatus = STATUS_INVALID_PARAMETER;
  608. USBD_KdPrint(3, ("' Inavlid parameter length length = 0x%x, expected = 0x%x\n",
  609. Urb->UrbHeader.Length,
  610. UrbDispatchTable[function].UrbRequestLength));
  611. }
  612. if (NT_SUCCESS(ntStatus)) {
  613. if (UrbDispatchTable[function].UrbHandler)
  614. ntStatus = (UrbDispatchTable[function].UrbHandler)(DeviceObject, Irp, Urb, IrpIsPending);
  615. else {
  616. //
  617. //Complete the Irp now with an error.
  618. //
  619. ntStatus = STATUS_NOT_IMPLEMENTED;
  620. }
  621. }
  622. USBD_ProcessURB_Done:
  623. //
  624. // if the URB error code is set then this will map to
  625. // the appropriate nt status code to that the irp will
  626. // be completed.
  627. //
  628. ntStatus = USBD_MapError_UrbToNT(Urb, ntStatus);
  629. USBD_KdPrint(3, ("'exit USBD_ProcessURB 0x%x\n", ntStatus));
  630. return ntStatus;
  631. }
  632. NTSTATUS
  633. USBD_MapError_UrbToNT(
  634. IN PURB Urb,
  635. IN NTSTATUS NtStatus
  636. )
  637. /*++
  638. Routine Description:
  639. Map a USBD specific error code in a URB to a NTSTATUS
  640. code.
  641. Arguments:
  642. Urb - ptr to USB request block
  643. Return Value:
  644. --*/
  645. {
  646. //
  647. // if we have an NT status code then just return
  648. // that.
  649. //
  650. if (!NT_SUCCESS(NtStatus)) {
  651. return NtStatus;
  652. }
  653. // otherwise...
  654. //
  655. // if the irp completed with no error code but the URB has an
  656. // error, map the error in the urb to an nt error code.
  657. //
  658. if (USBD_SUCCESS(Urb->UrbHeader.Status)) {
  659. NtStatus = STATUS_SUCCESS;
  660. } else {
  661. //
  662. // map the USBD status code to
  663. // an NT status code.
  664. //
  665. switch (Urb->UrbHeader.Status) {
  666. case USBD_STATUS_NO_MEMORY:
  667. NtStatus = STATUS_INSUFFICIENT_RESOURCES;
  668. break;
  669. case USBD_STATUS_INVALID_URB_FUNCTION:
  670. case USBD_STATUS_INVALID_PARAMETER:
  671. NtStatus = STATUS_INVALID_PARAMETER;
  672. break;
  673. default:
  674. NtStatus = STATUS_DEVICE_DATA_ERROR;
  675. }
  676. }
  677. return NtStatus;
  678. }
  679. NTSTATUS
  680. USBD_SCT_GetSetDescriptor(
  681. IN PDEVICE_OBJECT DeviceObject,
  682. IN PIRP Irp,
  683. IN PURB Urb,
  684. OUT PBOOLEAN IrpIsPending
  685. )
  686. /*++
  687. Routine Description:
  688. Arguments:
  689. DeviceObject -
  690. Irp - IO request block
  691. Urb - ptr to USB request block
  692. Return Value:
  693. --*/
  694. {
  695. NTSTATUS ntStatus = STATUS_SUCCESS;
  696. PUSB_STANDARD_SETUP_PACKET setupPacket;
  697. USBD_KdPrint(3, ("' enter USBD_SCT_GetSetDescriptor\n"));
  698. setupPacket = (PUSB_STANDARD_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  699. // setup common fields
  700. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  701. setupPacket->RequestCode =
  702. UrbDispatchTable[Urb->UrbHeader.Function].RequestCode;
  703. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  704. if (USB_DEVICE_TO_HOST & setupPacket->RequestCode) {
  705. USBD_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  706. } else {
  707. USBD_SET_TRANSFER_DIRECTION_OUT(Urb->UrbControlTransfer.TransferFlags);
  708. }
  709. #if DBG
  710. //
  711. // some parameter validation
  712. //
  713. {
  714. UCHAR bRequest = (UCHAR) (setupPacket->RequestCode >> 8);
  715. UCHAR dType, dIndex, *pch;
  716. dType = (UCHAR) (setupPacket->wValue >> 8);
  717. dIndex = (UCHAR) setupPacket->wValue;
  718. pch = (PUCHAR) setupPacket;
  719. USBD_KdPrint(3, ("'USB REQUEST %02.2x %02.2x %02.2x %02.2x ",
  720. *pch, *(pch+1), *(pch+2), *(pch+3)));
  721. USBD_KdPrint(3, ("'USB REQUEST %02.2x %02.2x %02.2x %02.2x\n",
  722. *(pch+4), *(pch+5), *(pch+6), *(pch+7)));
  723. USBD_KdPrint(3, ("'USB REQUEST bRequest = %x dType = %x dIndex = %x wLength = %x\n",
  724. bRequest, dType, dIndex, setupPacket->wLength));
  725. switch (bRequest) {
  726. // get descriptor command
  727. case USB_REQUEST_GET_DESCRIPTOR:
  728. case USB_REQUEST_SET_DESCRIPTOR:
  729. if (dType == 4 || dType == 5) {
  730. USBD_Warning(NULL,
  731. "USBD detects a bogus Get/Set Descriptor Request from driver\n",
  732. TRUE);
  733. }
  734. break;
  735. default:
  736. USBD_KdBreak(("Invalid Get/Set Descriptor request\n"));
  737. }
  738. }
  739. #endif
  740. if (NT_SUCCESS(ntStatus)) {
  741. ((PHCD_URB) Urb)->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
  742. ((PHCD_URB) Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint =
  743. ((PUSBD_PIPE)((PHCD_URB)Urb)->HcdUrbCommonTransfer.UsbdPipeHandle)->HcdEndpoint;
  744. *IrpIsPending = TRUE;
  745. }
  746. USBD_KdPrint(3, ("' exit USBD_SCT_GetSetDescriptor 0x%x\n", ntStatus));
  747. return ntStatus;
  748. }
  749. NTSTATUS
  750. USBD_SCT_SetClearFeature(
  751. IN PDEVICE_OBJECT DeviceObject,
  752. IN PIRP Irp,
  753. IN PURB Urb,
  754. OUT PBOOLEAN IrpIsPending
  755. )
  756. /*++
  757. Routine Description:
  758. Arguments:
  759. DeviceObject -
  760. Irp - IO request block
  761. Urb - ptr to USB request block
  762. Return Value:
  763. --*/
  764. {
  765. NTSTATUS ntStatus = STATUS_SUCCESS;
  766. PUSB_STANDARD_SETUP_PACKET setupPacket;
  767. USBD_KdPrint(3, ("' enter USBD_SCT_SetClearFeature\n"));
  768. setupPacket = (PUSB_STANDARD_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  769. // setup common fields
  770. setupPacket->wLength = 0;
  771. //setupPacket->wValue = Urb->UrbControlFeatureRequest.FeatureSelector;
  772. //setupPacket->wIndex = Urb->UrbControlFeatureRequest.Index;
  773. setupPacket->RequestCode =
  774. UrbDispatchTable[Urb->UrbHeader.Function].RequestCode;
  775. Urb->UrbControlTransfer.TransferBufferLength = 0;
  776. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  777. if (USB_DEVICE_TO_HOST & setupPacket->RequestCode) {
  778. USBD_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  779. } else {
  780. USBD_SET_TRANSFER_DIRECTION_OUT( Urb->UrbControlTransfer.TransferFlags);
  781. }
  782. if (NT_SUCCESS(ntStatus)) {
  783. ((PHCD_URB) Urb)->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
  784. ((PHCD_URB) Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint =
  785. ((PUSBD_PIPE)((PHCD_URB)Urb)->HcdUrbCommonTransfer.UsbdPipeHandle)->HcdEndpoint;
  786. *IrpIsPending = TRUE;
  787. }
  788. USBD_KdPrint(3, ("' exit USBD_SCT_SetClearFeature 0x%x\n", ntStatus));
  789. return ntStatus;
  790. }
  791. NTSTATUS
  792. USBD_SCT_GetStatus(
  793. IN PDEVICE_OBJECT DeviceObject,
  794. IN PIRP Irp,
  795. IN PURB Urb,
  796. OUT PBOOLEAN IrpIsPending
  797. )
  798. /*++
  799. Routine Description:
  800. Arguments:
  801. DeviceObject -
  802. Irp - IO request block
  803. Urb - ptr to USB request block
  804. Return Value:
  805. --*/
  806. {
  807. NTSTATUS ntStatus = STATUS_SUCCESS;
  808. PUSB_STANDARD_SETUP_PACKET setupPacket;
  809. USBD_KdPrint(3, ("' enter USBD_SCT_GetStatus\n"));
  810. setupPacket = (PUSB_STANDARD_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  811. //
  812. // setup common fields
  813. //
  814. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  815. if (setupPacket->wLength != 2) {
  816. ntStatus = STATUS_INVALID_PARAMETER;
  817. Urb->UrbHeader.Status =
  818. SET_USBD_ERROR(USBD_STATUS_INVALID_PARAMETER);
  819. goto USBD_SCT_GetStatus_Done;
  820. }
  821. setupPacket->wValue = 0;
  822. setupPacket->RequestCode =
  823. UrbDispatchTable[Urb->UrbHeader.Function].RequestCode;
  824. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  825. if (USB_DEVICE_TO_HOST & setupPacket->RequestCode) {
  826. USBD_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  827. } else {
  828. USBD_SET_TRANSFER_DIRECTION_OUT( Urb->UrbControlTransfer.TransferFlags);
  829. }
  830. if (NT_SUCCESS(ntStatus)) {
  831. ((PHCD_URB) Urb)->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
  832. ((PHCD_URB) Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint =
  833. ((PUSBD_PIPE)((PHCD_URB)Urb)->HcdUrbCommonTransfer.UsbdPipeHandle)->HcdEndpoint;
  834. *IrpIsPending = TRUE;
  835. }
  836. USBD_SCT_GetStatus_Done:
  837. USBD_KdPrint(3, ("' exit USBD_SCT_GetStatus 0x%x\n", ntStatus));
  838. return ntStatus;
  839. }
  840. NTSTATUS
  841. USBD_SCT_VendorClassCommand(
  842. IN PDEVICE_OBJECT DeviceObject,
  843. IN PIRP Irp,
  844. IN PURB Urb,
  845. OUT PBOOLEAN IrpIsPending
  846. )
  847. /*++
  848. Routine Description:
  849. Arguments:
  850. DeviceObject -
  851. Irp - IO request block
  852. Urb - ptr to USB request block
  853. Return Value:
  854. --*/
  855. {
  856. NTSTATUS ntStatus = STATUS_SUCCESS;
  857. PUSB_STANDARD_SETUP_PACKET setupPacket;
  858. UCHAR direction;
  859. USBD_KdPrint(3, ("' enter USBD_SCT_VendorClassCommand\n"));
  860. setupPacket = (PUSB_STANDARD_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  861. // setup common fields
  862. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  863. direction = (UCHAR)( (Urb->UrbControlTransfer.TransferFlags &
  864. USBD_TRANSFER_DIRECTION_IN) ?
  865. USB_DEVICE_TO_HOST : USB_HOST_TO_DEVICE);
  866. USBD_KdPrint(3, ("' direction = 0x%x\n", direction));
  867. // allow only reserved bits to be set by caller
  868. setupPacket->RequestCode &= ~0x00e3;
  869. setupPacket->RequestCode |=
  870. (direction | UrbDispatchTable[Urb->UrbHeader.Function].RequestCode);
  871. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  872. if (USB_DEVICE_TO_HOST & setupPacket->RequestCode) {
  873. USBD_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  874. } else {
  875. USBD_SET_TRANSFER_DIRECTION_OUT( Urb->UrbControlTransfer.TransferFlags);
  876. }
  877. if (NT_SUCCESS(ntStatus)) {
  878. ((PHCD_URB) Urb)->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
  879. ((PHCD_URB) Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint =
  880. ((PUSBD_PIPE)((PHCD_URB)Urb)->HcdUrbCommonTransfer.UsbdPipeHandle)->HcdEndpoint;
  881. *IrpIsPending = TRUE;
  882. }
  883. USBD_KdPrint(3, ("' exit USBD_SCT_VendorClassCommand 0x%x\n", ntStatus));
  884. return ntStatus;
  885. }
  886. NTSTATUS
  887. USBD_AsyncTransfer(
  888. IN PDEVICE_OBJECT DeviceObject,
  889. IN PIRP Irp,
  890. IN PURB Urb,
  891. OUT PBOOLEAN IrpIsPending
  892. )
  893. /*++
  894. Routine Description:
  895. pass interrupt or bulk transfer to HCD
  896. Arguments:
  897. Irp - IO request block
  898. Urb - ptr to USB request block
  899. Return Value:
  900. --*/
  901. {
  902. NTSTATUS ntStatus = STATUS_SUCCESS;
  903. PUSBD_DEVICE_DATA deviceData;
  904. PUSBD_PIPE pipeHandle;
  905. USBD_KdPrint(3, ("' enter USBD_AsyncTransfer\n"));
  906. deviceData = Urb->UrbHeader.UsbdDeviceHandle;
  907. // pass the irp to HCD
  908. // extract the pipe handle
  909. pipeHandle = (PUSBD_PIPE)((PHCD_URB)Urb)->HcdUrbCommonTransfer.UsbdPipeHandle;
  910. ASSERT_PIPE(pipeHandle);
  911. ((PHCD_URB)Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint = pipeHandle->HcdEndpoint;
  912. // set the proper direction based on the direction bit stored with the
  913. // endpoint address. if this is a control transfer then leave the direction
  914. // bit alone.
  915. if ((USB_ENDPOINT_TYPE_MASK & pipeHandle->EndpointDescriptor.bmAttributes)
  916. != USB_ENDPOINT_TYPE_CONTROL) {
  917. if (pipeHandle->EndpointDescriptor.bEndpointAddress &
  918. USB_ENDPOINT_DIRECTION_MASK) {
  919. USBD_SET_TRANSFER_DIRECTION_IN(((PHCD_URB)Urb)->HcdUrbCommonTransfer.TransferFlags);
  920. } else {
  921. USBD_SET_TRANSFER_DIRECTION_OUT(((PHCD_URB)Urb)->HcdUrbCommonTransfer.TransferFlags);
  922. }
  923. }
  924. *IrpIsPending = TRUE;
  925. USBD_KdPrint(3, ("' exit USBD_AsyncTransfer 0x%x\n", ntStatus));
  926. return ntStatus;
  927. }
  928. NTSTATUS
  929. USBD_IsochTransfer(
  930. IN PDEVICE_OBJECT DeviceObject,
  931. IN PIRP Irp,
  932. IN PURB Urb,
  933. OUT PBOOLEAN IrpIsPending
  934. )
  935. /*++
  936. Routine Description:
  937. pass interrupt transfer to HCD
  938. Arguments:
  939. Irp - IO request block
  940. Urb - ptr to USB request block
  941. Return Value:
  942. --*/
  943. {
  944. NTSTATUS ntStatus = STATUS_SUCCESS;
  945. PUSBD_DEVICE_DATA deviceData;
  946. PUSBD_PIPE pipeHandle;
  947. ULONG transferFlags;
  948. struct _URB_ISOCH_TRANSFER *iso;
  949. USBD_KdPrint(3, ("' enter USBD_IsochTransfer\n"));
  950. deviceData = Urb->UrbHeader.UsbdDeviceHandle;
  951. // pass the irp to HCD
  952. // extract the pipe handle
  953. pipeHandle = (PUSBD_PIPE)Urb->UrbIsochronousTransfer.PipeHandle;
  954. transferFlags = Urb->UrbIsochronousTransfer.TransferFlags;
  955. iso = (struct _URB_ISOCH_TRANSFER *)Urb;
  956. ASSERT_PIPE(pipeHandle);
  957. //
  958. // limit iso transfers to 255 packets per URB
  959. //
  960. if (iso->NumberOfPackets == 0 ||
  961. iso->NumberOfPackets > 255)
  962. {
  963. ntStatus = STATUS_INVALID_PARAMETER;
  964. Urb->UrbHeader.Status =
  965. SET_USBD_ERROR(USBD_STATUS_INVALID_PARAMETER);
  966. *IrpIsPending = FALSE;
  967. goto USBD_IsochTransfer_Done;
  968. }
  969. ((PHCD_URB)Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint = pipeHandle->HcdEndpoint;
  970. // set the proper direction based on the direction bit stored with the
  971. // endpoint address.
  972. if (pipeHandle->EndpointDescriptor.bEndpointAddress &
  973. USB_ENDPOINT_DIRECTION_MASK) {
  974. USBD_SET_TRANSFER_DIRECTION_IN(((PHCD_URB)Urb)->HcdUrbCommonTransfer.TransferFlags);
  975. } else {
  976. USBD_SET_TRANSFER_DIRECTION_OUT(((PHCD_URB)Urb)->HcdUrbCommonTransfer.TransferFlags);
  977. }
  978. *IrpIsPending = TRUE;
  979. USBD_IsochTransfer_Done:
  980. USBD_KdPrint(3, ("' exit USBD_IsochTransfer 0x%x\n", ntStatus));
  981. return ntStatus;
  982. }
  983. NTSTATUS
  984. USBD_PassThru(
  985. IN PDEVICE_OBJECT DeviceObject,
  986. IN PIRP Irp,
  987. IN PURB Urb,
  988. OUT PBOOLEAN IrpIsPending
  989. )
  990. /*++
  991. Routine Description:
  992. pass urb thru unmodified
  993. Arguments:
  994. Irp - IO request block
  995. Urb - ptr to USB request block
  996. Return Value:
  997. --*/
  998. {
  999. NTSTATUS ntStatus = STATUS_SUCCESS;
  1000. USBD_KdPrint(3, ("' enter USBD_PassThru\n"));
  1001. //deviceData = Urb->UrbHeader.UsbdDeviceHandle;
  1002. *IrpIsPending = TRUE;
  1003. USBD_KdPrint(3, ("' exit USBD_PassThru 0x%x\n", ntStatus));
  1004. return ntStatus;
  1005. }
  1006. NTSTATUS
  1007. USBD_ResetPipe(
  1008. IN PDEVICE_OBJECT DeviceObject,
  1009. IN PIRP Irp,
  1010. IN PURB Urb,
  1011. OUT PBOOLEAN IrpIsPending
  1012. )
  1013. /*++
  1014. Routine Description:
  1015. Process abort pipe request from the client driver
  1016. Arguments:
  1017. Irp - IO request block
  1018. Urb - ptr to USB request block
  1019. Return Value:
  1020. --*/
  1021. {
  1022. NTSTATUS ntStatus = STATUS_SUCCESS;
  1023. PHCD_URB hcdUrb = (PHCD_URB)Urb;
  1024. PUSBD_PIPE pipeHandle;
  1025. // this function blocks so it must not be called at DPC level
  1026. PAGED_CODE();
  1027. USBD_KdPrint(3, ("' enter USBD_ResetPipe\n"));
  1028. pipeHandle = (PUSBD_PIPE) Urb->UrbPipeRequest.PipeHandle;
  1029. ASSERT_PIPE(pipeHandle);
  1030. //
  1031. // first clear the stall on the device if this is a
  1032. // bulk or interrupt pipe.
  1033. //
  1034. // The reason we do this is to ensure that the data toggle
  1035. // on both the host and the device is reset.
  1036. //
  1037. if (((USB_ENDPOINT_TYPE_MASK & pipeHandle->EndpointDescriptor.bmAttributes)
  1038. == USB_ENDPOINT_TYPE_BULK) ||
  1039. ((USB_ENDPOINT_TYPE_MASK & pipeHandle->EndpointDescriptor.bmAttributes)
  1040. == USB_ENDPOINT_TYPE_INTERRUPT)) {
  1041. ntStatus = USBD_SendCommand(Urb->UrbHeader.UsbdDeviceHandle,
  1042. DeviceObject,
  1043. STANDARD_COMMAND_CLEAR_FEATURE_ENDPOINT,
  1044. USB_FEATURE_ENDPOINT_STALL,
  1045. pipeHandle->EndpointDescriptor.bEndpointAddress,
  1046. 0,
  1047. NULL,
  1048. 0,
  1049. NULL,
  1050. NULL);
  1051. }
  1052. if (NT_SUCCESS(ntStatus)) {
  1053. //
  1054. // Change the Urb command to set endpoint state
  1055. // note: we rely on these two structures being
  1056. // identical so that we can reuse the URB
  1057. //
  1058. ASSERT(sizeof(struct _URB_HCD_ENDPOINT_STATE) ==
  1059. sizeof(struct _URB_PIPE_REQUEST));
  1060. ASSERT_PIPE((PUSBD_PIPE) Urb->UrbPipeRequest.PipeHandle);
  1061. hcdUrb->HcdUrbEndpointState.Function = URB_FUNCTION_HCD_SET_ENDPOINT_STATE;
  1062. hcdUrb->HcdUrbEndpointState.HcdEndpoint =
  1063. ((PUSBD_PIPE) (Urb->UrbPipeRequest.PipeHandle))->HcdEndpoint;
  1064. // request to clear halt and reset toggle
  1065. hcdUrb->HcdUrbEndpointState.HcdEndpointState = HCD_ENDPOINT_RESET_DATA_TOGGLE;
  1066. *IrpIsPending = TRUE;
  1067. }
  1068. USBD_KdPrint(3, ("' exit USBD_ResetPipe 0x%x\n", ntStatus));
  1069. return ntStatus;
  1070. }
  1071. NTSTATUS
  1072. USBD_AbortPipe(
  1073. IN PDEVICE_OBJECT DeviceObject,
  1074. IN PIRP Irp,
  1075. IN PURB Urb,
  1076. OUT PBOOLEAN IrpIsPending
  1077. )
  1078. /*++
  1079. Routine Description:
  1080. Process abort pipe request from the client driver
  1081. Arguments:
  1082. Irp - IO request block
  1083. Urb - ptr to USB request block
  1084. Return Value:
  1085. --*/
  1086. {
  1087. NTSTATUS ntStatus = STATUS_SUCCESS;
  1088. PHCD_URB hcdUrb = (PHCD_URB)Urb;
  1089. USBD_KdPrint(3, ("' enter USBD_AbortPipe\n"));
  1090. //
  1091. // Change the Urb command to abort endpoint
  1092. //
  1093. ASSERT_PIPE((PUSBD_PIPE) Urb->UrbPipeRequest.PipeHandle);
  1094. hcdUrb->HcdUrbAbortEndpoint.Function = URB_FUNCTION_HCD_ABORT_ENDPOINT;
  1095. hcdUrb->HcdUrbAbortEndpoint.HcdEndpoint =
  1096. ((PUSBD_PIPE) (Urb->UrbPipeRequest.PipeHandle))->HcdEndpoint;
  1097. *IrpIsPending = TRUE;
  1098. USBD_KdPrint(3, ("' exit USBD_AbortPipe 0x%x\n", ntStatus));
  1099. return ntStatus;
  1100. }
  1101. NTSTATUS
  1102. USBD_SCT_GetInterface(
  1103. IN PDEVICE_OBJECT DeviceObject,
  1104. IN PIRP Irp,
  1105. IN PURB Urb,
  1106. OUT PBOOLEAN IrpIsPending
  1107. )
  1108. /*++
  1109. Routine Description:
  1110. Arguments:
  1111. DeviceObject -
  1112. Irp - IO request block
  1113. Urb - ptr to USB request block
  1114. Return Value:
  1115. --*/
  1116. {
  1117. NTSTATUS ntStatus = STATUS_SUCCESS;
  1118. PUSB_STANDARD_SETUP_PACKET setupPacket;
  1119. USBD_KdPrint(3, ("' enter USBD_SCT_GetStatus\n"));
  1120. setupPacket = (PUSB_STANDARD_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  1121. // setup common fields
  1122. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  1123. if (setupPacket->wLength != 1) {
  1124. ntStatus = STATUS_INVALID_PARAMETER;
  1125. goto USBD_SCT_GetInterface_Done;
  1126. }
  1127. setupPacket->wValue = 0;
  1128. setupPacket->wIndex = Urb->UrbControlGetInterfaceRequest.Interface;
  1129. setupPacket->RequestCode =
  1130. UrbDispatchTable[Urb->UrbHeader.Function].RequestCode;
  1131. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  1132. if (USB_DEVICE_TO_HOST & setupPacket->RequestCode) {
  1133. USBD_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  1134. } else {
  1135. USBD_SET_TRANSFER_DIRECTION_OUT( Urb->UrbControlTransfer.TransferFlags);
  1136. }
  1137. if (NT_SUCCESS(ntStatus)) {
  1138. ((PHCD_URB) Urb)->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
  1139. ((PHCD_URB) Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint =
  1140. ((PUSBD_PIPE)((PHCD_URB)Urb)->HcdUrbCommonTransfer.UsbdPipeHandle)->HcdEndpoint;
  1141. *IrpIsPending = TRUE;
  1142. }
  1143. USBD_SCT_GetInterface_Done:
  1144. USBD_KdPrint(3, ("' exit USBD_SCT_GetInterface 0x%x\n", ntStatus));
  1145. return ntStatus;
  1146. }
  1147. NTSTATUS
  1148. USBD_SCT_GetConfiguration(
  1149. IN PDEVICE_OBJECT DeviceObject,
  1150. IN PIRP Irp,
  1151. IN PURB Urb,
  1152. OUT PBOOLEAN IrpIsPending
  1153. )
  1154. /*++
  1155. Routine Description:
  1156. Arguments:
  1157. DeviceObject -
  1158. Irp - IO request block
  1159. Urb - ptr to USB request block
  1160. Return Value:
  1161. --*/
  1162. {
  1163. NTSTATUS ntStatus = STATUS_SUCCESS;
  1164. PUSB_STANDARD_SETUP_PACKET setupPacket;
  1165. USBD_KdPrint(3, ("' enter USBD_SCT_GetStatus\n"));
  1166. setupPacket = (PUSB_STANDARD_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  1167. // setup common fields
  1168. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  1169. USBD_ASSERT(setupPacket->wLength == 1);
  1170. setupPacket->wValue = 0;
  1171. setupPacket->wIndex = 0;
  1172. setupPacket->RequestCode =
  1173. UrbDispatchTable[Urb->UrbHeader.Function].RequestCode;
  1174. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  1175. if (USB_DEVICE_TO_HOST & setupPacket->RequestCode) {
  1176. USBD_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  1177. } else {
  1178. USBD_SET_TRANSFER_DIRECTION_OUT( Urb->UrbControlTransfer.TransferFlags);
  1179. }
  1180. if (NT_SUCCESS(ntStatus)) {
  1181. ((PHCD_URB) Urb)->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
  1182. ((PHCD_URB) Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint =
  1183. ((PUSBD_PIPE)((PHCD_URB)Urb)->HcdUrbCommonTransfer.UsbdPipeHandle)->HcdEndpoint;
  1184. *IrpIsPending = TRUE;
  1185. }
  1186. USBD_KdPrint(3, ("' exit USBD_SCT_GetConfiguration 0x%x\n", ntStatus));
  1187. return ntStatus;
  1188. }
  1189. NTSTATUS
  1190. USBD_TakeFrameLengthControl(
  1191. IN PDEVICE_OBJECT DeviceObject,
  1192. IN PIRP Irp,
  1193. IN PURB Urb,
  1194. OUT PBOOLEAN IrpIsPending
  1195. )
  1196. /*++
  1197. Routine Description:
  1198. Process abort pipe request from the client driver
  1199. Arguments:
  1200. Irp - IO request block
  1201. Urb - ptr to USB request block
  1202. Return Value:
  1203. --*/
  1204. {
  1205. NTSTATUS ntStatus = STATUS_SUCCESS;
  1206. PUSBD_DEVICE_DATA deviceData;
  1207. PUSBD_EXTENSION deviceExtension;
  1208. PAGED_CODE();
  1209. USBD_KdPrint(3, ("' enter USBD_TakeFrameLengthControl\n"));
  1210. deviceExtension = GET_DEVICE_EXTENSION(DeviceObject);
  1211. deviceData = Urb->UrbHeader.UsbdDeviceHandle;
  1212. *IrpIsPending = FALSE;
  1213. if (deviceExtension->FrameLengthControlOwner != NULL) {
  1214. Urb->UrbHeader.Status =
  1215. SET_USBD_ERROR(USBD_STATUS_FRAME_CONTROL_OWNED);
  1216. } else {
  1217. Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
  1218. deviceExtension->FrameLengthControlOwner =
  1219. deviceData;
  1220. }
  1221. USBD_KdPrint(3, ("' exit USBD_TakeFrameLengthControl 0x%x\n", ntStatus));
  1222. return ntStatus;
  1223. }
  1224. NTSTATUS
  1225. USBD_ReleaseFrameLengthControl(
  1226. IN PDEVICE_OBJECT DeviceObject,
  1227. IN PIRP Irp,
  1228. IN PURB Urb,
  1229. OUT PBOOLEAN IrpIsPending
  1230. )
  1231. /*++
  1232. Routine Description:
  1233. Process abort pipe request from the client driver
  1234. Arguments:
  1235. Irp - IO request block
  1236. Urb - ptr to USB request block
  1237. Return Value:
  1238. --*/
  1239. {
  1240. NTSTATUS ntStatus = STATUS_SUCCESS;
  1241. PUSBD_DEVICE_DATA deviceData;
  1242. PUSBD_EXTENSION deviceExtension;
  1243. USBD_KdPrint(3, ("' enter USBD_ReleaseFrameLengthControl\n"));
  1244. deviceExtension = GET_DEVICE_EXTENSION(DeviceObject);
  1245. deviceData = Urb->UrbHeader.UsbdDeviceHandle;
  1246. *IrpIsPending = FALSE;
  1247. if (deviceExtension->FrameLengthControlOwner == NULL ||
  1248. deviceExtension->FrameLengthControlOwner != deviceData) {
  1249. Urb->UrbHeader.Status =
  1250. SET_USBD_ERROR(USBD_STATUS_FRAME_CONTROL_NOT_OWNED);
  1251. } else {
  1252. Urb->UrbHeader.Status = STATUS_SUCCESS;
  1253. deviceExtension->FrameLengthControlOwner = NULL;
  1254. }
  1255. USBD_KdPrint(3, ("' exit USBD_ReleaseFrameLengthControl 0x%x\n", ntStatus));
  1256. return ntStatus;
  1257. }
  1258. NTSTATUS
  1259. USBD_GetFrameLength(
  1260. IN PDEVICE_OBJECT DeviceObject,
  1261. IN PIRP Irp,
  1262. IN PURB Urb,
  1263. OUT PBOOLEAN IrpIsPending
  1264. )
  1265. /*++
  1266. Routine Description:
  1267. Process abort pipe request from the client driver
  1268. Arguments:
  1269. Irp - IO request block
  1270. Urb - ptr to USB request block
  1271. Return Value:
  1272. --*/
  1273. {
  1274. NTSTATUS ntStatus = STATUS_SUCCESS;
  1275. PUSBD_DEVICE_DATA deviceData;
  1276. PUSBD_EXTENSION deviceExtension;
  1277. PAGED_CODE();
  1278. USBD_KdPrint(3, ("' enter USBD_GetFrameLength\n"));
  1279. deviceExtension = GET_DEVICE_EXTENSION(DeviceObject);
  1280. deviceData = Urb->UrbHeader.UsbdDeviceHandle;
  1281. if (NT_SUCCESS(ntStatus)) {
  1282. // pass on to HC
  1283. *IrpIsPending = TRUE;
  1284. }
  1285. USBD_KdPrint(3, ("' exit USBD_GetFrameLength 0x%x\n", ntStatus));
  1286. return ntStatus;
  1287. }
  1288. NTSTATUS
  1289. USBD_SetFrameLength(
  1290. IN PDEVICE_OBJECT DeviceObject,
  1291. IN PIRP Irp,
  1292. IN PURB Urb,
  1293. OUT PBOOLEAN IrpIsPending
  1294. )
  1295. /*++
  1296. Routine Description:
  1297. Process abort pipe request from the client driver
  1298. Arguments:
  1299. Irp - IO request block
  1300. Urb - ptr to USB request block
  1301. Return Value:
  1302. --*/
  1303. {
  1304. NTSTATUS ntStatus = STATUS_SUCCESS;
  1305. PUSBD_DEVICE_DATA deviceData;
  1306. PUSBD_EXTENSION deviceExtension;
  1307. PAGED_CODE();
  1308. USBD_KdPrint(3, ("' enter USBD_SetFrameLength\n"));
  1309. deviceExtension = GET_DEVICE_EXTENSION(DeviceObject);
  1310. deviceData = Urb->UrbHeader.UsbdDeviceHandle;
  1311. if (deviceExtension->FrameLengthControlOwner != deviceData) {
  1312. Urb->UrbHeader.Status =
  1313. SET_USBD_ERROR(USBD_STATUS_FRAME_CONTROL_NOT_OWNED);
  1314. ntStatus = STATUS_INVALID_PARAMETER;
  1315. }
  1316. if (Urb->UrbSetFrameLength.FrameLengthDelta < -1 ||
  1317. Urb->UrbSetFrameLength.FrameLengthDelta > 1) {
  1318. SET_USBD_ERROR(USBD_STATUS_INVALID_PARAMETER);
  1319. ntStatus = STATUS_INVALID_PARAMETER;
  1320. }
  1321. if (NT_SUCCESS(ntStatus)) {
  1322. // pass on to HC
  1323. *IrpIsPending = TRUE;
  1324. }
  1325. USBD_KdPrint(3, ("' exit USBD_SetFrameLength 0x%x\n", ntStatus));
  1326. return ntStatus;
  1327. }
  1328. #endif // USBD_DRIVER