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.

1793 lines
46 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. busif.c
  5. Abstract:
  6. bus interface for the usbport driver
  7. this is where we export the routines that create
  8. and remove devices on the bus for use by the hub
  9. driver.
  10. Environment:
  11. kernel mode only
  12. Notes:
  13. Revision History:
  14. 6-20-99 : created
  15. --*/
  16. #include "common.h"
  17. // paged functions
  18. #ifdef ALLOC_PRAGMA
  19. #pragma alloc_text(PAGE, USBPORT_GetBusInterface)
  20. #pragma alloc_text(PAGE, USBPORT_BusInterfaceReference)
  21. #pragma alloc_text(PAGE, USBPORT_BusInterfaceDereference)
  22. #pragma alloc_text(PAGE, USBPORTBUSIF_CreateUsbDevice)
  23. #pragma alloc_text(PAGE, USBPORTBUSIF_InitializeUsbDevice)
  24. #pragma alloc_text(PAGE, USBPORTBUSIF_GetUsbDescriptors)
  25. #pragma alloc_text(PAGE, USBPORTBUSIF_RemoveUsbDevice)
  26. #pragma alloc_text(PAGE, USBPORTBUSIF_RestoreUsbDevice)
  27. #endif
  28. // non paged functions
  29. //
  30. PDEVICE_OBJECT
  31. USBPORT_PdoFromBusContext(
  32. PVOID BusContext
  33. )
  34. /*++
  35. Routine Description:
  36. Arguments:
  37. Return Value:
  38. NT status code.
  39. --*/
  40. {
  41. PTRANSACTION_TRANSLATOR transactionTranslator = BusContext;
  42. if (transactionTranslator->Sig == SIG_TT) {
  43. return transactionTranslator->PdoDeviceObject;
  44. } else {
  45. return BusContext;
  46. }
  47. }
  48. VOID
  49. USBPORT_BusInterfaceReference(
  50. PVOID BusContext
  51. )
  52. /*++
  53. Routine Description:
  54. Arguments:
  55. Return Value:
  56. NT status code.
  57. --*/
  58. {
  59. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  60. PAGED_CODE();
  61. TEST_TRAP();
  62. }
  63. VOID
  64. USBPORT_BusInterfaceDereference(
  65. PVOID BusContext
  66. )
  67. /*++
  68. Routine Description:
  69. Arguments:
  70. Return Value:
  71. NT status code.
  72. --*/
  73. {
  74. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  75. PAGED_CODE();
  76. TEST_TRAP();
  77. }
  78. NTSTATUS
  79. USBPORT_GetBusInterface(
  80. PDEVICE_OBJECT FdoDeviceObject,
  81. PDEVICE_OBJECT PdoDeviceObject,
  82. PIRP Irp
  83. )
  84. /*++
  85. Routine Description:
  86. Arguments:
  87. Return Value:
  88. NT status code.
  89. --*/
  90. {
  91. PIO_STACK_LOCATION irpStack;
  92. NTSTATUS ntStatus;
  93. USHORT requestedSize, requestedVersion;
  94. PVOID interfaceData;
  95. PAGED_CODE();
  96. irpStack = IoGetCurrentIrpStackLocation(Irp);
  97. requestedSize = irpStack->Parameters.QueryInterface.Size;
  98. requestedVersion = irpStack->Parameters.QueryInterface.Version;
  99. USBPORT_KdPrint((1, "'USBPORT_GetBusInterface - Requested version = %d\n",
  100. requestedVersion));
  101. USBPORT_KdPrint((1, "'USBPORT_GetBusInterface - Requested size = %d\n",
  102. requestedSize));
  103. USBPORT_KdPrint((1, "'USBPORT_GetBusInterface - interface data = %x\n",
  104. irpStack->Parameters.QueryInterface.InterfaceSpecificData));
  105. interfaceData = irpStack->Parameters.QueryInterface.InterfaceSpecificData;
  106. // assume success
  107. ntStatus = STATUS_SUCCESS;
  108. // validate version, size and GUID
  109. if (RtlCompareMemory(irpStack->Parameters.QueryInterface.InterfaceType,
  110. &USB_BUS_INTERFACE_HUB_GUID,
  111. sizeof(GUID)) == sizeof(GUID)) {
  112. ntStatus = USBPORT_GetBusInterfaceHub(FdoDeviceObject,
  113. PdoDeviceObject,
  114. Irp);
  115. } else if (RtlCompareMemory(irpStack->Parameters.QueryInterface.InterfaceType,
  116. &USB_BUS_INTERFACE_USBDI_GUID,
  117. sizeof(GUID)) == sizeof(GUID)) {
  118. ntStatus = USBPORT_GetBusInterfaceUSBDI(FdoDeviceObject,
  119. PdoDeviceObject,
  120. interfaceData,
  121. Irp);
  122. } else {
  123. //
  124. // Don't change the status of an IRP that isn't understand.
  125. //
  126. ntStatus = Irp->IoStatus.Status;
  127. }
  128. return ntStatus;
  129. }
  130. NTSTATUS
  131. USBPORT_GetBusInterfaceHub(
  132. PDEVICE_OBJECT FdoDeviceObject,
  133. PDEVICE_OBJECT PdoDeviceObject,
  134. PIRP Irp
  135. )
  136. /*++
  137. Routine Description:
  138. Arguments:
  139. Return Value:
  140. NT status code.
  141. --*/
  142. {
  143. PIO_STACK_LOCATION irpStack;
  144. NTSTATUS ntStatus;
  145. USHORT requestedSize, requestedVersion;
  146. PAGED_CODE();
  147. irpStack = IoGetCurrentIrpStackLocation(Irp);
  148. requestedSize = irpStack->Parameters.QueryInterface.Size;
  149. requestedVersion = irpStack->Parameters.QueryInterface.Version;
  150. // assume success
  151. ntStatus = STATUS_SUCCESS;
  152. if (requestedVersion >= USB_BUSIF_HUB_VERSION_0) {
  153. PUSB_BUS_INTERFACE_HUB_V0 busInterface0;
  154. busInterface0 = (PUSB_BUS_INTERFACE_HUB_V0)
  155. irpStack->Parameters.QueryInterface.Interface;
  156. busInterface0->BusContext =
  157. PdoDeviceObject;
  158. busInterface0->InterfaceReference =
  159. USBPORT_BusInterfaceReference;
  160. busInterface0->InterfaceDereference =
  161. USBPORT_BusInterfaceDereference;
  162. busInterface0->Size = sizeof(USB_BUS_INTERFACE_HUB_V0);
  163. busInterface0->Version = USB_BUSIF_HUB_VERSION_0;
  164. }
  165. if (requestedVersion >= USB_BUSIF_HUB_VERSION_1) {
  166. PUSB_BUS_INTERFACE_HUB_V1 busInterface1;
  167. busInterface1 = (PUSB_BUS_INTERFACE_HUB_V1)
  168. irpStack->Parameters.QueryInterface.Interface;
  169. busInterface1->CreateUsbDevice =
  170. USBPORTBUSIF_CreateUsbDevice;
  171. busInterface1->InitializeUsbDevice =
  172. USBPORTBUSIF_InitializeUsbDevice;
  173. busInterface1->GetUsbDescriptors =
  174. USBPORTBUSIF_GetUsbDescriptors;
  175. busInterface1->RemoveUsbDevice =
  176. USBPORTBUSIF_RemoveUsbDevice;
  177. busInterface1->RestoreUsbDevice =
  178. USBPORTBUSIF_RestoreUsbDevice;
  179. busInterface1->QueryDeviceInformation =
  180. USBPORTBUSIF_BusQueryDeviceInformation;
  181. busInterface1->Size = sizeof(USB_BUS_INTERFACE_HUB_V1);
  182. busInterface1->Version = USB_BUSIF_HUB_VERSION_1;
  183. }
  184. // note that version 2 is a superset of version 1
  185. if (requestedVersion >= USB_BUSIF_HUB_VERSION_2) {
  186. PUSB_BUS_INTERFACE_HUB_V2 busInterface2;
  187. busInterface2 = (PUSB_BUS_INTERFACE_HUB_V2)
  188. irpStack->Parameters.QueryInterface.Interface;
  189. busInterface2->GetControllerInformation =
  190. USBPORTBUSIF_GetControllerInformation;
  191. busInterface2->ControllerSelectiveSuspend =
  192. USBPORTBUSIF_ControllerSelectiveSuspend;
  193. busInterface2->GetExtendedHubInformation =
  194. USBPORTBUSIF_GetExtendedHubInformation;
  195. busInterface2->GetRootHubSymbolicName =
  196. USBPORTBUSIF_GetRootHubSymbolicName;
  197. busInterface2->GetDeviceBusContext =
  198. USBPORTBUSIF_GetDeviceBusContext;
  199. busInterface2->Initialize20Hub =
  200. USBPORTBUSIF_InitailizeUsb2Hub;
  201. busInterface2->Size = sizeof(USB_BUS_INTERFACE_HUB_V2);
  202. busInterface2->Version = USB_BUSIF_HUB_VERSION_2;
  203. }
  204. // note that version 3 is a superset of version 2 & 1
  205. if (requestedVersion >= USB_BUSIF_HUB_VERSION_3) {
  206. PUSB_BUS_INTERFACE_HUB_V3 busInterface3;
  207. busInterface3 = (PUSB_BUS_INTERFACE_HUB_V3)
  208. irpStack->Parameters.QueryInterface.Interface;
  209. busInterface3->RootHubInitNotification =
  210. USBPORTBUSIF_RootHubInitNotification;
  211. busInterface3->Size = sizeof(USB_BUS_INTERFACE_HUB_V3);
  212. busInterface3->Version = USB_BUSIF_HUB_VERSION_3;
  213. }
  214. // note that version 4 is a superset of version 3,2 & 1
  215. if (requestedVersion >= USB_BUSIF_HUB_VERSION_4) {
  216. PUSB_BUS_INTERFACE_HUB_V4 busInterface4;
  217. busInterface4 = (PUSB_BUS_INTERFACE_HUB_V4)
  218. irpStack->Parameters.QueryInterface.Interface;
  219. busInterface4->FlushTransfers =
  220. USBPORTBUSIF_FlushTransfers;
  221. busInterface4->Size = sizeof(USB_BUS_INTERFACE_HUB_V4);
  222. busInterface4->Version = USB_BUSIF_HUB_VERSION_4;
  223. }
  224. if (requestedVersion >= USB_BUSIF_HUB_VERSION_5) {
  225. PUSB_BUS_INTERFACE_HUB_V5 busInterface5;
  226. busInterface5 = (PUSB_BUS_INTERFACE_HUB_V5)
  227. irpStack->Parameters.QueryInterface.Interface;
  228. busInterface5->SetDeviceHandleData =
  229. USBPORTBUSIF_SetDeviceHandleData;
  230. busInterface5->Size = sizeof(USB_BUS_INTERFACE_HUB_V5);
  231. busInterface5->Version = USB_BUSIF_HUB_VERSION_5;
  232. }
  233. return ntStatus;
  234. }
  235. NTSTATUS
  236. USBPORTBUSIF_CreateUsbDevice(
  237. PVOID BusContext,
  238. PUSB_DEVICE_HANDLE *NewDeviceHandle,
  239. PUSB_DEVICE_HANDLE HubDeviceHandle,
  240. USHORT PortStatus,
  241. USHORT PortNumber
  242. )
  243. /*++
  244. Routine Description:
  245. Arguments:
  246. Return Value:
  247. NT status code.
  248. --*/
  249. {
  250. NTSTATUS ntStatus;
  251. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  252. PDEVICE_EXTENSION rhDevExt;
  253. PUSBD_DEVICE_HANDLE deviceHandle;
  254. PAGED_CODE();
  255. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  256. ASSERT_PDOEXT(rhDevExt);
  257. ntStatus =
  258. USBPORT_CreateDevice(&deviceHandle,
  259. rhDevExt->HcFdoDeviceObject,
  260. HubDeviceHandle,
  261. PortStatus,
  262. PortNumber);
  263. *NewDeviceHandle = (PUSB_DEVICE_HANDLE) deviceHandle;
  264. return ntStatus;
  265. }
  266. NTSTATUS
  267. USBPORTBUSIF_RootHubInitNotification(
  268. PVOID BusContext,
  269. PVOID CallbackContext,
  270. PRH_INIT_CALLBACK CallbackRoutine
  271. )
  272. /*++
  273. Routine Description:
  274. This is where we hold the enumeration of the CC root hubs until
  275. the USB 2.0 controller has initialized.
  276. Arguments:
  277. Return Value:
  278. NT status code.
  279. --*/
  280. {
  281. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  282. PDEVICE_OBJECT fdoDeviceObject;
  283. PDEVICE_EXTENSION rhDevExt, devExt;
  284. KIRQL irql;
  285. PAGED_CODE();
  286. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  287. ASSERT_PDOEXT(rhDevExt);
  288. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  289. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  290. ASSERT_FDOEXT(devExt);
  291. // remember the callback
  292. KeAcquireSpinLock(&devExt->Fdo.HcSyncSpin.sl, &irql);
  293. rhDevExt->Pdo.HubInitContext = CallbackContext;
  294. rhDevExt->Pdo.HubInitCallback = CallbackRoutine;
  295. KeReleaseSpinLock(&devExt->Fdo.HcSyncSpin.sl, irql);
  296. return STATUS_SUCCESS;
  297. }
  298. NTSTATUS
  299. USBPORTBUSIF_InitailizeUsb2Hub(
  300. PVOID BusContext,
  301. PUSB_DEVICE_HANDLE HubDeviceHandle,
  302. ULONG TtCount
  303. )
  304. /*++
  305. Routine Description:
  306. Arguments:
  307. Return Value:
  308. NT status code.
  309. --*/
  310. {
  311. NTSTATUS ntStatus;
  312. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  313. PDEVICE_EXTENSION rhDevExt;
  314. PAGED_CODE();
  315. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  316. ASSERT_PDOEXT(rhDevExt);
  317. LOGENTRY(NULL, rhDevExt->HcFdoDeviceObject,
  318. LOG_MISC, 'i2hb', BusContext, HubDeviceHandle, TtCount);
  319. ntStatus =
  320. USBPORT_InitializeHsHub(rhDevExt->HcFdoDeviceObject,
  321. HubDeviceHandle,
  322. TtCount);
  323. return ntStatus;
  324. }
  325. NTSTATUS
  326. USBPORTBUSIF_InitializeUsbDevice(
  327. PVOID BusContext,
  328. PUSB_DEVICE_HANDLE DeviceHandle
  329. )
  330. /*++
  331. Routine Description:
  332. Arguments:
  333. Return Value:
  334. NT status code.
  335. --*/
  336. {
  337. NTSTATUS ntStatus;
  338. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  339. PDEVICE_EXTENSION rhDevExt;
  340. PAGED_CODE();
  341. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  342. ASSERT_PDOEXT(rhDevExt);
  343. ntStatus =
  344. USBPORT_InitializeDevice(DeviceHandle,
  345. rhDevExt->HcFdoDeviceObject);
  346. return ntStatus;
  347. }
  348. NTSTATUS
  349. USBPORTBUSIF_GetUsbDescriptors(
  350. PVOID BusContext,
  351. PUSB_DEVICE_HANDLE DeviceHandle,
  352. PUCHAR DeviceDescriptorBuffer,
  353. PULONG DeviceDescriptorBufferLength,
  354. PUCHAR ConfigDescriptorBuffer,
  355. PULONG ConfigDescriptorBufferLength
  356. )
  357. /*++
  358. Routine Description:
  359. Arguments:
  360. Return Value:
  361. NT status code.
  362. --*/
  363. {
  364. NTSTATUS ntStatus;
  365. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  366. PDEVICE_EXTENSION rhDevExt;
  367. PUSBD_DEVICE_HANDLE deviceHandle = DeviceHandle;
  368. PAGED_CODE();
  369. // assume success
  370. ntStatus = STATUS_SUCCESS;
  371. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  372. ASSERT_PDOEXT(rhDevExt);
  373. // Use the cached device descriptor instead of bothering the device with
  374. // another request for it. You would be surprised by how many devices
  375. // get confused if you ask for descriptors too often back to back.
  376. //
  377. if (DeviceDescriptorBuffer && *DeviceDescriptorBufferLength) {
  378. USBPORT_ASSERT(*DeviceDescriptorBufferLength ==
  379. sizeof(USB_DEVICE_DESCRIPTOR));
  380. USBPORT_ASSERT(deviceHandle->DeviceDescriptor.bLength >=
  381. sizeof(USB_DEVICE_DESCRIPTOR));
  382. if (*DeviceDescriptorBufferLength > sizeof(USB_DEVICE_DESCRIPTOR)) {
  383. *DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
  384. }
  385. RtlCopyMemory(DeviceDescriptorBuffer,
  386. &deviceHandle->DeviceDescriptor,
  387. *DeviceDescriptorBufferLength);
  388. }
  389. if (NT_SUCCESS(ntStatus)) {
  390. ntStatus =
  391. USBPORT_GetUsbDescriptor(DeviceHandle,
  392. rhDevExt->HcFdoDeviceObject,
  393. USB_CONFIGURATION_DESCRIPTOR_TYPE,
  394. ConfigDescriptorBuffer,
  395. ConfigDescriptorBufferLength);
  396. }
  397. return ntStatus;
  398. }
  399. NTSTATUS
  400. USBPORTBUSIF_RemoveUsbDevice(
  401. PVOID BusContext,
  402. PUSB_DEVICE_HANDLE DeviceHandle,
  403. ULONG Flags
  404. )
  405. /*++
  406. Routine Description:
  407. Arguments:
  408. Return Value:
  409. NT status code.
  410. --*/
  411. {
  412. NTSTATUS ntStatus;
  413. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  414. PDEVICE_EXTENSION rhDevExt;
  415. PUSBD_DEVICE_HANDLE deviceHandle = DeviceHandle;
  416. PAGED_CODE();
  417. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  418. ASSERT_PDOEXT(rhDevExt);
  419. ntStatus =
  420. USBPORT_RemoveDevice(deviceHandle,
  421. rhDevExt->HcFdoDeviceObject,
  422. Flags);
  423. return ntStatus;
  424. }
  425. NTSTATUS
  426. USBPORTBUSIF_RestoreUsbDevice(
  427. PVOID BusContext,
  428. PUSB_DEVICE_HANDLE OldDeviceHandle,
  429. PUSB_DEVICE_HANDLE NewDeviceHandle
  430. )
  431. /*++
  432. Routine Description:
  433. This function clones the configuration from the 'OldDeviceHandle'
  434. to the 'NewDevicehandle' iff the device has the same VID/PID .
  435. On completion the 'old' device handle is feed
  436. Arguments:
  437. Return Value:
  438. NT status code.
  439. --*/
  440. {
  441. NTSTATUS ntStatus;
  442. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  443. PDEVICE_EXTENSION rhDevExt;
  444. PAGED_CODE();
  445. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  446. ASSERT_PDOEXT(rhDevExt);
  447. ntStatus = USBPORT_CloneDevice(rhDevExt->HcFdoDeviceObject,
  448. OldDeviceHandle,
  449. NewDeviceHandle);
  450. return ntStatus;
  451. }
  452. NTSTATUS
  453. USBPORTBUSIF_BusQueryDeviceInformation(
  454. PVOID BusContext,
  455. PUSB_DEVICE_HANDLE DeviceHandle,
  456. PVOID DeviceInformationBuffer,
  457. ULONG DeviceInformationBufferLength,
  458. PULONG LengthOfDataCopied
  459. )
  460. /*++
  461. Routine Description:
  462. Arguments:
  463. Return Value:
  464. NT status code.
  465. --*/
  466. {
  467. ULONG need;
  468. PUSBD_CONFIG_HANDLE cfgHandle;
  469. ULONG i, j;
  470. PUSB_DEVICE_INFORMATION_0 level_0 = DeviceInformationBuffer;
  471. PUSB_LEVEL_INFORMATION levelInfo = DeviceInformationBuffer;
  472. ULONG numberOfPipes = 0;
  473. PUSBD_DEVICE_HANDLE deviceHandle = DeviceHandle;
  474. PAGED_CODE();
  475. *LengthOfDataCopied = 0;
  476. if (DeviceInformationBufferLength < sizeof(*levelInfo)) {
  477. return STATUS_BUFFER_TOO_SMALL;
  478. }
  479. if (levelInfo->InformationLevel > 0) {
  480. // only support level 0
  481. return STATUS_NOT_SUPPORTED;
  482. }
  483. // figure out how much room we need
  484. cfgHandle = deviceHandle->ConfigurationHandle;
  485. if (cfgHandle != NULL) {
  486. PLIST_ENTRY listEntry;
  487. PUSBD_INTERFACE_HANDLE_I iHandle;
  488. // walk the list
  489. GET_HEAD_LIST(cfgHandle->InterfaceHandleList, listEntry);
  490. while (listEntry &&
  491. listEntry != &cfgHandle->InterfaceHandleList) {
  492. // extract the handle from this entry
  493. iHandle = (PUSBD_INTERFACE_HANDLE_I) CONTAINING_RECORD(
  494. listEntry,
  495. struct _USBD_INTERFACE_HANDLE_I,
  496. InterfaceLink);
  497. ASSERT_INTERFACE(iHandle);
  498. numberOfPipes += iHandle->InterfaceDescriptor.bNumEndpoints;
  499. listEntry = iHandle->InterfaceLink.Flink;
  500. }
  501. }
  502. need = (numberOfPipes-1) * sizeof(USB_PIPE_INFORMATION_0) +
  503. sizeof(USB_DEVICE_INFORMATION_0);
  504. if (DeviceInformationBufferLength < need) {
  505. // report how much space if possible
  506. levelInfo->ActualLength = need;
  507. *LengthOfDataCopied = sizeof(*levelInfo);
  508. return STATUS_BUFFER_TOO_SMALL;
  509. }
  510. RtlZeroMemory(level_0, need);
  511. //
  512. // enough room, fill in the buffer
  513. //
  514. level_0->InformationLevel = 0;
  515. level_0->ActualLength = need;
  516. level_0->DeviceAddress = deviceHandle->DeviceAddress;
  517. level_0->DeviceDescriptor = deviceHandle->DeviceDescriptor;
  518. level_0->DeviceSpeed = deviceHandle->DeviceSpeed;
  519. switch(level_0->DeviceSpeed) {
  520. case UsbFullSpeed:
  521. case UsbLowSpeed:
  522. level_0->DeviceType = Usb11Device;
  523. break;
  524. case UsbHighSpeed:
  525. level_0->DeviceType = Usb20Device;
  526. break;
  527. }
  528. // level_0->PortNumber = xxx;
  529. level_0->NumberOfOpenPipes = numberOfPipes;
  530. // default to 'unconfigured'
  531. level_0->CurrentConfigurationValue = 0;
  532. // get the pipe information
  533. if (cfgHandle) {
  534. PLIST_ENTRY listEntry;
  535. PUSBD_INTERFACE_HANDLE_I iHandle;
  536. level_0->CurrentConfigurationValue =
  537. cfgHandle->ConfigurationDescriptor->bConfigurationValue;
  538. // walk the list
  539. GET_HEAD_LIST(cfgHandle->InterfaceHandleList, listEntry);
  540. j = 0;
  541. while (listEntry &&
  542. listEntry != &cfgHandle->InterfaceHandleList) {
  543. // extract the handle from this entry
  544. iHandle = (PUSBD_INTERFACE_HANDLE_I) CONTAINING_RECORD(
  545. listEntry,
  546. struct _USBD_INTERFACE_HANDLE_I,
  547. InterfaceLink);
  548. ASSERT_INTERFACE(iHandle);
  549. for (i=0; i<iHandle->InterfaceDescriptor.bNumEndpoints; i++) {
  550. if (TEST_FLAG(iHandle->PipeHandle[i].PipeStateFlags, USBPORT_PIPE_ZERO_BW)) {
  551. level_0->PipeList[j].ScheduleOffset = 1;
  552. } else {
  553. level_0->PipeList[j].ScheduleOffset =
  554. iHandle->PipeHandle[i].Endpoint->Parameters.ScheduleOffset;
  555. }
  556. RtlCopyMemory(&level_0->PipeList[j].EndpointDescriptor,
  557. &iHandle->PipeHandle[i].EndpointDescriptor,
  558. sizeof(USB_ENDPOINT_DESCRIPTOR));
  559. j++;
  560. }
  561. listEntry = iHandle->InterfaceLink.Flink;
  562. }
  563. }
  564. *LengthOfDataCopied = need;
  565. // dump the level data returned
  566. USBPORT_KdPrint((1, " USBD level 0 Device Information:\n"));
  567. USBPORT_KdPrint((1, " InformationLevel %d\n",
  568. level_0->InformationLevel));
  569. USBPORT_KdPrint((1, " ActualLength %d\n",
  570. level_0->ActualLength));
  571. USBPORT_KdPrint((1, " DeviceSpeed %d\n",
  572. level_0->DeviceSpeed));
  573. USBPORT_KdPrint((1, " DeviceType %d\n",
  574. level_0->DeviceType));
  575. USBPORT_KdPrint((1, " PortNumber %d\n",
  576. level_0->PortNumber));
  577. USBPORT_KdPrint((1, " CurrentConfigurationValue %d\n",
  578. level_0->CurrentConfigurationValue));
  579. USBPORT_KdPrint((1, " DeviceAddress %d\n",
  580. level_0->DeviceAddress));
  581. USBPORT_KdPrint((1, " NumberOfOpenPipes %d\n",
  582. level_0->NumberOfOpenPipes));
  583. for (i=0; i<level_0->NumberOfOpenPipes; i++) {
  584. USBPORT_KdPrint((1, " ScheduleOffset[%d] %d\n", i,
  585. level_0->PipeList[i].ScheduleOffset));
  586. USBPORT_KdPrint((1, " MaxPacket %d\n",
  587. level_0->PipeList[i].EndpointDescriptor.wMaxPacketSize));
  588. USBPORT_KdPrint((1, " Interval %d\n",
  589. level_0->PipeList[i].EndpointDescriptor.bInterval));
  590. // USBD_KdPrint(1, ("' \n", level_0->));
  591. // USBD_KdPrint(1, ("' \n", level_0->));
  592. }
  593. return STATUS_SUCCESS;
  594. }
  595. PVOID
  596. USBPORTBUSIF_GetDeviceBusContext(
  597. IN PVOID HubBusContext,
  598. IN PVOID DeviceHandle
  599. )
  600. /*++
  601. Routine Description:
  602. Retun the device relative bus context
  603. Arguments:
  604. Return Value:
  605. --*/
  606. {
  607. PDEVICE_OBJECT pdoDeviceObject =
  608. USBPORT_PdoFromBusContext(HubBusContext);
  609. PDEVICE_EXTENSION rhDevExt;
  610. PAGED_CODE();
  611. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  612. ASSERT_PDOEXT(rhDevExt);
  613. return USBPORT_GetDeviceBusContext(rhDevExt->HcFdoDeviceObject,
  614. DeviceHandle,
  615. HubBusContext);
  616. }
  617. PVOID
  618. USBPORT_GetDeviceBusContext(
  619. PDEVICE_OBJECT FdoDeviceObject,
  620. PUSBD_DEVICE_HANDLE DeviceHandle,
  621. PVOID HubBusContext
  622. )
  623. /*++
  624. Routine Description:
  625. Return the device relative bus context
  626. Arguments:
  627. Return Value:
  628. --*/
  629. {
  630. PDEVICE_EXTENSION devExt;
  631. ASSERT_DEVICE_HANDLE(DeviceHandle);
  632. GET_DEVICE_EXT(devExt, FdoDeviceObject);
  633. ASSERT_FDOEXT(devExt);
  634. // if this is not USB2 just return the hubs bus
  635. // context passed in as the device relative context,
  636. // ie there are no virtual 1.1 buses. Otherwise
  637. // return the tt handle for this device
  638. if (USBPORT_IS_USB20(devExt)) {
  639. return DeviceHandle->Tt;
  640. } else {
  641. return HubBusContext;
  642. }
  643. }
  644. BOOLEAN
  645. USBPORT_IsDeviceHighSpeed(
  646. PVOID BusContext
  647. )
  648. /*++
  649. Routine Description:
  650. return the speed of the given device
  651. Arguments:
  652. Return Value:
  653. speed
  654. --*/
  655. {
  656. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  657. PDEVICE_OBJECT fdoDeviceObject;
  658. PDEVICE_EXTENSION devExt, rhDevExt;
  659. PTRANSACTION_TRANSLATOR transactionTranslator = BusContext;
  660. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  661. ASSERT_PDOEXT(rhDevExt);
  662. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  663. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  664. if (transactionTranslator->Sig != SIG_TT) {
  665. // return true if bus is high speed
  666. if (USBPORT_IS_USB20(devExt)) {
  667. return TRUE;
  668. }
  669. }
  670. return FALSE;
  671. }
  672. NTSTATUS
  673. USBPORT_BusQueryBusInformation(
  674. PVOID BusContext,
  675. ULONG Level,
  676. PVOID BusInformationBuffer,
  677. PULONG BusInformationBufferLength,
  678. PULONG BusInformationActulaLength
  679. )
  680. /*++
  681. Routine Description:
  682. Arguments:
  683. Return Value:
  684. NT status code.
  685. --*/
  686. {
  687. NTSTATUS ntStatus = STATUS_NOT_SUPPORTED;
  688. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  689. PDEVICE_OBJECT fdoDeviceObject;
  690. PDEVICE_EXTENSION devExt, rhDevExt;
  691. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  692. ASSERT_PDOEXT(rhDevExt);
  693. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  694. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  695. ASSERT_FDOEXT(devExt);
  696. switch (Level) {
  697. case 0:
  698. {
  699. PUSB_BUS_INFORMATION_LEVEL_0 level_0;
  700. level_0 = BusInformationBuffer;
  701. LOGENTRY(NULL, fdoDeviceObject, LOG_MISC, 'lev1', 0, level_0, 0);
  702. if (BusInformationActulaLength != NULL) {
  703. *BusInformationActulaLength = sizeof(*level_0);
  704. }
  705. if (*BusInformationBufferLength >= sizeof(*level_0)) {
  706. *BusInformationBufferLength = sizeof(*level_0);
  707. // BUGBUG
  708. TEST_TRAP();
  709. level_0->TotalBandwidth =
  710. USBPORT_ComputeTotalBandwidth(fdoDeviceObject,
  711. BusContext);
  712. level_0->ConsumedBandwidth =
  713. USBPORT_ComputeAllocatedBandwidth(fdoDeviceObject,
  714. BusContext);
  715. ntStatus = STATUS_SUCCESS;
  716. } else {
  717. ntStatus = STATUS_BUFFER_TOO_SMALL;
  718. }
  719. }
  720. break;
  721. case 1:
  722. {
  723. PUSB_BUS_INFORMATION_LEVEL_1 level_1;
  724. ULONG need;
  725. level_1 = BusInformationBuffer;
  726. LOGENTRY(NULL, fdoDeviceObject, LOG_MISC, 'lev1', 0, level_1, 0);
  727. need = sizeof(*level_1) + devExt->SymbolicLinkName.Length;
  728. if (BusInformationActulaLength != NULL) {
  729. *BusInformationActulaLength = need;
  730. }
  731. if (*BusInformationBufferLength >= need) {
  732. *BusInformationBufferLength = need;
  733. level_1->TotalBandwidth =
  734. USBPORT_ComputeTotalBandwidth(fdoDeviceObject,
  735. BusContext);
  736. level_1->ConsumedBandwidth =
  737. USBPORT_ComputeAllocatedBandwidth(fdoDeviceObject,
  738. BusContext);
  739. level_1->ControllerNameLength =
  740. devExt->SymbolicLinkName.Length;
  741. RtlCopyMemory(level_1->ControllerNameUnicodeString,
  742. devExt->SymbolicLinkName.Buffer,
  743. level_1->ControllerNameLength);
  744. ntStatus = STATUS_SUCCESS;
  745. } else {
  746. ntStatus = STATUS_BUFFER_TOO_SMALL;
  747. }
  748. }
  749. }
  750. return ntStatus;
  751. }
  752. NTSTATUS
  753. USBPORT_GetBusInterfaceUSBDI(
  754. PDEVICE_OBJECT FdoDeviceObject,
  755. PDEVICE_OBJECT PdoDeviceObject,
  756. PUSBD_DEVICE_HANDLE DeviceHandle,
  757. PIRP Irp
  758. )
  759. /*++
  760. Routine Description:
  761. Arguments:
  762. Return Value:
  763. NT status code.
  764. --*/
  765. {
  766. PIO_STACK_LOCATION irpStack;
  767. NTSTATUS ntStatus;
  768. USHORT requestedSize, requestedVersion;
  769. PVOID usbBusContext;
  770. PDEVICE_EXTENSION rhDevExt;
  771. PAGED_CODE();
  772. GET_DEVICE_EXT(rhDevExt, PdoDeviceObject);
  773. ASSERT_PDOEXT(rhDevExt);
  774. if (DeviceHandle == NULL) {
  775. DeviceHandle = &rhDevExt->Pdo.RootHubDeviceHandle;
  776. }
  777. LOGENTRY(NULL, FdoDeviceObject, LOG_MISC, 'gbi1', FdoDeviceObject,
  778. DeviceHandle, 0);
  779. ASSERT_DEVICE_HANDLE(DeviceHandle);
  780. irpStack = IoGetCurrentIrpStackLocation(Irp);
  781. requestedSize = irpStack->Parameters.QueryInterface.Size;
  782. requestedVersion = irpStack->Parameters.QueryInterface.Version;
  783. // assume success
  784. ntStatus = STATUS_SUCCESS;
  785. if (requestedVersion >= USB_BUSIF_USBDI_VERSION_0) {
  786. PUSB_BUS_INTERFACE_USBDI_V0 busInterface0;
  787. busInterface0 = (PUSB_BUS_INTERFACE_USBDI_V0)
  788. irpStack->Parameters.QueryInterface.Interface;
  789. usbBusContext = PdoDeviceObject;
  790. // if the device handle is for a device attched to a TT
  791. // the the bus context is a TT not the root hub Pdo
  792. if (DeviceHandle->Tt != NULL) {
  793. usbBusContext = DeviceHandle->Tt;
  794. }
  795. busInterface0->BusContext = usbBusContext;
  796. busInterface0->InterfaceReference =
  797. USBPORT_BusInterfaceReference;
  798. busInterface0->InterfaceDereference =
  799. USBPORT_BusInterfaceDereference;
  800. busInterface0->GetUSBDIVersion =
  801. USBPORT_BusGetUSBDIVersion;
  802. busInterface0->QueryBusTime =
  803. USBPORT_BusQueryBusTime;
  804. busInterface0->QueryBusInformation =
  805. USBPORT_BusQueryBusInformation;
  806. busInterface0->Size = sizeof(USB_BUS_INTERFACE_USBDI_V0);
  807. busInterface0->Version = USB_BUSIF_USBDI_VERSION_0;
  808. }
  809. if (requestedVersion >= USB_BUSIF_USBDI_VERSION_1) {
  810. PUSB_BUS_INTERFACE_USBDI_V1 busInterface1;
  811. busInterface1 = (PUSB_BUS_INTERFACE_USBDI_V1)
  812. irpStack->Parameters.QueryInterface.Interface;
  813. // add version 1 extensions
  814. busInterface1->IsDeviceHighSpeed =
  815. USBPORT_IsDeviceHighSpeed;
  816. busInterface1->Size = sizeof(USB_BUS_INTERFACE_USBDI_V1);
  817. busInterface1->Version = USB_BUSIF_USBDI_VERSION_1;
  818. }
  819. if (requestedVersion >= USB_BUSIF_USBDI_VERSION_2) {
  820. PUSB_BUS_INTERFACE_USBDI_V2 busInterface2;
  821. busInterface2 = (PUSB_BUS_INTERFACE_USBDI_V2)
  822. irpStack->Parameters.QueryInterface.Interface;
  823. // add version 2 extensions
  824. busInterface2->EnumLogEntry =
  825. USBPORT_BusEnumLogEntry;
  826. busInterface2->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
  827. busInterface2->Version = USB_BUSIF_USBDI_VERSION_2;
  828. }
  829. return ntStatus;
  830. }
  831. VOID
  832. USBPORT_BusGetUSBDIVersion(
  833. PVOID BusContext,
  834. PUSBD_VERSION_INFORMATION VersionInformation,
  835. PULONG HcdCapabilities
  836. )
  837. /*++
  838. Routine Description:
  839. returns the current USB frame
  840. Arguments:
  841. Return Value:
  842. NT status code.
  843. --*/
  844. {
  845. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  846. PDEVICE_OBJECT fdoDeviceObject;
  847. PDEVICE_EXTENSION devExt, rhDevExt;
  848. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  849. ASSERT_PDOEXT(rhDevExt);
  850. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  851. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  852. ASSERT_FDOEXT(devExt);
  853. USBPORT_ASSERT(HcdCapabilities != NULL);
  854. *HcdCapabilities = 0;
  855. if (VersionInformation != NULL) {
  856. VersionInformation->USBDI_Version = USBDI_VERSION;
  857. if (USBPORT_IS_USB20(devExt)) {
  858. VersionInformation->Supported_USB_Version = 0x0200;
  859. } else {
  860. VersionInformation->Supported_USB_Version = 0x0110;
  861. }
  862. }
  863. // if (deviceExtensionUsbd->HcdSubmitIsoUrb != NULL) {
  864. // *HcdCapabilities = USB_HCD_CAPS_SUPPORTS_RT_THREADS;
  865. // }
  866. }
  867. NTSTATUS
  868. USBPORT_BusQueryBusTime(
  869. PVOID BusContext,
  870. PULONG CurrentFrame
  871. )
  872. /*++
  873. Routine Description:
  874. returns the current USB frame
  875. Arguments:
  876. Return Value:
  877. NT status code.
  878. --*/
  879. {
  880. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  881. PDEVICE_OBJECT fdoDeviceObject;
  882. PDEVICE_EXTENSION devExt, rhDevExt;
  883. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  884. ASSERT_PDOEXT(rhDevExt);
  885. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  886. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  887. ASSERT_FDOEXT(devExt);
  888. USBPORT_ASSERT(CurrentFrame != NULL);
  889. MP_Get32BitFrameNumber(devExt, *CurrentFrame);
  890. LOGENTRY(NULL, fdoDeviceObject, LOG_MISC, 'biCF', 0,
  891. CurrentFrame, *CurrentFrame);
  892. return STATUS_SUCCESS;
  893. }
  894. NTSTATUS
  895. USBPORT_BusEnumLogEntry(
  896. PVOID BusContext,
  897. ULONG DriverTag,
  898. ULONG EnumTag,
  899. ULONG P1,
  900. ULONG P2
  901. )
  902. /*++
  903. Routine Description:
  904. returns the current USB frame
  905. Arguments:
  906. Return Value:
  907. NT status code.
  908. --*/
  909. {
  910. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  911. PDEVICE_OBJECT fdoDeviceObject;
  912. PDEVICE_EXTENSION devExt, rhDevExt;
  913. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  914. ASSERT_PDOEXT(rhDevExt);
  915. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  916. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  917. ASSERT_FDOEXT(devExt);
  918. USBPORT_EnumLogEntry(fdoDeviceObject,
  919. DriverTag,
  920. EnumTag,
  921. P1,
  922. P2);
  923. return STATUS_SUCCESS;
  924. }
  925. NTSTATUS
  926. USBPORT_BusSubmitIsoOutUrb(
  927. PVOID BusContext,
  928. PURB Urb
  929. )
  930. /*++
  931. Routine Description:
  932. Arguments:
  933. Return Value:
  934. NT status code.
  935. --*/
  936. {
  937. TEST_TRAP();
  938. return STATUS_NOT_SUPPORTED;
  939. }
  940. NTSTATUS
  941. USBPORTBUSIF_GetControllerInformation(
  942. PVOID BusContext,
  943. PVOID ControllerInformationBuffer,
  944. ULONG ControllerInformationBufferLength,
  945. PULONG LengthOfDataCopied
  946. )
  947. /*++
  948. Routine Description:
  949. Arguments:
  950. Return Value:
  951. NT status code.
  952. --*/
  953. {
  954. ULONG len;
  955. PUSB_CONTROLLER_INFORMATION_0 level_0 = ControllerInformationBuffer;
  956. PUSB_LEVEL_INFORMATION levelInfo = ControllerInformationBuffer;
  957. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  958. PDEVICE_OBJECT fdoDeviceObject;
  959. PDEVICE_EXTENSION devExt, rhDevExt;
  960. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  961. ASSERT_PDOEXT(rhDevExt);
  962. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  963. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  964. ASSERT_FDOEXT(devExt);
  965. PAGED_CODE();
  966. *LengthOfDataCopied = 0;
  967. if (ControllerInformationBufferLength < sizeof(*levelInfo)) {
  968. return STATUS_BUFFER_TOO_SMALL;
  969. }
  970. *LengthOfDataCopied = sizeof(*levelInfo);
  971. switch (levelInfo->InformationLevel) {
  972. // level 0
  973. case 0:
  974. len = sizeof(*level_0);
  975. level_0->ActualLength = len;
  976. if (ControllerInformationBufferLength >= len) {
  977. *LengthOfDataCopied = len;
  978. level_0->SelectiveSuspendEnabled =
  979. TEST_FDO_FLAG(devExt, USBPORT_FDOFLAG_RH_CAN_SUSPEND) ?
  980. TRUE : FALSE;
  981. }
  982. *LengthOfDataCopied = sizeof(*level_0);
  983. return STATUS_SUCCESS;
  984. default:
  985. return STATUS_NOT_SUPPORTED;
  986. }
  987. return STATUS_NOT_SUPPORTED;
  988. }
  989. NTSTATUS
  990. USBPORTBUSIF_ControllerSelectiveSuspend(
  991. PVOID BusContext,
  992. BOOLEAN Enable
  993. )
  994. /*++
  995. Routine Description:
  996. Arguments:
  997. Return Value:
  998. NT status code.
  999. --*/
  1000. {
  1001. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  1002. PDEVICE_OBJECT fdoDeviceObject;
  1003. PDEVICE_EXTENSION devExt, rhDevExt;
  1004. NTSTATUS ntStatus;
  1005. ULONG disableSelectiveSuspend, keyLen;
  1006. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  1007. ASSERT_PDOEXT(rhDevExt);
  1008. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  1009. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  1010. ASSERT_FDOEXT(devExt);
  1011. PAGED_CODE();
  1012. if (TEST_FDO_FLAG(devExt, USBPORT_FDOFLAG_DISABLE_SS)) {
  1013. // if SS diabled by hardware then we will not allow UI
  1014. // to enable it
  1015. return STATUS_SUCCESS;
  1016. }
  1017. if (Enable) {
  1018. SET_FDO_FLAG(devExt, USBPORT_FDOFLAG_RH_CAN_SUSPEND);
  1019. disableSelectiveSuspend = 0;
  1020. } else {
  1021. CLEAR_FDO_FLAG(devExt, USBPORT_FDOFLAG_RH_CAN_SUSPEND);
  1022. disableSelectiveSuspend = 1;
  1023. }
  1024. keyLen = sizeof(DISABLE_SS_KEY);
  1025. ntStatus = USBPORT_SetRegistryKeyValueForPdo(
  1026. devExt->Fdo.PhysicalDeviceObject,
  1027. USBPORT_SW_BRANCH,
  1028. REG_DWORD,
  1029. DISABLE_SS_KEY,
  1030. keyLen,
  1031. &disableSelectiveSuspend,
  1032. sizeof(disableSelectiveSuspend));
  1033. if (NT_SUCCESS(ntStatus)) {
  1034. if (Enable) {
  1035. SET_FDO_FLAG(devExt, USBPORT_FDOFLAG_RH_CAN_SUSPEND);
  1036. } else {
  1037. CLEAR_FDO_FLAG(devExt, USBPORT_FDOFLAG_RH_CAN_SUSPEND);
  1038. }
  1039. }
  1040. return ntStatus;
  1041. }
  1042. NTSTATUS
  1043. USBPORTBUSIF_GetExtendedHubInformation(
  1044. PVOID BusContext,
  1045. PDEVICE_OBJECT HubPhysicalDeviceObject,
  1046. PVOID HubInformationBuffer,
  1047. ULONG HubInformationBufferLength,
  1048. PULONG LengthOfDataCopied
  1049. )
  1050. /*++
  1051. Routine Description:
  1052. Arguments:
  1053. Return Value:
  1054. NT status code.
  1055. --*/
  1056. {
  1057. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  1058. PDEVICE_OBJECT fdoDeviceObject;
  1059. PDEVICE_EXTENSION devExt, rhDevExt;
  1060. NTSTATUS ntStatus;
  1061. ULONG i;
  1062. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  1063. ASSERT_PDOEXT(rhDevExt);
  1064. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  1065. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  1066. ASSERT_FDOEXT(devExt);
  1067. // is this the root hub PDO, if so we'll report values from the
  1068. // registry
  1069. if (HubPhysicalDeviceObject == pdoDeviceObject) {
  1070. // root hub PDO
  1071. if (HubInformationBufferLength < sizeof(USB_EXTHUB_INFORMATION_0)) {
  1072. ntStatus = STATUS_BUFFER_TOO_SMALL;
  1073. *LengthOfDataCopied = 0;
  1074. } else {
  1075. PUSB_EXTHUB_INFORMATION_0 extendedHubInfo = HubInformationBuffer;
  1076. extendedHubInfo->NumberOfPorts = NUMBER_OF_PORTS(rhDevExt);
  1077. for (i=0; i< extendedHubInfo->NumberOfPorts; i++) {
  1078. // set up the defaults
  1079. extendedHubInfo->Port[i].PhysicalPortNumber = i+1;
  1080. extendedHubInfo->Port[i].PortLabelNumber = i+1;
  1081. extendedHubInfo->Port[i].VidOverride = 0;
  1082. extendedHubInfo->Port[i].PidOverride = 0;
  1083. extendedHubInfo->Port[i].PortAttributes = 0;
  1084. if (USBPORT_IS_USB20(devExt)) {
  1085. RH_PORT_STATUS portStatus;
  1086. USB_MINIPORT_STATUS mpStatus;
  1087. extendedHubInfo->Port[i].PortAttributes |=
  1088. USB_PORTATTR_SHARED_USB2;
  1089. MPRH_GetPortStatus(devExt,
  1090. (USHORT)(i+1),
  1091. &portStatus,
  1092. mpStatus);
  1093. if (portStatus.OwnedByCC) {
  1094. extendedHubInfo->Port[i].PortAttributes |=
  1095. USB_PORTATTR_OWNED_BY_CC;
  1096. }
  1097. } else {
  1098. if (TEST_FDO_FLAG(devExt, USBPORT_FDOFLAG_IS_CC) &&
  1099. USBPORT_FindUSB2Controller(fdoDeviceObject)) {
  1100. extendedHubInfo->Port[i].PortAttributes |=
  1101. USB_PORTATTR_NO_OVERCURRENT_UI;
  1102. }
  1103. }
  1104. }
  1105. // get optional registry parameters that describe port
  1106. // attributes
  1107. for (i=0; i < extendedHubInfo->NumberOfPorts; i++) {
  1108. WCHAR key[64];
  1109. ULONG portAttr, keyLen;
  1110. RtlCopyMemory(key,
  1111. PORT_ATTRIBUTES_KEY,
  1112. sizeof(PORT_ATTRIBUTES_KEY));
  1113. key[8] = '1'+i;
  1114. keyLen = sizeof(key);
  1115. portAttr = 0;
  1116. USBPORT_GetRegistryKeyValueForPdo(devExt->HcFdoDeviceObject,
  1117. devExt->Fdo.PhysicalDeviceObject,
  1118. USBPORT_HW_BRANCH,
  1119. key,
  1120. keyLen,
  1121. &portAttr,
  1122. sizeof(portAttr));
  1123. USBPORT_KdPrint((1, " Registry PortAttribute[%d] %x \n", i+1, portAttr));
  1124. // augment with registry value
  1125. extendedHubInfo->Port[i].PortAttributes |= portAttr;
  1126. }
  1127. #if DBG
  1128. for (i=0; i < extendedHubInfo->NumberOfPorts; i++) {
  1129. USBPORT_KdPrint((1, " PortAttribute[%d] %x \n", i+1,
  1130. extendedHubInfo->Port[i].PortAttributes));
  1131. }
  1132. #endif
  1133. // execute the control method to see if ACPI knows about
  1134. // any extended attributes here
  1135. *LengthOfDataCopied = sizeof(USB_EXTHUB_INFORMATION_0);
  1136. ntStatus = STATUS_SUCCESS;
  1137. }
  1138. } else {
  1139. // not supporting extended attributes for ports other than the
  1140. // root hub at this time
  1141. // if the BIOS supports the ACPI methods we will execute the
  1142. // method here
  1143. *LengthOfDataCopied = 0;
  1144. ntStatus = STATUS_NOT_SUPPORTED;
  1145. }
  1146. return ntStatus;
  1147. }
  1148. NTSTATUS
  1149. USBPORTBUSIF_GetRootHubSymbolicName(
  1150. PVOID BusContext,
  1151. PVOID HubSymNameBuffer,
  1152. ULONG HubSymNameBufferLength,
  1153. PULONG HubSymNameActualLength
  1154. )
  1155. /*++
  1156. Routine Description:
  1157. Arguments:
  1158. Return Value:
  1159. NT status code.
  1160. --*/
  1161. {
  1162. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  1163. PDEVICE_OBJECT fdoDeviceObject;
  1164. PDEVICE_EXTENSION devExt, rhDevExt;
  1165. NTSTATUS ntStatus;
  1166. UNICODE_STRING hubNameUnicodeString;
  1167. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  1168. ASSERT_PDOEXT(rhDevExt);
  1169. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  1170. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  1171. ASSERT_FDOEXT(devExt);
  1172. USBPORT_KdPrint((1, " HubSymNameBuffer %x \n", HubSymNameBuffer));
  1173. USBPORT_KdPrint((1, " HubSymNameBufferLength x%x \n", HubSymNameBufferLength));
  1174. USBPORT_KdPrint((1, " HubSymNameActualLength x%x \n", HubSymNameBufferLength));
  1175. ntStatus = USBPORT_GetSymbolicName(fdoDeviceObject,
  1176. devExt->Fdo.RootHubPdo,
  1177. &hubNameUnicodeString);
  1178. // copy what we can
  1179. if (HubSymNameBufferLength >= hubNameUnicodeString.Length) {
  1180. RtlCopyMemory(HubSymNameBuffer,
  1181. hubNameUnicodeString.Buffer,
  1182. hubNameUnicodeString.Length);
  1183. } else {
  1184. // too small return a NULL
  1185. RtlZeroMemory(HubSymNameBuffer,
  1186. sizeof(UNICODE_NULL));
  1187. }
  1188. *HubSymNameActualLength = hubNameUnicodeString.Length;
  1189. USBPORT_KdPrint((1, " hubNameUnicodeString.Buffer %x l %d\n",
  1190. hubNameUnicodeString.Buffer,
  1191. hubNameUnicodeString.Length));
  1192. USBPORT_KdPrint((1, " HubSymNameActualLength x%x \n", *HubSymNameActualLength));
  1193. RtlFreeUnicodeString(&hubNameUnicodeString);
  1194. // note we always return status success, in order to be backward
  1195. // compaible with the original IOCTL
  1196. return ntStatus;
  1197. }
  1198. VOID
  1199. USBPORTBUSIF_FlushTransfers(
  1200. PVOID BusContext,
  1201. PVOID DeviceHandle
  1202. )
  1203. /*++
  1204. Routine Description:
  1205. Flushes any outstanding tranfers for a device handle plus the bad request
  1206. list.
  1207. if no device handle is given just all tranfers on the bad request list
  1208. are flushed.
  1209. The purpose of this function is to complete any tranfers that may be pening
  1210. by client drivers that are about to unload.
  1211. Arguments:
  1212. Return Value:
  1213. --*/
  1214. {
  1215. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  1216. PDEVICE_OBJECT fdoDeviceObject;
  1217. PDEVICE_EXTENSION devExt, rhDevExt;
  1218. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  1219. ASSERT_PDOEXT(rhDevExt);
  1220. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  1221. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  1222. ASSERT_FDOEXT(devExt);
  1223. USBPORT_BadRequestFlush(fdoDeviceObject, TRUE);
  1224. return;
  1225. }
  1226. VOID
  1227. USBPORTBUSIF_SetDeviceHandleData(
  1228. PVOID BusContext,
  1229. PVOID DeviceHandle,
  1230. PDEVICE_OBJECT UsbDevicePdo
  1231. )
  1232. /*++
  1233. Routine Description:
  1234. Assocaites a particular PDO with a device handle for use
  1235. in post mortem debugging situaltions
  1236. This routine must be called at passive level.
  1237. Arguments:
  1238. Return Value:
  1239. --*/
  1240. {
  1241. PDEVICE_OBJECT pdoDeviceObject = USBPORT_PdoFromBusContext(BusContext);
  1242. PDEVICE_OBJECT fdoDeviceObject;
  1243. PDEVICE_EXTENSION devExt, rhDevExt;
  1244. PUSBD_DEVICE_HANDLE deviceHandle = DeviceHandle;
  1245. GET_DEVICE_EXT(rhDevExt, pdoDeviceObject);
  1246. ASSERT_PDOEXT(rhDevExt);
  1247. fdoDeviceObject = rhDevExt->HcFdoDeviceObject;
  1248. GET_DEVICE_EXT(devExt, fdoDeviceObject);
  1249. ASSERT_FDOEXT(devExt);
  1250. //USBPORT_ASSERT(UsbDevicePdo != NULL);
  1251. //USBPORT_ASSERT(deviceHandle != NULL);
  1252. USBPORT_KdPrint((1, " SetDeviceHandleData (PDO) %x dh (%x)\n",
  1253. UsbDevicePdo, deviceHandle));
  1254. if (UsbDevicePdo != NULL &&
  1255. deviceHandle != NULL) {
  1256. PDEVICE_OBJECT fdo;
  1257. // get driver name from device object.
  1258. deviceHandle->DevicePdo = UsbDevicePdo;
  1259. // walk up one location for the FDO
  1260. // note: this may be verifier but we
  1261. // need to know this a well
  1262. fdo = UsbDevicePdo->AttachedDevice;
  1263. USBPORT_KdPrint((1, " SetDeviceHandleData (FDO) %x \n",
  1264. fdo));
  1265. // there may be no FDO if the client driver necer attached
  1266. if (fdo != NULL &&
  1267. fdo->DriverObject != NULL ) {
  1268. PDRIVER_OBJECT driverObject;
  1269. ULONG len, i;
  1270. PWCHAR pwch;
  1271. driverObject = fdo->DriverObject;
  1272. pwch = driverObject->DriverName.Buffer;
  1273. // driver name length is in bytes, len is char count
  1274. len = (driverObject->DriverName.Length/sizeof(WCHAR)) > USB_DRIVER_NAME_LEN ?
  1275. USB_DRIVER_NAME_LEN :
  1276. driverObject->DriverName.Length/sizeof(WCHAR);
  1277. // grab the first 8 chars of the driver name
  1278. for (i=0; i<len && pwch; i++) {
  1279. deviceHandle->DriverName[i] =
  1280. *pwch;
  1281. pwch++;
  1282. }
  1283. }
  1284. }
  1285. return;
  1286. }