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.

1032 lines
25 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. busif.c
  5. Abstract:
  6. Exports PnP services thru a bus interface, this eleminates
  7. any dependency of usbhub on usbd.sys with regard to the 'port'
  8. driver support.
  9. Old services have been renamed ServiceNameX and a dummy entrypoint
  10. added
  11. Environment:
  12. kernel mode only
  13. Notes:
  14. Revision History:
  15. 10-29-95 : created
  16. --*/
  17. #include "wdm.h"
  18. #include "stdarg.h"
  19. #include "stdio.h"
  20. //#include "usbdi.h" //public data structures
  21. #include "usbdi.h"
  22. #include "hcdi.h"
  23. #include "usb200.h"
  24. #include "usbd.h" //private data strutures
  25. #include <initguid.h>
  26. #include "hubbusif.h" // hub service bus interface
  27. #include "usbbusif.h" // hub service bus interface
  28. #ifdef USBD_DRIVER // USBPORT supercedes most of USBD, so we will remove
  29. // the obsolete code by compiling it only if
  30. // USBD_DRIVER is set.
  31. NTSTATUS
  32. USBD_RestoreDeviceX(
  33. IN OUT PUSBD_DEVICE_DATA OldDeviceData,
  34. IN OUT PUSBD_DEVICE_DATA NewDeviceData,
  35. IN PDEVICE_OBJECT DeviceObject
  36. );
  37. NTSTATUS
  38. USBD_CreateDeviceX(
  39. IN OUT PUSBD_DEVICE_DATA *DeviceData,
  40. IN PDEVICE_OBJECT DeviceObject,
  41. IN BOOLEAN DeviceIsLowSpeed,
  42. IN ULONG MaxPacketSize_Endpoint0,
  43. IN OUT PULONG DeviceHackFlags
  44. );
  45. NTSTATUS
  46. USBD_RemoveDeviceX(
  47. IN PUSBD_DEVICE_DATA DeviceData,
  48. IN PDEVICE_OBJECT DeviceObject,
  49. IN UCHAR Flags
  50. );
  51. NTSTATUS
  52. USBD_InitializeDeviceX(
  53. IN PUSBD_DEVICE_DATA DeviceData,
  54. IN PDEVICE_OBJECT DeviceObject,
  55. IN OUT PUSB_DEVICE_DESCRIPTOR DeviceDescriptor,
  56. IN ULONG DeviceDescriptorLength,
  57. IN OUT PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor,
  58. IN ULONG ConfigDescriptorLength
  59. );
  60. NTSTATUS
  61. USBD_BusCreateDevice(
  62. IN PVOID BusContext,
  63. IN OUT PUSB_DEVICE_HANDLE *DeviceHandle,
  64. IN PUSB_DEVICE_HANDLE HubDevicehandle,
  65. IN USHORT PortStatus,
  66. IN USHORT PortNumber
  67. )
  68. /*++
  69. Routine Description:
  70. Arguments:
  71. Return Value:
  72. NT status code.
  73. --*/
  74. {
  75. NTSTATUS ntStatus;
  76. BOOLEAN isLowSpeed;
  77. PDEVICE_OBJECT rootHubPdo;
  78. ULONG hackFlags;
  79. PUSBD_DEVICE_DATA deviceData;
  80. rootHubPdo = BusContext;
  81. isLowSpeed = (PortStatus & USB_PORT_STATUS_LOW_SPEED) ? TRUE : FALSE;
  82. ntStatus = USBD_CreateDeviceX(
  83. &deviceData,
  84. rootHubPdo,
  85. isLowSpeed,
  86. 0, // max packet size override, it turns out we
  87. // never use this
  88. &hackFlags);
  89. *DeviceHandle = deviceData;
  90. return ntStatus;
  91. }
  92. NTSTATUS
  93. USBD_BusInitializeDevice(
  94. IN PVOID BusContext,
  95. IN OUT PUSB_DEVICE_HANDLE DeviceHandle
  96. )
  97. /*++
  98. Routine Description:
  99. Arguments:
  100. Return Value:
  101. NT status code.
  102. --*/
  103. {
  104. NTSTATUS ntStatus;
  105. PDEVICE_OBJECT rootHubPdo;
  106. rootHubPdo = BusContext;
  107. ntStatus = USBD_InitializeDeviceX(DeviceHandle,
  108. rootHubPdo,
  109. NULL,
  110. 0,
  111. NULL,
  112. 0);
  113. return ntStatus;
  114. }
  115. NTSTATUS
  116. USBD_BusRemoveDevice(
  117. IN PVOID BusContext,
  118. IN OUT PUSB_DEVICE_HANDLE DeviceHandle,
  119. IN ULONG Flags
  120. )
  121. /*++
  122. Routine Description:
  123. Arguments:
  124. Return Value:
  125. NT status code.
  126. --*/
  127. {
  128. NTSTATUS ntStatus;
  129. PDEVICE_OBJECT rootHubPdo;
  130. rootHubPdo = BusContext;
  131. // note old remove device only supports 8 flags
  132. ntStatus = USBD_RemoveDeviceX(
  133. DeviceHandle,
  134. rootHubPdo,
  135. (UCHAR) Flags);
  136. return ntStatus;
  137. }
  138. NTSTATUS
  139. USBD_BusGetUsbDescriptors(
  140. IN PVOID BusContext,
  141. IN OUT PUSB_DEVICE_HANDLE DeviceHandle,
  142. IN OUT PUCHAR DeviceDescriptorBuffer,
  143. IN OUT PULONG DeviceDescriptorBufferLength,
  144. IN OUT PUCHAR ConfigDescriptorBuffer,
  145. IN OUT PULONG ConfigDescriptorBufferLength
  146. )
  147. /*++
  148. Routine Description:
  149. Arguments:
  150. Return Value:
  151. NT status code.
  152. --*/
  153. {
  154. NTSTATUS ntStatus = STATUS_SUCCESS;
  155. PDEVICE_OBJECT rootHubPdo;
  156. PUSBD_DEVICE_DATA deviceData = DeviceHandle;
  157. rootHubPdo = BusContext;
  158. // use the cached device descriptor
  159. if (DeviceDescriptorBuffer && *DeviceDescriptorBufferLength) {
  160. RtlCopyMemory(DeviceDescriptorBuffer,
  161. &deviceData->DeviceDescriptor,
  162. *DeviceDescriptorBufferLength);
  163. *DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
  164. }
  165. // Fetch the config descriptor. If all that is desired is the 9 byte
  166. // config descriptor header, just return the cached config descriptor
  167. // header so that we don't send back to back requests for just the 9 byte
  168. // header to the device. That seems to confuse some devices, some usb
  169. // audio devices in particular when enumerating on OHCI host controllers.
  170. //
  171. if (ConfigDescriptorBuffer &&
  172. *ConfigDescriptorBufferLength == sizeof(USB_CONFIGURATION_DESCRIPTOR))
  173. {
  174. RtlCopyMemory(ConfigDescriptorBuffer,
  175. &deviceData->ConfigDescriptor,
  176. sizeof(USB_CONFIGURATION_DESCRIPTOR));
  177. }
  178. else if (ConfigDescriptorBuffer && *ConfigDescriptorBufferLength) {
  179. ULONG bytesReturned;
  180. ntStatus =
  181. USBD_SendCommand(deviceData,
  182. rootHubPdo,
  183. STANDARD_COMMAND_GET_DESCRIPTOR,
  184. USB_DESCRIPTOR_MAKE_TYPE_AND_INDEX(
  185. USB_CONFIGURATION_DESCRIPTOR_TYPE, 0),
  186. 0,
  187. (USHORT) *ConfigDescriptorBufferLength,
  188. (PUCHAR) ConfigDescriptorBuffer,
  189. *ConfigDescriptorBufferLength,
  190. &bytesReturned,
  191. NULL);
  192. if (NT_SUCCESS(ntStatus) &&
  193. bytesReturned < sizeof(USB_CONFIGURATION_DESCRIPTOR)) {
  194. // truncated config descriptor returned
  195. USBD_KdPrint(0,
  196. ("'WARNING: Truncated Config Descriptor returned - get JD\n"));
  197. ntStatus = STATUS_DEVICE_DATA_ERROR;
  198. }
  199. }
  200. return ntStatus;
  201. }
  202. NTSTATUS
  203. USBD_BusRestoreDevice(
  204. IN PVOID BusContext,
  205. IN OUT PUSB_DEVICE_HANDLE OldDeviceHandle,
  206. IN OUT PUSB_DEVICE_HANDLE NewDeviceHandle
  207. )
  208. /*++
  209. Routine Description:
  210. Arguments:
  211. Return Value:
  212. NT status code.
  213. --*/
  214. {
  215. NTSTATUS ntStatus;
  216. PDEVICE_OBJECT rootHubPdo;
  217. rootHubPdo = BusContext;
  218. ntStatus = USBD_RestoreDeviceX(OldDeviceHandle,
  219. NewDeviceHandle,
  220. rootHubPdo);
  221. return ntStatus;
  222. }
  223. NTSTATUS
  224. USBD_BusGetUsbDeviceHackFlags(
  225. IN PVOID BusContext,
  226. IN PUSB_DEVICE_HANDLE DeviceHandle,
  227. IN OUT PULONG HackFlags
  228. )
  229. /*++
  230. Routine Description:
  231. Arguments:
  232. Return Value:
  233. NT status code.
  234. --*/
  235. {
  236. NTSTATUS ntStatus = STATUS_SUCCESS;
  237. PDEVICE_OBJECT rootHubPdo;
  238. PUSBD_DEVICE_DATA deviceData = DeviceHandle;
  239. rootHubPdo = BusContext;
  240. TEST_TRAP();
  241. return ntStatus;
  242. }
  243. NTSTATUS
  244. USBD_BusGetUsbPortHackFlags(
  245. IN PVOID BusContext,
  246. IN OUT PULONG HackFlags
  247. )
  248. /*++
  249. Routine Description:
  250. Arguments:
  251. Return Value:
  252. NT status code.
  253. --*/
  254. {
  255. NTSTATUS ntStatus = STATUS_SUCCESS;
  256. PDEVICE_OBJECT rootHubPdo;
  257. PUSBD_EXTENSION deviceExtensionUsbd;
  258. rootHubPdo = BusContext;
  259. *HackFlags = 0;
  260. deviceExtensionUsbd = ((PUSBD_EXTENSION)rootHubPdo->DeviceExtension)->TrueDeviceExtension;
  261. if (deviceExtensionUsbd->DiagnosticMode) {
  262. *HackFlags |= USBD_DEVHACK_SET_DIAG_ID;
  263. }
  264. return ntStatus;
  265. }
  266. VOID
  267. USBD_BusInterfaceReference(
  268. IN PVOID BusContext
  269. )
  270. /*++
  271. Routine Description:
  272. Arguments:
  273. Return Value:
  274. NT status code.
  275. --*/
  276. {
  277. }
  278. VOID
  279. USBD_BusInterfaceDereference(
  280. IN PVOID BusContext
  281. )
  282. /*++
  283. Routine Description:
  284. Arguments:
  285. Return Value:
  286. NT status code.
  287. --*/
  288. {
  289. }
  290. NTSTATUS
  291. USBD_BusQueryBusTime(
  292. IN PVOID BusContext,
  293. IN PULONG CurrentFrame
  294. )
  295. /*++
  296. Routine Description:
  297. returns the current USB frame
  298. Arguments:
  299. Return Value:
  300. NT status code.
  301. --*/
  302. {
  303. PUSBD_EXTENSION deviceExtensionUsbd;
  304. PDEVICE_OBJECT rootHubPdo = BusContext;
  305. deviceExtensionUsbd = rootHubPdo->DeviceExtension;
  306. deviceExtensionUsbd = deviceExtensionUsbd->TrueDeviceExtension;
  307. return deviceExtensionUsbd->HcdGetCurrentFrame(
  308. deviceExtensionUsbd->HcdDeviceObject,
  309. CurrentFrame);
  310. }
  311. VOID
  312. USBD_GetUSBDIVersion(
  313. PUSBD_VERSION_INFORMATION VersionInformation
  314. );
  315. VOID
  316. USBD_BusGetUSBDIVersion(
  317. IN PVOID BusContext,
  318. IN OUT PUSBD_VERSION_INFORMATION VersionInformation,
  319. IN OUT PULONG HcdCapabilities
  320. )
  321. /*++
  322. Routine Description:
  323. returns the current USB frame
  324. Arguments:
  325. Return Value:
  326. NT status code.
  327. --*/
  328. {
  329. PUSBD_EXTENSION deviceExtensionUsbd;
  330. PDEVICE_OBJECT rootHubPdo = BusContext;
  331. deviceExtensionUsbd = rootHubPdo->DeviceExtension;
  332. deviceExtensionUsbd = deviceExtensionUsbd->TrueDeviceExtension;
  333. USBD_GetUSBDIVersion(VersionInformation);
  334. *HcdCapabilities = 0;
  335. if (deviceExtensionUsbd->HcdSubmitIsoUrb != NULL) {
  336. *HcdCapabilities = USB_HCD_CAPS_SUPPORTS_RT_THREADS;
  337. }
  338. }
  339. NTSTATUS
  340. USBD_BusSubmitIsoOutUrb(
  341. IN PVOID BusContext,
  342. IN OUT PURB Urb
  343. )
  344. /*++
  345. Routine Description:
  346. Arguments:
  347. Return Value:
  348. NT status code.
  349. --*/
  350. {
  351. PUSBD_EXTENSION deviceExtensionUsbd;
  352. PDEVICE_OBJECT rootHubPdo = BusContext;
  353. NTSTATUS ntStatus;
  354. // PUSBD_DEVICE_DATA deviceData;
  355. PUSBD_PIPE pipeHandle;
  356. pipeHandle = (PUSBD_PIPE)Urb->UrbIsochronousTransfer.PipeHandle;
  357. ASSERT_PIPE(pipeHandle);
  358. deviceExtensionUsbd = rootHubPdo->DeviceExtension;
  359. deviceExtensionUsbd = deviceExtensionUsbd->TrueDeviceExtension;
  360. ((PHCD_URB)Urb)->HcdUrbCommonTransfer.hca.HcdEndpoint =
  361. pipeHandle->HcdEndpoint;
  362. if (pipeHandle->EndpointDescriptor.bEndpointAddress &
  363. USB_ENDPOINT_DIRECTION_MASK) {
  364. USBD_SET_TRANSFER_DIRECTION_IN(((PHCD_URB)Urb)->HcdUrbCommonTransfer.TransferFlags);
  365. } else {
  366. USBD_SET_TRANSFER_DIRECTION_OUT(((PHCD_URB)Urb)->HcdUrbCommonTransfer.TransferFlags);
  367. }
  368. if (deviceExtensionUsbd->HcdSubmitIsoUrb == NULL) {
  369. // fast iso interface not supported by HCD
  370. TEST_TRAP();
  371. ntStatus = STATUS_NOT_SUPPORTED;
  372. } else {
  373. ntStatus = deviceExtensionUsbd->HcdSubmitIsoUrb(
  374. deviceExtensionUsbd->HcdDeviceObject,
  375. Urb);
  376. }
  377. return ntStatus;
  378. }
  379. NTSTATUS
  380. USBD_BusQueryDeviceInformation(
  381. IN PVOID BusContext,
  382. IN PUSB_DEVICE_HANDLE DeviceHandle,
  383. IN OUT PVOID DeviceInformationBuffer,
  384. IN ULONG DeviceInformationBufferLength,
  385. IN OUT PULONG LengthOfDataCopied
  386. )
  387. /*++
  388. Routine Description:
  389. Arguments:
  390. Return Value:
  391. NT status code.
  392. --*/
  393. {
  394. ULONG need;
  395. PUSBD_CONFIG configHandle;
  396. ULONG i,j,k;
  397. PUSB_DEVICE_INFORMATION_0 level_0 = DeviceInformationBuffer;
  398. PUSB_LEVEL_INFORMATION levelInfo = DeviceInformationBuffer;
  399. ULONG numberOfPipes = 0;
  400. PUSBD_DEVICE_DATA deviceData = DeviceHandle;
  401. // bugbug
  402. // need more validation here
  403. PAGED_CODE();
  404. *LengthOfDataCopied = 0;
  405. if (DeviceInformationBufferLength < sizeof(*levelInfo)) {
  406. return STATUS_BUFFER_TOO_SMALL;
  407. }
  408. if (levelInfo->InformationLevel > 0) {
  409. // usbd only supports level 0
  410. return STATUS_NOT_SUPPORTED;
  411. }
  412. // figure out how much room we need
  413. configHandle = deviceData->ConfigurationHandle;
  414. if (configHandle) {
  415. // count the pipes in each interface
  416. for (i=0;
  417. i< configHandle->ConfigurationDescriptor->bNumInterfaces;
  418. i++) {
  419. numberOfPipes +=
  420. configHandle->InterfaceHandle[i]->
  421. InterfaceInformation->NumberOfPipes;
  422. }
  423. }
  424. need = (numberOfPipes-1) * sizeof(USB_PIPE_INFORMATION_0) +
  425. sizeof(USB_DEVICE_INFORMATION_0);
  426. if (DeviceInformationBufferLength < need) {
  427. // report how much space if possible
  428. levelInfo->ActualLength = need;
  429. *LengthOfDataCopied = sizeof(*levelInfo);
  430. return STATUS_BUFFER_TOO_SMALL;
  431. }
  432. RtlZeroMemory(level_0, need);
  433. //
  434. // enough room, fill in the buffer
  435. //
  436. level_0->InformationLevel = 0;
  437. level_0->ActualLength = need;
  438. level_0->DeviceAddress = deviceData->DeviceAddress;
  439. level_0->DeviceDescriptor = deviceData->DeviceDescriptor;
  440. if (deviceData->LowSpeed) {
  441. level_0->DeviceSpeed = UsbLowSpeed;
  442. } else {
  443. level_0->DeviceSpeed = UsbFullSpeed;
  444. }
  445. // if (DeviceData->xxx) {
  446. level_0->DeviceType = Usb11Device;
  447. // } else {
  448. // level_0->DeviceSpeed = UsbFullSpeed;
  449. // }
  450. // level_0->PortNumber = xxx;
  451. level_0->NumberOfOpenPipes = numberOfPipes;
  452. level_0->CurrentConfigurationValue = 0;
  453. // get the pipe information
  454. if (configHandle) {
  455. level_0->CurrentConfigurationValue =
  456. configHandle->ConfigurationDescriptor->bConfigurationValue;
  457. j=0;
  458. for (i=0;
  459. i<configHandle->ConfigurationDescriptor->bNumInterfaces;
  460. i++) {
  461. PUSBD_INTERFACE interfaceHandle =
  462. configHandle->InterfaceHandle[i];
  463. for (k=0;
  464. k<interfaceHandle->InterfaceInformation->NumberOfPipes;
  465. k++, j++) {
  466. ASSERT(j < numberOfPipes);
  467. level_0->PipeList[j].ScheduleOffset =
  468. interfaceHandle->PipeHandle[k].ScheduleOffset;
  469. RtlCopyMemory(&level_0->PipeList[j].
  470. EndpointDescriptor,
  471. &interfaceHandle->PipeHandle[k].
  472. EndpointDescriptor,
  473. sizeof(USB_ENDPOINT_DESCRIPTOR));
  474. }
  475. }
  476. }
  477. *LengthOfDataCopied = need;
  478. // dump the level data returned
  479. USBD_KdPrint(1, (" USBD level 0 Device Information:\n"));
  480. USBD_KdPrint(1, (" InformationLevel %d\n",
  481. level_0->InformationLevel));
  482. // USBD_KdPrint(1, (" DeviceDescriptor %d\n",
  483. // level_0->InformationLevel));
  484. USBD_KdPrint(1, (" ActualLength %d\n",
  485. level_0->ActualLength));
  486. USBD_KdPrint(1, (" DeviceSpeed %d\n",
  487. level_0->DeviceSpeed));
  488. USBD_KdPrint(1, (" PortNumber %d\n",
  489. level_0->PortNumber));
  490. USBD_KdPrint(1, (" CurrentConfigurationValue %d\n",
  491. level_0->CurrentConfigurationValue));
  492. USBD_KdPrint(1, (" DeviceAddress %d\n",
  493. level_0->DeviceAddress));
  494. USBD_KdPrint(1, (" NumberOfOpenPipes %d\n",
  495. level_0->NumberOfOpenPipes));
  496. for (i=0; i< level_0->NumberOfOpenPipes; i++) {
  497. USBD_KdPrint(1, (" ScheduleOffset[%d] %d\n", i,
  498. level_0->PipeList[i].ScheduleOffset));
  499. USBD_KdPrint(1, (" MaxPacket %d\n",
  500. level_0->PipeList[i].EndpointDescriptor.wMaxPacketSize));
  501. USBD_KdPrint(1, (" Interval %d\n",
  502. level_0->PipeList[i].EndpointDescriptor.bInterval));
  503. // USBD_KdPrint(1, ("' \n", level_0->));
  504. // USBD_KdPrint(1, ("' \n", level_0->));
  505. }
  506. return STATUS_SUCCESS;
  507. }
  508. NTSTATUS
  509. USBD_BusQueryBusInformation(
  510. IN PVOID BusContext,
  511. IN ULONG Level,
  512. IN OUT PVOID BusInformationBuffer,
  513. IN OUT PULONG BusInformationBufferLength,
  514. OUT PULONG BusInformationActulaLength
  515. )
  516. /*++
  517. Routine Description:
  518. Arguments:
  519. Return Value:
  520. NT status code.
  521. --*/
  522. {
  523. NTSTATUS ntStatus = STATUS_NOT_SUPPORTED;
  524. PUSB_BUS_INFORMATION_LEVEL_0 level_0;
  525. PUSB_BUS_INFORMATION_LEVEL_1 level_1;
  526. PDEVICE_OBJECT rootHubPdo = BusContext;
  527. PUSBD_EXTENSION deviceExtensionUsbd;
  528. ULONG len, need;
  529. deviceExtensionUsbd = rootHubPdo->DeviceExtension;
  530. deviceExtensionUsbd = deviceExtensionUsbd->TrueDeviceExtension;
  531. switch (Level) {
  532. case 0:
  533. level_0 = BusInformationBuffer;
  534. if (BusInformationActulaLength != NULL) {
  535. *BusInformationActulaLength = sizeof(*level_0);
  536. }
  537. if (*BusInformationBufferLength >= sizeof(*level_0)) {
  538. *BusInformationBufferLength = sizeof(*level_0);
  539. level_0->TotalBandwidth = 12000; // 12 Mbits
  540. level_0->ConsumedBandwidth =
  541. deviceExtensionUsbd->HcdGetConsumedBW(
  542. deviceExtensionUsbd->HcdDeviceObject);
  543. ntStatus = STATUS_SUCCESS;
  544. } else {
  545. ntStatus = STATUS_BUFFER_TOO_SMALL;
  546. }
  547. break;
  548. case 1:
  549. level_1 = BusInformationBuffer;
  550. need = sizeof(*level_1) +
  551. deviceExtensionUsbd->DeviceLinkUnicodeString.Length;
  552. if (BusInformationActulaLength != NULL) {
  553. *BusInformationActulaLength = need;
  554. }
  555. if (*BusInformationBufferLength >= need) {
  556. *BusInformationBufferLength = need;
  557. level_1->TotalBandwidth = 12000; // 12 Mbits
  558. level_1->ConsumedBandwidth =
  559. deviceExtensionUsbd->HcdGetConsumedBW(
  560. deviceExtensionUsbd->HcdDeviceObject);
  561. level_1->ControllerNameLength =
  562. deviceExtensionUsbd->DeviceLinkUnicodeString.Length;
  563. len = deviceExtensionUsbd->DeviceLinkUnicodeString.Length;
  564. if (len > sizeof(level_1->ControllerNameUnicodeString)) {
  565. len = sizeof(level_1->ControllerNameUnicodeString);
  566. }
  567. RtlCopyMemory(&level_1->ControllerNameUnicodeString[0],
  568. deviceExtensionUsbd->DeviceLinkUnicodeString.Buffer,
  569. len);
  570. ntStatus = STATUS_SUCCESS;
  571. } else {
  572. ntStatus = STATUS_BUFFER_TOO_SMALL;
  573. }
  574. break;
  575. }
  576. return ntStatus;
  577. }
  578. NTSTATUS
  579. USBD_BusGetBusInformation(
  580. IN PVOID BusContext,
  581. IN ULONG Level,
  582. IN PUSB_DEVICE_HANDLE DeviceHandle,
  583. IN OUT PVOID DeviceInformationBuffer,
  584. IN OUT PULONG DeviceInformationBufferLength
  585. )
  586. /*++
  587. Routine Description:
  588. Arguments:
  589. Return Value:
  590. NT status code.
  591. --*/
  592. {
  593. NTSTATUS ntStatus = STATUS_SUCCESS;
  594. TEST_TRAP();
  595. return ntStatus;
  596. }
  597. NTSTATUS
  598. USBD_GetBusInterfaceHub(
  599. IN PDEVICE_OBJECT RootHubPdo,
  600. IN PIRP Irp
  601. )
  602. /*++
  603. Routine Description:
  604. Return the Hub Bus Interface to the caller
  605. Arguments:
  606. Return Value:
  607. NT status code.
  608. --*/
  609. {
  610. PIO_STACK_LOCATION irpStack;
  611. NTSTATUS ntStatus;
  612. USHORT requestedSize, requestedVersion;
  613. PAGED_CODE();
  614. irpStack = IoGetCurrentIrpStackLocation(Irp);
  615. requestedSize = irpStack->Parameters.QueryInterface.Size;
  616. requestedVersion = irpStack->Parameters.QueryInterface.Version;
  617. // assume success
  618. ntStatus = STATUS_SUCCESS;
  619. if (requestedVersion >= USB_BUSIF_HUB_VERSION_0) {
  620. PUSB_BUS_INTERFACE_HUB_V0 busInterface0;
  621. busInterface0 = (PUSB_BUS_INTERFACE_HUB_V0)
  622. irpStack->Parameters.QueryInterface.Interface;
  623. busInterface0->BusContext =
  624. RootHubPdo;
  625. busInterface0->InterfaceReference =
  626. USBD_BusInterfaceReference;
  627. busInterface0->InterfaceDereference =
  628. USBD_BusInterfaceDereference;
  629. busInterface0->Size = sizeof(USB_BUS_INTERFACE_HUB_V0);
  630. busInterface0->Version = USB_BUSIF_HUB_VERSION_0;
  631. }
  632. if (requestedVersion >= USB_BUSIF_HUB_VERSION_1) {
  633. PUSB_BUS_INTERFACE_HUB_V1 busInterface1;
  634. busInterface1 = (PUSB_BUS_INTERFACE_HUB_V1)
  635. irpStack->Parameters.QueryInterface.Interface;
  636. busInterface1->CreateUsbDevice =
  637. USBD_BusCreateDevice;
  638. busInterface1->InitializeUsbDevice =
  639. USBD_BusInitializeDevice;
  640. busInterface1->GetUsbDescriptors =
  641. USBD_BusGetUsbDescriptors;
  642. busInterface1->RemoveUsbDevice =
  643. USBD_BusRemoveDevice;
  644. busInterface1->RestoreUsbDevice =
  645. USBD_BusRestoreDevice;
  646. busInterface1->GetPortHackFlags =
  647. USBD_BusGetUsbPortHackFlags;
  648. busInterface1->QueryDeviceInformation =
  649. USBD_BusQueryDeviceInformation;
  650. busInterface1->Size = sizeof(USB_BUS_INTERFACE_HUB_V1);
  651. busInterface1->Version = USB_BUSIF_HUB_VERSION_1;
  652. }
  653. return ntStatus;
  654. }
  655. NTSTATUS
  656. USBD_GetBusInterfaceUSBDI(
  657. IN PDEVICE_OBJECT RootHubPdo,
  658. IN PIRP Irp
  659. )
  660. /*++
  661. Routine Description:
  662. Return the Hub Bus Interface to the caller
  663. Arguments:
  664. Return Value:
  665. NT status code.
  666. --*/
  667. {
  668. PIO_STACK_LOCATION irpStack;
  669. NTSTATUS ntStatus;
  670. USHORT requestedSize, requestedVersion;
  671. PAGED_CODE();
  672. irpStack = IoGetCurrentIrpStackLocation(Irp);
  673. requestedSize = irpStack->Parameters.QueryInterface.Size;
  674. requestedVersion = irpStack->Parameters.QueryInterface.Version;
  675. // assume success
  676. ntStatus = STATUS_SUCCESS;
  677. if (requestedVersion >= USB_BUSIF_USBDI_VERSION_0) {
  678. PUSB_BUS_INTERFACE_USBDI_V0 busInterface0;
  679. busInterface0 = (PUSB_BUS_INTERFACE_USBDI_V0)
  680. irpStack->Parameters.QueryInterface.Interface;
  681. busInterface0->BusContext =
  682. RootHubPdo;
  683. busInterface0->InterfaceReference =
  684. USBD_BusInterfaceReference;
  685. busInterface0->InterfaceDereference =
  686. USBD_BusInterfaceDereference;
  687. busInterface0->GetUSBDIVersion =
  688. USBD_BusGetUSBDIVersion;
  689. busInterface0->QueryBusTime =
  690. USBD_BusQueryBusTime;
  691. busInterface0->SubmitIsoOutUrb =
  692. USBD_BusSubmitIsoOutUrb;
  693. busInterface0->QueryBusInformation =
  694. USBD_BusQueryBusInformation;
  695. busInterface0->Size = sizeof(USB_BUS_INTERFACE_USBDI_V0);
  696. busInterface0->Version = USB_BUSIF_USBDI_VERSION_0;
  697. }
  698. return ntStatus;
  699. }
  700. NTSTATUS
  701. USBD_GetBusInterface(
  702. IN PDEVICE_OBJECT RootHubPdo,
  703. IN PIRP Irp
  704. )
  705. /*++
  706. Routine Description:
  707. Return the Hub Bus Interface to the caller
  708. Arguments:
  709. Return Value:
  710. NT status code.
  711. --*/
  712. {
  713. PIO_STACK_LOCATION irpStack;
  714. NTSTATUS ntStatus;
  715. USHORT requestedSize, requestedVersion;
  716. PAGED_CODE();
  717. irpStack = IoGetCurrentIrpStackLocation(Irp);
  718. requestedSize = irpStack->Parameters.QueryInterface.Size;
  719. requestedVersion = irpStack->Parameters.QueryInterface.Version;
  720. // USBPORT_KdPrint((1, "'USBPORT_GetBusInterface - Requested version = %d\n",
  721. // requestedVersion));
  722. // USBPORT_KdPrint((1, "'USBPORT_GetBusInterface - Requested size = %d\n",
  723. // requestedSize));
  724. // USBPORT_KdPrint((1, "'USBPORT_GetBusInterface - interface data = %x\n",
  725. // irpStack->Parameters.QueryInterface.InterfaceSpecificData));
  726. // Initialize ntStatus as IRP status, because we're not supposed to
  727. // touch the IRP status for interfaces that we do not support.
  728. // (USBD_PdoPnP sets IRP status to ntStatus on exit.)
  729. ntStatus = Irp->IoStatus.Status;
  730. // validate version, size and GUID
  731. if (RtlCompareMemory(irpStack->Parameters.QueryInterface.InterfaceType,
  732. &USB_BUS_INTERFACE_HUB_GUID,
  733. sizeof(GUID)) == sizeof(GUID)) {
  734. ntStatus = USBD_GetBusInterfaceHub(RootHubPdo,
  735. Irp);
  736. } else if (RtlCompareMemory(irpStack->Parameters.QueryInterface.InterfaceType,
  737. &USB_BUS_INTERFACE_USBDI_GUID,
  738. sizeof(GUID)) == sizeof(GUID)) {
  739. ntStatus = USBD_GetBusInterfaceUSBDI(RootHubPdo,
  740. Irp);
  741. }
  742. return ntStatus;
  743. }
  744. #endif // USBD_DRIVER