2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbohci/hub_controller.cpp
5 * PURPOSE: USB OHCI device driver.
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
14 VOID
StatusChangeEndpointCallBack(
17 class CHubController
: public IHubController
,
21 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
23 STDMETHODIMP_(ULONG
) AddRef()
25 InterlockedIncrement(&m_Ref
);
28 STDMETHODIMP_(ULONG
) Release()
30 InterlockedDecrement(&m_Ref
);
40 // IHubController interface functions
41 virtual NTSTATUS
Initialize(IN PDRIVER_OBJECT DriverObject
, IN PHCDCONTROLLER Controller
, IN PUSBHARDWAREDEVICE Device
, IN BOOLEAN IsRootHubDevice
, IN ULONG DeviceAddress
);
42 virtual NTSTATUS
GetHubControllerDeviceObject(PDEVICE_OBJECT
* HubDeviceObject
);
43 virtual NTSTATUS
GetHubControllerSymbolicLink(ULONG BufferLength
, PVOID Buffer
, PULONG RequiredLength
);
45 // IDispatchIrp interface functions
46 virtual NTSTATUS
HandlePnp(IN PDEVICE_OBJECT DeviceObject
, IN OUT PIRP Irp
);
47 virtual NTSTATUS
HandlePower(IN PDEVICE_OBJECT DeviceObject
, IN OUT PIRP Irp
);
48 virtual NTSTATUS
HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject
, IN OUT PIRP Irp
);
51 NTSTATUS
HandleQueryInterface(PIO_STACK_LOCATION IoStack
);
52 NTSTATUS
SetDeviceInterface(BOOLEAN bEnable
);
53 NTSTATUS
CreatePDO(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT
* OutDeviceObject
);
54 PUSBHARDWAREDEVICE
GetUsbHardware();
55 ULONG
AcquireDeviceAddress();
56 VOID
ReleaseDeviceAddress(ULONG DeviceAddress
);
57 BOOLEAN
ValidateUsbDevice(PUSBDEVICE UsbDevice
);
58 NTSTATUS
AddUsbDevice(PUSBDEVICE UsbDevice
);
59 NTSTATUS
RemoveUsbDevice(PUSBDEVICE UsbDevice
);
60 VOID
SetNotification(PVOID CallbackContext
, PRH_INIT_CALLBACK CallbackRoutine
);
61 // internal ioctl routines
62 NTSTATUS
HandleGetDescriptor(IN OUT PIRP Irp
, PURB Urb
);
63 NTSTATUS
HandleGetDescriptorFromInterface(IN OUT PIRP Irp
, PURB Urb
);
64 NTSTATUS
HandleClassDevice(IN OUT PIRP Irp
, PURB Urb
);
65 NTSTATUS
HandleGetStatusFromDevice(IN OUT PIRP Irp
, PURB Urb
);
66 NTSTATUS
HandleSelectConfiguration(IN OUT PIRP Irp
, PURB Urb
);
67 NTSTATUS
HandleSelectInterface(IN OUT PIRP Irp
, PURB Urb
);
68 NTSTATUS
HandleClassOther(IN OUT PIRP Irp
, PURB Urb
);
69 NTSTATUS
HandleClassInterface(IN OUT PIRP Irp
, PURB Urb
);
70 NTSTATUS
HandleClassEndpoint(IN OUT PIRP Irp
, PURB Urb
);
71 NTSTATUS
HandleBulkOrInterruptTransfer(IN OUT PIRP Irp
, PURB Urb
);
72 NTSTATUS
HandleIsochronousTransfer(IN OUT PIRP Irp
, PURB Urb
);
74 friend VOID
StatusChangeEndpointCallBack(PVOID Context
);
76 // constructor / destructor
77 CHubController(IUnknown
*OuterUnknown
){}
78 virtual ~CHubController(){}
82 PHCDCONTROLLER m_Controller
;
83 PUSBHARDWAREDEVICE m_Hardware
;
84 BOOLEAN m_IsRootHubDevice
;
85 ULONG m_DeviceAddress
;
87 BOOLEAN m_InterfaceEnabled
;
88 UNICODE_STRING m_HubDeviceInterfaceString
;
90 PDEVICE_OBJECT m_HubControllerDeviceObject
;
91 PDRIVER_OBJECT m_DriverObject
;
93 PVOID m_HubCallbackContext
;
94 PRH_INIT_CALLBACK m_HubCallbackRoutine
;
96 USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
;
99 RTL_BITMAP m_DeviceAddressBitmap
;
100 PULONG m_DeviceAddressBitmapBuffer
;
101 LIST_ENTRY m_UsbDeviceList
;
102 PIRP m_PendingSCEIrp
;
105 BOOLEAN
QueryStatusChageEndpoint(PIRP Irp
);
112 }USBDEVICE_ENTRY
, *PUSBDEVICE_ENTRY
;
114 /* Lifted from Linux with slight changes */
115 const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR
[] =
118 USB_DEVICE_DESCRIPTOR_TYPE
, /* bDescriptorType; Device */
119 0x00, 0x20, /* bcdUSB; v1.1 */
120 USB_DEVICE_CLASS_HUB
, /* bDeviceClass; HUB_CLASSCODE */
121 0x01, /* bDeviceSubClass; */
122 0x00, /* bDeviceProtocol; [ low/full speeds only ] */
123 0x08, /* bMaxPacketSize0; 8 Bytes */
124 /* Fill Vendor and Product in when init root hub */
125 0x00, 0x00, /* idVendor; */
126 0x00, 0x00, /* idProduct; */
127 0x00, 0x00, /* bcdDevice */
128 0x00, /* iManufacturer; */
129 0x00, /* iProduct; */
130 0x00, /* iSerialNumber; */
131 0x01 /* bNumConfigurations; */
135 const USB_CONFIGURATION_DESCRIPTOR ROOTHUB2_CONFIGURATION_DESCRIPTOR
=
137 sizeof(USB_CONFIGURATION_DESCRIPTOR
),
138 USB_CONFIGURATION_DESCRIPTOR_TYPE
,
139 sizeof(USB_CONFIGURATION_DESCRIPTOR
) + sizeof(USB_INTERFACE_DESCRIPTOR
) + sizeof(USB_ENDPOINT_DESCRIPTOR
),
143 0x40, /* self powered */
147 const USB_INTERFACE_DESCRIPTOR ROOTHUB2_INTERFACE_DESCRIPTOR
=
149 sizeof(USB_INTERFACE_DESCRIPTOR
), /* bLength */
150 USB_INTERFACE_DESCRIPTOR_TYPE
, /* bDescriptorType; Interface */
151 0, /* bInterfaceNumber; */
152 0, /* bAlternateSetting; */
153 0x1, /* bNumEndpoints; */
154 0x09, /* bInterfaceClass; HUB_CLASSCODE */
155 0x01, /* bInterfaceSubClass; */
156 0x00, /* bInterfaceProtocol: */
157 0x00, /* iInterface; */
160 const USB_ENDPOINT_DESCRIPTOR ROOTHUB2_ENDPOINT_DESCRIPTOR
=
162 sizeof(USB_ENDPOINT_DESCRIPTOR
), /* bLength */
163 USB_ENDPOINT_DESCRIPTOR_TYPE
, /* bDescriptorType */
164 0x81, /* bEndPointAddress */
165 USB_ENDPOINT_TYPE_INTERRUPT
, /* bmAttributes */
166 0x01, /* wMaxPacketSize */
170 //----------------------------------------------------------------------------------------
173 CHubController::QueryInterface(
177 return STATUS_UNSUCCESSFUL
;
179 //----------------------------------------------------------------------------------------
181 CHubController::Initialize(
182 IN PDRIVER_OBJECT DriverObject
,
183 IN PHCDCONTROLLER Controller
,
184 IN PUSBHARDWAREDEVICE Device
,
185 IN BOOLEAN IsRootHubDevice
,
186 IN ULONG DeviceAddress
)
189 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
190 USHORT VendorID
, DeviceID
;
193 DPRINT1("CHubController::Initialize\n");
196 // initialize members
198 m_Controller
= Controller
;
200 m_IsRootHubDevice
= IsRootHubDevice
;
201 m_DeviceAddress
= DeviceAddress
;
202 m_DriverObject
= DriverObject
;
203 KeInitializeSpinLock(&m_Lock
);
204 InitializeListHead(&m_UsbDeviceList
);
207 // allocate device address bitmap buffer
209 m_DeviceAddressBitmapBuffer
= (PULONG
)ExAllocatePoolWithTag(NonPagedPool
, 16, TAG_USBOHCI
);
210 if (!m_DeviceAddressBitmapBuffer
)
215 return STATUS_INSUFFICIENT_RESOURCES
;
219 // initialize device address bitmap
221 RtlInitializeBitMap(&m_DeviceAddressBitmap
, m_DeviceAddressBitmapBuffer
, 128);
222 RtlClearAllBits(&m_DeviceAddressBitmap
);
228 Status
= CreatePDO(m_DriverObject
, &m_HubControllerDeviceObject
);
229 if (!NT_SUCCESS(Status
))
232 // failed to create hub device object
238 // get device extension
240 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)m_HubControllerDeviceObject
->DeviceExtension
;
243 // initialize device extension
245 DeviceExtension
->IsFDO
= FALSE
;
246 DeviceExtension
->IsHub
= TRUE
; //FIXME
247 DeviceExtension
->Dispatcher
= PDISPATCHIRP(this);
250 // intialize device descriptor
252 C_ASSERT(sizeof(USB_DEVICE_DESCRIPTOR
) == sizeof(ROOTHUB2_DEVICE_DESCRIPTOR
));
253 RtlMoveMemory(&m_DeviceDescriptor
, ROOTHUB2_DEVICE_DESCRIPTOR
, sizeof(USB_DEVICE_DESCRIPTOR
));
255 if (NT_SUCCESS(m_Hardware
->GetDeviceDetails(&VendorID
, &DeviceID
, &Dummy1
, &Dummy1
)))
258 // update device descriptor
260 m_DeviceDescriptor
.idVendor
= VendorID
;
261 m_DeviceDescriptor
.idProduct
= DeviceID
;
262 m_DeviceDescriptor
.bcdUSB
= 0x110; //FIXME
266 // Set the SCE Callback that the Hardware Device will call on port status change
268 Device
->SetStatusChangeEndpointCallBack((PVOID
)StatusChangeEndpointCallBack
, this);
273 m_HubControllerDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
275 return STATUS_SUCCESS
;
279 // Queries the ports to see if there has been a device connected or removed.
282 CHubController::QueryStatusChageEndpoint(
285 ULONG PortCount
, PortId
;
286 PIO_STACK_LOCATION IoStack
;
287 USHORT PortStatus
, PortChange
;
289 PUCHAR TransferBuffer
;
290 UCHAR Changed
= FALSE
;
293 // get current stack location
295 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
301 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
305 // Get the number of ports and check each one for device connected
307 m_Hardware
->GetDeviceDetails(NULL
, NULL
, &PortCount
, NULL
);
308 DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
, Urb
->UrbBulkOrInterruptTransfer
.TransferBufferLength
, Urb
->UrbBulkOrInterruptTransfer
.TransferFlags
, Urb
->UrbBulkOrInterruptTransfer
.TransferBufferMDL
);
310 TransferBuffer
= (PUCHAR
)Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
;
315 for (PortId
= 0; PortId
< PortCount
; PortId
++)
317 m_Hardware
->GetPortStatus(PortId
, &PortStatus
, &PortChange
);
319 DPRINT1("Port %d: Status %x, Change %x\n", PortId
, PortStatus
, PortChange
);
323 // If theres a flag in PortChange return TRUE so the SCE Irp will be completed
327 DPRINT1("Change state on port %d\n", PortId
);
328 // Set the value for the port number
329 *TransferBuffer
= 1 << ((PortId
+ 1) & 7);
337 //-----------------------------------------------------------------------------------------
339 CHubController::GetHubControllerDeviceObject(PDEVICE_OBJECT
* HubDeviceObject
)
342 // store controller object
344 *HubDeviceObject
= m_HubControllerDeviceObject
;
346 return STATUS_SUCCESS
;
348 //-----------------------------------------------------------------------------------------
350 CHubController::GetHubControllerSymbolicLink(
353 PULONG RequiredLength
)
355 if (!m_InterfaceEnabled
)
358 // device interface not yet enabled
360 return STATUS_UNSUCCESSFUL
;
363 if (BufferLength
< (ULONG
)m_HubDeviceInterfaceString
.Length
- 8)
367 // length is without '\??\'
369 *RequiredLength
= m_HubDeviceInterfaceString
.Length
- 8;
374 return STATUS_BUFFER_OVERFLOW
;
378 // copy symbolic link
380 RtlCopyMemory(Buffer
, &m_HubDeviceInterfaceString
.Buffer
[4], m_HubDeviceInterfaceString
.Length
- 8);
383 // store length, length is without '\??\'
385 *RequiredLength
= m_HubDeviceInterfaceString
.Length
- 8;
390 return STATUS_SUCCESS
;
393 //-----------------------------------------------------------------------------------------
395 CHubController::HandlePnp(
396 IN PDEVICE_OBJECT DeviceObject
,
399 PIO_STACK_LOCATION IoStack
;
400 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
401 PDEVICE_CAPABILITIES DeviceCapabilities
;
402 PPNP_BUS_INFORMATION BusInformation
;
403 PDEVICE_RELATIONS DeviceRelations
;
405 ULONG Index
= 0, Length
;
406 USHORT VendorID
, DeviceID
;
407 ULONG HiSpeed
, NumPorts
;
412 // get device extension
414 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
419 ASSERT(DeviceExtension
->IsFDO
== FALSE
);
422 // get current stack location
424 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
426 switch(IoStack
->MinorFunction
)
428 case IRP_MN_START_DEVICE
:
430 DPRINT1("CHubController::HandlePnp IRP_MN_START_DEVICE\n");
432 // register device interface
434 Status
= SetDeviceInterface(TRUE
);
437 case IRP_MN_QUERY_ID
:
439 DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack
->Parameters
.QueryId
.IdType
);
441 if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryDeviceID
)
448 Status
= m_Hardware
->GetDeviceDetails(&VendorID
, &DeviceID
, &NumPorts
, &HiSpeed
);
450 if (HiSpeed
== 0x200)
455 swprintf(Buffer
, L
"USB\\ROOT_HUB20");
462 swprintf(Buffer
, L
"USB\\ROOT_HUB");
465 DPRINT1("Name %S\n", Buffer
);
470 Length
= (wcslen(Buffer
) + 1);
475 DeviceName
= (LPWSTR
)ExAllocatePoolWithTag(PagedPool
, Length
* sizeof(WCHAR
), TAG_USBOHCI
);
482 Status
= STATUS_INSUFFICIENT_RESOURCES
;
489 wcscpy(DeviceName
, Buffer
);
494 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceName
;
495 Status
= STATUS_SUCCESS
;
498 Status
= STATUS_UNSUCCESSFUL
;
503 if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryHardwareIDs
)
510 Status
= m_Hardware
->GetDeviceDetails(&VendorID
, &DeviceID
, &NumPorts
, &HiSpeed
);
512 if (!NT_SUCCESS(Status
))
514 DPRINT1("CHubController::HandlePnp> failed to get hardware id %x\n", Status
);
519 if (HiSpeed
== 0x200)
524 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB20&VID%04x&PID%04x&REV0000", VendorID
, DeviceID
) + 1;
525 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB20&VID%04x&PID%04x", VendorID
, DeviceID
) + 1;
526 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB20") + 1;
533 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB&VID%04x&PID%04x&REV0000", VendorID
, DeviceID
) + 1;
534 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB&VID%04x&PID%04x", VendorID
, DeviceID
) + 1;
535 Index
+= swprintf(&Buffer
[Index
], L
"USB\\ROOT_HUB") + 1;
538 Buffer
[Index
] = UNICODE_NULL
;
542 DPRINT1("Name %S\n", Buffer
);
547 DeviceName
= (LPWSTR
)ExAllocatePoolWithTag(PagedPool
, Index
* sizeof(WCHAR
), TAG_USBOHCI
);
554 Status
= STATUS_INSUFFICIENT_RESOURCES
;
561 RtlMoveMemory(DeviceName
, Buffer
, Index
* sizeof(WCHAR
));
566 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceName
;
567 Status
= STATUS_SUCCESS
;
571 Status
= STATUS_SUCCESS
;
574 case IRP_MN_QUERY_CAPABILITIES
:
576 DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_CAPABILITIES\n");
578 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)IoStack
->Parameters
.DeviceCapabilities
.Capabilities
;
580 DeviceCapabilities
->LockSupported
= FALSE
;
581 DeviceCapabilities
->EjectSupported
= FALSE
;
582 DeviceCapabilities
->Removable
= FALSE
;
583 DeviceCapabilities
->DockDevice
= FALSE
;
584 DeviceCapabilities
->UniqueID
= FALSE
;
585 DeviceCapabilities
->SilentInstall
= FALSE
;
586 DeviceCapabilities
->RawDeviceOK
= FALSE
;
587 DeviceCapabilities
->SurpriseRemovalOK
= FALSE
;
588 DeviceCapabilities
->Address
= 0;
589 DeviceCapabilities
->UINumber
= 0;
590 DeviceCapabilities
->DeviceD2
= 1;
593 DeviceCapabilities
->HardwareDisabled
= FALSE
;
594 DeviceCapabilities
->NoDisplayInUI
= FALSE
;
595 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
;
596 for (Index
= 1; Index
< PowerSystemMaximum
; Index
++)
597 DeviceCapabilities
->DeviceState
[Index
] = PowerDeviceD3
;
598 DeviceCapabilities
->DeviceWake
= PowerDeviceUnspecified
;
599 DeviceCapabilities
->D1Latency
= 0;
600 DeviceCapabilities
->D2Latency
= 0;
601 DeviceCapabilities
->D3Latency
= 0;
603 Status
= STATUS_SUCCESS
;
606 case IRP_MN_QUERY_INTERFACE
:
608 DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_INTERFACE\n");
611 // handle device interface requests
613 Status
= HandleQueryInterface(IoStack
);
616 case IRP_MN_REMOVE_DEVICE
:
618 DPRINT1("CHubController::HandlePnp IRP_MN_REMOVE_DEVICE\n");
621 // deactivate device interface for BUS PDO
623 SetDeviceInterface(FALSE
);
626 // complete the request first
628 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
629 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
634 IoDeleteDevice(m_HubControllerDeviceObject
);
639 m_HubControllerDeviceObject
= 0;
644 return STATUS_SUCCESS
;
646 case IRP_MN_QUERY_DEVICE_RELATIONS
:
648 DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %x\n", IoStack
->Parameters
.QueryDeviceRelations
.Type
);
650 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
== TargetDeviceRelation
)
653 // allocate device relations
655 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePoolWithTag(PagedPool
, sizeof(DEVICE_RELATIONS
), TAG_USBOHCI
);
656 if (!DeviceRelations
)
661 Status
= STATUS_INSUFFICIENT_RESOURCES
;
666 // initialize device relations
668 DeviceRelations
->Count
= 1;
669 DeviceRelations
->Objects
[0] = DeviceObject
;
670 ObReferenceObject(DeviceObject
);
675 Status
= STATUS_SUCCESS
;
676 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
683 Status
= Irp
->IoStatus
.Status
;
687 case IRP_MN_QUERY_BUS_INFORMATION
:
689 DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n");
692 // allocate buffer for bus information
694 BusInformation
= (PPNP_BUS_INFORMATION
)ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
700 RtlMoveMemory(&BusInformation
->BusTypeGuid
, &GUID_BUS_TYPE_USB
, sizeof(GUID
));
705 BusInformation
->LegacyBusType
= PNPBus
;
706 BusInformation
->BusNumber
= 0;
708 Status
= STATUS_SUCCESS
;
709 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
716 Status
= STATUS_INSUFFICIENT_RESOURCES
;
720 case IRP_MN_STOP_DEVICE
:
722 DPRINT1("CHubController::HandlePnp IRP_MN_STOP_DEVICE\n");
726 Status
= STATUS_SUCCESS
;
732 // ignore request with default status
734 Status
= Irp
->IoStatus
.Status
;
742 Irp
->IoStatus
.Status
= Status
;
743 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
751 //-----------------------------------------------------------------------------------------
753 CHubController::HandlePower(
754 IN PDEVICE_OBJECT DeviceObject
,
758 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
759 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
760 return STATUS_NOT_IMPLEMENTED
;
763 //-----------------------------------------------------------------------------------------
765 CHubController::HandleIsochronousTransfer(
769 PUSBDEVICE UsbDevice
;
770 PUSB_ENDPOINT_DESCRIPTOR EndPointDesc
= NULL
;
773 // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
775 EndPointDesc
= (PUSB_ENDPOINT_DESCRIPTOR
)Urb
->UrbIsochronousTransfer
.PipeHandle
;
779 DPRINT1("No EndpointDesc\n");
780 Urb
->UrbIsochronousTransfer
.Hdr
.Status
= USBD_STATUS_INVALID_PIPE_HANDLE
;
781 return STATUS_INVALID_PARAMETER
;
787 ASSERT(EndPointDesc
);
788 ASSERT((EndPointDesc
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
) == USB_ENDPOINT_TYPE_ISOCHRONOUS
);
791 // check if this is a valid usb device handle
793 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
795 DPRINT1("HandleIsochronousTransfer invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
798 // invalid device handle
800 return STATUS_DEVICE_NOT_CONNECTED
;
806 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
808 return UsbDevice
->SubmitIrp(Irp
);
811 //-----------------------------------------------------------------------------------------
813 CHubController::HandleBulkOrInterruptTransfer(
817 PUSBDEVICE UsbDevice
;
818 PUSB_ENDPOINT_DESCRIPTOR EndPointDesc
= NULL
;
820 // First check if the request is for the Status Change Endpoint
824 // Is the Request for the root hub
826 if (Urb
->UrbHeader
.UsbdDeviceHandle
== 0)
828 ASSERT(m_PendingSCEIrp
== NULL
);
829 if (QueryStatusChageEndpoint(Irp
))
831 StatusChangeEndpointCallBack(this);
832 return STATUS_SUCCESS
;
836 // Else pend the IRP, to be completed when a device connects or disconnects.
838 DPRINT1("Pending SCE Irp\n");;
839 m_PendingSCEIrp
= Irp
;
840 IoMarkIrpPending(Irp
);
841 return STATUS_PENDING
;
845 // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
847 EndPointDesc
= (PUSB_ENDPOINT_DESCRIPTOR
)Urb
->UrbBulkOrInterruptTransfer
.PipeHandle
;
852 ASSERT(EndPointDesc
);
853 ASSERT((EndPointDesc
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
) == USB_ENDPOINT_TYPE_BULK
|| (EndPointDesc
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
) == USB_ENDPOINT_TYPE_INTERRUPT
);
856 // check if this is a valid usb device handle
858 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
860 DPRINT1("HandleBuldOrInterruptTransfer invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
863 // invalid device handle
865 return STATUS_DEVICE_NOT_CONNECTED
;
871 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
873 return UsbDevice
->SubmitIrp(Irp
);
876 //-----------------------------------------------------------------------------------------
878 CHubController::HandleClassOther(
882 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
883 USHORT PortStatus
= 0, PortChange
= 0;
888 DPRINT("CHubController::HandleClassOther> Request %x Value %x\n", Urb
->UrbControlVendorClassRequest
.Request
, Urb
->UrbControlVendorClassRequest
.Value
);
891 // get number of ports available
893 Status
= m_Hardware
->GetDeviceDetails(NULL
, NULL
, &NumPort
, NULL
);
894 PC_ASSERT(Status
== STATUS_SUCCESS
);
899 PC_ASSERT(Urb
->UrbControlVendorClassRequest
.Index
- 1 < (USHORT
)NumPort
);
902 // port range reported start from 1 -n
903 // convert back port id so it matches the hardware
905 PortId
= Urb
->UrbControlVendorClassRequest
.Index
- 1;
908 // check request code
910 switch(Urb
->UrbControlVendorClassRequest
.Request
)
912 case USB_REQUEST_GET_STATUS
:
917 PC_ASSERT(Urb
->UrbControlVendorClassRequest
.TransferBufferLength
== sizeof(USHORT
) * 2);
918 PC_ASSERT(Urb
->UrbControlVendorClassRequest
.TransferBuffer
);
923 Status
= m_Hardware
->GetPortStatus(PortId
, &PortStatus
, &PortChange
);
925 if (NT_SUCCESS(Status
))
928 // request contains buffer of 2 ushort which are used from submitting port status and port change status
930 DPRINT("PortId %x PortStatus %x PortChange %x\n", PortId
, PortStatus
, PortChange
);
931 Buffer
= (PUSHORT
)Urb
->UrbControlVendorClassRequest
.TransferBuffer
;
934 // store status, then port change
936 *Buffer
= PortStatus
;
938 *Buffer
= PortChange
;
946 case USB_REQUEST_CLEAR_FEATURE
:
948 switch (Urb
->UrbControlVendorClassRequest
.Value
)
950 case C_PORT_CONNECTION
:
951 Status
= m_Hardware
->ClearPortStatus(PortId
, C_PORT_CONNECTION
);
954 Status
= m_Hardware
->ClearPortStatus(PortId
, C_PORT_RESET
);
957 DPRINT("Unknown Value for Clear Feature %x \n", Urb
->UrbControlVendorClassRequest
.Value
);
961 Status
= STATUS_SUCCESS
;
964 case USB_REQUEST_SET_FEATURE
:
967 // request set feature
969 switch(Urb
->UrbControlVendorClassRequest
.Value
)
976 Status
= m_Hardware
->SetPortFeature(PortId
, PORT_ENABLE
);
983 // set suspend port feature
985 Status
= m_Hardware
->SetPortFeature(PortId
, PORT_SUSPEND
);
991 // set power feature on port
993 Status
= m_Hardware
->SetPortFeature(PortId
, PORT_POWER
);
1000 // reset port feature
1002 Status
= m_Hardware
->SetPortFeature(PortId
, PORT_RESET
);
1003 PC_ASSERT(Status
== STATUS_SUCCESS
);
1007 DPRINT1("Unsupported request id %x\n", Urb
->UrbControlVendorClassRequest
.Value
);
1013 DPRINT1("CHubController::HandleClassOther Unknown request code %x\n", Urb
->UrbControlVendorClassRequest
.Request
);
1015 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1020 //-----------------------------------------------------------------------------------------
1022 CHubController::HandleSelectConfiguration(
1026 PUSBDEVICE UsbDevice
;
1027 PUSBD_INTERFACE_INFORMATION InterfaceInfo
;
1030 // is the request for the Root Hub
1032 if (Urb
->UrbHeader
.UsbdDeviceHandle
== NULL
)
1035 // FIXME: support setting device to unconfigured state
1037 PC_ASSERT(Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
);
1040 // set device handle
1042 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= (PVOID
)&ROOTHUB2_CONFIGURATION_DESCRIPTOR
;
1045 // copy interface info
1047 InterfaceInfo
= &Urb
->UrbSelectConfiguration
.Interface
;
1049 InterfaceInfo
->InterfaceHandle
= (USBD_INTERFACE_HANDLE
)&ROOTHUB2_INTERFACE_DESCRIPTOR
;
1050 InterfaceInfo
->Class
= ROOTHUB2_INTERFACE_DESCRIPTOR
.bInterfaceClass
;
1051 InterfaceInfo
->SubClass
= ROOTHUB2_INTERFACE_DESCRIPTOR
.bInterfaceSubClass
;
1052 InterfaceInfo
->Protocol
= ROOTHUB2_INTERFACE_DESCRIPTOR
.bInterfaceProtocol
;
1053 InterfaceInfo
->Reserved
= 0;
1058 PC_ASSERT(InterfaceInfo
->NumberOfPipes
== 1);
1063 InterfaceInfo
->Pipes
[0].MaximumPacketSize
= ROOTHUB2_ENDPOINT_DESCRIPTOR
.wMaxPacketSize
;
1064 InterfaceInfo
->Pipes
[0].EndpointAddress
= ROOTHUB2_ENDPOINT_DESCRIPTOR
.bEndpointAddress
;
1065 InterfaceInfo
->Pipes
[0].Interval
= ROOTHUB2_ENDPOINT_DESCRIPTOR
.bInterval
;
1066 InterfaceInfo
->Pipes
[0].PipeType
= (USBD_PIPE_TYPE
)(ROOTHUB2_ENDPOINT_DESCRIPTOR
.bmAttributes
& USB_ENDPOINT_TYPE_MASK
);
1067 InterfaceInfo
->Pipes
[0].PipeHandle
= (PVOID
)&ROOTHUB2_ENDPOINT_DESCRIPTOR
;
1069 return STATUS_SUCCESS
;
1074 // check if this is a valid usb device handle
1076 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1078 DPRINT1("HandleSelectConfiguration invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1081 // invalid device handle
1083 return STATUS_DEVICE_NOT_CONNECTED
;
1089 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1092 // select configuration
1094 return UsbDevice
->SelectConfiguration(Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
, &Urb
->UrbSelectConfiguration
.Interface
, &Urb
->UrbSelectConfiguration
.ConfigurationHandle
);
1098 //-----------------------------------------------------------------------------------------
1100 CHubController::HandleSelectInterface(
1104 PUSBDEVICE UsbDevice
;
1109 PC_ASSERT(Urb
->UrbSelectInterface
.ConfigurationHandle
);
1112 // is the request for the Root Hub
1114 if (Urb
->UrbHeader
.UsbdDeviceHandle
== NULL
)
1117 // no op for root hub
1119 return STATUS_SUCCESS
;
1124 // check if this is a valid usb device handle
1126 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1128 DPRINT1("HandleSelectInterface invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1131 // invalid device handle
1133 return STATUS_DEVICE_NOT_CONNECTED
;
1139 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1144 return UsbDevice
->SelectInterface(Urb
->UrbSelectInterface
.ConfigurationHandle
, &Urb
->UrbSelectInterface
.Interface
);
1148 //-----------------------------------------------------------------------------------------
1150 CHubController::HandleGetStatusFromDevice(
1154 PUSHORT DeviceStatus
;
1155 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1157 PUSBDEVICE UsbDevice
;
1162 PC_ASSERT(Urb
->UrbControlGetStatusRequest
.Index
== 0);
1163 PC_ASSERT(Urb
->UrbControlGetStatusRequest
.TransferBufferLength
>= sizeof(USHORT
));
1164 PC_ASSERT(Urb
->UrbControlGetStatusRequest
.TransferBuffer
);
1167 // get status buffer
1169 DeviceStatus
= (PUSHORT
)Urb
->UrbControlGetStatusRequest
.TransferBuffer
;
1172 if (Urb
->UrbHeader
.UsbdDeviceHandle
== NULL
)
1175 // FIXME need more flags ?
1177 *DeviceStatus
= USB_PORT_STATUS_CONNECT
;
1178 return STATUS_SUCCESS
;
1182 // check if this is a valid usb device handle
1184 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1186 DPRINT1("HandleGetStatusFromDevice invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1189 // invalid device handle
1191 return STATUS_DEVICE_NOT_CONNECTED
;
1197 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1201 // generate setup packet
1203 CtrlSetup
.bRequest
= USB_REQUEST_GET_STATUS
;
1204 CtrlSetup
.wValue
.LowByte
= 0;
1205 CtrlSetup
.wValue
.HiByte
= 0;
1206 CtrlSetup
.wIndex
.W
= Urb
->UrbControlGetStatusRequest
.Index
;
1207 CtrlSetup
.wLength
= (USHORT
)Urb
->UrbControlGetStatusRequest
.TransferBufferLength
;
1208 CtrlSetup
.bmRequestType
.B
= 0x80;
1211 // submit setup packet
1213 Status
= UsbDevice
->SubmitSetupPacket(&CtrlSetup
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
, Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1214 ASSERT(Status
== STATUS_SUCCESS
);
1215 DPRINT1("CHubController::HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", Status
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
, *DeviceStatus
);
1223 //-----------------------------------------------------------------------------------------
1225 CHubController::HandleClassDevice(
1229 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
1230 PUSB_HUB_DESCRIPTOR UsbHubDescriptor
;
1231 ULONG PortCount
, Dummy2
;
1233 PUSBDEVICE UsbDevice
;
1234 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1236 DPRINT("CHubController::HandleClassDevice Request %x Class %x\n", Urb
->UrbControlVendorClassRequest
.Request
, Urb
->UrbControlVendorClassRequest
.Value
>> 8);
1239 // check class request type
1241 switch(Urb
->UrbControlVendorClassRequest
.Request
)
1243 case USB_REQUEST_GET_STATUS
:
1246 // check if this is a valid usb device handle
1248 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1250 DPRINT1("USB_REQUEST_GET_STATUS invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1253 // invalid device handle
1255 return STATUS_DEVICE_NOT_CONNECTED
;
1261 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1265 // generate setup packet
1267 CtrlSetup
.bRequest
= USB_REQUEST_GET_STATUS
;
1268 CtrlSetup
.wValue
.LowByte
= Urb
->UrbControlVendorClassRequest
.Index
;
1269 CtrlSetup
.wValue
.W
= Urb
->UrbControlVendorClassRequest
.Value
;
1270 CtrlSetup
.wIndex
.W
= Urb
->UrbControlVendorClassRequest
.Index
;
1271 CtrlSetup
.wLength
= (USHORT
)Urb
->UrbControlGetStatusRequest
.TransferBufferLength
;
1272 CtrlSetup
.bmRequestType
.B
= 0xA0;
1275 // submit setup packet
1277 Status
= UsbDevice
->SubmitSetupPacket(&CtrlSetup
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
, Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1278 ASSERT(Status
== STATUS_SUCCESS
);
1281 case USB_REQUEST_GET_DESCRIPTOR
:
1283 switch (Urb
->UrbControlVendorClassRequest
.Value
>> 8)
1285 case USB_DEVICE_CLASS_RESERVED
: // FALL THROUGH
1286 case USB_DEVICE_CLASS_HUB
:
1291 PC_ASSERT(Urb
->UrbControlVendorClassRequest
.TransferBuffer
);
1292 PC_ASSERT(Urb
->UrbControlVendorClassRequest
.TransferBufferLength
>= sizeof(USB_HUB_DESCRIPTOR
));
1295 // get hub descriptor
1297 UsbHubDescriptor
= (PUSB_HUB_DESCRIPTOR
)Urb
->UrbControlVendorClassRequest
.TransferBuffer
;
1300 // one hub is handled
1302 UsbHubDescriptor
->bDescriptorLength
= sizeof(USB_HUB_DESCRIPTOR
);
1303 Urb
->UrbControlVendorClassRequest
.TransferBufferLength
= sizeof(USB_HUB_DESCRIPTOR
);
1306 // type should 0x29 according to msdn
1308 UsbHubDescriptor
->bDescriptorType
= 0x29;
1313 Status
= m_Hardware
->GetDeviceDetails(&Dummy1
, &Dummy1
, &PortCount
, &Dummy2
);
1314 PC_ASSERT(Status
== STATUS_SUCCESS
);
1317 // FIXME: retrieve values
1319 UsbHubDescriptor
->bNumberOfPorts
= (UCHAR
)PortCount
;
1320 UsbHubDescriptor
->wHubCharacteristics
= 0x00;
1321 UsbHubDescriptor
->bPowerOnToPowerGood
= 0x01;
1322 UsbHubDescriptor
->bHubControlCurrent
= 0x00;
1327 Status
= STATUS_SUCCESS
;
1331 DPRINT1("CHubController::HandleClassDevice Class %x not implemented\n", Urb
->UrbControlVendorClassRequest
.Value
>> 8);
1337 DPRINT1("CHubController::HandleClassDevice Type %x not implemented\n", Urb
->UrbControlVendorClassRequest
.Request
);
1343 //-----------------------------------------------------------------------------------------
1345 CHubController::HandleGetDescriptorFromInterface(
1349 PUSBDEVICE UsbDevice
;
1350 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1356 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
1357 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1360 // check if this is a valid usb device handle
1362 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1364 DPRINT1("HandleGetDescriptorFromInterface invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1367 // invalid device handle
1369 return STATUS_DEVICE_NOT_CONNECTED
;
1375 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1378 // generate setup packet
1380 CtrlSetup
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1381 CtrlSetup
.wValue
.LowByte
= Urb
->UrbControlDescriptorRequest
.Index
;
1382 CtrlSetup
.wValue
.HiByte
= Urb
->UrbControlDescriptorRequest
.DescriptorType
;
1383 CtrlSetup
.wIndex
.W
= Urb
->UrbControlDescriptorRequest
.LanguageId
;
1384 CtrlSetup
.wLength
= (USHORT
)Urb
->UrbControlDescriptorRequest
.TransferBufferLength
;
1385 CtrlSetup
.bmRequestType
.B
= 0x81;
1388 // submit setup packet
1390 Status
= UsbDevice
->SubmitSetupPacket(&CtrlSetup
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
, Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1391 ASSERT(Status
== STATUS_SUCCESS
);
1399 //-----------------------------------------------------------------------------------------
1401 CHubController::HandleGetDescriptor(
1405 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
1406 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
;
1407 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1409 PUSBDEVICE UsbDevice
;
1412 DPRINT("CHubController::HandleGetDescriptor\n");
1415 // check descriptor type
1417 switch(Urb
->UrbControlDescriptorRequest
.DescriptorType
)
1419 case USB_DEVICE_DESCRIPTOR_TYPE
:
1424 PC_ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBufferLength
>= sizeof(USB_DEVICE_DESCRIPTOR
));
1425 PC_ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1427 if (Urb
->UrbHeader
.UsbdDeviceHandle
== NULL
)
1430 // copy root hub device descriptor
1432 RtlCopyMemory((PUCHAR
)Urb
->UrbControlDescriptorRequest
.TransferBuffer
, &m_DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
1433 Status
= STATUS_SUCCESS
;
1438 // check if this is a valid usb device handle
1440 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1442 DPRINT1("HandleGetDescriptor invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1445 // invalid device handle
1447 return STATUS_DEVICE_NOT_CONNECTED
;
1453 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1456 // retrieve device descriptor from device
1458 UsbDevice
->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR
)Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1459 Status
= STATUS_SUCCESS
;
1463 case USB_CONFIGURATION_DESCRIPTOR_TYPE
:
1468 PC_ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1469 PC_ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBufferLength
>= sizeof(USB_CONFIGURATION_DESCRIPTOR
));
1471 if (Urb
->UrbHeader
.UsbdDeviceHandle
== NULL
)
1474 // request is for the root bus controller
1476 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, &ROOTHUB2_CONFIGURATION_DESCRIPTOR
, sizeof(USB_CONFIGURATION_DESCRIPTOR
));
1479 // get configuration descriptor, very retarded!
1481 ConfigurationDescriptor
= (PUSB_CONFIGURATION_DESCRIPTOR
)Urb
->UrbControlDescriptorRequest
.TransferBuffer
;
1484 // check if buffer can hold interface and endpoint descriptor
1486 if (ConfigurationDescriptor
->wTotalLength
> Urb
->UrbControlDescriptorRequest
.TransferBufferLength
)
1491 Status
= STATUS_SUCCESS
;
1497 // copy interface descriptor template
1499 Buffer
= (PUCHAR
)(ConfigurationDescriptor
+ 1);
1500 RtlCopyMemory(Buffer
, &ROOTHUB2_INTERFACE_DESCRIPTOR
, sizeof(USB_INTERFACE_DESCRIPTOR
));
1503 // copy end point descriptor template
1505 Buffer
+= sizeof(USB_INTERFACE_DESCRIPTOR
);
1506 RtlCopyMemory(Buffer
, &ROOTHUB2_ENDPOINT_DESCRIPTOR
, sizeof(USB_ENDPOINT_DESCRIPTOR
));
1511 Status
= STATUS_SUCCESS
;
1517 // check if this is a valid usb device handle
1519 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1521 DPRINT1("USB_CONFIGURATION_DESCRIPTOR_TYPE invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1524 // invalid device handle
1526 return STATUS_DEVICE_NOT_CONNECTED
;
1532 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1534 if (sizeof(USB_CONFIGURATION_DESCRIPTOR
) > Urb
->UrbControlDescriptorRequest
.TransferBufferLength
)
1539 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= UsbDevice
->GetConfigurationDescriptorsLength();
1544 Status
= STATUS_SUCCESS
;
1549 // perform work in IUSBDevice
1551 UsbDevice
->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR
)Urb
->UrbControlDescriptorRequest
.TransferBuffer
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
, &Length
);
1554 // store result size
1556 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= Length
;
1557 Status
= STATUS_SUCCESS
;
1561 case USB_STRING_DESCRIPTOR_TYPE
:
1566 PC_ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1567 PC_ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
1570 // check if this is a valid usb device handle
1572 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1574 DPRINT1("USB_STRING_DESCRIPTOR_TYPE invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1577 // invalid device handle
1579 return STATUS_DEVICE_NOT_CONNECTED
;
1585 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1588 // generate setup packet
1590 CtrlSetup
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1591 CtrlSetup
.wValue
.LowByte
= Urb
->UrbControlDescriptorRequest
.Index
;
1592 CtrlSetup
.wValue
.HiByte
= Urb
->UrbControlDescriptorRequest
.DescriptorType
;
1593 CtrlSetup
.wIndex
.W
= Urb
->UrbControlDescriptorRequest
.LanguageId
;
1594 CtrlSetup
.wLength
= (USHORT
)Urb
->UrbControlDescriptorRequest
.TransferBufferLength
;
1595 CtrlSetup
.bmRequestType
.B
= 0x80;
1598 // submit setup packet
1600 Status
= UsbDevice
->SubmitSetupPacket(&CtrlSetup
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
, Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1604 DPRINT1("CHubController::HandleGetDescriptor DescriptorType %x unimplemented\n", Urb
->UrbControlDescriptorRequest
.DescriptorType
);
1614 //-----------------------------------------------------------------------------------------
1616 CHubController::HandleClassEndpoint(
1620 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1622 PUSBDEVICE UsbDevice
;
1627 PC_ASSERT(Urb
->UrbControlVendorClassRequest
.TransferBuffer
);
1628 PC_ASSERT(Urb
->UrbControlVendorClassRequest
.TransferBufferLength
);
1629 PC_ASSERT(Urb
->UrbHeader
.UsbdDeviceHandle
);
1632 // check if this is a valid usb device handle
1634 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1636 DPRINT1("HandleClassEndpoint invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1639 // invalid device handle
1641 return STATUS_DEVICE_NOT_CONNECTED
;
1647 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1650 DPRINT1("URB_FUNCTION_CLASS_ENDPOINT\n");
1651 DPRINT1("TransferFlags %x\n", Urb
->UrbControlVendorClassRequest
.TransferFlags
);
1652 DPRINT1("TransferBufferLength %x\n", Urb
->UrbControlVendorClassRequest
.TransferBufferLength
);
1653 DPRINT1("TransferBuffer %x\n", Urb
->UrbControlVendorClassRequest
.TransferBuffer
);
1654 DPRINT1("TransferBufferMDL %x\n", Urb
->UrbControlVendorClassRequest
.TransferBufferMDL
);
1655 DPRINT1("RequestTypeReservedBits %x\n", Urb
->UrbControlVendorClassRequest
.RequestTypeReservedBits
);
1656 DPRINT1("Request %x\n", Urb
->UrbControlVendorClassRequest
.Request
);
1657 DPRINT1("Value %x\n", Urb
->UrbControlVendorClassRequest
.Value
);
1658 DPRINT1("Index %x\n", Urb
->UrbControlVendorClassRequest
.Index
);
1661 // initialize setup packet
1663 CtrlSetup
.bmRequestType
.B
= 0x22; //FIXME: Const.
1664 CtrlSetup
.bRequest
= Urb
->UrbControlVendorClassRequest
.Request
;
1665 CtrlSetup
.wValue
.W
= Urb
->UrbControlVendorClassRequest
.Value
;
1666 CtrlSetup
.wIndex
.W
= Urb
->UrbControlVendorClassRequest
.Index
;
1667 CtrlSetup
.wLength
= Urb
->UrbControlVendorClassRequest
.TransferBufferLength
;
1669 if (Urb
->UrbControlVendorClassRequest
.TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1672 // data direction is device to host
1674 CtrlSetup
.bmRequestType
.B
|= 0x80;
1681 Status
= UsbDevice
->SubmitSetupPacket(&CtrlSetup
, Urb
->UrbControlVendorClassRequest
.TransferBufferLength
, Urb
->UrbControlVendorClassRequest
.TransferBuffer
);
1684 // assert on failure
1686 PC_ASSERT(NT_SUCCESS(Status
));
1695 //-----------------------------------------------------------------------------------------
1697 CHubController::HandleClassInterface(
1701 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1703 PUSBDEVICE UsbDevice
;
1708 //ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer || Urb->UrbControlVendorClassRequest.TransferBufferMDL);
1709 //ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
1710 PC_ASSERT(Urb
->UrbHeader
.UsbdDeviceHandle
);
1713 // check if this is a valid usb device handle
1715 if (!ValidateUsbDevice(PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
)))
1717 DPRINT1("HandleClassInterface invalid device handle %p\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
1720 // invalid device handle
1722 return STATUS_DEVICE_NOT_CONNECTED
;
1728 UsbDevice
= PUSBDEVICE(Urb
->UrbHeader
.UsbdDeviceHandle
);
1731 DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n");
1732 DPRINT1("TransferFlags %x\n", Urb
->UrbControlVendorClassRequest
.TransferFlags
);
1733 DPRINT1("TransferBufferLength %x\n", Urb
->UrbControlVendorClassRequest
.TransferBufferLength
);
1734 DPRINT1("TransferBuffer %x\n", Urb
->UrbControlVendorClassRequest
.TransferBuffer
);
1735 DPRINT1("TransferBufferMDL %x\n", Urb
->UrbControlVendorClassRequest
.TransferBufferMDL
);
1736 DPRINT1("RequestTypeReservedBits %x\n", Urb
->UrbControlVendorClassRequest
.RequestTypeReservedBits
);
1737 DPRINT1("Request %x\n", Urb
->UrbControlVendorClassRequest
.Request
);
1738 DPRINT1("Value %x\n", Urb
->UrbControlVendorClassRequest
.Value
);
1739 DPRINT1("Index %x\n", Urb
->UrbControlVendorClassRequest
.Index
);
1742 // initialize setup packet
1744 CtrlSetup
.bmRequestType
.B
= 0x21;
1745 CtrlSetup
.bRequest
= Urb
->UrbControlVendorClassRequest
.Request
;
1746 CtrlSetup
.wValue
.W
= Urb
->UrbControlVendorClassRequest
.Value
;
1747 CtrlSetup
.wIndex
.W
= Urb
->UrbControlVendorClassRequest
.Index
;
1748 CtrlSetup
.wLength
= Urb
->UrbControlVendorClassRequest
.TransferBufferLength
;
1750 if (Urb
->UrbControlVendorClassRequest
.TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1753 // data direction is device to host
1755 CtrlSetup
.bmRequestType
.B
|= 0x80;
1761 Status
= UsbDevice
->SubmitSetupPacket(&CtrlSetup
, Urb
->UrbControlVendorClassRequest
.TransferBufferLength
, Urb
->UrbControlVendorClassRequest
.TransferBuffer
);
1764 // assert on failure
1766 if (!NT_SUCCESS(Status
))
1771 DPRINT1("URB_FUNCTION_CLASS_INTERFACE failed with Urb Status %x\n", Urb
->UrbHeader
.Status
);
1780 //-----------------------------------------------------------------------------------------
1782 CHubController::HandleDeviceControl(
1783 IN PDEVICE_OBJECT DeviceObject
,
1786 PIO_STACK_LOCATION IoStack
;
1787 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
1789 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
1792 // get current stack location
1794 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1797 // get device extension
1799 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1802 // determine which request should be performed
1804 switch(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
)
1806 case IOCTL_INTERNAL_USB_SUBMIT_URB
:
1811 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
1814 switch (Urb
->UrbHeader
.Function
)
1816 case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
:
1817 Status
= HandleGetDescriptorFromInterface(Irp
, Urb
);
1819 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
:
1820 Status
= HandleGetDescriptor(Irp
, Urb
);
1822 case URB_FUNCTION_CLASS_DEVICE
:
1823 Status
= HandleClassDevice(Irp
, Urb
);
1825 case URB_FUNCTION_GET_STATUS_FROM_DEVICE
:
1826 Status
= HandleGetStatusFromDevice(Irp
, Urb
);
1828 case URB_FUNCTION_SELECT_CONFIGURATION
:
1829 Status
= HandleSelectConfiguration(Irp
, Urb
);
1831 case URB_FUNCTION_SELECT_INTERFACE
:
1832 Status
= HandleSelectInterface(Irp
, Urb
);
1834 case URB_FUNCTION_CLASS_OTHER
:
1835 Status
= HandleClassOther(Irp
, Urb
);
1837 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
:
1838 Status
= HandleBulkOrInterruptTransfer(Irp
, Urb
);
1840 case URB_FUNCTION_ISOCH_TRANSFER
:
1841 Status
= HandleIsochronousTransfer(Irp
, Urb
);
1843 case URB_FUNCTION_CLASS_INTERFACE
:
1844 Status
= HandleClassInterface(Irp
, Urb
);
1846 case URB_FUNCTION_CLASS_ENDPOINT
:
1847 Status
= HandleClassEndpoint(Irp
, Urb
);
1850 DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb
->UrbHeader
.Function
);
1854 // request completed
1858 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
:
1860 DPRINT("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %p\n", this);
1862 if (IoStack
->Parameters
.Others
.Argument1
)
1865 // store object as device handle
1867 *(PVOID
*)IoStack
->Parameters
.Others
.Argument1
= (PVOID
)this;
1868 Status
= STATUS_SUCCESS
;
1873 // mis-behaving hub driver
1875 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1879 // request completed
1883 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
:
1885 DPRINT("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
1888 // this is the first request send, it delivers the PDO to the caller
1890 if (IoStack
->Parameters
.Others
.Argument1
)
1893 // store root hub pdo object
1895 *(PVOID
*)IoStack
->Parameters
.Others
.Argument1
= DeviceObject
;
1898 if (IoStack
->Parameters
.Others
.Argument2
)
1901 // documentation claims to deliver the hcd controller object, although it is wrong
1903 *(PVOID
*)IoStack
->Parameters
.Others
.Argument2
= DeviceObject
;
1907 // request completed
1909 Status
= STATUS_SUCCESS
;
1912 case IOCTL_INTERNAL_USB_GET_HUB_COUNT
:
1914 DPRINT("IOCTL_INTERNAL_USB_GET_HUB_COUNT\n");
1917 // after IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO is delivered, the usbhub driver
1918 // requests this ioctl to deliver the number of presents.
1920 if (IoStack
->Parameters
.Others
.Argument1
)
1923 // FIXME / verify: there is only one hub
1925 *(PULONG
)IoStack
->Parameters
.Others
.Argument1
= 1;
1929 // request completed
1931 Status
= STATUS_SUCCESS
;
1932 Irp
->IoStatus
.Information
= sizeof(ULONG
);
1935 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION
:
1937 DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION UNIMPLEMENTED\n");
1938 Status
= STATUS_SUCCESS
;
1943 DPRINT1("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu NOT IMPLEMENTED\n",
1944 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
,
1945 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
1946 IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
1950 if (Status
!= STATUS_PENDING
)
1952 Irp
->IoStatus
.Status
= Status
;
1953 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1959 //-----------------------------------------------------------------------------------------
1961 CHubController::GetUsbHardware()
1966 //-----------------------------------------------------------------------------------------
1968 CHubController::AcquireDeviceAddress()
1971 ULONG DeviceAddress
;
1974 // acquire device lock
1976 KeAcquireSpinLock(&m_Lock
, &OldLevel
);
1981 DeviceAddress
= RtlFindClearBits(&m_DeviceAddressBitmap
, 1, 0);
1982 if (DeviceAddress
!= MAXULONG
)
1987 RtlSetBits(&m_DeviceAddressBitmap
, DeviceAddress
, 1);
1990 // device addresses start from 0x1 - 0xFF
1996 // release spin lock
1998 KeReleaseSpinLock(&m_Lock
, OldLevel
);
2001 // return device address
2003 return DeviceAddress
;
2005 //-----------------------------------------------------------------------------------------
2007 CHubController::ReleaseDeviceAddress(
2008 ULONG DeviceAddress
)
2013 // acquire device lock
2015 KeAcquireSpinLock(&m_Lock
, &OldLevel
);
2020 PC_ASSERT(DeviceAddress
!= 0);
2023 // convert back to bit number
2030 RtlClearBits(&m_DeviceAddressBitmap
, DeviceAddress
, 1);
2035 KeReleaseSpinLock(&m_Lock
, OldLevel
);
2037 //-----------------------------------------------------------------------------------------
2039 CHubController::RemoveUsbDevice(
2040 PUSBDEVICE UsbDevice
)
2042 PUSBDEVICE_ENTRY DeviceEntry
;
2044 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
2050 KeAcquireSpinLock(&m_Lock
, &OldLevel
);
2053 // point to first entry
2055 Entry
= m_UsbDeviceList
.Flink
;
2058 // find matching entry
2060 while(Entry
!= &m_UsbDeviceList
)
2065 DeviceEntry
= (PUSBDEVICE_ENTRY
)CONTAINING_RECORD(Entry
, USBDEVICE_ENTRY
, Entry
);
2068 // is it current entry
2070 if (DeviceEntry
->Device
== UsbDevice
)
2075 RemoveEntryList(Entry
);
2080 ExFreePoolWithTag(DeviceEntry
, TAG_USBOHCI
);
2085 Status
= STATUS_SUCCESS
;
2092 Entry
= Entry
->Flink
;
2098 KeReleaseSpinLock(&m_Lock
, OldLevel
);
2105 //-----------------------------------------------------------------------------------------
2107 CHubController::ValidateUsbDevice(PUSBDEVICE UsbDevice
)
2109 PUSBDEVICE_ENTRY DeviceEntry
;
2112 BOOLEAN Result
= FALSE
;
2117 KeAcquireSpinLock(&m_Lock
, &OldLevel
);
2120 // point to first entry
2122 Entry
= m_UsbDeviceList
.Flink
;
2125 // find matching entry
2127 while(Entry
!= &m_UsbDeviceList
)
2132 DeviceEntry
= (PUSBDEVICE_ENTRY
)CONTAINING_RECORD(Entry
, USBDEVICE_ENTRY
, Entry
);
2135 // is it current entry
2137 if (DeviceEntry
->Device
== UsbDevice
)
2149 Entry
= Entry
->Flink
;
2155 KeReleaseSpinLock(&m_Lock
, OldLevel
);
2164 //-----------------------------------------------------------------------------------------
2166 CHubController::AddUsbDevice(
2167 PUSBDEVICE UsbDevice
)
2169 PUSBDEVICE_ENTRY DeviceEntry
;
2173 // allocate device entry
2175 DeviceEntry
= (PUSBDEVICE_ENTRY
)ExAllocatePoolWithTag(NonPagedPool
, sizeof(USBDEVICE_ENTRY
), TAG_USBOHCI
);
2181 return STATUS_INSUFFICIENT_RESOURCES
;
2187 DeviceEntry
->Device
= UsbDevice
;
2192 KeAcquireSpinLock(&m_Lock
, &OldLevel
);
2197 InsertTailList(&m_UsbDeviceList
, &DeviceEntry
->Entry
);
2200 // release spin lock
2202 KeReleaseSpinLock(&m_Lock
, OldLevel
);
2207 return STATUS_SUCCESS
;
2210 //-----------------------------------------------------------------------------------------
2212 CHubController::SetNotification(
2213 PVOID CallbackContext
,
2214 PRH_INIT_CALLBACK CallbackRoutine
)
2219 // acquire hub controller lock
2221 KeAcquireSpinLock(&m_Lock
, &OldLevel
);
2224 // now set the callback routine and context of the hub
2226 m_HubCallbackContext
= CallbackContext
;
2227 m_HubCallbackRoutine
= CallbackRoutine
;
2230 // release hub controller lock
2232 KeReleaseSpinLock(&m_Lock
, OldLevel
);
2235 //=================================================================================================
2237 // Generic Interface functions
2241 USBI_InterfaceReference(
2244 CHubController
* Controller
= (CHubController
*)BusContext
;
2246 DPRINT1("USBH_InterfaceReference\n");
2251 Controller
->AddRef();
2256 USBI_InterfaceDereference(
2259 CHubController
* Controller
= (CHubController
*)BusContext
;
2261 DPRINT1("USBH_InterfaceDereference\n");
2266 Controller
->Release();
2268 //=================================================================================================
2270 // USB Hub Interface functions
2274 USBHI_CreateUsbDevice(
2276 PUSB_DEVICE_HANDLE
*NewDevice
,
2277 PUSB_DEVICE_HANDLE HubDeviceHandle
,
2281 PUSBDEVICE NewUsbDevice
;
2282 CHubController
* Controller
;
2285 DPRINT1("USBHI_CreateUsbDevice\n");
2288 // first get hub controller
2290 Controller
= (CHubController
*)BusContext
;
2295 PC_ASSERT(Controller
);
2296 PC_ASSERT(BusContext
== HubDeviceHandle
);
2299 // now allocate usb device
2301 Status
= CreateUSBDevice(&NewUsbDevice
);
2304 // check for success
2306 if (!NT_SUCCESS(Status
))
2309 // release controller
2311 Controller
->Release();
2312 DPRINT1("USBHI_CreateUsbDevice: failed to create usb device %x\n", Status
);
2317 // now initialize device
2319 Status
= NewUsbDevice
->Initialize(PHUBCONTROLLER(Controller
), Controller
->GetUsbHardware(),PVOID(Controller
), PortNumber
, PortStatus
);
2322 // check for success
2324 if (!NT_SUCCESS(Status
))
2327 // release usb device
2329 NewUsbDevice
->Release();
2330 DPRINT1("USBHI_CreateUsbDevice: failed to initialize usb device %x\n", Status
);
2337 Status
= Controller
->AddUsbDevice(NewUsbDevice
);
2339 // check for success
2341 if (!NT_SUCCESS(Status
))
2344 // release usb device
2346 NewUsbDevice
->Release();
2348 DPRINT1("USBHI_CreateUsbDevice: failed to add usb device %x\n", Status
);
2355 *NewDevice
= NewUsbDevice
;
2360 return STATUS_SUCCESS
;
2365 USBHI_InitializeUsbDevice(
2367 PUSB_DEVICE_HANDLE DeviceHandle
)
2369 PUSBDEVICE UsbDevice
;
2370 CHubController
* Controller
;
2371 ULONG DeviceAddress
;
2375 DPRINT1("USBHI_InitializeUsbDevice\n");
2378 // first get controller
2380 Controller
= (CHubController
*)BusContext
;
2381 PC_ASSERT(Controller
);
2384 // get device object
2386 UsbDevice
= (PUSBDEVICE
)DeviceHandle
;
2387 PC_ASSERT(UsbDevice
);
2390 // validate device handle
2392 if (!Controller
->ValidateUsbDevice(UsbDevice
))
2394 DPRINT1("USBHI_InitializeUsbDevice invalid device handle %p\n", DeviceHandle
);
2397 // invalid device handle
2399 return STATUS_DEVICE_NOT_CONNECTED
;
2403 // now reserve an address
2405 DeviceAddress
= Controller
->AcquireDeviceAddress();
2408 // is the device address valid
2410 if (DeviceAddress
== MAXULONG
)
2413 // failed to get an device address from the device address pool
2415 DPRINT1("USBHI_InitializeUsbDevice failed to get device address\n");
2416 return STATUS_DEVICE_DATA_ERROR
;
2422 // now set the device address
2424 Status
= UsbDevice
->SetDeviceAddress((UCHAR
)DeviceAddress
);
2426 if (NT_SUCCESS(Status
))
2429 }while(Index
++ < 3 );
2432 // check for failure
2434 if (!NT_SUCCESS(Status
))
2437 // failed to set device address
2439 DPRINT1("USBHI_InitializeUsbDevice failed to set address with %x\n", Status
);
2444 Controller
->ReleaseDeviceAddress(DeviceAddress
);
2449 return STATUS_DEVICE_DATA_ERROR
;
2455 return STATUS_SUCCESS
;
2460 USBHI_GetUsbDescriptors(
2462 PUSB_DEVICE_HANDLE DeviceHandle
,
2463 PUCHAR DeviceDescriptorBuffer
,
2464 PULONG DeviceDescriptorBufferLength
,
2465 PUCHAR ConfigDescriptorBuffer
,
2466 PULONG ConfigDescriptorBufferLength
)
2468 PUSBDEVICE UsbDevice
;
2469 CHubController
* Controller
;
2471 DPRINT1("USBHI_GetUsbDescriptors\n");
2476 PC_ASSERT(DeviceDescriptorBuffer
);
2477 PC_ASSERT(DeviceDescriptorBufferLength
);
2478 PC_ASSERT(*DeviceDescriptorBufferLength
>= sizeof(USB_DEVICE_DESCRIPTOR
));
2479 PC_ASSERT(ConfigDescriptorBufferLength
);
2480 PC_ASSERT(*ConfigDescriptorBufferLength
>= sizeof(USB_CONFIGURATION_DESCRIPTOR
));
2483 // first get controller
2485 Controller
= (CHubController
*)BusContext
;
2486 PC_ASSERT(Controller
);
2490 // get device object
2492 UsbDevice
= (PUSBDEVICE
)DeviceHandle
;
2493 PC_ASSERT(UsbDevice
);
2496 // validate device handle
2498 if (!Controller
->ValidateUsbDevice(UsbDevice
))
2500 DPRINT1("USBHI_GetUsbDescriptors invalid device handle %p\n", DeviceHandle
);
2503 // invalid device handle
2505 return STATUS_DEVICE_NOT_CONNECTED
;
2509 // get device descriptor
2511 UsbDevice
->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR
)DeviceDescriptorBuffer
);
2514 // store result length
2516 *DeviceDescriptorBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
2519 // get configuration descriptor
2521 UsbDevice
->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR
)ConfigDescriptorBuffer
, *ConfigDescriptorBufferLength
, ConfigDescriptorBufferLength
);
2524 // complete the request
2526 return STATUS_SUCCESS
;
2531 USBHI_RemoveUsbDevice(
2533 PUSB_DEVICE_HANDLE DeviceHandle
,
2536 PUSBDEVICE UsbDevice
;
2537 CHubController
* Controller
;
2540 DPRINT1("USBHI_RemoveUsbDevice\n");
2543 // first get controller
2545 Controller
= (CHubController
*)BusContext
;
2546 PC_ASSERT(Controller
);
2549 // get device object
2551 UsbDevice
= (PUSBDEVICE
)DeviceHandle
;
2552 PC_ASSERT(UsbDevice
);
2555 // validate device handle
2557 if (!Controller
->ValidateUsbDevice(UsbDevice
))
2559 DPRINT1("USBHI_RemoveUsbDevice invalid device handle %p\n", DeviceHandle
);
2562 // invalid device handle
2564 return STATUS_DEVICE_NOT_CONNECTED
;
2568 // check if there were flags passed
2570 if (Flags
& USBD_KEEP_DEVICE_DATA
|| Flags
& USBD_MARK_DEVICE_BUSY
)
2573 // ignore flags for now
2575 return STATUS_SUCCESS
;
2581 Status
= Controller
->RemoveUsbDevice(UsbDevice
);
2582 if (!NT_SUCCESS(Status
))
2585 // invalid device handle
2587 DPRINT1("USBHI_RemoveUsbDevice Invalid device handle %p\n", UsbDevice
);
2589 return STATUS_DEVICE_NOT_CONNECTED
;
2593 // release usb device
2595 UsbDevice
->Release();
2600 return STATUS_SUCCESS
;
2605 USBHI_RestoreUsbDevice(
2607 PUSB_DEVICE_HANDLE OldDeviceHandle
,
2608 PUSB_DEVICE_HANDLE NewDeviceHandle
)
2610 PUSBDEVICE OldUsbDevice
, NewUsbDevice
;
2611 CHubController
* Controller
;
2613 DPRINT1("USBHI_RestoreUsbDevice\n");
2616 // first get controller
2618 Controller
= (CHubController
*)BusContext
;
2619 PC_ASSERT(Controller
);
2622 // get device object
2624 OldUsbDevice
= (PUSBDEVICE
)OldDeviceHandle
;
2625 NewUsbDevice
= (PUSBDEVICE
)NewDeviceHandle
;
2626 PC_ASSERT(OldUsbDevice
);
2627 PC_ASSERT(NewDeviceHandle
);
2630 // validate device handle
2632 PC_ASSERT(Controller
->ValidateUsbDevice(NewUsbDevice
));
2633 PC_ASSERT(Controller
->ValidateUsbDevice(OldUsbDevice
));
2635 DPRINT1("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice
->GetDeviceAddress());
2636 DPRINT1("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice
->GetDeviceAddress());
2639 // remove old device handle
2641 USBHI_RemoveUsbDevice(BusContext
, OldDeviceHandle
, 0);
2643 return STATUS_SUCCESS
;
2648 USBHI_QueryDeviceInformation(
2650 PUSB_DEVICE_HANDLE DeviceHandle
,
2651 PVOID DeviceInformationBuffer
,
2652 ULONG DeviceInformationBufferLength
,
2653 PULONG LengthReturned
)
2655 PUSB_DEVICE_INFORMATION_0 DeviceInfo
;
2656 PUSBDEVICE UsbDevice
;
2657 CHubController
* Controller
;
2659 DPRINT1("USBHI_QueryDeviceInformation %p\n", BusContext
);
2664 PC_ASSERT(DeviceInformationBufferLength
>= sizeof(USB_DEVICE_INFORMATION_0
));
2665 PC_ASSERT(DeviceInformationBuffer
);
2666 PC_ASSERT(LengthReturned
);
2669 // get controller object
2671 Controller
= (CHubController
*)BusContext
;
2672 PC_ASSERT(Controller
);
2675 // get device object
2677 UsbDevice
= (PUSBDEVICE
)DeviceHandle
;
2678 PC_ASSERT(UsbDevice
);
2680 if (BusContext
!= DeviceHandle
)
2683 // validate device handle
2685 if (!Controller
->ValidateUsbDevice(UsbDevice
))
2687 DPRINT1("USBHI_QueryDeviceInformation invalid device handle %p\n", DeviceHandle
);
2690 // invalid device handle
2692 return STATUS_DEVICE_NOT_CONNECTED
;
2696 // access information buffer
2698 DeviceInfo
= (PUSB_DEVICE_INFORMATION_0
)DeviceInformationBuffer
;
2701 // initialize with default values
2703 DeviceInfo
->InformationLevel
= 0;
2704 DeviceInfo
->ActualLength
= sizeof(USB_DEVICE_INFORMATION_0
);
2705 DeviceInfo
->PortNumber
= UsbDevice
->GetPort();
2706 DeviceInfo
->CurrentConfigurationValue
= UsbDevice
->GetConfigurationValue();
2707 DeviceInfo
->DeviceAddress
= UsbDevice
->GetDeviceAddress();
2708 DeviceInfo
->HubAddress
= 0; //FIXME
2709 DeviceInfo
->DeviceSpeed
= UsbDevice
->GetSpeed();
2710 DeviceInfo
->DeviceType
= UsbDevice
->GetType();
2711 DeviceInfo
->NumberOfOpenPipes
= 0; //FIXME
2714 // get device descriptor
2716 UsbDevice
->GetDeviceDescriptor(&DeviceInfo
->DeviceDescriptor
);
2719 // FIXME return pipe information
2723 // store result length
2725 *LengthReturned
= sizeof(USB_DEVICE_INFORMATION_0
);
2727 return STATUS_SUCCESS
;
2731 // access information buffer
2733 DeviceInfo
= (PUSB_DEVICE_INFORMATION_0
)DeviceInformationBuffer
;
2736 // initialize with default values
2738 DeviceInfo
->InformationLevel
= 0;
2739 DeviceInfo
->ActualLength
= sizeof(USB_DEVICE_INFORMATION_0
);
2740 DeviceInfo
->PortNumber
= 0;
2741 DeviceInfo
->CurrentConfigurationValue
= 0; //FIXME;
2742 DeviceInfo
->DeviceAddress
= 0;
2743 DeviceInfo
->HubAddress
= 0; //FIXME
2744 DeviceInfo
->DeviceSpeed
= UsbFullSpeed
; //FIXME
2745 DeviceInfo
->DeviceType
= Usb11Device
; //FIXME
2746 DeviceInfo
->NumberOfOpenPipes
= 0; //FIXME
2749 // get device descriptor
2751 RtlMoveMemory(&DeviceInfo
->DeviceDescriptor
, ROOTHUB2_DEVICE_DESCRIPTOR
, sizeof(USB_DEVICE_DESCRIPTOR
));
2754 // FIXME return pipe information
2758 // store result length
2761 *LengthReturned
= FIELD_OFFSET(USB_DEVICE_INFORMATION_0
, PipeList
[DeviceInfo
->NumberOfOpenPipes
]);
2763 *LengthReturned
= sizeof(USB_DEVICE_INFORMATION_0
) + (DeviceInfo
->NumberOfOpenPipes
> 1 ? (DeviceInfo
->NumberOfOpenPipes
- 1) * sizeof(USB_PIPE_INFORMATION_0
) : 0);
2768 return STATUS_SUCCESS
;
2773 USBHI_GetControllerInformation(
2775 PVOID ControllerInformationBuffer
,
2776 ULONG ControllerInformationBufferLength
,
2777 PULONG LengthReturned
)
2779 PUSB_CONTROLLER_INFORMATION_0 ControllerInfo
;
2781 DPRINT1("USBHI_GetControllerInformation\n");
2786 PC_ASSERT(ControllerInformationBuffer
);
2787 PC_ASSERT(ControllerInformationBufferLength
>= sizeof(USB_CONTROLLER_INFORMATION_0
));
2790 // get controller info buffer
2792 ControllerInfo
= (PUSB_CONTROLLER_INFORMATION_0
)ControllerInformationBuffer
;
2795 // FIXME only version 0 is supported for now
2797 PC_ASSERT(ControllerInfo
->InformationLevel
== 0);
2800 // fill in information
2802 ControllerInfo
->ActualLength
= sizeof(USB_CONTROLLER_INFORMATION_0
);
2803 ControllerInfo
->SelectiveSuspendEnabled
= FALSE
; //FIXME
2804 ControllerInfo
->IsHighSpeedController
= FALSE
;
2807 // set length returned
2809 *LengthReturned
= ControllerInfo
->ActualLength
;
2814 return STATUS_SUCCESS
;
2819 USBHI_ControllerSelectiveSuspend(
2824 return STATUS_NOT_IMPLEMENTED
;
2829 USBHI_GetExtendedHubInformation(
2831 PDEVICE_OBJECT HubPhysicalDeviceObject
,
2832 PVOID HubInformationBuffer
,
2833 ULONG HubInformationBufferLength
,
2834 PULONG LengthReturned
)
2836 PUSB_EXTHUB_INFORMATION_0 HubInfo
;
2837 CHubController
* Controller
;
2838 PUSBHARDWAREDEVICE Hardware
;
2840 ULONG NumPort
, Dummy2
;
2844 DPRINT1("USBHI_GetExtendedHubInformation\n");
2849 PC_ASSERT(HubInformationBuffer
);
2850 PC_ASSERT(HubInformationBufferLength
== sizeof(USB_EXTHUB_INFORMATION_0
));
2851 PC_ASSERT(LengthReturned
);
2854 // get hub controller
2856 Controller
= (CHubController
*)BusContext
;
2857 PC_ASSERT(Controller
);
2860 // get usb hardware device
2862 Hardware
= Controller
->GetUsbHardware();
2865 // retrieve number of ports
2867 Status
= Hardware
->GetDeviceDetails(&Dummy1
, &Dummy1
, &NumPort
, &Dummy2
);
2868 if (!NT_SUCCESS(Status
))
2871 // failed to get hardware details, ouch ;)
2873 DPRINT1("USBHI_GetExtendedHubInformation failed to get hardware details with %x\n", Status
);
2878 // get hub information buffer
2880 HubInfo
= (PUSB_EXTHUB_INFORMATION_0
)HubInformationBuffer
;
2883 // initialize hub information
2885 HubInfo
->InformationLevel
= 0;
2890 HubInfo
->NumberOfPorts
= NumPort
;
2893 // initialize port information
2895 for(Index
= 0; Index
< NumPort
; Index
++)
2897 HubInfo
->Port
[Index
].PhysicalPortNumber
= Index
+ 1;
2898 HubInfo
->Port
[Index
].PortLabelNumber
= Index
+ 1;
2899 HubInfo
->Port
[Index
].VidOverride
= 0;
2900 HubInfo
->Port
[Index
].PidOverride
= 0;
2901 HubInfo
->Port
[Index
].PortAttributes
= 0; //FIXME
2905 // store result length
2908 *LengthReturned
= FIELD_OFFSET(USB_EXTHUB_INFORMATION_0
, Port
[HubInfo
->NumberOfPorts
]);
2910 *LengthReturned
= FIELD_OFFSET(USB_EXTHUB_INFORMATION_0
, Port
) + sizeof(USB_EXTPORT_INFORMATION_0
) * HubInfo
->NumberOfPorts
;
2916 return STATUS_SUCCESS
;
2921 USBHI_GetRootHubSymbolicName(
2923 PVOID HubSymNameBuffer
,
2924 ULONG HubSymNameBufferLength
,
2925 PULONG HubSymNameActualLength
)
2928 return STATUS_NOT_IMPLEMENTED
;
2933 USBHI_GetDeviceBusContext(
2934 PVOID HubBusContext
,
2943 USBHI_RootHubInitNotification(
2945 PVOID CallbackContext
,
2946 PRH_INIT_CALLBACK CallbackRoutine
)
2948 CHubController
* Controller
;
2950 DPRINT("USBHI_RootHubInitNotification %p \n", CallbackContext
);
2953 // get controller object
2955 Controller
= (CHubController
*)BusContext
;
2956 PC_ASSERT(Controller
);
2959 // set notification routine
2961 Controller
->SetNotification(CallbackContext
, CallbackRoutine
);
2964 // FIXME: determine when to perform callback
2966 CallbackRoutine(CallbackContext
);
2971 return STATUS_SUCCESS
;
2976 USBHI_FlushTransfers(
2985 USBHI_SetDeviceHandleData(
2988 PDEVICE_OBJECT UsbDevicePdo
)
2990 PUSBDEVICE UsbDevice
;
2991 CHubController
* Controller
;
2996 Controller
= (CHubController
*)BusContext
;
2997 PC_ASSERT(Controller
);
3000 // get device handle
3002 UsbDevice
= (PUSBDEVICE
)DeviceHandle
;
3005 // validate device handle
3007 if (!Controller
->ValidateUsbDevice(UsbDevice
))
3009 DPRINT1("USBHI_SetDeviceHandleData DeviceHandle %p is invalid\n", DeviceHandle
);
3019 // usbhub sends this request as a part of the Pnp startup sequence
3020 // looks like we need apply a dragon voodoo to fixup the device stack
3021 // otherwise usbhub will cause a bugcheck
3023 DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo
);
3028 PC_ASSERT(UsbDevicePdo
->AttachedDevice
);
3031 // should be usbstor
3032 // fixup device stack voodoo part #2
3034 UsbDevicePdo
->AttachedDevice
->StackSize
++;
3037 // set device handle data
3039 UsbDevice
->SetDeviceHandleData(UsbDevicePdo
);
3043 //=================================================================================================
3045 // USB Device Interface functions
3050 USBDI_GetUSBDIVersion(
3052 PUSBD_VERSION_INFORMATION VersionInformation
,
3053 PULONG HcdCapabilites
)
3055 CHubController
* Controller
;
3056 PUSBHARDWAREDEVICE Device
;
3057 ULONG Speed
, Dummy2
;
3060 DPRINT1("USBDI_GetUSBDIVersion\n");
3065 Controller
= (CHubController
*)BusContext
;
3070 Device
= Controller
->GetUsbHardware();
3073 if (VersionInformation
)
3076 // windows xp supported
3078 VersionInformation
->USBDI_Version
= 0x00000500;
3083 Device
->GetDeviceDetails(&Dummy1
, &Dummy1
, &Dummy2
, &Speed
);
3086 // store speed details
3088 VersionInformation
->Supported_USB_Version
= Speed
;
3092 // no flags supported
3094 *HcdCapabilites
= 0;
3101 PULONG CurrentFrame
)
3104 return STATUS_NOT_IMPLEMENTED
;
3109 USBDI_SubmitIsoOutUrb(
3114 return STATUS_NOT_IMPLEMENTED
;
3119 USBDI_QueryBusInformation(
3122 PVOID BusInformationBuffer
,
3123 PULONG BusInformationBufferLength
,
3124 PULONG BusInformationActualLength
)
3127 return STATUS_NOT_IMPLEMENTED
;
3132 USBDI_IsDeviceHighSpeed(
3135 CHubController
* Controller
;
3136 PUSBHARDWAREDEVICE Device
;
3137 ULONG Speed
, Dummy2
;
3140 DPRINT1("USBDI_IsDeviceHighSpeed\n");
3145 Controller
= (CHubController
*)BusContext
;
3150 Device
= Controller
->GetUsbHardware();
3156 Device
->GetDeviceDetails(&Dummy1
, &Dummy1
, &Dummy2
, &Speed
);
3159 // USB 2.0 equals 0x200
3161 return (Speed
== 0x200);
3174 return STATUS_NOT_IMPLEMENTED
;
3178 CHubController::HandleQueryInterface(
3179 PIO_STACK_LOCATION IoStack
)
3181 PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub
;
3182 PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI
;
3183 UNICODE_STRING GuidBuffer
;
3186 if (IsEqualGUIDAligned(*IoStack
->Parameters
.QueryInterface
.InterfaceType
, USB_BUS_INTERFACE_HUB_GUID
))
3189 // get request parameters
3191 InterfaceHub
= (PUSB_BUS_INTERFACE_HUB_V5
)IoStack
->Parameters
.QueryInterface
.Interface
;
3192 InterfaceHub
->Version
= IoStack
->Parameters
.QueryInterface
.Version
;
3197 if (IoStack
->Parameters
.QueryInterface
.Version
>= 6)
3199 DPRINT1("USB_BUS_INTERFACE_HUB_GUID version %x not supported!\n", IoStack
->Parameters
.QueryInterface
.Version
);
3202 // version not supported
3204 return STATUS_NOT_SUPPORTED
;
3208 // Interface version 0
3210 if (IoStack
->Parameters
.QueryInterface
.Version
>= 0)
3212 InterfaceHub
->Size
= IoStack
->Parameters
.QueryInterface
.Size
;
3213 InterfaceHub
->BusContext
= PVOID(this);
3214 InterfaceHub
->InterfaceReference
= USBI_InterfaceReference
;
3215 InterfaceHub
->InterfaceDereference
= USBI_InterfaceDereference
;
3219 // Interface version 1
3221 if (IoStack
->Parameters
.QueryInterface
.Version
>= 1)
3223 InterfaceHub
->CreateUsbDevice
= USBHI_CreateUsbDevice
;
3224 InterfaceHub
->InitializeUsbDevice
= USBHI_InitializeUsbDevice
;
3225 InterfaceHub
->GetUsbDescriptors
= USBHI_GetUsbDescriptors
;
3226 InterfaceHub
->RemoveUsbDevice
= USBHI_RemoveUsbDevice
;
3227 InterfaceHub
->RestoreUsbDevice
= USBHI_RestoreUsbDevice
;
3228 InterfaceHub
->QueryDeviceInformation
= USBHI_QueryDeviceInformation
;
3232 // Interface version 2
3234 if (IoStack
->Parameters
.QueryInterface
.Version
>= 2)
3236 InterfaceHub
->GetControllerInformation
= USBHI_GetControllerInformation
;
3237 InterfaceHub
->ControllerSelectiveSuspend
= USBHI_ControllerSelectiveSuspend
;
3238 InterfaceHub
->GetExtendedHubInformation
= USBHI_GetExtendedHubInformation
;
3239 InterfaceHub
->GetRootHubSymbolicName
= USBHI_GetRootHubSymbolicName
;
3240 InterfaceHub
->GetDeviceBusContext
= USBHI_GetDeviceBusContext
;
3244 // Interface version 3
3246 if (IoStack
->Parameters
.QueryInterface
.Version
>= 3)
3248 InterfaceHub
->RootHubInitNotification
= USBHI_RootHubInitNotification
;
3252 // Interface version 4
3254 if (IoStack
->Parameters
.QueryInterface
.Version
>= 4)
3256 InterfaceHub
->FlushTransfers
= USBHI_FlushTransfers
;
3260 // Interface version 5
3262 if (IoStack
->Parameters
.QueryInterface
.Version
>= 5)
3264 InterfaceHub
->SetDeviceHandleData
= USBHI_SetDeviceHandleData
;
3268 // request completed
3270 return STATUS_SUCCESS
;
3272 else if (IsEqualGUIDAligned(*IoStack
->Parameters
.QueryInterface
.InterfaceType
, USB_BUS_INTERFACE_USBDI_GUID
))
3275 // get request parameters
3277 InterfaceDI
= (PUSB_BUS_INTERFACE_USBDI_V2
) IoStack
->Parameters
.QueryInterface
.Interface
;
3278 InterfaceDI
->Version
= IoStack
->Parameters
.QueryInterface
.Version
;
3283 if (IoStack
->Parameters
.QueryInterface
.Version
>= 3)
3285 DPRINT1("USB_BUS_INTERFACE_USBDI_GUID version %x not supported!\n", IoStack
->Parameters
.QueryInterface
.Version
);
3288 // version not supported
3290 return STATUS_NOT_SUPPORTED
;
3294 // interface version 0
3296 if (IoStack
->Parameters
.QueryInterface
.Version
>= 0)
3298 InterfaceDI
->Size
= IoStack
->Parameters
.QueryInterface
.Size
;
3299 InterfaceDI
->BusContext
= PVOID(this);
3300 InterfaceDI
->InterfaceReference
= USBI_InterfaceReference
;
3301 InterfaceDI
->InterfaceDereference
= USBI_InterfaceDereference
;
3302 InterfaceDI
->GetUSBDIVersion
= USBDI_GetUSBDIVersion
;
3303 InterfaceDI
->QueryBusTime
= USBDI_QueryBusTime
;
3304 InterfaceDI
->SubmitIsoOutUrb
= USBDI_SubmitIsoOutUrb
;
3305 InterfaceDI
->QueryBusInformation
= USBDI_QueryBusInformation
;
3309 // interface version 1
3311 if (IoStack
->Parameters
.QueryInterface
.Version
>= 1)
3313 InterfaceDI
->IsDeviceHighSpeed
= USBDI_IsDeviceHighSpeed
;
3317 // interface version 2
3319 if (IoStack
->Parameters
.QueryInterface
.Version
>= 2)
3321 InterfaceDI
->EnumLogEntry
= USBDI_EnumLogEntry
;
3325 // request completed
3327 return STATUS_SUCCESS
;
3332 // convert guid to string
3334 Status
= RtlStringFromGUID(*IoStack
->Parameters
.QueryInterface
.InterfaceType
, &GuidBuffer
);
3335 if (NT_SUCCESS(Status
))
3340 DPRINT1("HandleQueryInterface UNKNOWN INTERFACE GUID: %wZ Version %x\n", &GuidBuffer
, IoStack
->Parameters
.QueryInterface
.Version
);
3345 RtlFreeUnicodeString(&GuidBuffer
);
3348 return STATUS_NOT_SUPPORTED
;
3352 CHubController::SetDeviceInterface(
3355 NTSTATUS Status
= STATUS_SUCCESS
;
3360 // register device interface
3362 Status
= IoRegisterDeviceInterface(m_HubControllerDeviceObject
, &GUID_DEVINTERFACE_USB_HUB
, 0, &m_HubDeviceInterfaceString
);
3364 if (NT_SUCCESS(Status
))
3367 // now enable the device interface
3369 Status
= IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString
, TRUE
);
3374 m_InterfaceEnabled
= TRUE
;
3377 else if (m_InterfaceEnabled
)
3380 // disable device interface
3382 Status
= IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString
, FALSE
);
3384 if (NT_SUCCESS(Status
))
3387 // now delete interface string
3389 RtlFreeUnicodeString(&m_HubDeviceInterfaceString
);
3393 // disable interface
3395 m_InterfaceEnabled
= FALSE
;
3401 return STATUS_SUCCESS
;
3405 CHubController::CreatePDO(
3406 PDRIVER_OBJECT DriverObject
,
3407 PDEVICE_OBJECT
* OutDeviceObject
)
3409 WCHAR CharDeviceName
[64];
3411 ULONG UsbDeviceNumber
= 0;
3412 UNICODE_STRING DeviceName
;
3417 // construct device name
3419 swprintf(CharDeviceName
, L
"\\Device\\USBPDO-%d", UsbDeviceNumber
);
3422 // initialize device name
3424 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
3429 Status
= IoCreateDevice(DriverObject
,
3430 sizeof(COMMON_DEVICE_EXTENSION
),
3432 FILE_DEVICE_CONTROLLER
,
3437 /* check for success */
3438 if (NT_SUCCESS(Status
))
3442 // is there a device object with that same name
3444 if ((Status
== STATUS_OBJECT_NAME_EXISTS
) || (Status
== STATUS_OBJECT_NAME_COLLISION
))
3447 // Try the next name
3454 // bail out on other errors
3456 if (!NT_SUCCESS(Status
))
3458 DPRINT1("CreatePDO: Failed to create %wZ, Status %x\n", &DeviceName
, Status
);
3463 DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName
);
3466 // fixup device stack voodoo part #1
3468 (*OutDeviceObject
)->StackSize
++;
3477 CreateHubController(
3478 PHUBCONTROLLER
*OutHcdController
)
3480 PHUBCONTROLLER This
;
3483 // allocate controller
3485 This
= new(NonPagedPool
, TAG_USBOHCI
) CHubController(0);
3489 // failed to allocate
3491 return STATUS_INSUFFICIENT_RESOURCES
;
3495 // add reference count
3502 *OutHcdController
= (PHUBCONTROLLER
)This
;
3507 return STATUS_SUCCESS
;
3510 VOID
StatusChangeEndpointCallBack(PVOID Context
)
3512 CHubController
* This
;
3514 This
= (CHubController
*)Context
;
3518 Irp
= This
->m_PendingSCEIrp
;
3521 DPRINT1("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n");
3525 This
->m_PendingSCEIrp
= NULL
;
3526 This
->QueryStatusChageEndpoint(Irp
);
3528 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
3529 Irp
->IoStatus
.Information
= 0;
3531 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);