Leaked source code of windows server 2003
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.

2515 lines
74 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. urb.c
  5. Abstract:
  6. main urb "handler"
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. 6-20-99 : created
  12. --*/
  13. #include "common.h"
  14. // paged functions
  15. #ifdef ALLOC_PRAGMA
  16. #endif
  17. // non paged functions
  18. //USBPORT_ProcessURB
  19. //USBPORT_SelectConfiguration;
  20. //USBPORT_SelectInterface;
  21. //USBPORT_AsyncTransfer;
  22. //USBPORT_IsochTransfer;
  23. //USBPORT_AbortPipe;
  24. //USBPORT_ResetPipe;
  25. //USBPORT_SCT_GetSetDescriptor;
  26. //USBPORT_SCT_SetClearFeature;
  27. //USBPORT_SCT_GetStatus;
  28. //USBPORT_SCT_VendorClassCommand;
  29. //USBPORT_SCT_GetInterface;
  30. //USBPORT_SCT_GetConfiguration;
  31. //USBPORT_TakeFrameLengthControl;
  32. //USBPORT_ReleaseFrameLengthControl;
  33. //USBPORT_GetFrameLength;
  34. //USBPORT_SetFrameLength;
  35. //USBPORT_BulkTransfer;
  36. //USBPORT_GetCurrentFrame;
  37. //USBPORT_InvalidFunction
  38. //USBPORT_GetMSFeartureDescriptor
  39. //USBPORT_SyncClearStall
  40. //USBPORT_GetMSFeartureDescriptor
  41. /*
  42. ** URB handler routines
  43. Handler --
  44. This function handles the specific USBDI request, if the request is queued
  45. by the handler the STATUS_PENDING is returned
  46. */
  47. typedef NTSTATUS URB_HANDLER(PDEVICE_OBJECT FdoDeviceObject, PIRP Irp, PURB Urb);
  48. typedef struct _URB_DISPATCH_ENTRY {
  49. // USB API handler
  50. URB_HANDLER *UrbHandler;
  51. // length of the URB expected for this request
  52. USHORT UrbRequestLength;
  53. USHORT Pad2;
  54. // request code for setup packet if standard command
  55. UCHAR Direction;
  56. UCHAR Type;
  57. UCHAR Recipient;
  58. UCHAR bRequest;
  59. // tell the generic urb dispatch routine what to do
  60. ULONG Flags;
  61. #if DBG
  62. ULONG ExpectedFunctionCode;
  63. #endif
  64. } URB_DISPATCH_ENTRY;
  65. URB_HANDLER USBPORT_SelectConfiguration;
  66. URB_HANDLER USBPORT_SelectInterface;
  67. URB_HANDLER USBPORT_AsyncTransfer;
  68. URB_HANDLER USBPORT_IsochTransfer;
  69. URB_HANDLER USBPORT_AbortPipe;
  70. URB_HANDLER USBPORT_SyncResetPipeAndClearStall;
  71. URB_HANDLER USBPORT_SyncResetPipe;
  72. URB_HANDLER USBPORT_SyncClearStall;
  73. URB_HANDLER USBPORT_SCT_GetSetDescriptor;
  74. URB_HANDLER USBPORT_SCT_SetClearFeature;
  75. URB_HANDLER USBPORT_SCT_GetStatus;
  76. URB_HANDLER USBPORT_SCT_VendorClassCommand;
  77. URB_HANDLER USBPORT_SCT_GetInterface;
  78. URB_HANDLER USBPORT_SCT_GetConfiguration;
  79. URB_HANDLER USBPORT_TakeFrameLengthControl;
  80. URB_HANDLER USBPORT_ReleaseFrameLengthControl;
  81. URB_HANDLER USBPORT_GetFrameLength;
  82. URB_HANDLER USBPORT_SetFrameLength;
  83. URB_HANDLER USBPORT_BulkTransfer;
  84. URB_HANDLER USBPORT_GetCurrentFrame;
  85. URB_HANDLER USBPORT_InvalidFunction;
  86. URB_HANDLER USBPORT_GetMSFeartureDescriptor;
  87. // last supported function
  88. #define URB_FUNCTION_LAST URB_FUNCTION_SYNC_CLEAR_STALL
  89. // last valid function
  90. URB_DISPATCH_ENTRY UrbDispatchTable[URB_FUNCTION_LAST+1] =
  91. {
  92. //URB_FUNCTION_SELECT_CONFIGURATION
  93. USBPORT_SelectConfiguration,
  94. 0, // Length, handler will validate length
  95. 0, // Pad2
  96. 0, // bmRequestType.Dir
  97. 0, // bmRequestType.Type
  98. 0, // bmRequestType.Recipient
  99. 0, // bRequest
  100. 0, // Flags
  101. #if DBG
  102. URB_FUNCTION_SELECT_CONFIGURATION,
  103. #endif
  104. //URB_FUNCTION_SELECT_INTERFACE
  105. USBPORT_SelectInterface, // Function
  106. 0, // Length
  107. 0, // Pad2
  108. 0, // bmRequestType.Dir
  109. 0, // bmRequestType.Type
  110. 0, // bmRequestType.Recipient
  111. 0, // bRequest
  112. 0, // Flags
  113. #if DBG
  114. URB_FUNCTION_SELECT_INTERFACE,
  115. #endif
  116. //URB_FUNCTION_ABORT_PIPE
  117. USBPORT_AbortPipe, // Function
  118. sizeof(struct _URB_PIPE_REQUEST), // Length
  119. 0, // Pad2
  120. 0, // bmRequestType.Dir
  121. 0, // bmRequestType.Type
  122. 0, // bmRequestType.Recipient
  123. 0, // bRequest
  124. 0, // Flags
  125. #if DBG
  126. URB_FUNCTION_ABORT_PIPE,
  127. #endif
  128. //URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL
  129. USBPORT_TakeFrameLengthControl, // Function
  130. sizeof(struct _URB_FRAME_LENGTH_CONTROL), // Length
  131. 0, // Pad2
  132. 0, // bmRequestType.Dir
  133. 0, // bmRequestType.Type
  134. 0, // bmRequestType.Recipient
  135. 0, // bRequest
  136. 0, // Flags
  137. #if DBG
  138. URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL,
  139. #endif
  140. //URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL
  141. USBPORT_ReleaseFrameLengthControl, // Function
  142. sizeof(struct _URB_FRAME_LENGTH_CONTROL), // Length
  143. 0, // Pad2
  144. 0, // bmRequestType.Dir
  145. 0, // bmRequestType.Type
  146. 0, // bmRequestType.Recipient
  147. 0, // bRequest
  148. 0, // Flags
  149. #if DBG
  150. URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL,
  151. #endif
  152. //URB_FUNCTION_GET_FRAME_LENGTH
  153. USBPORT_GetFrameLength, // Function
  154. sizeof(struct _URB_GET_FRAME_LENGTH), // Length
  155. 0, // Pad2
  156. 0, // bmRequestType.Dir
  157. 0, // bmRequestType.Type
  158. 0, // bmRequestType.Recipient
  159. 0, // bRequest
  160. 0, // Flags
  161. #if DBG
  162. URB_FUNCTION_GET_FRAME_LENGTH,
  163. #endif
  164. //URB_FUNCTION_SET_FRAME_LENGTH
  165. USBPORT_SetFrameLength, // Function
  166. sizeof(struct _URB_SET_FRAME_LENGTH), // Length
  167. 0, // Pad2
  168. 0, // bmRequestType.Dir
  169. 0, // bmRequestType.Type
  170. 0, // bmRequestType.Recipient
  171. 0, // bRequest
  172. 0, // Flags
  173. #if DBG
  174. URB_FUNCTION_SET_FRAME_LENGTH,
  175. #endif
  176. //URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
  177. USBPORT_GetCurrentFrame, // Function
  178. 0, // Length
  179. 0, // Pad2
  180. 0, // bmRequestType.Dir
  181. 0, // bmRequestType.Type
  182. 0, // bmRequestType.Recipient
  183. 0, // bRequest
  184. 0, // Flags
  185. #if DBG
  186. URB_FUNCTION_GET_CURRENT_FRAME_NUMBER,
  187. #endif
  188. //URB_FUNCTION_CONTROL_TRANSFER
  189. USBPORT_AsyncTransfer, // Function
  190. sizeof(struct _URB_CONTROL_TRANSFER), // Length
  191. 0, // Pad2
  192. 0, // bmRequestType.Dir
  193. 0, // bmRequestType.Type
  194. 0, // bmRequestType.Recipient
  195. 0, // bRequest
  196. USBPORT_REQUEST_IS_TRANSFER, // Flags
  197. #if DBG
  198. URB_FUNCTION_CONTROL_TRANSFER,
  199. #endif
  200. //URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
  201. USBPORT_AsyncTransfer, // Function
  202. sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), // Length
  203. 0, // Pad2
  204. 0, // bmRequestType.Dir
  205. 0, // bmRequestType.Type
  206. 0, // bmRequestType.Recipient
  207. 0, // bRequest
  208. USBPORT_REQUEST_IS_TRANSFER, // Flags
  209. #if DBG
  210. URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER,
  211. #endif
  212. //URB_FUNCTION_ISOCH_TRANSFER
  213. USBPORT_IsochTransfer, // Function
  214. 0, // Length
  215. 0, // Pad2
  216. 0, // bmRequestType.Dir
  217. 0, // bmRequestType.Type
  218. 0, // bmRequestType.Recipient
  219. 0, // bRequest
  220. USBPORT_REQUEST_IS_TRANSFER, // Flags
  221. #if DBG
  222. URB_FUNCTION_ISOCH_TRANSFER,
  223. #endif
  224. //URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
  225. USBPORT_SCT_GetSetDescriptor, // Function
  226. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), // Length
  227. 0, // Pad2
  228. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  229. BMREQUEST_STANDARD, // bmRequestType.Type
  230. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  231. USB_REQUEST_GET_DESCRIPTOR, // bRequest
  232. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  233. #if DBG
  234. URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE,
  235. #endif
  236. //URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE
  237. USBPORT_SCT_GetSetDescriptor, // Function
  238. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), // Length
  239. 0, // Pad2
  240. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  241. BMREQUEST_STANDARD, // bmRequestType.Type
  242. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  243. USB_REQUEST_SET_DESCRIPTOR, // bRequest
  244. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  245. #if DBG
  246. URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE,
  247. #endif
  248. //URB_FUNCTION_SET_FEATURE_TO_DEVICE
  249. USBPORT_SCT_SetClearFeature, // Function
  250. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  251. 0, // Pad2
  252. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  253. BMREQUEST_STANDARD, // bmRequestType.Type
  254. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  255. USB_REQUEST_SET_FEATURE, // bRequest
  256. USBPORT_REQUEST_IS_TRANSFER | \
  257. USBPORT_REQUEST_USES_DEFAULT_PIPE | \
  258. USBPORT_REQUEST_NO_DATA_PHASE, // Flags
  259. #if DBG
  260. URB_FUNCTION_SET_FEATURE_TO_DEVICE,
  261. #endif
  262. //URB_FUNCTION_SET_FEATURE_TO_INTERFACE
  263. USBPORT_SCT_SetClearFeature, // Function
  264. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  265. 0, // Pad2
  266. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  267. BMREQUEST_STANDARD, // bmRequestType.Type
  268. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  269. USB_REQUEST_SET_FEATURE, // bRequest
  270. USBPORT_REQUEST_IS_TRANSFER | \
  271. USBPORT_REQUEST_USES_DEFAULT_PIPE | \
  272. USBPORT_REQUEST_NO_DATA_PHASE, // Flags
  273. #if DBG
  274. URB_FUNCTION_SET_FEATURE_TO_INTERFACE,
  275. #endif
  276. //URB_FUNCTION_SET_FEATURE_TO_ENDPOINT
  277. USBPORT_SCT_SetClearFeature, // Function
  278. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  279. 0, // Pad2
  280. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  281. BMREQUEST_STANDARD, // bmRequestType.Type
  282. BMREQUEST_TO_ENDPOINT, // bmRequestType.Recipient
  283. USB_REQUEST_SET_FEATURE, // bRequest
  284. USBPORT_REQUEST_IS_TRANSFER | \
  285. USBPORT_REQUEST_USES_DEFAULT_PIPE | \
  286. USBPORT_REQUEST_NO_DATA_PHASE, // Length
  287. #if DBG
  288. URB_FUNCTION_SET_FEATURE_TO_ENDPOINT,
  289. #endif
  290. //URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE
  291. USBPORT_SCT_SetClearFeature, // Function
  292. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  293. 0, // Pad2
  294. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  295. BMREQUEST_STANDARD, // bmRequestType.Type
  296. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  297. USB_REQUEST_CLEAR_FEATURE, // bRequest
  298. USBPORT_REQUEST_IS_TRANSFER | \
  299. USBPORT_REQUEST_USES_DEFAULT_PIPE | \
  300. USBPORT_REQUEST_NO_DATA_PHASE, // Flags
  301. #if DBG
  302. URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE,
  303. #endif
  304. //URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE
  305. USBPORT_SCT_SetClearFeature, // Function
  306. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  307. 0, // Pad2
  308. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  309. BMREQUEST_STANDARD, // bmRequestType.Type
  310. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  311. USB_REQUEST_CLEAR_FEATURE, // bRequest
  312. USBPORT_REQUEST_IS_TRANSFER | \
  313. USBPORT_REQUEST_USES_DEFAULT_PIPE | \
  314. USBPORT_REQUEST_NO_DATA_PHASE, // Flags
  315. #if DBG
  316. URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE,
  317. #endif
  318. //URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT
  319. USBPORT_SCT_SetClearFeature, // Function
  320. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  321. 0, // Pad2
  322. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  323. BMREQUEST_STANDARD, // bmRequestType.Type
  324. BMREQUEST_TO_ENDPOINT, // bmRequestType.Recipient
  325. USB_REQUEST_CLEAR_FEATURE, // bRequest
  326. USBPORT_REQUEST_IS_TRANSFER | \
  327. USBPORT_REQUEST_USES_DEFAULT_PIPE | \
  328. USBPORT_REQUEST_NO_DATA_PHASE, // Flags
  329. #if DBG
  330. URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,
  331. #endif
  332. //URB_FUNCTION_GET_STATUS_FROM_DEVICE
  333. USBPORT_SCT_GetStatus, // Function
  334. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST), // Length
  335. 0, // Pad2
  336. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  337. BMREQUEST_STANDARD, // bmRequestType.Type
  338. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  339. USB_REQUEST_GET_STATUS, // bRequest
  340. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  341. #if DBG
  342. URB_FUNCTION_GET_STATUS_FROM_DEVICE,
  343. #endif
  344. //URB_FUNCTION_GET_STATUS_FROM_INTERFACE
  345. USBPORT_SCT_GetStatus, // Function
  346. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST), // Length
  347. 0, // Pad2
  348. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  349. BMREQUEST_STANDARD, // bmRequestType.Type
  350. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  351. USB_REQUEST_GET_STATUS, // bRequest
  352. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  353. #if DBG
  354. URB_FUNCTION_GET_STATUS_FROM_INTERFACE,
  355. #endif
  356. //URB_FUNCTION_GET_STATUS_FROM_ENDPOINT
  357. USBPORT_SCT_GetStatus, // Function
  358. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST), // Length
  359. 0, // Pad2
  360. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  361. BMREQUEST_STANDARD, // bmRequestType.Type
  362. BMREQUEST_TO_ENDPOINT, // bmRequestType.Recipient
  363. USB_REQUEST_GET_STATUS, // bRequest
  364. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  365. #if DBG
  366. URB_FUNCTION_GET_STATUS_FROM_ENDPOINT,
  367. #endif
  368. //URB_FUNCTION_SYNC_FRAME
  369. NULL, // Function
  370. 0, // Length
  371. 0, // Pad2
  372. 0, // bmRequestType.Dir
  373. 0, // bmRequestType.Type
  374. 0, // bmRequestType.Recipient
  375. 0, // bRequest
  376. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  377. #if DBG
  378. 0, //URB_FUNCTION_SYNC_FRAME,
  379. #endif
  380. //URB_FUNCTION_VENDOR_DEVICE
  381. USBPORT_SCT_VendorClassCommand, // Function
  382. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  383. 0, // Pad2
  384. 0, // bmRequestType.Dir, user defined
  385. BMREQUEST_VENDOR, // bmRequestType.Type
  386. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  387. 0, // bRequest, user defined
  388. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  389. #if DBG
  390. URB_FUNCTION_VENDOR_DEVICE,
  391. #endif
  392. //URB_FUNCTION_VENDOR_INTERFACE
  393. USBPORT_SCT_VendorClassCommand, // Function
  394. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  395. 0, // Pad2
  396. 0, // bmRequestType.Dir, user defined
  397. BMREQUEST_VENDOR, // bmRequestType.Type
  398. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  399. 0, // bRequest, user defined
  400. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Length
  401. #if DBG
  402. URB_FUNCTION_VENDOR_INTERFACE,
  403. #endif
  404. //URB_FUNCTION_VENDOR_ENDPOINT
  405. USBPORT_SCT_VendorClassCommand, // Function
  406. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  407. 0, // Pad2
  408. 0, // bmRequestType.Dir, user defined
  409. BMREQUEST_VENDOR, // bmRequestType.Type
  410. BMREQUEST_TO_ENDPOINT, // bmRequestType.Recipient
  411. 0, // bRequest, user defined
  412. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  413. #if DBG
  414. URB_FUNCTION_VENDOR_ENDPOINT,
  415. #endif
  416. //URB_FUNCTION_CLASS_DEVICE
  417. USBPORT_SCT_VendorClassCommand, // Function
  418. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  419. 0, // Pad2
  420. 0, // bmRequestType.Dir, user defined
  421. BMREQUEST_CLASS, // bmRequestType.Type
  422. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  423. 0, // bRequest, user defined
  424. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  425. #if DBG
  426. URB_FUNCTION_CLASS_DEVICE,
  427. #endif
  428. //URB_FUNCTION_CLASS_INTERFACE
  429. USBPORT_SCT_VendorClassCommand, // Function
  430. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  431. 0, // Pad2
  432. 0, // bmRequestType.Dir, user defined
  433. BMREQUEST_CLASS, // bmRequestType.Type
  434. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  435. 0, // bRequest, user defined
  436. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  437. #if DBG
  438. URB_FUNCTION_CLASS_INTERFACE,
  439. #endif
  440. //URB_FUNCTION_CLASS_ENDPOINT
  441. USBPORT_SCT_VendorClassCommand, // Function
  442. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  443. 0, // Pad2
  444. 0, // bmRequestType.Dir, user defined
  445. BMREQUEST_CLASS, // bmRequestType.Type
  446. BMREQUEST_TO_ENDPOINT, // bmRequestType.Recipient
  447. 0, // bRequest, user defined
  448. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  449. #if DBG
  450. URB_FUNCTION_CLASS_ENDPOINT,
  451. #endif
  452. //URB_FUNCTION_ NOT USED
  453. NULL, // Function
  454. 0, // Length
  455. 0, // Pad2
  456. 0, // bmRequestType.Dir
  457. 0, // bmRequestType.Type
  458. 0, // bmRequestType.Recipient
  459. 0, // bRequest
  460. 0, // Flags
  461. #if DBG
  462. URB_FUNCTION_RESERVE_0X001D,
  463. #endif
  464. //URB_FUNCTION_RESET_PIPE
  465. USBPORT_SyncResetPipeAndClearStall, // Function
  466. sizeof(struct _URB_PIPE_REQUEST), // Length
  467. 0, // Pad2
  468. 0, // bmRequestType.Dir
  469. 0, // bmRequestType.Type
  470. 0, // bmRequestType.Recipient
  471. 0, // bRequest
  472. 0, // Flags
  473. #if DBG
  474. URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL,
  475. #endif
  476. //URB_FUNCTION_CLASS_OTHER
  477. USBPORT_SCT_VendorClassCommand, // Function
  478. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  479. 0, // Pad2
  480. 0, // bmRequestType.Dir, user defined
  481. BMREQUEST_CLASS, // bmRequestType.Type
  482. BMREQUEST_TO_OTHER, // bmRequestType.Recipient
  483. 0, // bRequest, user defined
  484. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Length
  485. #if DBG
  486. URB_FUNCTION_CLASS_OTHER,
  487. #endif
  488. //URB_FUNCTION_VENDOR_OTHER
  489. USBPORT_SCT_VendorClassCommand, // Function
  490. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), // Length
  491. 0, // Pad2
  492. 0, // bmRequestType.Dir, user defined
  493. BMREQUEST_VENDOR, // bmRequestType.Type
  494. BMREQUEST_TO_OTHER, // bmRequestType.Recipient
  495. 0, // bRequest, user defined
  496. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  497. #if DBG
  498. URB_FUNCTION_VENDOR_OTHER,
  499. #endif
  500. //URB_FUNCTION_GET_STATUS_FROM_OTHER
  501. USBPORT_SCT_GetStatus, // Function
  502. sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST), // Length
  503. 0, // Pad2
  504. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  505. BMREQUEST_STANDARD, // bmRequestType.Type
  506. BMREQUEST_TO_OTHER, // bmRequestType.Recipient
  507. USB_REQUEST_GET_STATUS, // bRequest
  508. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  509. #if DBG
  510. URB_FUNCTION_GET_STATUS_FROM_OTHER,
  511. #endif
  512. //URB_FUNCTION_CLEAR_FEATURE_TO_OTHER
  513. USBPORT_SCT_SetClearFeature, // Function
  514. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  515. 0, // Pad2
  516. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  517. BMREQUEST_STANDARD, // bmRequestType.Type
  518. BMREQUEST_TO_OTHER, // bmRequestType.Recipient
  519. USB_REQUEST_CLEAR_FEATURE, // bRequest
  520. USBPORT_REQUEST_IS_TRANSFER |
  521. USBPORT_REQUEST_USES_DEFAULT_PIPE |
  522. USBPORT_REQUEST_NO_DATA_PHASE,
  523. #if DBG
  524. URB_FUNCTION_CLEAR_FEATURE_TO_OTHER,
  525. #endif
  526. //URB_FUNCTION_SET_FEATURE_TO_OTHER
  527. USBPORT_SCT_SetClearFeature, // Function
  528. sizeof(struct _URB_CONTROL_FEATURE_REQUEST), // Length
  529. 0, // Pad2
  530. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  531. BMREQUEST_STANDARD, // bmRequestType.Type
  532. BMREQUEST_TO_OTHER, // bmRequestType.Recipient
  533. USB_REQUEST_SET_FEATURE, // bRequest
  534. USBPORT_REQUEST_IS_TRANSFER |
  535. USBPORT_REQUEST_USES_DEFAULT_PIPE |
  536. USBPORT_REQUEST_NO_DATA_PHASE, // Flags
  537. #if DBG
  538. URB_FUNCTION_SET_FEATURE_TO_INTERFACE,
  539. #endif
  540. //URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT
  541. USBPORT_SCT_GetSetDescriptor, // Function
  542. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), // Length
  543. 0, // Pad2
  544. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  545. BMREQUEST_STANDARD, // bmRequestType.Type
  546. BMREQUEST_TO_ENDPOINT, // bmRequestType.Recipient
  547. USB_REQUEST_GET_DESCRIPTOR, // bRequest
  548. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  549. #if DBG
  550. URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT,
  551. #endif
  552. //URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT
  553. USBPORT_SCT_GetSetDescriptor, // Function
  554. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), // Length
  555. 0, // Pad2
  556. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  557. BMREQUEST_STANDARD, // bmRequestType.Type
  558. BMREQUEST_TO_ENDPOINT, // bmRequestType.Recipient
  559. USB_REQUEST_SET_DESCRIPTOR, // bRequest
  560. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  561. #if DBG
  562. URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT,
  563. #endif
  564. //URB_FUNCTION_GET_CONFIGURATION
  565. USBPORT_SCT_GetConfiguration, // Function
  566. sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST), // Length
  567. 0, // Pad2
  568. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  569. BMREQUEST_STANDARD, // bmRequestType.Type
  570. BMREQUEST_TO_DEVICE, // bmRequestType.Recipient
  571. USB_REQUEST_GET_CONFIGURATION, // bRequest
  572. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  573. #if DBG
  574. URB_FUNCTION_GET_CONFIGURATION,
  575. #endif
  576. //URB_FUNCTION_GET_INTERFACE
  577. USBPORT_SCT_GetInterface, // Function
  578. sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST), // Length
  579. 0, // Pad2
  580. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  581. BMREQUEST_STANDARD, // bmRequestType.Type
  582. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  583. USB_REQUEST_GET_INTERFACE, // bRequest
  584. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  585. #if DBG
  586. URB_FUNCTION_GET_INTERFACE,
  587. #endif
  588. //URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
  589. USBPORT_SCT_GetSetDescriptor, // Function
  590. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), // Length
  591. 0, // Pad2
  592. BMREQUEST_DEVICE_TO_HOST, // bmRequestType.Dir
  593. BMREQUEST_STANDARD, // bmRequestType.Type
  594. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  595. USB_REQUEST_GET_DESCRIPTOR, // bRequest
  596. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  597. #if DBG
  598. URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE,
  599. #endif
  600. //URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE
  601. USBPORT_SCT_GetSetDescriptor, // Function
  602. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), // Length
  603. 0, // Pad2
  604. BMREQUEST_HOST_TO_DEVICE, // bmRequestType.Dir
  605. BMREQUEST_STANDARD, // bmRequestType.Type
  606. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  607. USB_REQUEST_SET_DESCRIPTOR, // bRequest
  608. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  609. #if DBG
  610. URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE,
  611. #endif
  612. //URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR
  613. USBPORT_GetMSFeartureDescriptor, // Function
  614. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), // Length
  615. 0, // Pad2
  616. 0, // bmRequestType.Dir
  617. BMREQUEST_STANDARD, // bmRequestType.Type
  618. BMREQUEST_TO_INTERFACE, // bmRequestType.Recipient
  619. USB_REQUEST_SET_DESCRIPTOR, // bRequest
  620. USBPORT_REQUEST_IS_TRANSFER | USBPORT_REQUEST_USES_DEFAULT_PIPE, // Flags
  621. #if DBG
  622. URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR,
  623. #endif
  624. //URB_FUNCTION_2b
  625. USBPORT_InvalidFunction, // Function
  626. 0, // Length
  627. 0, // Pad2
  628. 0, // bmRequestType.Dir
  629. 0, // bmRequestType.Type
  630. 0, // bmRequestType.Recipient
  631. 0, // bRequest
  632. 0, // Flags
  633. #if DBG
  634. 0x002b,
  635. #endif
  636. //URB_FUNCTION_2c
  637. USBPORT_InvalidFunction, // Function
  638. 0, // Length
  639. 0, // Pad2
  640. 0, // bmRequestType.Dir
  641. 0, // bmRequestType.Type
  642. 0, // bmRequestType.Recipient
  643. 0, // bRequest
  644. 0, // Flags
  645. #if DBG
  646. 0x002c,
  647. #endif
  648. //URB_FUNCTION_2d
  649. USBPORT_InvalidFunction, // Function
  650. 0, // Length
  651. 0, // Pad2
  652. 0, // bmRequestType.Dir
  653. 0, // bmRequestType.Type
  654. 0, // bmRequestType.Recipient
  655. 0, // bRequest
  656. 0, // Flags
  657. #if DBG
  658. 0x002d,
  659. #endif
  660. //URB_FUNCTION_2e
  661. USBPORT_InvalidFunction, // Function
  662. 0, // Length
  663. 0, // Pad2
  664. 0, // bmRequestType.Dir
  665. 0, // bmRequestType.Type
  666. 0, // bmRequestType.Recipient
  667. 0, // bRequest
  668. 0, // Flags
  669. #if DBG
  670. 0x002e,
  671. #endif
  672. //URB_FUNCTION_2f
  673. USBPORT_InvalidFunction, // Function
  674. 0, // Length
  675. 0, // Pad2
  676. 0, // bmRequestType.Dir
  677. 0, // bmRequestType.Type
  678. 0, // bmRequestType.Recipient
  679. 0, // bRequest
  680. 0, // Flags
  681. #if DBG
  682. 0x002f,
  683. #endif
  684. //URB_FUNCTION_SYNC_RESET_PIPE
  685. USBPORT_SyncResetPipe, // Function
  686. sizeof(struct _URB_PIPE_REQUEST), // Length
  687. 0, // Pad2
  688. 0, // bmRequestType.Dir
  689. 0, // bmRequestType.Type
  690. 0, // bmRequestType.Recipient
  691. 0, // bRequest
  692. 0, // Flags
  693. #if DBG
  694. URB_FUNCTION_SYNC_RESET_PIPE,
  695. #endif
  696. //URB_FUNCTION_SYNC_CLEAR_STALL
  697. USBPORT_SyncClearStall, // Function
  698. sizeof(struct _URB_PIPE_REQUEST), // Length
  699. 0, // Pad2
  700. 0, // bmRequestType.Dir
  701. 0, // bmRequestType.Type
  702. 0, // bmRequestType.Recipient
  703. 0, // bRequest
  704. 0, // Flags
  705. #if DBG
  706. URB_FUNCTION_SYNC_CLEAR_STALL,
  707. #endif
  708. };
  709. PURB
  710. USBPORT_UrbFromIrp(
  711. PIRP Irp
  712. )
  713. {
  714. PIO_STACK_LOCATION irpStack;
  715. PURB urb;
  716. irpStack = IoGetCurrentIrpStackLocation(Irp);
  717. urb = irpStack->Parameters.Others.Argument1;
  718. USBPORT_ASSERT(urb);
  719. return urb;
  720. }
  721. NTSTATUS
  722. USBPORT_ProcessURB(
  723. PDEVICE_OBJECT PdoDeviceObject,
  724. PDEVICE_OBJECT FdoDeviceObject,
  725. PIRP Irp,
  726. PURB Urb
  727. )
  728. /*++
  729. Routine Description:
  730. Processes a URB from a client IRP.
  731. Essentially what we do here is look at the URB and validate some
  732. of the the parameters for the client.
  733. In some cases we translate the urb in to multiple bus transactions.
  734. Arguments:
  735. FdoDeviceObject - Device object associated with this IRP request
  736. Irp - IO request block
  737. Urb - ptr to USB request block
  738. IrpIsPending - FALSE if USBPORT completes the IRP
  739. Return Value:
  740. --*/
  741. {
  742. NTSTATUS ntStatus;
  743. USHORT function;
  744. PUSBD_PIPE_HANDLE_I pipeHandle;
  745. PUSBD_DEVICE_HANDLE deviceHandle = NULL;
  746. PDEVICE_EXTENSION devExt;
  747. USBPORT_KdPrint((3, "'enter USBPORT_ProcessURB\n"));
  748. GET_DEVICE_EXT(devExt, FdoDeviceObject);
  749. ASSERT_FDOEXT(devExt);
  750. // assume success
  751. ntStatus = STATUS_SUCCESS;
  752. // initialize the error code to success,
  753. // some drivers do not initailize on entry
  754. Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
  755. function = Urb->UrbHeader.Function;
  756. // don't log to dev handle since it may not be valid
  757. LOGENTRY(NULL,
  758. FdoDeviceObject, LOG_URB, 'pURB', Urb, Irp, function);
  759. // Initialize flags field for this request
  760. Urb->UrbHeader.UsbdFlags = 0;
  761. USBPORT_KdPrint((3, "'USBPORT_ProcessURB, function = 0x%x\n", function));
  762. if (function > URB_FUNCTION_LAST) {
  763. ntStatus =
  764. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_URB_FUNCTION);
  765. goto USBPORT_ProcessURB_Done;
  766. }
  767. #if DBG
  768. else {
  769. USBPORT_ASSERT(UrbDispatchTable[function].ExpectedFunctionCode == function);
  770. }
  771. #endif
  772. //
  773. // do some special transfer specific stuff
  774. //
  775. GET_DEVICE_HANDLE(deviceHandle, Urb);
  776. // check for requests and fail them at low power
  777. //#if 0
  778. if (TEST_FDO_FLAG(devExt, USBPORT_FDOFLAG_FAIL_URBS)) {
  779. KIRQL irql;
  780. PUSB_IRP_CONTEXT irpContext;
  781. USBPORT_KdPrint((1, "'Error: Bad Request to root hub\n"));
  782. LOGENTRY(NULL,
  783. FdoDeviceObject, LOG_URB, '!URr', Urb, Irp, function);
  784. ALLOC_POOL_Z(irpContext, NonPagedPool, sizeof(*irpContext));
  785. if (irpContext) {
  786. irpContext->Sig = SIG_IRPC;
  787. irpContext->DeviceHandle = deviceHandle;
  788. irpContext->Irp = Irp;
  789. ACQUIRE_BADREQUEST_LOCK(FdoDeviceObject, irql);
  790. // put it on our list to complete
  791. //InsertTailList(&devExt->Fdo.BadRequestList,
  792. // &Irp->Tail.Overlay.ListEntry);
  793. InsertTailList(&devExt->Fdo.BadRequestList,
  794. &irpContext->ListEntry);
  795. // if handle is invalid assume this device has been removed
  796. // this will set the USBD status
  797. ntStatus =
  798. SET_USBD_ERROR(Urb, USBD_STATUS_DEVICE_GONE);
  799. // overwrite ntStatus,
  800. // mark pending for the delayed failure
  801. ntStatus = Irp->IoStatus.Status = STATUS_PENDING;
  802. IoMarkIrpPending(Irp);
  803. RELEASE_BADREQUEST_LOCK(FdoDeviceObject, irql);
  804. } else {
  805. TEST_TRAP();
  806. // no memory for link, just complete it now
  807. ntStatus =
  808. SET_USBD_ERROR(Urb, USBD_STATUS_DEVICE_GONE);
  809. }
  810. goto USBPORT_ProcessURB_Done;
  811. }
  812. //#endif
  813. if (deviceHandle == NULL) {
  814. PDEVICE_EXTENSION rhDevExt;
  815. GET_DEVICE_EXT(rhDevExt, PdoDeviceObject);
  816. ASSERT_PDOEXT(rhDevExt);
  817. // null device handle indicates a urb for
  818. // the root hub, set the devhandle to the
  819. // roothub
  820. deviceHandle = Urb->UrbHeader.UsbdDeviceHandle =
  821. &rhDevExt->Pdo.RootHubDeviceHandle;
  822. }
  823. // don't log with dev handle since it may not be valid
  824. LOGENTRY(NULL,
  825. FdoDeviceObject, LOG_URB, 'devH', deviceHandle, Urb, 0);
  826. // if this is request for the deafult pipe
  827. // validate the state of the device
  828. if (!USBPORT_ValidateDeviceHandle(FdoDeviceObject,
  829. deviceHandle,
  830. TRUE)) {
  831. KIRQL irql;
  832. PUSB_IRP_CONTEXT irpContext;
  833. USBPORT_DebugClient(("'Invalid Device Handle Passed in\n"));
  834. LOGENTRY(NULL,
  835. FdoDeviceObject, LOG_URB, '!URB', Urb, Irp, function);
  836. // set to NULL, we can't defrefence it
  837. deviceHandle = NULL;
  838. ALLOC_POOL_Z(irpContext, NonPagedPool, sizeof(*irpContext));
  839. if (irpContext) {
  840. irpContext->Sig = SIG_IRPC;
  841. irpContext->DeviceHandle = (PUSBD_DEVICE_HANDLE) -1;
  842. irpContext->Irp = Irp;
  843. ACQUIRE_BADREQUEST_LOCK(FdoDeviceObject, irql);
  844. // put it on our list to complete
  845. //InsertTailList(&devExt->Fdo.BadRequestList,
  846. // &Irp->Tail.Overlay.ListEntry);
  847. InsertTailList(&devExt->Fdo.BadRequestList,
  848. &irpContext->ListEntry);
  849. // if handle is invalid assume this device has been removed
  850. ntStatus =
  851. SET_USBD_ERROR(Urb, USBD_STATUS_DEVICE_GONE);
  852. // mark pending for the delayed failure
  853. ntStatus = Irp->IoStatus.Status = STATUS_PENDING;
  854. IoMarkIrpPending(Irp);
  855. RELEASE_BADREQUEST_LOCK(FdoDeviceObject, irql);
  856. // ntStatus = SET_USBD_ERROR(Urb, USBD_STATUS_DEVICE_GONE);
  857. } else {
  858. ntStatus =
  859. SET_USBD_ERROR(Urb, USBD_STATUS_DEVICE_GONE);
  860. }
  861. goto USBPORT_ProcessURB_Done;
  862. }
  863. // device handle is valid
  864. LOGENTRY(NULL,
  865. FdoDeviceObject, LOG_URB, 'dURB', Urb, Irp, function);
  866. /*
  867. This action is performed by passing TRUE to ValidateDeviceHandle above
  868. InterlockedIncrement(&deviceHandle->PendingUrbs);
  869. */
  870. // is this a transfer request for the default pipe
  871. // set the pipe handle in the urb
  872. if (UrbDispatchTable[function].Flags & USBPORT_REQUEST_USES_DEFAULT_PIPE) {
  873. PTRANSFER_URB transferUrb = (PTRANSFER_URB) Urb;
  874. transferUrb->UsbdPipeHandle =
  875. &deviceHandle->DefaultPipe;
  876. SET_FLAG(transferUrb->TransferFlags, USBD_DEFAULT_PIPE_TRANSFER);
  877. }
  878. if (UrbDispatchTable[function].Flags & USBPORT_REQUEST_IS_TRANSFER) {
  879. PTRANSFER_URB transferUrb = (PTRANSFER_URB) Urb;
  880. if (TEST_FLAG(transferUrb->TransferFlags, USBD_DEFAULT_PIPE_TRANSFER) &&
  881. function == URB_FUNCTION_CONTROL_TRANSFER) {
  882. transferUrb->UsbdPipeHandle =
  883. &deviceHandle->DefaultPipe;
  884. }
  885. // we do not support linked URBs
  886. if (transferUrb->ReservedMBNull != NULL) {
  887. ntStatus =
  888. SET_USBD_ERROR(transferUrb, USBD_STATUS_INVALID_PARAMETER);
  889. DEBUG_BREAK();
  890. goto USBPORT_ProcessURB_Done;
  891. }
  892. // zero out context field now in case the client
  893. // is recycling the urb
  894. transferUrb->pd.HcdTransferContext = NULL;
  895. // no data phase therefore no buffer
  896. if (UrbDispatchTable[function].Flags & USBPORT_REQUEST_NO_DATA_PHASE) {
  897. transferUrb->TransferBuffer = NULL;
  898. transferUrb->TransferBufferMDL = NULL;
  899. transferUrb->TransferBufferLength = 0;
  900. }
  901. if (function == URB_FUNCTION_CONTROL_TRANSFER &&
  902. transferUrb->UsbdPipeHandle == 0) {
  903. TEST_TRAP(); // old diag code baggage?
  904. }
  905. if (TEST_FLAG(transferUrb->TransferFlags, USBD_DEFAULT_PIPE_TRANSFER)) {
  906. // usbd never supported control transfers > 4k
  907. if (transferUrb->TransferBufferLength > 4096) {
  908. TEST_TRAP();
  909. ntStatus =
  910. SET_USBD_ERROR(transferUrb, USBD_STATUS_INVALID_PARAMETER);
  911. goto USBPORT_ProcessURB_Done;
  912. }
  913. }
  914. // fetch the pipe handle
  915. pipeHandle = transferUrb->UsbdPipeHandle;
  916. // make sure the pipe handle the client s passing is still valid
  917. if (!USBPORT_ValidatePipeHandle(deviceHandle, pipeHandle)) {
  918. USBPORT_KdPrint((1, "'Error: Invalid Device Handle Passed in\n"));
  919. DEBUG_BREAK();
  920. ntStatus =
  921. SET_USBD_ERROR(transferUrb, USBD_STATUS_INVALID_PIPE_HANDLE);
  922. goto USBPORT_ProcessURB_Done;
  923. }
  924. // If there is a non-zero transfer length then either an MDL or
  925. // or system buffer address is required.
  926. //
  927. if (transferUrb->TransferBuffer == NULL &&
  928. transferUrb->TransferBufferMDL == NULL &&
  929. transferUrb->TransferBufferLength != 0) {
  930. ntStatus =
  931. SET_USBD_ERROR(transferUrb, USBD_STATUS_INVALID_PARAMETER);
  932. goto USBPORT_ProcessURB_Done;
  933. }
  934. // if only a system buffer address is specified then
  935. // the caller has passed in a buffer allocated from the
  936. // non-paged pool.
  937. // in this case we allocate an MDL for the request
  938. if (transferUrb->TransferBufferMDL == NULL &&
  939. transferUrb->TransferBufferLength != 0) {
  940. if ((transferUrb->TransferBufferMDL =
  941. IoAllocateMdl(transferUrb->TransferBuffer,
  942. transferUrb->TransferBufferLength,
  943. FALSE,
  944. FALSE,
  945. NULL)) == NULL) {
  946. ntStatus =
  947. SET_USBD_ERROR(transferUrb,
  948. USBD_STATUS_INSUFFICIENT_RESOURCES);
  949. goto USBPORT_ProcessURB_Done;
  950. } else {
  951. SET_FLAG(transferUrb->Hdr.UsbdFlags,
  952. USBPORT_REQUEST_MDL_ALLOCATED);
  953. MmBuildMdlForNonPagedPool(transferUrb->TransferBufferMDL);
  954. }
  955. }
  956. if (transferUrb->TransferBufferMDL != NULL &&
  957. transferUrb->TransferBufferLength == 0) {
  958. ntStatus =
  959. SET_USBD_ERROR(transferUrb, USBD_STATUS_INVALID_PARAMETER);
  960. goto USBPORT_ProcessURB_Done;
  961. }
  962. // transfer looks valid,
  963. // set up the per transfer context
  964. {
  965. USBD_STATUS usbdStatus;
  966. // inialize the transfer
  967. usbdStatus = USBPORT_AllocTransfer(FdoDeviceObject,
  968. transferUrb,
  969. deviceHandle,
  970. Irp,
  971. NULL,
  972. 0);
  973. if (!USBD_SUCCESS(usbdStatus)) {
  974. ntStatus = SET_USBD_ERROR(transferUrb, usbdStatus);
  975. DEBUG_BREAK();
  976. goto USBPORT_ProcessURB_Done;
  977. }
  978. }
  979. }
  980. // non-transfer functions must validate their own parameters
  981. //
  982. // validate the length field based on the function
  983. //
  984. USBPORT_ASSERT(NT_SUCCESS(ntStatus));
  985. if (UrbDispatchTable[function].UrbRequestLength &&
  986. UrbDispatchTable[function].UrbRequestLength != Urb->UrbHeader.Length) {
  987. USBPORT_KdPrint((1, "'Inavlid parameter length length = 0x%x, expected = 0x%x\n",
  988. Urb->UrbHeader.Length,
  989. UrbDispatchTable[function].UrbRequestLength));
  990. DEBUG_BREAK();
  991. ntStatus =
  992. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PARAMETER);
  993. goto USBPORT_ProcessURB_Done;
  994. }
  995. USBPORT_ASSERT(NT_SUCCESS(ntStatus));
  996. // call our handler for this specific USBDI function
  997. if (UrbDispatchTable[function].UrbHandler) {
  998. LOGENTRY(NULL, FdoDeviceObject, LOG_URB, 'Urb>', 0, function, Irp);
  999. ntStatus =
  1000. (UrbDispatchTable[function].UrbHandler)
  1001. (FdoDeviceObject, Irp, Urb);
  1002. LOGENTRY(NULL, FdoDeviceObject, LOG_URB, 'Urb<', ntStatus, function, 0);
  1003. // NOTE that the URB and Irp may be gone at this point
  1004. // if STATUS_PENDING is returned
  1005. } else {
  1006. //
  1007. // really should not get here
  1008. //
  1009. DEBUG_BREAK();
  1010. ntStatus =
  1011. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PARAMETER);
  1012. USBPORT_ASSERT(FALSE);
  1013. }
  1014. USBPORT_ProcessURB_Done:
  1015. //
  1016. // if the URB error code is set then we should also be returning
  1017. // an error in ntStatus
  1018. //
  1019. if (ntStatus != STATUS_PENDING) {
  1020. // request was not queued, complete the irp now
  1021. #if DBG
  1022. // if there is an error code in the URB then
  1023. // we should be returning an error in ntstatus
  1024. // as well
  1025. if (Urb->UrbHeader.Status != USBD_STATUS_SUCCESS &&
  1026. NT_SUCCESS(ntStatus)) {
  1027. // this is a bug
  1028. USBPORT_ASSERT(FALSE);
  1029. }
  1030. #endif
  1031. // if we allocate a transfer structure we will need to free it
  1032. if (TEST_FLAG(Urb->UrbHeader.UsbdFlags, USBPORT_TRANSFER_ALLOCATED)) {
  1033. PHCD_TRANSFER_CONTEXT t;
  1034. t = USBPORT_UnlinkTransfer(FdoDeviceObject, (PTRANSFER_URB) Urb);
  1035. FREE_POOL(FdoDeviceObject, t);
  1036. }
  1037. LOGENTRY(NULL,
  1038. FdoDeviceObject, LOG_URB, 'Uerr', ntStatus, function, Irp);
  1039. if (deviceHandle != NULL) {
  1040. ASSERT_DEVICE_HANDLE(deviceHandle);
  1041. InterlockedDecrement(&deviceHandle->PendingUrbs);
  1042. }
  1043. // complete the irp status code returned by the
  1044. // handler
  1045. // NOTE: we complete to the PDO becuse that is the DeviceObject
  1046. // that the client driver passed the URB to
  1047. USBPORT_CompleteIrp(PdoDeviceObject, Irp, ntStatus, 0);
  1048. }
  1049. USBPORT_KdPrint((3, "'exit USBPORT_ProcessURB 0x%x\n", ntStatus));
  1050. return ntStatus;
  1051. }
  1052. NTSTATUS
  1053. USBPORT_SCT_GetSetDescriptor(
  1054. PDEVICE_OBJECT FdoDeviceObject,
  1055. PIRP Irp,
  1056. PURB Urb
  1057. )
  1058. /*++
  1059. Routine Description:
  1060. Control transfer to get or set a descriptor
  1061. Arguments:
  1062. FdoDeviceObject -
  1063. Irp - IO request block
  1064. Urb - ptr to USB request block
  1065. Return Value:
  1066. --*/
  1067. {
  1068. PUSB_DEFAULT_PIPE_SETUP_PACKET setupPacket;
  1069. USBPORT_KdPrint((3, "' enter USBPORT_SCT_GetSetDescriptor\n"));
  1070. LOGENTRY(NULL,
  1071. FdoDeviceObject, LOG_URB, 'gsDE', 0, 0, Urb);
  1072. setupPacket =
  1073. (PUSB_DEFAULT_PIPE_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  1074. // setup common fields
  1075. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  1076. setupPacket->bRequest =
  1077. UrbDispatchTable[Urb->UrbHeader.Function].bRequest;
  1078. setupPacket->bmRequestType.Type =
  1079. UrbDispatchTable[Urb->UrbHeader.Function].Type;
  1080. setupPacket->bmRequestType.Dir =
  1081. UrbDispatchTable[Urb->UrbHeader.Function].Direction;
  1082. setupPacket->bmRequestType.Recipient =
  1083. UrbDispatchTable[Urb->UrbHeader.Function].Recipient;
  1084. setupPacket->bmRequestType.Reserved = 0;
  1085. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  1086. if (setupPacket->bmRequestType.Dir == BMREQUEST_DEVICE_TO_HOST) {
  1087. USBPORT_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  1088. } else {
  1089. USBPORT_SET_TRANSFER_DIRECTION_OUT(Urb->UrbControlTransfer.TransferFlags);
  1090. }
  1091. USBPORT_QueueTransferUrb((PTRANSFER_URB)Urb);
  1092. return STATUS_PENDING;
  1093. }
  1094. NTSTATUS
  1095. USBPORT_SCT_SetClearFeature(
  1096. PDEVICE_OBJECT FdoDeviceObject,
  1097. PIRP Irp,
  1098. PURB Urb
  1099. )
  1100. /*++
  1101. Routine Description:
  1102. Arguments:
  1103. FdoDeviceObject -
  1104. Irp - IO request block
  1105. Urb - ptr to USB request block
  1106. Return Value:
  1107. --*/
  1108. {
  1109. PUSB_DEFAULT_PIPE_SETUP_PACKET setupPacket;
  1110. USBPORT_KdPrint((2, "'SCT_SetClearFeature\n"));
  1111. LOGENTRY(NULL,
  1112. FdoDeviceObject, LOG_URB, 'scFE', 0, 0, 0);
  1113. setupPacket =
  1114. (PUSB_DEFAULT_PIPE_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  1115. // setup common fields
  1116. setupPacket->wLength = 0;
  1117. setupPacket->bmRequestType.Type =
  1118. UrbDispatchTable[Urb->UrbHeader.Function].Type;
  1119. setupPacket->bmRequestType.Dir =
  1120. UrbDispatchTable[Urb->UrbHeader.Function].Direction;
  1121. setupPacket->bmRequestType.Recipient =
  1122. UrbDispatchTable[Urb->UrbHeader.Function].Recipient;
  1123. setupPacket->bmRequestType.Reserved = 0;
  1124. //setupPacket->wValue = Urb->UrbControlFeatureRequest.FeatureSelector;
  1125. //setupPacket->wIndex = Urb->UrbControlFeatureRequest.Index;
  1126. setupPacket->bRequest =
  1127. UrbDispatchTable[Urb->UrbHeader.Function].bRequest;
  1128. Urb->UrbControlTransfer.TransferBufferLength = 0;
  1129. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  1130. if (setupPacket->bmRequestType.Dir == BMREQUEST_DEVICE_TO_HOST) {
  1131. USBPORT_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  1132. } else {
  1133. USBPORT_SET_TRANSFER_DIRECTION_OUT( Urb->UrbControlTransfer.TransferFlags);
  1134. }
  1135. USBPORT_QueueTransferUrb((PTRANSFER_URB)Urb);
  1136. return STATUS_PENDING;
  1137. }
  1138. NTSTATUS
  1139. USBPORT_SCT_GetStatus(
  1140. PDEVICE_OBJECT FdoDeviceObject,
  1141. PIRP Irp,
  1142. PURB Urb
  1143. )
  1144. /*++
  1145. Routine Description:
  1146. Arguments:
  1147. FdoDeviceObject -
  1148. Irp - IO request block
  1149. Urb - ptr to USB request block
  1150. Return Value:
  1151. --*/
  1152. {
  1153. PUSB_DEFAULT_PIPE_SETUP_PACKET setupPacket;
  1154. NTSTATUS ntStatus;
  1155. USBPORT_KdPrint((2, "'SCT_GetStatus\n"));
  1156. setupPacket
  1157. = (PUSB_DEFAULT_PIPE_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  1158. //
  1159. // setup common fields
  1160. //
  1161. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  1162. setupPacket->wValue.W = 0;
  1163. setupPacket->bmRequestType.Type =
  1164. UrbDispatchTable[Urb->UrbHeader.Function].Type;
  1165. setupPacket->bmRequestType.Dir =
  1166. UrbDispatchTable[Urb->UrbHeader.Function].Direction;
  1167. setupPacket->bmRequestType.Recipient =
  1168. UrbDispatchTable[Urb->UrbHeader.Function].Recipient;
  1169. setupPacket->bmRequestType.Reserved = 0;
  1170. setupPacket->bRequest =
  1171. UrbDispatchTable[Urb->UrbHeader.Function].bRequest;
  1172. // some parameter validation
  1173. if (setupPacket->wLength != 2) {
  1174. ntStatus =
  1175. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PARAMETER);
  1176. USBPORT_DebugClient(("Bad wLength for GetStatus\n"));
  1177. goto USBD_SCT_GetStatus_Done;
  1178. }
  1179. ntStatus = STATUS_PENDING;
  1180. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  1181. if (setupPacket->bmRequestType.Dir == BMREQUEST_DEVICE_TO_HOST) {
  1182. USBPORT_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  1183. } else {
  1184. USBPORT_SET_TRANSFER_DIRECTION_OUT(Urb->UrbControlTransfer.TransferFlags);
  1185. }
  1186. USBPORT_QueueTransferUrb((PTRANSFER_URB)Urb);
  1187. USBD_SCT_GetStatus_Done:
  1188. return ntStatus;
  1189. }
  1190. NTSTATUS
  1191. USBPORT_SCT_VendorClassCommand(
  1192. PDEVICE_OBJECT FdoDeviceObject,
  1193. PIRP Irp,
  1194. PURB Urb
  1195. )
  1196. /*++
  1197. Routine Description:
  1198. Arguments:
  1199. FdoDeviceObject -
  1200. Irp - IO request block
  1201. Urb - ptr to USB request block
  1202. Return Value:
  1203. --*/
  1204. {
  1205. PUSB_DEFAULT_PIPE_SETUP_PACKET setupPacket;
  1206. UCHAR direction;
  1207. USBPORT_KdPrint((2, "'SCT_VendorClassCommand\n"));
  1208. setupPacket =
  1209. (PUSB_DEFAULT_PIPE_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  1210. // setup common fields
  1211. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  1212. // if a direction was specified in the URB then
  1213. // set direction based on URB transfer flags
  1214. direction = (UCHAR)( (Urb->UrbControlTransfer.TransferFlags &
  1215. USBD_TRANSFER_DIRECTION_IN) ?
  1216. BMREQUEST_DEVICE_TO_HOST : BMREQUEST_HOST_TO_DEVICE);
  1217. // note that we override only the Recipient,Dir and Type fields
  1218. setupPacket->bmRequestType.Dir = direction;
  1219. setupPacket->bmRequestType.Type =
  1220. UrbDispatchTable[Urb->UrbHeader.Function].Type;
  1221. setupPacket->bmRequestType.Recipient =
  1222. UrbDispatchTable[Urb->UrbHeader.Function].Recipient;
  1223. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  1224. USBPORT_QueueTransferUrb((PTRANSFER_URB)Urb);
  1225. return STATUS_PENDING;
  1226. }
  1227. NTSTATUS
  1228. USBPORT_AsyncTransfer(
  1229. PDEVICE_OBJECT FdoDeviceObject,
  1230. PIRP Irp,
  1231. PURB Urb
  1232. )
  1233. /*++
  1234. Routine Description:
  1235. pass interrupt or bulk transfer to HCD
  1236. Arguments:
  1237. Irp - IO request block
  1238. Urb - ptr to USB request block
  1239. Return Value:
  1240. --*/
  1241. {
  1242. PUSBD_PIPE_HANDLE_I pipeHandle;
  1243. PTRANSFER_URB transferUrb = (PTRANSFER_URB) Urb;
  1244. PHCD_ENDPOINT endpoint;
  1245. USBPORT_KdPrint((2, "'AsyncTransfer\n"));
  1246. // extract the pipe handle
  1247. pipeHandle = transferUrb->UsbdPipeHandle;
  1248. // pipe handle should have been validated
  1249. // before we got here
  1250. ASSERT_PIPE_HANDLE(pipeHandle);
  1251. endpoint = pipeHandle->Endpoint;
  1252. ASSERT_ENDPOINT(endpoint);
  1253. // set the proper direction based on the direction bit stored with the
  1254. // endpoint address. if this is a control transfer then leave the direction
  1255. // bit alone.
  1256. if (endpoint->Parameters.TransferType != Control) {
  1257. if (endpoint->Parameters.TransferDirection == In) {
  1258. USBPORT_SET_TRANSFER_DIRECTION_IN(transferUrb->TransferFlags);
  1259. } else {
  1260. USBPORT_SET_TRANSFER_DIRECTION_OUT(transferUrb->TransferFlags);
  1261. }
  1262. }
  1263. USBPORT_QueueTransferUrb(transferUrb);
  1264. return STATUS_PENDING;
  1265. }
  1266. #define UHCD_ASAP_LATENCY 5
  1267. NTSTATUS
  1268. USBPORT_IsochTransfer(
  1269. PDEVICE_OBJECT FdoDeviceObject,
  1270. PIRP Irp,
  1271. PURB Urb
  1272. )
  1273. /*++
  1274. Routine Description:
  1275. pass interrupt transfer to HCD
  1276. Arguments:
  1277. Irp - IO request block
  1278. Urb - ptr to USB request block
  1279. Return Value:
  1280. --*/
  1281. {
  1282. NTSTATUS ntStatus;
  1283. PTRANSFER_URB transferUrb = (PTRANSFER_URB) Urb;
  1284. ULONG startFrame, frameCount, p , i, cf, packetCount, maxPacketCount;
  1285. PUSBD_PIPE_HANDLE_I pipeHandle;
  1286. PHCD_ENDPOINT endpoint;
  1287. PDEVICE_EXTENSION devExt;
  1288. KIRQL oldIrql;
  1289. BOOLEAN highSpeed = FALSE;
  1290. #define ABS(x) ( (0 < (x)) ? (x) : (0 - (x)))
  1291. GET_DEVICE_EXT(devExt, FdoDeviceObject);
  1292. ASSERT_FDOEXT(devExt);
  1293. KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
  1294. USBPORT_KdPrint((2, "'IsochTransfer\n"));
  1295. LOGENTRY(NULL,
  1296. FdoDeviceObject, LOG_URB, 'sISO', Urb, 0, 0);
  1297. // extract the pipe handle
  1298. pipeHandle = transferUrb->UsbdPipeHandle;
  1299. // pipe handle should have been validated
  1300. // before we got here
  1301. ASSERT_PIPE_HANDLE(pipeHandle);
  1302. if (TEST_FLAG(pipeHandle->PipeStateFlags, USBPORT_PIPE_ZERO_BW)) {
  1303. // bugbug better error code please
  1304. ntStatus =
  1305. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PARAMETER);
  1306. goto USBPORT_IsochTransfer_Done;
  1307. }
  1308. endpoint = pipeHandle->Endpoint;
  1309. ASSERT_ENDPOINT(endpoint);
  1310. if (endpoint->Parameters.DeviceSpeed == HighSpeed) {
  1311. highSpeed = TRUE;
  1312. }
  1313. MP_Get32BitFrameNumber(devExt, cf);
  1314. LOGENTRY(endpoint,
  1315. FdoDeviceObject, LOG_ISO, '>ISO', Urb, 0, cf);
  1316. // process an iso transfer request
  1317. // validate the number of packets per urb, USBD validated
  1318. // the the count was less than 256 and some tests rely on this.
  1319. // NOTE that usbport is capable of handling
  1320. // larger requests so we allow larger requests thru an
  1321. // enhanced URB or if the device is high speed.
  1322. maxPacketCount = 255;
  1323. if (highSpeed) {
  1324. // size of schedule
  1325. maxPacketCount = 1024;
  1326. }
  1327. // more validation or 'security'
  1328. // we will just fail this case with error since it doesn't make sense
  1329. //
  1330. if (transferUrb->TransferBufferLength == 0 &&
  1331. transferUrb->TransferBufferMDL == NULL &&
  1332. transferUrb->TransferBuffer == NULL) {
  1333. // this is invalid
  1334. USBPORT_DebugClient((
  1335. "Isoch, no buffer\n"));
  1336. TEST_TRAP();
  1337. LOGENTRY(endpoint,
  1338. FdoDeviceObject, LOG_ISO, 'badP', transferUrb, 0, 0);
  1339. ntStatus =
  1340. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PARAMETER);
  1341. goto USBPORT_IsochTransfer_Done;
  1342. }
  1343. if (transferUrb->u.Isoch.NumberOfPackets == 0 ||
  1344. transferUrb->u.Isoch.NumberOfPackets > maxPacketCount) {
  1345. // this is invalid
  1346. USBPORT_DebugClient((
  1347. "Isoch, numberOfPackets = 0\n"));
  1348. LOGENTRY(endpoint,
  1349. FdoDeviceObject, LOG_ISO, 'badF', transferUrb, 0, 0);
  1350. ntStatus =
  1351. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PARAMETER);
  1352. goto USBPORT_IsochTransfer_Done;
  1353. }
  1354. // first get the current USB frame number
  1355. MP_Get32BitFrameNumber(devExt, cf);
  1356. packetCount = transferUrb->u.Isoch.NumberOfPackets;
  1357. if (highSpeed) {
  1358. frameCount = packetCount / 8;
  1359. } else {
  1360. frameCount = transferUrb->u.Isoch.NumberOfPackets;
  1361. }
  1362. // initailize all packet status codes to 'not_set'
  1363. for (p = 0;
  1364. p < packetCount;
  1365. p++) {
  1366. transferUrb->u.Isoch.IsoPacket[p].Status = USBD_STATUS_NOT_SET;
  1367. }
  1368. // see if ASAP flag is set
  1369. if (TEST_FLAG(transferUrb->TransferFlags,
  1370. USBD_START_ISO_TRANSFER_ASAP)) {
  1371. // Yes,
  1372. // if this is the first transfer on the endpoint
  1373. // AKA virgin then set the current frame
  1374. if (TEST_FLAG(endpoint->Flags, EPFLAG_VIRGIN)) {
  1375. LOGENTRY(endpoint,
  1376. FdoDeviceObject, LOG_ISO, 'aspV', Urb, 0, cf);
  1377. // use the same asap latency as the UHCD driver for
  1378. // compatibility
  1379. startFrame =
  1380. endpoint->NextTransferStartFrame = cf+UHCD_ASAP_LATENCY;
  1381. } else {
  1382. startFrame = endpoint->NextTransferStartFrame;
  1383. LOGENTRY(endpoint,
  1384. FdoDeviceObject, LOG_ISO, 'aspN', Urb, startFrame, cf);
  1385. if (ABS((LONG)(cf - startFrame)) > 256) {
  1386. // next asap request out of range, treat this like
  1387. // the virgin case instead of erroring out
  1388. LOGENTRY(endpoint,
  1389. FdoDeviceObject, LOG_ISO, 'resV', Urb, 0, cf);
  1390. startFrame =
  1391. endpoint->NextTransferStartFrame = cf+UHCD_ASAP_LATENCY;
  1392. }
  1393. }
  1394. } else {
  1395. // No,
  1396. // absolute frame number set
  1397. startFrame =
  1398. endpoint->NextTransferStartFrame =
  1399. transferUrb->u.Isoch.StartFrame;
  1400. LOGENTRY(endpoint,
  1401. FdoDeviceObject, LOG_ISO, 'absF', Urb, startFrame, cf);
  1402. }
  1403. LOGENTRY(endpoint,
  1404. FdoDeviceObject, LOG_ISO, 'ISsf', Urb, startFrame, cf);
  1405. transferUrb->u.Isoch.StartFrame = startFrame;
  1406. #if DBG
  1407. if (!highSpeed) {
  1408. USBPORT_ASSERT(frameCount == packetCount);
  1409. }
  1410. #endif
  1411. endpoint->NextTransferStartFrame += frameCount;
  1412. // now that we have computed a start frame validate it
  1413. if (ABS((LONG)(startFrame - cf)) > USBD_ISO_START_FRAME_RANGE) {
  1414. // set all iso packet status codes to not_accessed
  1415. LOGENTRY(endpoint,
  1416. FdoDeviceObject, LOG_ISO, 'iLAT', Urb, 0, 0);
  1417. for (p = 0;
  1418. p < packetCount;
  1419. p++) {
  1420. USBPORT_ASSERT(transferUrb->u.Isoch.IsoPacket[p].Status ==
  1421. USBD_STATUS_NOT_SET);
  1422. transferUrb->u.Isoch.IsoPacket[p].Status =
  1423. USBD_STATUS_ISO_NOT_ACCESSED_LATE;
  1424. }
  1425. ntStatus =
  1426. SET_USBD_ERROR(Urb, USBD_STATUS_BAD_START_FRAME);
  1427. } else {
  1428. // we can transmit at least some of the data
  1429. // set the errors for any packets that got to us too late
  1430. // from the client
  1431. for (i = startFrame;
  1432. i < startFrame + frameCount;
  1433. i++) {
  1434. if (i <= cf) {
  1435. p = i - startFrame;
  1436. if (highSpeed) {
  1437. ULONG j;
  1438. p = p*8;
  1439. for (j=0; j< 8; j++) {
  1440. USBPORT_ASSERT(transferUrb->u.Isoch.IsoPacket[p+j].Status ==
  1441. USBD_STATUS_NOT_SET);
  1442. transferUrb->u.Isoch.IsoPacket[p+j].Status =
  1443. USBD_STATUS_ISO_NOT_ACCESSED_LATE;
  1444. }
  1445. } else {
  1446. USBPORT_ASSERT(transferUrb->u.Isoch.IsoPacket[p].Status ==
  1447. USBD_STATUS_NOT_SET);
  1448. transferUrb->u.Isoch.IsoPacket[p].Status =
  1449. USBD_STATUS_ISO_NOT_ACCESSED_LATE;
  1450. }
  1451. }
  1452. }
  1453. if (endpoint->Parameters.TransferDirection == In) {
  1454. USBPORT_SET_TRANSFER_DIRECTION_IN(transferUrb->TransferFlags);
  1455. } else {
  1456. USBPORT_SET_TRANSFER_DIRECTION_OUT(transferUrb->TransferFlags);
  1457. }
  1458. // now queue the urb for processing by HW
  1459. USBPORT_QueueTransferUrb(transferUrb);
  1460. LOGENTRY(endpoint,
  1461. FdoDeviceObject, LOG_ISO, 'ISO<',0, 0, 0);
  1462. ntStatus = STATUS_PENDING;
  1463. }
  1464. USBPORT_IsochTransfer_Done:
  1465. KeLowerIrql(oldIrql);
  1466. return ntStatus;
  1467. }
  1468. NTSTATUS
  1469. USBPORT_GetMSFeartureDescriptor(
  1470. PDEVICE_OBJECT FdoDeviceObject,
  1471. PIRP Irp,
  1472. PURB Urb
  1473. )
  1474. /*++
  1475. Routine Description:
  1476. pass interrupt transfer to HCD
  1477. Arguments:
  1478. Irp - IO request block
  1479. Urb - ptr to USB request block
  1480. Return Value:
  1481. --*/
  1482. {
  1483. NTSTATUS ntStatus;
  1484. TEST_TRAP();
  1485. ntStatus =
  1486. SET_USBD_ERROR(Urb, USBD_STATUS_NOT_SUPPORTED);
  1487. return ntStatus;
  1488. }
  1489. NTSTATUS
  1490. USBPORT_InvalidFunction(
  1491. PDEVICE_OBJECT FdoDeviceObject,
  1492. PIRP Irp,
  1493. PURB Urb
  1494. )
  1495. /*++
  1496. Routine Description:
  1497. pass interrupt transfer to HCD
  1498. Arguments:
  1499. Irp - IO request block
  1500. Urb - ptr to USB request block
  1501. Return Value:
  1502. --*/
  1503. {
  1504. NTSTATUS ntStatus;
  1505. TEST_TRAP();
  1506. ntStatus =
  1507. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_URB_FUNCTION);
  1508. return ntStatus;
  1509. }
  1510. NTSTATUS
  1511. USBPORT_SyncResetPipe(
  1512. PDEVICE_OBJECT FdoDeviceObject,
  1513. PIRP Irp,
  1514. PURB Urb
  1515. )
  1516. /*++
  1517. Routine Description:
  1518. This API resets the host side pipe state in response to
  1519. a stall pid.
  1520. data toggle is reset if the USBDFLAGS feild specifies data
  1521. toggle reset
  1522. Arguments:
  1523. Irp - IO request block
  1524. Urb - ptr to USB request block
  1525. Return Value:
  1526. --*/
  1527. {
  1528. NTSTATUS ntStatus;
  1529. PUSBD_PIPE_HANDLE_I pipeHandle;
  1530. PUSBD_DEVICE_HANDLE deviceHandle;
  1531. PHCD_ENDPOINT endpoint;
  1532. PDEVICE_EXTENSION devExt;
  1533. // this function blocks so it must not be called at DPC level
  1534. USBPORT_KdPrint((2, "'SyncResetPipe\n"));
  1535. LOGENTRY(NULL,
  1536. FdoDeviceObject, LOG_URB, 'syrP', Urb, 0, 0);
  1537. GET_DEVICE_EXT(devExt, FdoDeviceObject);
  1538. ASSERT_FDOEXT(devExt);
  1539. GET_DEVICE_HANDLE(deviceHandle, Urb);
  1540. pipeHandle = (PUSBD_PIPE_HANDLE_I) Urb->UrbPipeRequest.PipeHandle;
  1541. if (!USBPORT_ValidatePipeHandle(deviceHandle, pipeHandle)) {
  1542. USBPORT_KdPrint((1, "'Error: Invalid Device Handle Passed in\n"));
  1543. DEBUG_BREAK();
  1544. ntStatus =
  1545. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PIPE_HANDLE);
  1546. goto USBPORT_SyncResetPipe_Done;
  1547. }
  1548. // our bug
  1549. ASSERT_PIPE_HANDLE(pipeHandle);
  1550. endpoint = pipeHandle->Endpoint;
  1551. ASSERT_ENDPOINT(endpoint);
  1552. LOGENTRY(endpoint,
  1553. FdoDeviceObject, LOG_URB, 'syrp', Urb, 0, 0);
  1554. ACQUIRE_ENDPOINT_LOCK(endpoint, FdoDeviceObject, 'LeH0');
  1555. // see if we have active transfers, if so we cannot
  1556. // reset the pipe.
  1557. // NOTE: this is a synchronization bug in the client.
  1558. if (IsListEmpty(&endpoint->ActiveList)) {
  1559. // clear the pipe state
  1560. if (TEST_FLAG(Urb->UrbHeader.UsbdFlags, USBPORT_RESET_DATA_TOGGLE)) {
  1561. MP_SetEndpointDataToggle(devExt, endpoint, 0);
  1562. }
  1563. ntStatus = SET_USBD_ERROR(Urb, USBD_STATUS_SUCCESS);
  1564. } else {
  1565. USBPORT_DebugClient((
  1566. "reset pipe with active transfers\n"));
  1567. ntStatus = SET_USBD_ERROR(Urb, USBD_STATUS_ERROR_BUSY);
  1568. }
  1569. LOGENTRY(endpoint,
  1570. FdoDeviceObject, LOG_ISO, 'virg', Urb, 0, 0);
  1571. SET_FLAG(endpoint->Flags, EPFLAG_VIRGIN);
  1572. // set the endpoint state to Active
  1573. MP_SetEndpointStatus(devExt, endpoint, ENDPOINT_STATUS_RUN);
  1574. RELEASE_ENDPOINT_LOCK(endpoint, FdoDeviceObject, 'UeH0');
  1575. USBPORT_SyncResetPipe_Done:
  1576. return ntStatus;
  1577. }
  1578. NTSTATUS
  1579. USBPORT_SyncClearStall(
  1580. PDEVICE_OBJECT FdoDeviceObject,
  1581. PIRP Irp,
  1582. PURB Urb
  1583. )
  1584. /*++
  1585. Routine Description:
  1586. Clear stall on an endpoint note: data toggle is unaffected
  1587. Arguments:
  1588. Irp - IO request block
  1589. Urb - ptr to USB request block
  1590. Return Value:
  1591. --*/
  1592. {
  1593. NTSTATUS ntStatus;
  1594. PUSBD_PIPE_HANDLE_I pipeHandle;
  1595. PUSBD_DEVICE_HANDLE deviceHandle;
  1596. PHCD_ENDPOINT endpoint;
  1597. USB_DEFAULT_PIPE_SETUP_PACKET setupPacket;
  1598. USBD_STATUS usbdStatus;
  1599. // this function blocks so it must not be called at DPC level
  1600. PAGED_CODE();
  1601. USBPORT_KdPrint((2, "'SyncClearStall\n"));
  1602. GET_DEVICE_HANDLE(deviceHandle, Urb);
  1603. pipeHandle = (PUSBD_PIPE_HANDLE_I) Urb->UrbPipeRequest.PipeHandle;
  1604. if (!USBPORT_ValidatePipeHandle(deviceHandle, pipeHandle)) {
  1605. USBPORT_KdPrint((1, "'Error: Invalid Device Handle Passed in\n"));
  1606. DEBUG_BREAK();
  1607. ntStatus =
  1608. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PIPE_HANDLE);
  1609. goto USBPORT_SyncClearStall_Done;
  1610. }
  1611. // our bug
  1612. ASSERT_PIPE_HANDLE(pipeHandle);
  1613. endpoint = pipeHandle->Endpoint;
  1614. ASSERT_ENDPOINT(endpoint);
  1615. // setup packet for clear endpoint stall
  1616. USBPORT_INIT_SETUP_PACKET(setupPacket,
  1617. USB_REQUEST_CLEAR_FEATURE, // bRequest
  1618. BMREQUEST_HOST_TO_DEVICE, // Dir
  1619. BMREQUEST_TO_ENDPOINT, // Recipient
  1620. BMREQUEST_STANDARD, // Type
  1621. USB_FEATURE_ENDPOINT_STALL, // wValue
  1622. endpoint->Parameters.EndpointAddress, // wIndex
  1623. 0); // wLength
  1624. ntStatus =
  1625. USBPORT_SendCommand(deviceHandle,
  1626. FdoDeviceObject,
  1627. &setupPacket,
  1628. NULL,
  1629. 0,
  1630. NULL,
  1631. &usbdStatus);
  1632. ntStatus = SET_USBD_ERROR(Urb, usbdStatus);
  1633. USBPORT_SyncClearStall_Done:
  1634. return ntStatus;
  1635. }
  1636. NTSTATUS
  1637. USBPORT_SyncResetPipeAndClearStall(
  1638. PDEVICE_OBJECT FdoDeviceObject,
  1639. PIRP Irp,
  1640. PURB Urb
  1641. )
  1642. /*++
  1643. Routine Description:
  1644. Process a reset pipe request from the client driver
  1645. synchronously
  1646. legacy function from usb 1.1 stack sends the clear endpoint
  1647. stall command and resets ths host side state including data
  1648. toggle for the endpoint.
  1649. Arguments:
  1650. Irp - IO request block
  1651. Urb - ptr to USB request block
  1652. Return Value:
  1653. --*/
  1654. {
  1655. NTSTATUS ntStatus;
  1656. PUSBD_PIPE_HANDLE_I pipeHandle;
  1657. PUSBD_DEVICE_HANDLE deviceHandle;
  1658. PHCD_ENDPOINT endpoint;
  1659. USBD_STATUS usbdStatus;
  1660. GET_DEVICE_HANDLE(deviceHandle, Urb);
  1661. pipeHandle = (PUSBD_PIPE_HANDLE_I) Urb->UrbPipeRequest.PipeHandle;
  1662. if (!USBPORT_ValidatePipeHandle(deviceHandle, pipeHandle)) {
  1663. USBPORT_KdPrint((1, "'Error: Invalid Pipe Handle Passed in\n"));
  1664. DEBUG_BREAK();
  1665. ntStatus =
  1666. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PIPE_HANDLE);
  1667. } else {
  1668. // our bug
  1669. ASSERT_PIPE_HANDLE(pipeHandle);
  1670. // check for a zero load (BW) endpoint, if so there is
  1671. // nothing to do -- just complete the request with success
  1672. if (TEST_FLAG(pipeHandle->PipeStateFlags, USBPORT_PIPE_ZERO_BW)) {
  1673. ntStatus = SET_USBD_ERROR(Urb, USBD_STATUS_SUCCESS);
  1674. } else {
  1675. endpoint = pipeHandle->Endpoint;
  1676. ASSERT_ENDPOINT(endpoint);
  1677. InterlockedIncrement(&deviceHandle->PendingUrbs);
  1678. // clear the stall first on the device
  1679. // then reset the pipe
  1680. if (endpoint->Parameters.TransferType == Isochronous) {
  1681. // This is a nop for iso endpoints
  1682. //
  1683. // the orginal win9x/2k stack did not send this request
  1684. // for iso endpoints so we don't either. Some devices
  1685. // are confused by this. A client driver may override
  1686. // this behavior by call ing clear_stall and reset_pipe
  1687. // directly
  1688. LOGENTRY(endpoint,
  1689. FdoDeviceObject, LOG_ISO, 'iRES', endpoint, 0, 0);
  1690. ntStatus = SET_USBD_ERROR(Urb, USBD_STATUS_SUCCESS);
  1691. } else {
  1692. // only need to reset data toggle if we cleared stall
  1693. // ie only for non-iso endpoints
  1694. SET_FLAG(Urb->UrbHeader.UsbdFlags, USBPORT_RESET_DATA_TOGGLE);
  1695. ntStatus = USBPORT_SyncClearStall(FdoDeviceObject,
  1696. Irp,
  1697. Urb);
  1698. }
  1699. if (NT_SUCCESS(ntStatus)) {
  1700. ntStatus = USBPORT_SyncResetPipe(FdoDeviceObject,
  1701. Irp,
  1702. Urb);
  1703. if (endpoint->Parameters.TransferType == Isochronous) {
  1704. MP_ENDPOINT_STATE currentState;
  1705. do {
  1706. ACQUIRE_ENDPOINT_LOCK(endpoint, FdoDeviceObject, 'LeH0');
  1707. currentState = USBPORT_GetEndpointState(endpoint);
  1708. LOGENTRY(endpoint,
  1709. FdoDeviceObject, LOG_ISO, 'iWAT', endpoint,
  1710. currentState, 0);
  1711. if (currentState == ENDPOINT_PAUSE &&
  1712. IsListEmpty(&endpoint->ActiveList)) {
  1713. LOGENTRY(endpoint,
  1714. FdoDeviceObject, LOG_ISO, 'frcA', endpoint,
  1715. 0, 0);
  1716. USBPORT_SetEndpointState(endpoint, ENDPOINT_ACTIVE);
  1717. }
  1718. RELEASE_ENDPOINT_LOCK(endpoint, FdoDeviceObject, 'UeH0');
  1719. if (currentState == ENDPOINT_ACTIVE) {
  1720. // quick release
  1721. break;
  1722. }
  1723. ASSERT_PASSIVE();
  1724. USBPORT_Wait(FdoDeviceObject, 1);
  1725. } while (currentState != ENDPOINT_ACTIVE);
  1726. }
  1727. }
  1728. InterlockedDecrement(&deviceHandle->PendingUrbs);
  1729. }
  1730. }
  1731. return ntStatus;
  1732. }
  1733. NTSTATUS
  1734. USBPORT_AbortPipe(
  1735. PDEVICE_OBJECT FdoDeviceObject,
  1736. PIRP Irp,
  1737. PURB Urb
  1738. )
  1739. /*++
  1740. Routine Description:
  1741. Process abort pipe request from the client driver
  1742. Arguments:
  1743. Irp - IO request block
  1744. Urb - ptr to USB request block
  1745. Return Value:
  1746. --*/
  1747. {
  1748. NTSTATUS ntStatus;
  1749. PUSBD_PIPE_HANDLE_I pipeHandle;
  1750. PHCD_ENDPOINT endpoint;
  1751. PUSBD_DEVICE_HANDLE deviceHandle;
  1752. USBPORT_KdPrint((2, "'AbortPipe\n"));
  1753. LOGENTRY(Endpoint,
  1754. FdoDeviceObject, LOG_URB, 'ARP>', 0, Irp, Urb);
  1755. // extract the pipe handle
  1756. GET_DEVICE_HANDLE(deviceHandle, Urb);
  1757. pipeHandle = Urb->UrbPipeRequest.PipeHandle;
  1758. // processurb only validate transfer pipe handles so
  1759. // we need to do it here
  1760. if (!USBPORT_ValidatePipeHandle(deviceHandle, pipeHandle)) {
  1761. USBPORT_KdPrint((1, "'Error: Invalid Pipe Handle Passed in\n"));
  1762. DEBUG_BREAK();
  1763. ntStatus =
  1764. SET_USBD_ERROR(Urb, USBD_STATUS_INVALID_PIPE_HANDLE);
  1765. } else {
  1766. if (TEST_FLAG(pipeHandle->PipeStateFlags, USBPORT_PIPE_ZERO_BW)) {
  1767. // just succeed the request if its a no bw pipe
  1768. ntStatus =
  1769. SET_USBD_ERROR(Urb, USBD_STATUS_SUCCESS);
  1770. } else {
  1771. endpoint = pipeHandle->Endpoint;
  1772. ASSERT_ENDPOINT(endpoint);
  1773. // the USBD/UHCD driver always pended this request when it passed
  1774. // it thru startio so we are safe to pend it here as well.
  1775. // We will pend this request until all outstanding transfers
  1776. // (at the time of the abort) have been completed
  1777. ntStatus = Irp->IoStatus.Status = STATUS_PENDING;
  1778. IoMarkIrpPending(Irp);
  1779. // now do the abort
  1780. USBPORT_AbortEndpoint(FdoDeviceObject,
  1781. endpoint,
  1782. Irp);
  1783. }
  1784. }
  1785. LOGENTRY(Endpoint,
  1786. FdoDeviceObject, LOG_URB, 'ARP<', 0, Irp, ntStatus);
  1787. return ntStatus;
  1788. }
  1789. NTSTATUS
  1790. USBPORT_SCT_GetInterface(
  1791. PDEVICE_OBJECT FdoDeviceObject,
  1792. PIRP Irp,
  1793. PURB Urb
  1794. )
  1795. /*++
  1796. Routine Description:
  1797. Arguments:
  1798. FdoDeviceObject -
  1799. Irp - IO request block
  1800. Urb - ptr to USB request block
  1801. Return Value:
  1802. --*/
  1803. {
  1804. NTSTATUS ntStatus;
  1805. TEST_TRAP();
  1806. ntStatus =
  1807. SET_USBD_ERROR(Urb, USBD_STATUS_NOT_SUPPORTED);
  1808. return ntStatus;
  1809. }
  1810. NTSTATUS
  1811. USBPORT_SCT_GetConfiguration(
  1812. PDEVICE_OBJECT FdoDeviceObject,
  1813. PIRP Irp,
  1814. PURB Urb
  1815. )
  1816. /*++
  1817. Routine Description:
  1818. Arguments:
  1819. FdoDeviceObject -
  1820. Irp - IO request block
  1821. Urb - ptr to USB request block
  1822. Return Value:
  1823. --*/
  1824. {
  1825. PUSB_DEFAULT_PIPE_SETUP_PACKET setupPacket;
  1826. UCHAR direction;
  1827. USBPORT_KdPrint((2, "'SCT_GetConfiguration\n"));
  1828. setupPacket =
  1829. (PUSB_DEFAULT_PIPE_SETUP_PACKET) &Urb->UrbControlTransfer.SetupPacket[0];
  1830. setupPacket->bRequest =
  1831. UrbDispatchTable[Urb->UrbHeader.Function].bRequest;
  1832. setupPacket->bmRequestType.Type =
  1833. UrbDispatchTable[Urb->UrbHeader.Function].Type;
  1834. setupPacket->bmRequestType.Dir =
  1835. UrbDispatchTable[Urb->UrbHeader.Function].Direction;
  1836. setupPacket->bmRequestType.Recipient =
  1837. UrbDispatchTable[Urb->UrbHeader.Function].Recipient;
  1838. setupPacket->bmRequestType.Reserved = 0;
  1839. setupPacket->wValue.W = 0;
  1840. setupPacket->wIndex.W = 0;
  1841. setupPacket->wLength = (USHORT) Urb->UrbControlTransfer.TransferBufferLength;
  1842. if (setupPacket->bmRequestType.Dir == BMREQUEST_DEVICE_TO_HOST) {
  1843. USBPORT_SET_TRANSFER_DIRECTION_IN(Urb->UrbControlTransfer.TransferFlags);
  1844. } else {
  1845. USBPORT_SET_TRANSFER_DIRECTION_OUT(Urb->UrbControlTransfer.TransferFlags);
  1846. }
  1847. Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  1848. USBPORT_QueueTransferUrb((PTRANSFER_URB)Urb);
  1849. return STATUS_PENDING;
  1850. }
  1851. NTSTATUS
  1852. USBPORT_TakeFrameLengthControl(
  1853. PDEVICE_OBJECT FdoDeviceObject,
  1854. PIRP Irp,
  1855. PURB Urb
  1856. )
  1857. /*++
  1858. Routine Description:
  1859. Process abort pipe request from the client driver
  1860. Arguments:
  1861. Irp - IO request block
  1862. Urb - ptr to USB request block
  1863. Return Value:
  1864. --*/
  1865. {
  1866. NTSTATUS ntStatus;
  1867. TEST_TRAP();
  1868. // This function is no longer supported
  1869. ntStatus =
  1870. SET_USBD_ERROR(Urb, USBD_STATUS_NOT_SUPPORTED);
  1871. return ntStatus;
  1872. }
  1873. NTSTATUS
  1874. USBPORT_ReleaseFrameLengthControl(
  1875. PDEVICE_OBJECT FdoDeviceObject,
  1876. PIRP Irp,
  1877. PURB Urb
  1878. )
  1879. /*++
  1880. Routine Description:
  1881. Process abort pipe request from the client driver
  1882. Arguments:
  1883. Irp - IO request block
  1884. Urb - ptr to USB request block
  1885. Return Value:
  1886. --*/
  1887. {
  1888. NTSTATUS ntStatus;
  1889. TEST_TRAP();
  1890. // This function is no longer supported
  1891. ntStatus =
  1892. SET_USBD_ERROR(Urb, USBD_STATUS_NOT_SUPPORTED);
  1893. return ntStatus;
  1894. }
  1895. NTSTATUS
  1896. USBPORT_GetFrameLength(
  1897. PDEVICE_OBJECT FdoDeviceObject,
  1898. PIRP Irp,
  1899. PURB Urb
  1900. )
  1901. /*++
  1902. Routine Description:
  1903. Process abort pipe request from the client driver
  1904. Arguments:
  1905. Irp - IO request block
  1906. Urb - ptr to USB request block
  1907. Return Value:
  1908. --*/
  1909. {
  1910. NTSTATUS ntStatus;
  1911. TEST_TRAP();
  1912. // This function is no longer supported
  1913. ntStatus =
  1914. SET_USBD_ERROR(Urb, USBD_STATUS_NOT_SUPPORTED);
  1915. return ntStatus;
  1916. }
  1917. NTSTATUS
  1918. USBPORT_SetFrameLength(
  1919. PDEVICE_OBJECT FdoDeviceObject,
  1920. PIRP Irp,
  1921. PURB Urb
  1922. )
  1923. /*++
  1924. Routine Description:
  1925. Process abort pipe request from the client driver
  1926. Arguments:
  1927. Irp - IO request block
  1928. Urb - ptr to USB request block
  1929. Return Value:
  1930. --*/
  1931. {
  1932. NTSTATUS ntStatus;
  1933. TEST_TRAP();
  1934. // This function is no longer supported
  1935. ntStatus =
  1936. SET_USBD_ERROR(Urb, USBD_STATUS_NOT_SUPPORTED);
  1937. return ntStatus;
  1938. }
  1939. NTSTATUS
  1940. USBPORT_GetCurrentFrame(
  1941. PDEVICE_OBJECT FdoDeviceObject,
  1942. PIRP Irp,
  1943. PURB Urb
  1944. )
  1945. /*++
  1946. Routine Description:
  1947. get the 32 bit frame number from the miniport
  1948. Arguments:
  1949. Irp - IO request block
  1950. Urb - ptr to USB request block
  1951. Return Value:
  1952. --*/
  1953. {
  1954. NTSTATUS ntStatus;
  1955. PDEVICE_EXTENSION devExt;
  1956. ULONG cf;
  1957. GET_DEVICE_EXT(devExt, FdoDeviceObject);
  1958. ASSERT_FDOEXT(devExt);
  1959. MP_Get32BitFrameNumber(devExt, cf);
  1960. LOGENTRY(NULL,
  1961. FdoDeviceObject, LOG_URB, 'Ugcf', Urb, cf, 0);
  1962. Urb->UrbGetCurrentFrameNumber.FrameNumber = cf;
  1963. ntStatus =
  1964. SET_USBD_ERROR(Urb, USBD_STATUS_SUCCESS);
  1965. return ntStatus;
  1966. }