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/usbehci/usbiffn.c
5 * PURPOSE: Direct Call Interface Functions.
14 PVOID
InternalCreateUsbDevice(UCHAR DeviceNumber
, ULONG Port
, PUSB_DEVICE Parent
, BOOLEAN Hub
)
16 PUSB_DEVICE UsbDevicePointer
= NULL
;
17 UsbDevicePointer
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(USB_DEVICE
), USB_POOL_TAG
);
19 if (!UsbDevicePointer
)
21 DPRINT1("Out of memory\n");
25 RtlZeroMemory(UsbDevicePointer
, sizeof(USB_DEVICE
));
27 if ((Hub
) && (!Parent
))
29 DPRINT1("This is the root hub\n");
32 UsbDevicePointer
->Address
= DeviceNumber
;
33 UsbDevicePointer
->Port
= Port
;
34 UsbDevicePointer
->ParentDevice
= Parent
;
36 UsbDevicePointer
->IsHub
= Hub
;
38 return UsbDevicePointer
;
42 IsHandleValid(PVOID BusContext
,
43 PUSB_DEVICE_HANDLE DeviceHandle
)
45 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
48 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
) BusContext
;
53 for (i
= 0; i
< 128; i
++)
55 if (PdoDeviceExtension
->UsbDevices
[i
] == DeviceHandle
)
64 InterfaceReference(PVOID BusContext
)
66 DPRINT1("InterfaceReference called\n");
71 InterfaceDereference(PVOID BusContext
)
73 DPRINT1("InterfaceDereference called\n");
76 /* Bus Interface Hub V5 Functions */
80 CreateUsbDevice(PVOID BusContext
,
81 PUSB_DEVICE_HANDLE
*NewDevice
,
82 PUSB_DEVICE_HANDLE HubDeviceHandle
,
83 USHORT PortStatus
, USHORT PortNumber
)
85 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
86 PUSB_DEVICE UsbDevice
;
88 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)BusContext
)->DeviceExtension
;
89 DPRINT1("CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle
, PortStatus
, PortNumber
);
91 UsbDevice
= InternalCreateUsbDevice(PdoDeviceExtension
->ChildDeviceCount
, PortNumber
, HubDeviceHandle
, FALSE
);
93 /* Add it to the list */
96 if (PdoDeviceExtension
->UsbDevices
[i
] == NULL
)
98 PdoDeviceExtension
->UsbDevices
[i
] = (PUSB_DEVICE
)UsbDevice
;
99 PdoDeviceExtension
->UsbDevices
[i
]->Address
= i
+ 1;
100 PdoDeviceExtension
->UsbDevices
[i
]->Port
= PortNumber
;
107 *NewDevice
= UsbDevice
;
108 return STATUS_SUCCESS
;
111 /* Called when SCE reports a change */
112 /* FIXME: Do something better for memory */
115 InitializeUsbDevice(PVOID BusContext
, PUSB_DEVICE_HANDLE DeviceHandle
)
117 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
118 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
119 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
120 PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc
;
121 PUSB_INTERFACE_DESCRIPTOR InterfaceDesc
;
122 PUSB_ENDPOINT_DESCRIPTOR EndpointDesc
;
123 PUSB_DEVICE UsbDevice
;
129 DPRINT1("InitializeUsbDevice called, device %x\n", DeviceHandle
);
130 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)BusContext
)->DeviceExtension
;
131 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)PdoDeviceExtension
->ControllerFdo
->DeviceExtension
;
132 UsbDevice
= (PUSB_DEVICE
) DeviceHandle
;
134 Buffer
= ExAllocatePoolWithTag(NonPagedPool
, PAGE_SIZE
, USB_POOL_TAG
);
138 DPRINT1("Out of memory\n");
139 return STATUS_NO_MEMORY
;
143 /* Set the device address */
144 CtrlSetup
.bmRequestType
._BM
.Recipient
= BMREQUEST_TO_DEVICE
;
145 CtrlSetup
.bmRequestType
._BM
.Type
= BMREQUEST_STANDARD
;
146 CtrlSetup
.bmRequestType
._BM
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
147 CtrlSetup
.bRequest
= USB_REQUEST_SET_ADDRESS
;
148 CtrlSetup
.wValue
.W
= UsbDevice
->Address
;
149 CtrlSetup
.wIndex
.W
= 0;
150 CtrlSetup
.wLength
= 0;
152 ResultOk
= ExecuteControlRequest(FdoDeviceExtension
, &CtrlSetup
, 0, 0, NULL
, 0);
154 /* Get the Device Descriptor */
155 CtrlSetup
.bmRequestType
._BM
.Recipient
= BMREQUEST_TO_DEVICE
;
156 CtrlSetup
.bmRequestType
._BM
.Type
= BMREQUEST_STANDARD
;
157 CtrlSetup
.bmRequestType
._BM
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
158 CtrlSetup
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
159 CtrlSetup
.wValue
.LowByte
= 0;
160 CtrlSetup
.wValue
.HiByte
= USB_DEVICE_DESCRIPTOR_TYPE
;
161 CtrlSetup
.wIndex
.W
= 0;
162 CtrlSetup
.wLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
164 ResultOk
= ExecuteControlRequest(FdoDeviceExtension
, &CtrlSetup
, UsbDevice
->Address
, UsbDevice
->Port
,
165 &UsbDevice
->DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
167 DPRINT1("bLength %x\n", UsbDevice
->DeviceDescriptor
.bLength
);
168 DPRINT1("bDescriptorType %x\n", UsbDevice
->DeviceDescriptor
.bDescriptorType
);
169 DPRINT1("bNumDescriptors %x\n", UsbDevice
->DeviceDescriptor
.bNumConfigurations
);
171 if (UsbDevice
->DeviceDescriptor
.bNumConfigurations
== 0)
172 return STATUS_DEVICE_DATA_ERROR
;
174 UsbDevice
->Configs
= ExAllocatePoolWithTag(NonPagedPool
,
175 sizeof(PVOID
) * UsbDevice
->DeviceDescriptor
.bNumConfigurations
,
178 if (!UsbDevice
->Configs
)
180 DPRINT1("Out of memory\n");
181 return STATUS_NO_MEMORY
;
184 for (i
= 0; i
< UsbDevice
->DeviceDescriptor
.bNumConfigurations
; i
++)
186 /* Get the Device Configuration Descriptor */
187 CtrlSetup
.bmRequestType
._BM
.Recipient
= BMREQUEST_TO_DEVICE
;
188 CtrlSetup
.bmRequestType
._BM
.Type
= BMREQUEST_STANDARD
;
189 CtrlSetup
.bmRequestType
._BM
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
190 CtrlSetup
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
191 CtrlSetup
.wValue
.LowByte
= 0;
192 CtrlSetup
.wValue
.HiByte
= USB_CONFIGURATION_DESCRIPTOR_TYPE
;
193 CtrlSetup
.wIndex
.W
= 0;
194 CtrlSetup
.wLength
= PAGE_SIZE
;
196 ResultOk
= ExecuteControlRequest(FdoDeviceExtension
, &CtrlSetup
, UsbDevice
->Address
, UsbDevice
->Port
, Buffer
, PAGE_SIZE
);
198 ConfigDesc
= (PUSB_CONFIGURATION_DESCRIPTOR
)Ptr
;
200 ASSERT(ConfigDesc
->wTotalLength
<= PAGE_SIZE
);
202 UsbDevice
->Configs
[i
] = ExAllocatePoolWithTag(NonPagedPool
,
203 sizeof(USB_CONFIGURATION
) + sizeof(PVOID
) * ConfigDesc
->bNumInterfaces
,
205 UsbDevice
->Configs
[i
]->Device
= UsbDevice
;
206 RtlCopyMemory(&UsbDevice
->Configs
[0]->ConfigurationDescriptor
,
207 ConfigDesc
, sizeof(USB_CONFIGURATION_DESCRIPTOR
));
208 Ptr
+= ConfigDesc
->bLength
;
210 for (j
= 0; j
< ConfigDesc
->bNumInterfaces
; j
++)
212 InterfaceDesc
= (PUSB_INTERFACE_DESCRIPTOR
) Ptr
;
213 UsbDevice
->Configs
[i
]->Interfaces
[j
] = ExAllocatePoolWithTag(NonPagedPool
,
214 sizeof(USB_INTERFACE
) + sizeof(PVOID
) * InterfaceDesc
->bNumEndpoints
,
216 RtlCopyMemory(&UsbDevice
->Configs
[i
]->Interfaces
[j
]->InterfaceDescriptor
,
218 sizeof(USB_INTERFACE_DESCRIPTOR
));
220 Ptr
+= InterfaceDesc
->bLength
;
222 for (k
= 0; k
< InterfaceDesc
->bNumEndpoints
; k
++)
224 EndpointDesc
= (PUSB_ENDPOINT_DESCRIPTOR
)Ptr
;
225 UsbDevice
->Configs
[i
]->Interfaces
[j
]->EndPoints
[k
] = ExAllocatePoolWithTag(NonPagedPool
, sizeof(USB_ENDPOINT
), USB_POOL_TAG
);
226 RtlCopyMemory(&UsbDevice
->Configs
[i
]->Interfaces
[j
]->EndPoints
[k
]->EndPointDescriptor
,
227 EndpointDesc
, sizeof(USB_ENDPOINT_DESCRIPTOR
));
233 UsbDevice
->ActiveConfig
= UsbDevice
->Configs
[0];
234 UsbDevice
->ActiveInterface
= UsbDevice
->Configs
[0]->Interfaces
[0];
236 return STATUS_SUCCESS
;
241 GetUsbDescriptors(PVOID BusContext
,
242 PUSB_DEVICE_HANDLE DeviceHandle
,
243 PUCHAR DeviceDescriptorBuffer
,
244 PULONG DeviceDescriptorBufferLength
,
245 PUCHAR ConfigDescriptorBuffer
,
246 PULONG ConfigDescriptorBufferLength
)
248 PUSB_DEVICE UsbDevice
;
249 DPRINT1("GetUsbDescriptor %x, %d, %x, %d\n", DeviceDescriptorBuffer
, DeviceDescriptorBufferLength
, ConfigDescriptorBuffer
, ConfigDescriptorBufferLength
);
251 UsbDevice
= (PUSB_DEVICE
) DeviceHandle
;
253 if ((DeviceDescriptorBuffer
) && (DeviceDescriptorBufferLength
))
255 RtlCopyMemory(DeviceDescriptorBuffer
, &UsbDevice
->DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
256 *DeviceDescriptorBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
258 if ((ConfigDescriptorBuffer
) && (ConfigDescriptorBufferLength
))
260 RtlCopyMemory(ConfigDescriptorBuffer
, &UsbDevice
->ActiveConfig
->ConfigurationDescriptor
, sizeof(USB_CONFIGURATION_DESCRIPTOR
));
261 *ConfigDescriptorBufferLength
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
264 return STATUS_SUCCESS
;
269 RemoveUsbDevice(PVOID BusContext
, PUSB_DEVICE_HANDLE DeviceHandle
, ULONG Flags
)
271 DPRINT1("RemoveUsbDevice called\n");
272 return STATUS_SUCCESS
;
277 RestoreUsbDevice(PVOID BusContext
, PUSB_DEVICE_HANDLE OldDeviceHandle
, PUSB_DEVICE_HANDLE NewDeviceHandle
)
279 DPRINT1("RestoreUsbDevice called\n");
280 return STATUS_NOT_SUPPORTED
;
285 GetPortHackFlags(PVOID BusContext
, PULONG Flags
)
287 DPRINT1("GetPortHackFlags called\n");
288 return STATUS_NOT_SUPPORTED
;
293 QueryDeviceInformation(PVOID BusContext
,
294 PUSB_DEVICE_HANDLE DeviceHandle
,
295 PVOID DeviceInformationBuffer
,
296 ULONG DeviceInformationBufferLength
,
297 PULONG LengthReturned
)
299 PUSB_DEVICE_INFORMATION_0 DeviceInfo
= DeviceInformationBuffer
;
300 PUSB_DEVICE UsbDevice
= (PUSB_DEVICE
) DeviceHandle
;
304 DPRINT1("QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext
, DeviceHandle
, DeviceInformationBuffer
, DeviceInformationBufferLength
, LengthReturned
);
306 /* Search for a valid usb device in this BusContext */
307 if (!IsHandleValid(BusContext
, DeviceHandle
))
309 DPRINT1("Not a valid DeviceHandle\n");
310 return STATUS_INVALID_PARAMETER
;
313 SizeNeeded
= FIELD_OFFSET(USB_DEVICE_INFORMATION_0
, PipeList
[UsbDevice
->ActiveInterface
->InterfaceDescriptor
.bNumEndpoints
]);
314 *LengthReturned
= SizeNeeded
;
316 DeviceInfo
->ActualLength
= SizeNeeded
;
318 if (DeviceInformationBufferLength
< SizeNeeded
)
320 DPRINT1("Buffer to small\n");
321 return STATUS_BUFFER_TOO_SMALL
;
324 if (DeviceInfo
->InformationLevel
!= 0)
326 DPRINT1("Invalid Param\n");
327 return STATUS_INVALID_PARAMETER
;
330 DeviceInfo
->PortNumber
= UsbDevice
->Port
;
331 DeviceInfo
->HubAddress
= 1;
332 DeviceInfo
->DeviceAddress
= UsbDevice
->Address
;
333 DeviceInfo
->DeviceSpeed
= UsbDevice
->DeviceSpeed
;
334 DeviceInfo
->DeviceType
= UsbDevice
->DeviceType
;
335 DeviceInfo
->CurrentConfigurationValue
= UsbDevice
->ActiveConfig
->ConfigurationDescriptor
.bConfigurationValue
;
336 DeviceInfo
->NumberOfOpenPipes
= UsbDevice
->ActiveInterface
->InterfaceDescriptor
.bNumEndpoints
;
338 RtlCopyMemory(&DeviceInfo
->DeviceDescriptor
, &UsbDevice
->DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
340 for (i
= 0; i
< UsbDevice
->ActiveInterface
->InterfaceDescriptor
.bNumEndpoints
; i
++)
342 RtlCopyMemory(&DeviceInfo
->PipeList
[i
].EndpointDescriptor
, &UsbDevice
->ActiveInterface
->EndPoints
[i
]->EndPointDescriptor
, sizeof(USB_ENDPOINT_DESCRIPTOR
));
344 return STATUS_SUCCESS
;
349 GetControllerInformation(PVOID BusContext
,
350 PVOID ControllerInformationBuffer
,
351 ULONG ControllerInformationBufferLength
,
352 PULONG LengthReturned
)
354 PUSB_CONTROLLER_INFORMATION_0 ControllerInfo
;
356 DPRINT1("GetControllerInformation called\n");
358 ControllerInfo
= ControllerInformationBuffer
;
360 if (ControllerInformationBufferLength
< sizeof(USB_CONTROLLER_INFORMATION_0
))
362 DPRINT1("Buffer to small\n");
363 return STATUS_BUFFER_TOO_SMALL
;
366 if (ControllerInfo
->InformationLevel
!= 0)
368 DPRINT1("InformationLevel other than 0 not supported\n");
369 return STATUS_NOT_SUPPORTED
;
372 ControllerInfo
->ActualLength
= sizeof(USB_CONTROLLER_INFORMATION_0
);
373 ControllerInfo
->SelectiveSuspendEnabled
= FALSE
;
374 ControllerInfo
->IsHighSpeedController
= TRUE
;
376 *LengthReturned
= ControllerInfo
->ActualLength
;
378 return STATUS_SUCCESS
;
383 ControllerSelectiveSuspend(PVOID BusContext
, BOOLEAN Enable
)
385 DPRINT1("ControllerSelectiveSuspend called\n");
386 return STATUS_NOT_SUPPORTED
;
391 GetExtendedHubInformation(PVOID BusContext
,
392 PDEVICE_OBJECT HubPhysicalDeviceObject
,
393 PVOID HubInformationBuffer
,
394 ULONG HubInformationBufferLength
,
395 PULONG LengthReturned
)
398 PUSB_EXTHUB_INFORMATION_0 UsbExtHubInfo
= HubInformationBuffer
;
399 PPDO_DEVICE_EXTENSION PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)BusContext
)->DeviceExtension
;
400 PFDO_DEVICE_EXTENSION FdoDeviceExntension
= (PFDO_DEVICE_EXTENSION
)PdoDeviceExtension
->ControllerFdo
->DeviceExtension
;
402 DPRINT1("GetExtendedHubInformation\n");
403 /* Set the default return value */
405 /* Caller must have set InformationLevel to 0 */
406 if (UsbExtHubInfo
->InformationLevel
!= 0)
408 return STATUS_NOT_SUPPORTED
;
411 UsbExtHubInfo
->NumberOfPorts
= 8;
413 for (i
=0; i
< UsbExtHubInfo
->NumberOfPorts
; i
++)
415 UsbExtHubInfo
->Port
[i
].PhysicalPortNumber
= i
+ 1;
416 UsbExtHubInfo
->Port
[i
].PortLabelNumber
= FdoDeviceExntension
->ECHICaps
.HCSParams
.PortCount
;
417 UsbExtHubInfo
->Port
[i
].VidOverride
= 0;
418 UsbExtHubInfo
->Port
[i
].PidOverride
= 0;
419 UsbExtHubInfo
->Port
[i
].PortAttributes
= USB_PORTATTR_SHARED_USB2
;
422 *LengthReturned
= FIELD_OFFSET(USB_EXTHUB_INFORMATION_0
, Port
[8]);
424 return STATUS_SUCCESS
;
429 GetRootHubSymbolicName(PVOID BusContext
,
430 PVOID HubSymNameBuffer
,
431 ULONG HubSymNameBufferLength
,
432 PULONG HubSymNameActualLength
)
434 DPRINT1("GetRootHubSymbolicName called\n");
436 if (HubSymNameBufferLength
< 16)
437 return STATUS_UNSUCCESSFUL
;
438 RtlCopyMemory(HubSymNameBuffer
, L
"ROOT_HUB", HubSymNameBufferLength
);
439 *HubSymNameActualLength
= 16;
441 return STATUS_SUCCESS
;
446 GetDeviceBusContext(PVOID HubBusContext
, PVOID DeviceHandle
)
448 DPRINT1("GetDeviceBusContext called\n");
454 Initialize20Hub(PVOID BusContext
, PUSB_DEVICE_HANDLE HubDeviceHandle
, ULONG TtCount
)
456 DPRINT1("Initialize20Hub called, HubDeviceHandle: %x\n", HubDeviceHandle
);
459 /* Create the Irp Queue for SCE */
460 /* Should queue be created for each device or each enpoint??? */
461 return STATUS_SUCCESS
;
466 RootHubInitNotification(PVOID BusContext
, PVOID CallbackContext
, PRH_INIT_CALLBACK CallbackRoutine
)
468 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
469 DPRINT1("RootHubInitNotification %x, %x, %x\n", BusContext
, CallbackContext
, CallbackRoutine
);
471 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)BusContext
)->DeviceExtension
;
472 PdoDeviceExtension
->CallbackContext
= CallbackContext
;
473 PdoDeviceExtension
->CallbackRoutine
= CallbackRoutine
;
474 if (PdoDeviceExtension
->CallbackRoutine
)
476 DPRINT1("Called Callbackrountine\n");
477 PdoDeviceExtension
->CallbackRoutine(PdoDeviceExtension
->CallbackContext
);
478 DPRINT1("Done Callbackrountine\n");
482 DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n");
485 return STATUS_SUCCESS
;
490 FlushTransfers(PVOID BusContext
, PVOID DeviceHandle
)
492 DPRINT1("FlushTransfers\n");
497 SetDeviceHandleData(PVOID BusContext
, PVOID DeviceHandle
, PDEVICE_OBJECT UsbDevicePdo
)
499 DPRINT1("SetDeviceHandleData called\n");
503 /* USB_BUS_INTERFACE_USBDI_V2 Functions */
507 GetUSBDIVersion(PVOID BusContext
, PUSBD_VERSION_INFORMATION VersionInformation
, PULONG HcdCapabilites
)
509 DPRINT1("GetUSBDIVersion called\n");
515 QueryBusTime(PVOID BusContext
, PULONG CurrentFrame
)
517 DPRINT1("QueryBusTime called\n");
518 return STATUS_NOT_SUPPORTED
;
523 SubmitIsoOutUrb(PVOID BusContext
, PURB Urb
)
525 DPRINT1("SubmitIsoOutUrb called\n");
526 return STATUS_NOT_SUPPORTED
;
531 QueryBusInformation(PVOID BusContext
,
533 PVOID BusInformationBuffer
,
534 PULONG BusInformationBufferLength
,
535 PULONG BusInformationActualLength
)
537 DPRINT1("QueryBusInformation called\n");
538 return STATUS_NOT_SUPPORTED
;
543 IsDeviceHighSpeed(PVOID BusContext
)
545 DPRINT1("IsDeviceHighSpeed called\n");
551 EnumLogEntry(PVOID BusContext
, ULONG DriverTag
, ULONG EnumTag
, ULONG P1
, ULONG P2
)
553 DPRINT1("EnumLogEntry called\n");
554 return STATUS_NOT_SUPPORTED
;