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.

943 lines
37 KiB

  1. /***************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. USBUTIL.C
  5. Abstract:
  6. Generic USB routines - must be called at PASSIVE_LEVEL
  7. Environment:
  8. Kernel Mode Only
  9. Notes:
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
  15. Revision History:
  16. 01/08/2001 : created
  17. Authors:
  18. Tom Green
  19. ****************************************************************************/
  20. #include "pch.h"
  21. #include <usb.h>
  22. #include <usbdrivr.h>
  23. #include <usbdlib.h>
  24. #include "intread.h"
  25. #include "usbutil.h"
  26. #include "usbpriv.h"
  27. #include "usbdbg.h"
  28. #ifdef ALLOC_PRAGMA
  29. #endif // ALLOC_PRAGMA
  30. #if DBG
  31. ULONG USBUtil_DebugTraceLevel = 0;
  32. PUSB_WRAP_PRINT USBUtil_DbgPrint = DbgPrint;
  33. #endif
  34. /************************************************************************/
  35. /* USBCallSync */
  36. /************************************************************************/
  37. /* */
  38. /* Routine Description: */
  39. /* */
  40. /* Send URB down USB stack. Synchronous call. */
  41. /* Caller is responsible for URB (allocating and freeing) */
  42. /* */
  43. /* Arguments: */
  44. /* */
  45. /* LowerDevObj - pointer to a device object */
  46. /* Urb - pointer to URB */
  47. /* MillisecondsTimeout - milliseconds to wait for completion */
  48. /* RemoveLock - pointer to remove lock */
  49. /* */
  50. /* Return Value: */
  51. /* */
  52. /* NTSTATUS */
  53. /* */
  54. /************************************************************************/
  55. NTSTATUS
  56. USBCallSyncEx(IN PDEVICE_OBJECT LowerDevObj,
  57. IN PURB Urb,
  58. IN LONG MillisecondsTimeout,
  59. IN PIO_REMOVE_LOCK RemoveLock,
  60. IN ULONG RemLockSize)
  61. {
  62. NTSTATUS ntStatus = STATUS_SUCCESS;
  63. PIRP irp = NULL;
  64. KEVENT event;
  65. PIO_STACK_LOCATION nextStack;
  66. BOOLEAN gotRemoveLock = FALSE;
  67. __try
  68. {
  69. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBCallSync\n"));
  70. ntStatus = IoAcquireRemoveLockEx(RemoveLock,
  71. LowerDevObj,
  72. __FILE__,
  73. __LINE__,
  74. RemLockSize);
  75. if(NT_SUCCESS(ntStatus))
  76. {
  77. gotRemoveLock = TRUE;
  78. }
  79. else
  80. {
  81. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBCallSync: Pending remove on device\n"));
  82. __leave;
  83. }
  84. // do some parameter checking before going too far
  85. if(LowerDevObj == NULL || Urb == NULL || MillisecondsTimeout < 0)
  86. {
  87. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBCallSync: Invalid paramemter passed in\n"));
  88. ntStatus = STATUS_INVALID_PARAMETER;
  89. __leave;
  90. }
  91. // issue a synchronous request
  92. KeInitializeEvent(&event, SynchronizationEvent, FALSE);
  93. irp = IoAllocateIrp(LowerDevObj->StackSize, FALSE);
  94. // check to see if we allocated an Irp
  95. if(!irp)
  96. {
  97. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBCallSync: Couldn't allocate Irp\n"));
  98. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  99. __leave;
  100. }
  101. // Set the Irp parameters
  102. nextStack = IoGetNextIrpStackLocation(irp);
  103. nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  104. nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
  105. nextStack->Parameters.Others.Argument1 = Urb;
  106. // Set the completion routine, which will signal the event
  107. IoSetCompletionRoutine(irp,
  108. USBCallSyncCompletionRoutine,
  109. &event,
  110. TRUE, // InvokeOnSuccess
  111. TRUE, // InvokeOnError
  112. TRUE); // InvokeOnCancel
  113. ntStatus = IoCallDriver(LowerDevObj, irp);
  114. // block on pending request
  115. if(ntStatus == STATUS_PENDING)
  116. {
  117. LARGE_INTEGER timeout;
  118. PLARGE_INTEGER pTimeout = NULL;
  119. // check and see if they have passed in a number of milliseconds to time out
  120. if(MillisecondsTimeout)
  121. {
  122. // setup timeout
  123. timeout = RtlEnlargedIntegerMultiply(ONE_MILLISECOND_TIMEOUT, MillisecondsTimeout);
  124. pTimeout = &timeout;
  125. }
  126. ntStatus = KeWaitForSingleObject(&event,
  127. Executive,
  128. KernelMode,
  129. FALSE,
  130. pTimeout);
  131. // if it timed out, cancel the irp and return appropriate status
  132. if(ntStatus == STATUS_TIMEOUT)
  133. {
  134. ntStatus = STATUS_IO_TIMEOUT;
  135. // Cancel the Irp we just sent.
  136. IoCancelIrp(irp);
  137. // Wait until the cancel completes
  138. KeWaitForSingleObject(&event,
  139. Executive,
  140. KernelMode,
  141. FALSE,
  142. NULL);
  143. }
  144. else
  145. {
  146. // didn't timeout, so return current status
  147. ntStatus = irp->IoStatus.Status;
  148. }
  149. }
  150. }
  151. __finally
  152. {
  153. if(gotRemoveLock)
  154. {
  155. IoReleaseRemoveLockEx(RemoveLock, LowerDevObj, RemLockSize);
  156. }
  157. if(irp)
  158. {
  159. IoFreeIrp(irp);
  160. }
  161. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBCallSync\n"));
  162. }
  163. return ntStatus;
  164. } // USBCallSync
  165. /************************************************************************/
  166. /* USBCallSyncCompletionRoutine */
  167. /************************************************************************/
  168. /* */
  169. /* Routine Description: */
  170. /* */
  171. /* Completion routine for USB sync request. */
  172. /* */
  173. /* Arguments: */
  174. /* */
  175. /* DeviceObject - pointer to device object */
  176. /* Irp - pointer to an I/O Request Packet */
  177. /* Context - pointer to context of call */
  178. /* */
  179. /* Return Value: */
  180. /* */
  181. /* NTSTATUS */
  182. /* */
  183. /************************************************************************/
  184. NTSTATUS
  185. USBCallSyncCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
  186. IN PIRP Irp,
  187. IN PVOID Context)
  188. {
  189. PKEVENT kevent;
  190. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBCallSyncCompletionRoutine\n"));
  191. kevent = (PKEVENT) Context;
  192. KeSetEvent(kevent, IO_NO_INCREMENT, FALSE);
  193. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBCallSyncCompletionRoutine\n"));
  194. return STATUS_MORE_PROCESSING_REQUIRED;
  195. } // USBCallSyncCompletionRoutine
  196. /************************************************************************/
  197. /* USBVendorRequest */
  198. /************************************************************************/
  199. /* */
  200. /* Routine Description: */
  201. /* */
  202. /* Issue USB vendor specific request */
  203. /* */
  204. /* Arguments: */
  205. /* */
  206. /* LowerDevObj - pointer to a device object */
  207. /* Request - request field of vendor specific command */
  208. /* Value - value field of vendor specific command */
  209. /* Index - index field of vendor specific command */
  210. /* Buffer - pointer to data buffer */
  211. /* BufferSize - data buffer length */
  212. /* Read - data direction flag */
  213. /* Timeout - number of milliseconds to wait for completion */
  214. /* RemoveLock - pointer to remove lock */
  215. /* */
  216. /* Return Value: */
  217. /* */
  218. /* NTSTATUS */
  219. /* */
  220. /************************************************************************/
  221. NTSTATUS
  222. USBVendorRequestEx(IN PDEVICE_OBJECT LowerDevObj,
  223. IN REQUEST_RECIPIENT Recipient,
  224. IN UCHAR Request,
  225. IN USHORT Value,
  226. IN USHORT Index,
  227. IN OUT PVOID Buffer,
  228. IN OUT PULONG BufferSize,
  229. IN BOOLEAN Read,
  230. IN LONG MillisecondsTimeout,
  231. IN PIO_REMOVE_LOCK RemoveLock,
  232. IN ULONG RemLockSize)
  233. {
  234. NTSTATUS ntStatus = STATUS_SUCCESS;
  235. PURB urb = NULL;
  236. ULONG size;
  237. ULONG length;
  238. USHORT function;
  239. PAGED_CODE();
  240. __try
  241. {
  242. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBVendorRequest\n"));
  243. // do some parameter checking before going too far
  244. if(LowerDevObj == NULL || MillisecondsTimeout < 0)
  245. {
  246. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBClassRequest: Invalid paramemter passed in\n"));
  247. ntStatus = STATUS_INVALID_PARAMETER;
  248. __leave;
  249. }
  250. // length of buffer passed in
  251. length = BufferSize ? *BufferSize : 0;
  252. // set the buffer length to 0 in case of error
  253. if(BufferSize)
  254. {
  255. *BufferSize = 0;
  256. }
  257. size = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
  258. // allocate memory for the Urb
  259. urb = ALLOC_MEM(NonPagedPool, size, USBLIB_TAG);
  260. // check to see if we allocated a urb
  261. if(!urb)
  262. {
  263. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBVendorRequest: Couldn't allocate URB\n"));
  264. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  265. __leave;
  266. }
  267. switch (Recipient) {
  268. case Device:
  269. function = URB_FUNCTION_VENDOR_DEVICE;
  270. break;
  271. case Interface:
  272. function = URB_FUNCTION_VENDOR_INTERFACE;
  273. break;
  274. case Endpoint:
  275. function = URB_FUNCTION_VENDOR_ENDPOINT;
  276. break;
  277. case Other:
  278. function = URB_FUNCTION_VENDOR_OTHER;
  279. break;
  280. }
  281. UsbBuildVendorRequest(urb, function,
  282. (USHORT) size,
  283. Read ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT,
  284. 0, Request, Value, Index, Buffer, NULL, length, NULL);
  285. ntStatus = USBCallSyncEx(LowerDevObj,
  286. urb,
  287. MillisecondsTimeout,
  288. RemoveLock,
  289. RemLockSize);
  290. // get length of buffer
  291. if(BufferSize)
  292. {
  293. *BufferSize = urb->UrbControlVendorClassRequest.TransferBufferLength;
  294. }
  295. }
  296. __finally
  297. {
  298. if(urb)
  299. {
  300. FREE_MEM(urb);
  301. }
  302. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBVendorRequest\n"));
  303. }
  304. return ntStatus;
  305. } // USBVendorRequest
  306. /************************************************************************/
  307. /* USBClassRequest */
  308. /************************************************************************/
  309. /* */
  310. /* Routine Description: */
  311. /* */
  312. /* Issue USB Class specific request */
  313. /* */
  314. /* Arguments: */
  315. /* */
  316. /* LowerDevObj - pointer to a device object */
  317. /* Recipient - request recipient
  318. /* Request - request field of class specific command */
  319. /* Value - value field of class specific command */
  320. /* Index - index field of class specific command */
  321. /* Buffer - pointer to data buffer */
  322. /* BufferSize - data buffer length */
  323. /* Read - data direction flag */
  324. /* RemoveLock - pointer to remove lock */
  325. /* Timeout - number of milliseconds to wait for completion */
  326. /* */
  327. /* Return Value: */
  328. /* */
  329. /* NTSTATUS */
  330. /* */
  331. /************************************************************************/
  332. NTSTATUS
  333. USBClassRequestEx(IN PDEVICE_OBJECT LowerDevObj,
  334. IN REQUEST_RECIPIENT Recipient,
  335. IN UCHAR Request,
  336. IN USHORT Value,
  337. IN USHORT Index,
  338. IN OUT PVOID Buffer,
  339. IN OUT PULONG BufferSize,
  340. IN BOOLEAN Read,
  341. IN LONG MillisecondsTimeout,
  342. IN PIO_REMOVE_LOCK RemoveLock,
  343. IN ULONG RemLockSize)
  344. {
  345. NTSTATUS ntStatus = STATUS_SUCCESS;
  346. PURB urb = NULL;
  347. ULONG size;
  348. ULONG length;
  349. USHORT function;
  350. __try
  351. {
  352. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBClassRequest\n"));
  353. // do some parameter checking before going too far
  354. if(LowerDevObj == NULL || MillisecondsTimeout < 0)
  355. {
  356. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBClassRequest: Invalid paramemter passed in\n"));
  357. ntStatus = STATUS_INVALID_PARAMETER;
  358. __leave;
  359. }
  360. // length of buffer passed in
  361. length = BufferSize ? *BufferSize : 0;
  362. // set the buffer length to 0 in case of error
  363. if(BufferSize)
  364. {
  365. *BufferSize = 0;
  366. }
  367. size = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
  368. // allocate memory for the Urb
  369. urb = ALLOC_MEM(NonPagedPool, size, USBLIB_TAG);
  370. // check to see if we allocated a urb
  371. if(!urb)
  372. {
  373. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBClassRequest: Couldn't allocate URB\n"));
  374. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  375. __leave;
  376. }
  377. switch (Recipient) {
  378. case Device:
  379. function = URB_FUNCTION_CLASS_DEVICE;
  380. break;
  381. case Interface:
  382. function = URB_FUNCTION_CLASS_INTERFACE;
  383. break;
  384. case Endpoint:
  385. function = URB_FUNCTION_CLASS_ENDPOINT;
  386. break;
  387. case Other:
  388. function = URB_FUNCTION_CLASS_OTHER;
  389. break;
  390. }
  391. UsbBuildVendorRequest(urb, function,
  392. (USHORT) size,
  393. Read ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT,
  394. 0, Request, Value, Index, Buffer, NULL, length, NULL);
  395. ntStatus = USBCallSyncEx(LowerDevObj,
  396. urb,
  397. MillisecondsTimeout,
  398. RemoveLock,
  399. RemLockSize);
  400. // get length of buffer
  401. if(BufferSize)
  402. {
  403. *BufferSize = urb->UrbControlVendorClassRequest.TransferBufferLength;
  404. }
  405. }
  406. __finally
  407. {
  408. if(urb)
  409. {
  410. FREE_MEM(urb);
  411. }
  412. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBClassRequest\n"));
  413. }
  414. return ntStatus;
  415. } // USBClassRequest
  416. /************************************************************************/
  417. /* USBInitializeInterruptTransfers */
  418. /************************************************************************/
  419. /* */
  420. /* Routine Description: */
  421. /* */
  422. /* Initialize interrupt read pipe */
  423. /* */
  424. /* Arguments: */
  425. /* */
  426. /* DeviceObject - pointer to the device object */
  427. /* LowerDevObj - pointer to the lower device object */
  428. /* Buffer - pointer to buffer for data from interrupt pipe */
  429. /* BuffSize - size of buffer passed in */
  430. /* InterruptPipe - pipe descriptor */
  431. /* DriverContext - context passed to driver callback routine */
  432. /* DriverCallback - driver routines called on completion */
  433. /* RemoveLock - pointer to remove lock for device */
  434. /* */
  435. /* Return Value: */
  436. /* */
  437. /* USB_WRAPPER_HANDLE */
  438. /* */
  439. /************************************************************************/
  440. USB_WRAPPER_HANDLE
  441. USBInitializeInterruptTransfersEx(IN PDEVICE_OBJECT DeviceObject,
  442. IN PDEVICE_OBJECT LowerDevObj,
  443. IN ULONG MaxTransferSize,
  444. IN PUSBD_PIPE_INFORMATION InterruptPipe,
  445. IN PVOID DriverContext,
  446. IN INTERRUPT_CALLBACK DriverCallback,
  447. IN ULONG NotificationTypes,
  448. IN ULONG PingPongCount,
  449. IN PIO_REMOVE_LOCK RemoveLock,
  450. IN ULONG RemLockSize)
  451. {
  452. PUSB_WRAPPER_EXTENSION pUsbWrapperExtension = NULL;
  453. ULONG size;
  454. NTSTATUS status;
  455. BOOLEAN error = FALSE;
  456. PAGED_CODE();
  457. __try
  458. {
  459. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBInitializeInterruptTransfers\n"));
  460. //
  461. // Parameter Checking
  462. //
  463. if ((LowerDevObj == NULL) || (InterruptPipe == NULL) || (RemoveLock == NULL)) {
  464. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBInitializeInterruptTransfers: Invalid paramemter passed in\n"));
  465. error = TRUE;
  466. __leave;
  467. }
  468. //
  469. // Allocate UsbWrapperExtension
  470. //
  471. pUsbWrapperExtension = ALLOC_MEM(NonPagedPool,
  472. sizeof(USB_WRAPPER_EXTENSION),
  473. USBLIB_TAG);
  474. if(!pUsbWrapperExtension)
  475. {
  476. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBInitializeInterruptTransfers: Couldn't allocate Wrapper Extension\n"));
  477. error = TRUE;
  478. __leave;
  479. }
  480. //
  481. // Initialize UsbWrapperExtension
  482. //
  483. pUsbWrapperExtension->DeviceObject = DeviceObject;
  484. pUsbWrapperExtension->LowerDeviceObject = LowerDevObj;
  485. pUsbWrapperExtension->RemoveLock = RemoveLock;
  486. pUsbWrapperExtension->RemLockSize = RemLockSize;
  487. //
  488. //Initialize Interrupt Read Wrap
  489. //
  490. UsbWrapInitializeInterruptReadData(
  491. pUsbWrapperExtension,
  492. InterruptPipe,
  493. DriverCallback,
  494. DriverContext,
  495. MaxTransferSize,
  496. NotificationTypes,
  497. PingPongCount);
  498. InterlockedExchange(&pUsbWrapperExtension->IntReadWrap.HandlingError, 0);
  499. //
  500. // Init ping-pong stuff
  501. //
  502. status = UsbWrapInitializePingPongIrps(pUsbWrapperExtension);
  503. if(!NT_SUCCESS(status)) {
  504. DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBInitializeInterruptTransfers: Couldn't initialize ping pong irps\n"));
  505. error = TRUE;
  506. __leave;
  507. }
  508. __leave;
  509. }
  510. __finally
  511. {
  512. if (error && pUsbWrapperExtension) {
  513. if (pUsbWrapperExtension->IntReadWrap.PingPongs) {
  514. UsbWrapDestroyPingPongs(pUsbWrapperExtension);
  515. }
  516. FREE_MEM(pUsbWrapperExtension);
  517. }
  518. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBInitializeInterruptTransfers\n"));
  519. }
  520. return (USB_WRAPPER_HANDLE) pUsbWrapperExtension;
  521. } // USBInitializeInterruptTransfers
  522. /************************************************************************/
  523. /* USBStartInterruptTransfers */
  524. /************************************************************************/
  525. /* */
  526. /* Routine Description: */
  527. /* */
  528. /* Start transfers on interrupt pipe */
  529. /* */
  530. /* Arguments: */
  531. /* */
  532. /* WrapperHandle - pointer to wrapper handle from Init call */
  533. /* */
  534. /* Return Value: */
  535. /* */
  536. /* NTSTATUS */
  537. /* */
  538. /************************************************************************/
  539. NTSTATUS
  540. USBStartInterruptTransfers(IN USB_WRAPPER_HANDLE WrapperHandle)
  541. {
  542. PUSB_WRAPPER_EXTENSION wrapExt = (PUSB_WRAPPER_EXTENSION) WrapperHandle;
  543. NTSTATUS status;
  544. __try
  545. {
  546. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStartInterruptTransfers\n"));
  547. if (!wrapExt) {
  548. status = STATUS_INVALID_PARAMETER;
  549. __leave;
  550. }
  551. ASSERT(IsListEmpty(&wrapExt->IntReadWrap.IncomingQueue));
  552. status = UsbWrapStartAllPingPongs(wrapExt);
  553. }
  554. __finally
  555. {
  556. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStartInterruptTransfers\n"));
  557. }
  558. return status;
  559. }
  560. /************************************************************************/
  561. /* USBStopInterruptTransfers */
  562. /************************************************************************/
  563. /* */
  564. /* Routine Description: */
  565. /* */
  566. /* Stop transfers on interrupt pipe and free resources */
  567. /* */
  568. /* Arguments: */
  569. /* */
  570. /* WrapperHandle - pointer to wrapper handle from Init call */
  571. /* */
  572. /* Return Value: */
  573. /* */
  574. /* NTSTATUS */
  575. /* */
  576. /************************************************************************/
  577. NTSTATUS
  578. USBStopInterruptTransfers(IN USB_WRAPPER_HANDLE WrapperHandle)
  579. {
  580. PUSB_WRAPPER_EXTENSION wrapExt = WrapperHandle;
  581. NTSTATUS status = STATUS_SUCCESS;
  582. PAGED_CODE();
  583. __try
  584. {
  585. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStopInterruptTransfers\n"));
  586. if (!WrapperHandle) {
  587. status = STATUS_INVALID_PARAMETER;
  588. __leave;
  589. }
  590. InterlockedExchange(&wrapExt->IntReadWrap.PumpState,
  591. PUMP_STOPPED);
  592. UsbWrapCancelAllPingPongIrps(wrapExt);
  593. UsbWrapEmptyQueue(wrapExt,
  594. &wrapExt->IntReadWrap.IncomingQueue);
  595. }
  596. __finally
  597. {
  598. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStopInterruptTransfers\n"));
  599. }
  600. return STATUS_SUCCESS;
  601. } // USBStopInterruptTransfers
  602. /************************************************************************/
  603. /* USBReleaseInterruptTransfers */
  604. /************************************************************************/
  605. /* */
  606. /* Routine Description: */
  607. /* */
  608. /* Frees all resources allocated in */
  609. /* USBInitializeInterruptTransfers */
  610. /* */
  611. /* Arguments: */
  612. /* */
  613. /* WrapperHandle - pointer to wrapper handle from Init call */
  614. /* */
  615. /* Return Value: */
  616. /* */
  617. /* NTSTATUS */
  618. /* */
  619. /************************************************************************/
  620. NTSTATUS
  621. USBReleaseInterruptTransfers(IN USB_WRAPPER_HANDLE WrapperHandle)
  622. {
  623. PUSB_WRAPPER_EXTENSION wrapExt = (PUSB_WRAPPER_EXTENSION) WrapperHandle;
  624. NTSTATUS status = STATUS_SUCCESS;
  625. __try
  626. {
  627. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBReleaseInterruptTransfers\n"));
  628. if (!wrapExt) {
  629. status = STATUS_INVALID_PARAMETER;
  630. __leave;
  631. }
  632. UsbWrapDestroyPingPongs(wrapExt);
  633. UsbWrapEmptyQueue(wrapExt, &wrapExt->IntReadWrap.IncomingQueue);
  634. UsbWrapEmptyQueue(wrapExt, &wrapExt->IntReadWrap.SavedQueue);
  635. FREE_MEM(wrapExt);
  636. wrapExt = NULL;
  637. }
  638. __finally
  639. {
  640. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBReleaseInterruptTransfers\n"));
  641. }
  642. return status;
  643. }
  644. /************************************************************************/
  645. /* USBStartSelectiveSuspend */
  646. /************************************************************************/
  647. /* */
  648. /* Routine Description: */
  649. /* */
  650. /* Start selective suspend support for device */
  651. /* */
  652. /* Arguments: */
  653. /* */
  654. /* LowerDevObj - pointer to device object */
  655. /* */
  656. /* Return Value: */
  657. /* */
  658. /* USB_WRAPPER_HANDLE */
  659. /* */
  660. /************************************************************************/
  661. USB_WRAPPER_HANDLE
  662. USBStartSelectiveSuspend(IN PDEVICE_OBJECT LowerDevObj)
  663. {
  664. PAGED_CODE();
  665. __try
  666. {
  667. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStartSelectiveSuspend\n"));
  668. }
  669. __finally
  670. {
  671. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStartSelectiveSuspend\n"));
  672. }
  673. return NULL;
  674. } // USBStartSelectiveSuspend
  675. /************************************************************************/
  676. /* USBStopSelectiveSuspend */
  677. /************************************************************************/
  678. /* */
  679. /* Routine Description: */
  680. /* */
  681. /* Stop selective suspend support for device */
  682. /* */
  683. /* Arguments: */
  684. /* */
  685. /* WrapperHandle - wrapper handle returned by start routine */
  686. /* */
  687. /* Return Value: */
  688. /* */
  689. /* NTSTATUS */
  690. /* */
  691. /************************************************************************/
  692. NTSTATUS
  693. USBStopSelectiveSuspend(IN USB_WRAPPER_HANDLE WrapperHandle)
  694. {
  695. PAGED_CODE();
  696. __try
  697. {
  698. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStopSelectiveSuspend\n"));
  699. }
  700. __finally
  701. {
  702. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStopSelectiveSuspend\n"));
  703. }
  704. return STATUS_SUCCESS;
  705. } // USBStopSelectiveSuspend
  706. /************************************************************************/
  707. /* USBRequestIdle */
  708. /************************************************************************/
  709. /* */
  710. /* Routine Description: */
  711. /* */
  712. /* Idle request for device */
  713. /* */
  714. /* Arguments: */
  715. /* */
  716. /* WrapperHandle - wrapper handle returned by start routine */
  717. /* */
  718. /* Return Value: */
  719. /* */
  720. /* NTSTATUS */
  721. /* */
  722. /************************************************************************/
  723. NTSTATUS
  724. USBRequestIdle(IN USB_WRAPPER_HANDLE WrapperHandle)
  725. {
  726. PAGED_CODE();
  727. __try
  728. {
  729. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBRequestIdle\n"));
  730. }
  731. __finally
  732. {
  733. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBRequestIdle\n"));
  734. }
  735. return STATUS_SUCCESS;
  736. } // USBRequestIdle
  737. /************************************************************************/
  738. /* USBRequestWake */
  739. /************************************************************************/
  740. /* */
  741. /* Routine Description: */
  742. /* */
  743. /* Wake request for device */
  744. /* */
  745. /* Arguments: */
  746. /* */
  747. /* WrapperHandle - wrapper handle returned by start routine */
  748. /* */
  749. /* Return Value: */
  750. /* */
  751. /* NTSTATUS */
  752. /* */
  753. /************************************************************************/
  754. NTSTATUS
  755. USBRequestWake(IN USB_WRAPPER_HANDLE WrapperHandle)
  756. {
  757. PAGED_CODE();
  758. __try
  759. {
  760. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBRequestWake\n"));
  761. }
  762. __finally
  763. {
  764. DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBRequestWake\n"));
  765. }
  766. return STATUS_SUCCESS;
  767. } // USBRequestWake