* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
-
-#define INITGUID
#include "libusb.h"
-VOID StatusChangeEndpointCallBack(
+#define NDEBUG
+#include <debug.h>
+
+VOID NTAPI StatusChangeEndpointCallBack(
PVOID Context);
class CHubController : public IHubController,
virtual NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
virtual NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
virtual NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
+ virtual NTSTATUS HandleSystemControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
// local functions
NTSTATUS HandleQueryInterface(PIO_STACK_LOCATION IoStack);
NTSTATUS HandleSyncResetAndClearStall(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleAbortPipe(IN OUT PIRP Irp, PURB Urb);
- friend VOID StatusChangeEndpointCallBack(PVOID Context);
+ friend VOID NTAPI StatusChangeEndpointCallBack(PVOID Context);
// constructor / destructor
CHubController(IUnknown *OuterUnknown){}
//Internal Functions
- BOOLEAN QueryStatusChageEndpoint(PIRP Irp);
+ BOOLEAN QueryStatusChangeEndpoint(PIRP Irp);
};
typedef struct
// Queries the ports to see if there has been a device connected or removed.
//
BOOLEAN
-CHubController::QueryStatusChageEndpoint(
+CHubController::QueryStatusChangeEndpoint(
PIRP Irp)
{
ULONG PortCount, PortId;
IN OUT PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
- PCOMMON_DEVICE_EXTENSION DeviceExtension;
PDEVICE_CAPABILITIES DeviceCapabilities;
PPNP_BUS_INFORMATION BusInformation;
PDEVICE_RELATIONS DeviceRelations;
WCHAR Buffer[300];
LPWSTR DeviceName;
- //
- // get device extension
- //
- DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
- ASSERT(DeviceExtension->IsFDO == FALSE);
-
//
// get current stack location
//
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp)
{
- UNIMPLEMENTED
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ Status = Irp->IoStatus.Status;
+ PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
+ return Status;
+}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleSystemControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN OUT PIRP Irp)
+{
+ NTSTATUS Status;
+ Status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
//-----------------------------------------------------------------------------------------
if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this) || Urb->UrbHeader.UsbdDeviceHandle == NULL)
{
ASSERT(m_PendingSCEIrp == NULL);
- if (QueryStatusChageEndpoint(Irp))
+ if (QueryStatusChangeEndpoint(Irp))
{
- StatusChangeEndpointCallBack(this);
+ //
+ // We've seen a change already, so return immediately
+ //
return STATUS_SUCCESS;
}
// select configuration
//
Status = UsbDevice->SelectConfiguration(Urb->UrbSelectConfiguration.ConfigurationDescriptor, &Urb->UrbSelectConfiguration.Interface, &Urb->UrbSelectConfiguration.ConfigurationHandle);
- if (NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status))
{
// successfully configured device
Urb->UrbSelectConfiguration.Hdr.Status = USBD_STATUS_SUCCESS;
Length = BufferLength > sizeof(USB_CONFIGURATION_DESCRIPTOR) ?
sizeof(USB_CONFIGURATION_DESCRIPTOR) : BufferLength;
RtlCopyMemory(Buffer, &ROOTHUB2_CONFIGURATION_DESCRIPTOR, Length);
-
+
//
// Check if we still have some space left
//
Length = BufferLength > sizeof(USB_INTERFACE_DESCRIPTOR) ?
sizeof(USB_INTERFACE_DESCRIPTOR) : BufferLength;
RtlCopyMemory(Buffer, &ROOTHUB2_INTERFACE_DESCRIPTOR, Length);
-
+
//
// Check if we still have some space left
//
//
Buffer += Length;
BufferLength -= Length;
-
-
+
+
//
// copy end point descriptor template
//
// get device
//
UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
-
+
//
// Allocate temporary buffer
//
// perform work in IUSBDevice
//
UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)Buffer, BufferLength, &Length);
-
+
//
// Copy what we can
//
- Length = Urb->UrbControlDescriptorRequest.TransferBufferLength > Length ?
+ Length = Urb->UrbControlDescriptorRequest.TransferBufferLength > Length ?
Length : Urb->UrbControlDescriptorRequest.TransferBufferLength;
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Buffer, Length);
-
+
//
// Free temporary buffer
//
UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
- DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n");
- DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
- DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
- DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer);
- DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL);
- DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
- DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request);
- DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
- DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
+ DPRINT("URB_FUNCTION_CLASS_INTERFACE\n");
+ DPRINT("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
+ DPRINT("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
+ DPRINT("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer);
+ DPRINT("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL);
+ DPRINT("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
+ DPRINT("Request %x\n", Urb->UrbControlVendorClassRequest.Request);
+ DPRINT("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
+ DPRINT("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
//
// initialize setup packet
IN OUT PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
- PCOMMON_DEVICE_EXTENSION DeviceExtension;
PURB Urb;
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
- //
- // get device extension
- //
- DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
//
// determine which request should be performed
//
return STATUS_SUCCESS;
}
+
+WORKER_THREAD_ROUTINE InitRootHub;
+
+VOID
+NTAPI
+InitRootHub(IN PVOID Context)
+{
+ PINIT_ROOT_HUB_CONTEXT WorkItem;
+
+ //
+ // get context
+ //
+ WorkItem = (PINIT_ROOT_HUB_CONTEXT)Context;
+
+ //
+ // perform callback
+ //
+ WorkItem->CallbackRoutine(WorkItem->CallbackContext);
+
+ //
+ // free contextg
+ //
+ ExFreePoolWithTag(Context, TAG_USBLIB);
+}
+
NTSTATUS
USB_BUSIFFN
USBHI_RootHubInitNotification(
PRH_INIT_CALLBACK CallbackRoutine)
{
CHubController * Controller;
+ PINIT_ROOT_HUB_CONTEXT WorkItem;
DPRINT("USBHI_RootHubInitNotification %p \n", CallbackContext);
Controller->SetNotification(CallbackContext, CallbackRoutine);
//
- // FIXME: determine when to perform callback
+ // Create and initialize work item data
+ //
+ WorkItem = (PINIT_ROOT_HUB_CONTEXT)ExAllocatePoolWithTag(NonPagedPool, sizeof(INIT_ROOT_HUB_CONTEXT), TAG_USBLIB);
+ if (!WorkItem)
+ {
+ DPRINT1("Failed to allocate memory!n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // init context
+ //
+ WorkItem->CallbackRoutine = CallbackRoutine;
+ WorkItem->CallbackContext = CallbackContext;
+
+ //
+ // Queue the work item to handle initializing the device
//
- CallbackRoutine(CallbackContext);
+ ExInitializeWorkItem(&WorkItem->WorkItem, InitRootHub, (PVOID)WorkItem);
+ ExQueueWorkItem(&WorkItem->WorkItem, DelayedWorkQueue);
//
// done
return STATUS_SUCCESS;
}
-VOID StatusChangeEndpointCallBack(PVOID Context)
+VOID NTAPI StatusChangeEndpointCallBack(PVOID Context)
{
CHubController* This;
PIRP Irp;
}
This->m_PendingSCEIrp = NULL;
- This->QueryStatusChageEndpoint(Irp);
+ This->QueryStatusChangeEndpoint(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;