#define INITGUID
#include "usbehci.h"
+VOID StatusChangeEndpointCallBack(
+ PVOID Context);
+
class CHubController : public IHubController,
public IDispatchIrp
{
VOID SetNotification(PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine);
// internal ioctl routines
NTSTATUS HandleGetDescriptor(IN OUT PIRP Irp, PURB Urb);
+ NTSTATUS HandleGetDescriptorFromInterface(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleClassDevice(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleGetStatusFromDevice(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
+ NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
+ NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb);
+ NTSTATUS HandleClassEndpoint(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
+ NTSTATUS HandleIsochronousTransfer(IN OUT PIRP Irp, PURB Urb);
+ friend VOID StatusChangeEndpointCallBack(PVOID Context);
// constructor / destructor
CHubController(IUnknown *OuterUnknown){}
RTL_BITMAP m_DeviceAddressBitmap;
PULONG m_DeviceAddressBitmapBuffer;
LIST_ENTRY m_UsbDeviceList;
+ PIRP m_PendingSCEIrp;
+
+ //Internal Functions
+ BOOLEAN QueryStatusChageEndpoint(PIRP Irp);
};
typedef struct
};
-const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] =
+const USB_CONFIGURATION_DESCRIPTOR ROOTHUB2_CONFIGURATION_DESCRIPTOR =
{
- /* one configuration */
- 0x09, /* bLength; */
- 0x02, /* bDescriptorType; Configuration */
- 0x19, 0x00, /* wTotalLength; */
- 0x01, /* bNumInterfaces; (1) */
- 0x23, /* bConfigurationValue; */
- 0x00, /* iConfiguration; */
- 0x40, /* bmAttributes; */
- 0x00 /* MaxPower; */
+ sizeof(USB_CONFIGURATION_DESCRIPTOR),
+ USB_CONFIGURATION_DESCRIPTOR_TYPE,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
+ 1,
+ 1,
+ 0,
+ 0x40, /* self powered */
+ 0x0
};
-const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] =
+const USB_INTERFACE_DESCRIPTOR ROOTHUB2_INTERFACE_DESCRIPTOR =
{
- /* one interface */
- 0x09, /* bLength: Interface; */
- 0x04, /* bDescriptorType; Interface */
- 0x00, /* bInterfaceNumber; */
- 0x00, /* bAlternateSetting; */
- 0x01, /* bNumEndpoints; */
- 0x09, /* bInterfaceClass; HUB_CLASSCODE */
- 0x01, /* bInterfaceSubClass; */
- 0x00, /* bInterfaceProtocol: */
- 0x00 /* iInterface; */
+ sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType; Interface */
+ 0, /* bInterfaceNumber; */
+ 0, /* bAlternateSetting; */
+ 0x1, /* bNumEndpoints; */
+ 0x09, /* bInterfaceClass; HUB_CLASSCODE */
+ 0x01, /* bInterfaceSubClass; */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface; */
};
-const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
+const USB_ENDPOINT_DESCRIPTOR ROOTHUB2_ENDPOINT_DESCRIPTOR =
{
- /* one endpoint (status change endpoint) */
- 0x07, /* bLength; */
- 0x05, /* bDescriptorType; Endpoint */
- 0x81, /* bEndpointAddress; IN Endpoint 1 */
- 0x03, /* bmAttributes; Interrupt */
- 0x08, 0x00, /* wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
- 0xFF /* bInterval; (255ms -- usb 2.0 spec) */
+ sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 0x81, /* bEndPointAddress */
+ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
+ 0x01, /* wMaxPacketSize */
+ 0xC /* bInterval */
};
//----------------------------------------------------------------------------------------
m_DeviceDescriptor.bcdUSB = 0x200; //FIXME
}
+ //
+ // Set the SCE Callback that the Hardware Device will call on port status change
+ //
+ Device->SetStatusChangeEndpointCallBack((PVOID)StatusChangeEndpointCallBack, this);
+
//
// clear init flag
//
m_HubControllerDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
return STATUS_SUCCESS;
}
+//
+// Queries the ports to see if there has been a device connected or removed.
+//
+BOOLEAN
+CHubController::QueryStatusChageEndpoint(
+ PIRP Irp)
+{
+ ULONG PortCount, PortId;
+ PIO_STACK_LOCATION IoStack;
+ USHORT PortStatus, PortChange;
+ PURB Urb;
+ PUCHAR TransferBuffer;
+ UCHAR Changed = FALSE;
+
+ //
+ // get current stack location
+ //
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+ ASSERT(IoStack);
+
+ //
+ // Get the Urb
+ //
+ Urb = (PURB)IoStack->Parameters.Others.Argument1;
+ ASSERT(Urb);
+
+ //
+ // Get the number of ports and check each one for device connected
+ //
+ m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
+ DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
+
+ TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer;
+
+ //
+ // Loop the ports
+ //
+ for (PortId = 0; PortId < PortCount; PortId++)
+ {
+ m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
+
+ DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange);
+
+
+ //
+ // If theres a flag in PortChange return TRUE so the SCE Irp will be completed
+ //
+ if (PortChange != 0)
+ {
+ DPRINT1("Change state on port %d\n", PortId);
+ // Set the value for the port number
+ *TransferBuffer = 1 << ((PortId + 1) & 7);
+ Changed = TRUE;
+ }
+ }
+
+ return Changed;
+}
+
//-----------------------------------------------------------------------------------------
NTSTATUS
CHubController::GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject)
return STATUS_UNSUCCESSFUL;
}
- if (BufferLength < m_HubDeviceInterfaceString.Length - 8)
+ if (BufferLength < (ULONG)m_HubDeviceInterfaceString.Length - 8)
{
//
// buffer too small
DeviceCapabilities->HardwareDisabled = FALSE;
DeviceCapabilities->NoDisplayInUI = FALSE;
DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
- for (Index = 0; Index < PowerSystemMaximum; Index++)
+ for (Index = 1; Index < PowerSystemMaximum; Index++)
DeviceCapabilities->DeviceState[Index] = PowerDeviceD3;
DeviceCapabilities->DeviceWake = PowerDeviceUnspecified;
DeviceCapabilities->D1Latency = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED;
}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleIsochronousTransfer(
+ IN OUT PIRP Irp,
+ PURB Urb)
+{
+ PUSBDEVICE UsbDevice;
+ PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
+
+ //
+ // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
+ //
+ EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbIsochronousTransfer.PipeHandle;
+
+ if (!EndPointDesc)
+ {
+ DPRINT1("No EndpointDesc\n");
+ Urb->UrbIsochronousTransfer.Hdr.Status = USBD_STATUS_INVALID_PIPE_HANDLE;
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ //
+ // sanity checks
+ //
+ ASSERT(EndPointDesc);
+ ASSERT((EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_ISOCHRONOUS);
+
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleIsochronousTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ return UsbDevice->SubmitIrp(Irp);
+}
+
//-----------------------------------------------------------------------------------------
NTSTATUS
CHubController::HandleBulkOrInterruptTransfer(
IN OUT PIRP Irp,
PURB Urb)
{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ PUSBDEVICE UsbDevice;
+ PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
+ //
+ // First check if the request is for the Status Change Endpoint
+ //
+
+ //
+ // Is the Request for the root hub
+ //
+ if (Urb->UrbHeader.UsbdDeviceHandle == 0)
+ {
+ ASSERT(m_PendingSCEIrp == NULL);
+ if (QueryStatusChageEndpoint(Irp))
+ {
+ StatusChangeEndpointCallBack(this);
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // Else pend the IRP, to be completed when a device connects or disconnects.
+ //
+ DPRINT1("Pending SCE Irp\n");;
+ m_PendingSCEIrp = Irp;
+ IoMarkIrpPending(Irp);
+ return STATUS_PENDING;
+ }
+
+ //
+ // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
+ //
+ EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+
+ //
+ // sanity checks
+ //
+ ASSERT(EndPointDesc);
+ ASSERT((EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK || (EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT);
+
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleBulkOrInterruptTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ return UsbDevice->SubmitIrp(Irp);
}
//-----------------------------------------------------------------------------------------
ULONG NumPort;
ULONG PortId;
- //DPRINT1("CHubController::HandleClassOther> Request %x Value %x not implemented\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value);
+ DPRINT("CHubController::HandleClassOther> Request %x Value %x\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value);
//
// get number of ports available
//
// sanity check
//
- PC_ASSERT(Urb->UrbControlVendorClassRequest.Index - 1 < NumPort);
+ PC_ASSERT(Urb->UrbControlVendorClassRequest.Index - 1 < (USHORT)NumPort);
//
// port range reported start from 1 -n
//
// get port status
//
- //Status = m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
+ Status = m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
- Status = STATUS_SUCCESS;
if (NT_SUCCESS(Status))
{
//
// request contains buffer of 2 ushort which are used from submitting port status and port change status
//
+ DPRINT("PortId %x PortStatus %x PortChange %x\n", PortId, PortStatus, PortChange);
Buffer = (PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer;
//
switch (Urb->UrbControlVendorClassRequest.Value)
{
case C_PORT_CONNECTION:
- //Status = m_Hardware->ClearPortStatus(PortId, C_PORT_CONNECTION);
+ Status = m_Hardware->ClearPortStatus(PortId, C_PORT_CONNECTION);
break;
case C_PORT_RESET:
- //Status= m_Hardware->ClearPortStatus(PortId, C_PORT_RESET);
+ Status= m_Hardware->ClearPortStatus(PortId, C_PORT_RESET);
break;
default:
DPRINT("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value);
- PC_ASSERT(FALSE);
break;
}
//
// set suspend port feature
//
- Status = STATUS_SUCCESS; //m_Hardware->SetPortFeature(PortId, PORT_SUSPEND);
+ Status = m_Hardware->SetPortFeature(PortId, PORT_SUSPEND);
break;
}
case PORT_POWER:
//
// set power feature on port
//
- Status = STATUS_SUCCESS; //m_Hardware->SetPortFeature(PortId, PORT_POWER);
+ Status = m_Hardware->SetPortFeature(PortId, PORT_POWER);
break;
}
//
// reset port feature
//
- Status = m_Hardware->ResetPort(PortId);
+ Status = m_Hardware->SetPortFeature(PortId, PORT_RESET);
PC_ASSERT(Status == STATUS_SUCCESS);
break;
}
PC_ASSERT(0);
Status = STATUS_INVALID_DEVICE_REQUEST;
}
-
-
- return STATUS_SUCCESS;
+ return Status;
}
//-----------------------------------------------------------------------------------------
IN OUT PIRP Irp,
PURB Urb)
{
- //
- // sanity checks
- //
+ PUSBDEVICE UsbDevice;
+ PUSBD_INTERFACE_INFORMATION InterfaceInfo;
//
- // FIXME: support devices
+ // is the request for the Root Hub
//
- PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle == NULL);
+ if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+ {
+ //
+ // FIXME: support setting device to unconfigured state
+ //
+ PC_ASSERT(Urb->UrbSelectConfiguration.ConfigurationDescriptor);
- //
- // FIXME: support setting device to unconfigured state
- //
- PC_ASSERT(Urb->UrbSelectConfiguration.ConfigurationDescriptor);
+ //
+ // set device handle
+ //
+ Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&ROOTHUB2_CONFIGURATION_DESCRIPTOR;
+
+ //
+ // copy interface info
+ //
+ InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
+
+ InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&ROOTHUB2_INTERFACE_DESCRIPTOR;
+ InterfaceInfo->Class = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceClass;
+ InterfaceInfo->SubClass = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceSubClass;
+ InterfaceInfo->Protocol = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceProtocol;
+ InterfaceInfo->Reserved = 0;
+
+ //
+ // sanity check
+ //
+ PC_ASSERT(InterfaceInfo->NumberOfPipes == 1);
+
+ //
+ // copy pipe info
+ //
+ InterfaceInfo->Pipes[0].MaximumPacketSize = ROOTHUB2_ENDPOINT_DESCRIPTOR.wMaxPacketSize;
+ InterfaceInfo->Pipes[0].EndpointAddress = ROOTHUB2_ENDPOINT_DESCRIPTOR.bEndpointAddress;
+ InterfaceInfo->Pipes[0].Interval = ROOTHUB2_ENDPOINT_DESCRIPTOR.bInterval;
+ InterfaceInfo->Pipes[0].PipeType = (USBD_PIPE_TYPE)(ROOTHUB2_ENDPOINT_DESCRIPTOR.bmAttributes & USB_ENDPOINT_TYPE_MASK);
+ InterfaceInfo->Pipes[0].PipeHandle = (PVOID)&ROOTHUB2_ENDPOINT_DESCRIPTOR;
+
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleSelectConfiguration invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // select configuration
+ //
+ return UsbDevice->SelectConfiguration(Urb->UrbSelectConfiguration.ConfigurationDescriptor, &Urb->UrbSelectConfiguration.Interface, &Urb->UrbSelectConfiguration.ConfigurationHandle);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleSelectInterface(
+ IN OUT PIRP Irp,
+ PURB Urb)
+{
+ PUSBDEVICE UsbDevice;
//
- // set device handle
+ // sanity check
//
- Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)ROOTHUB2_CONFIGURATION_DESCRIPTOR;
+ PC_ASSERT(Urb->UrbSelectInterface.ConfigurationHandle);
//
- // TODO: copy interface info
+ // is the request for the Root Hub
//
- return STATUS_SUCCESS;
+ if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+ {
+ //
+ // no op for root hub
+ //
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleSelectInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // select interface
+ //
+ return UsbDevice->SelectInterface(Urb->UrbSelectInterface.ConfigurationHandle, &Urb->UrbSelectInterface.Interface);
+ }
}
//-----------------------------------------------------------------------------------------
IN OUT PIRP Irp,
PURB Urb)
{
- PUSHORT Status;
+ PUSHORT DeviceStatus;
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ NTSTATUS Status;
+ PUSBDEVICE UsbDevice;
//
// sanity checks
PC_ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBufferLength >= sizeof(USHORT));
PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBuffer);
- PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle == NULL);
//
// get status buffer
//
- Status = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
+ DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
+
+
+ if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+ {
+ //
+ // FIXME need more flags ?
+ //
+ *DeviceStatus = USB_PORT_STATUS_CONNECT;
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleGetStatusFromDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
//
- // FIXME need more flags ?
+ // get device
//
- *Status = USB_PORT_STATUS_CONNECT;
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+ //
+ // generate setup packet
+ //
+ CtrlSetup.bRequest = USB_REQUEST_GET_STATUS;
+ CtrlSetup.wValue.LowByte = 0;
+ CtrlSetup.wValue.HiByte = 0;
+ CtrlSetup.wIndex.W = Urb->UrbControlGetStatusRequest.Index;
+ CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength;
+ CtrlSetup.bmRequestType.B = 0x80;
+
+ //
+ // submit setup packet
+ //
+ Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
+ ASSERT(Status == STATUS_SUCCESS);
+ DPRINT1("CHubController::HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", Status, Urb->UrbControlDescriptorRequest.TransferBufferLength, *DeviceStatus);
//
// done
//
- return STATUS_SUCCESS;
+ return Status;
}
//-----------------------------------------------------------------------------------------
PUSB_HUB_DESCRIPTOR UsbHubDescriptor;
ULONG PortCount, Dummy2;
USHORT Dummy1;
+ PUSBDEVICE UsbDevice;
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+
+ DPRINT("CHubController::HandleClassDevice Request %x Class %x\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value >> 8);
//
// check class request type
//
switch(Urb->UrbControlVendorClassRequest.Request)
{
+ case USB_REQUEST_GET_STATUS:
+ {
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleClassDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+ //
+ // generate setup packet
+ //
+ CtrlSetup.bRequest = USB_REQUEST_GET_STATUS;
+ CtrlSetup.wValue.LowByte = Urb->UrbControlVendorClassRequest.Index;
+ CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+ CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+ CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength;
+ CtrlSetup.bmRequestType.B = 0xA0;
+
+ //
+ // submit setup packet
+ //
+ Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
+ ASSERT(Status == STATUS_SUCCESS);
+ break;
+ }
case USB_REQUEST_GET_DESCRIPTOR:
{
switch (Urb->UrbControlVendorClassRequest.Value >> 8)
//
// FIXME: retrieve values
//
- UsbHubDescriptor->bNumberOfPorts = PortCount;
- UsbHubDescriptor->wHubCharacteristics = 0x0012;
+ UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount;
+ UsbHubDescriptor->wHubCharacteristics = 0x00;
UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
UsbHubDescriptor->bHubControlCurrent = 0x00;
//
Status = STATUS_SUCCESS;
break;
- }
- default:
- DPRINT1("CHubController::HandleClassDevice Class %x not implemented\n", Urb->UrbControlVendorClassRequest.Value >> 8);
- break;
- }
- break;
- }
- default:
- DPRINT1("CHubController::HandleClassDevice Type %x not implemented\n", Urb->UrbControlVendorClassRequest.Request);
- }
+ }
+ default:
+ DPRINT1("CHubController::HandleClassDevice Class %x not implemented\n", Urb->UrbControlVendorClassRequest.Value >> 8);
+ break;
+ }
+ break;
+ }
+ default:
+ DPRINT1("CHubController::HandleClassDevice Type %x not implemented\n", Urb->UrbControlVendorClassRequest.Request);
+ }
+
+ return Status;
+}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleGetDescriptorFromInterface(
+ IN OUT PIRP Irp,
+ IN OUT PURB Urb)
+{
+ PUSBDEVICE UsbDevice;
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ NTSTATUS Status;
+
+ //
+ // sanity check
+ //
+ ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength);
+ ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
+
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleGetDescriptorFromInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // generate setup packet
+ //
+ CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+ CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
+ CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
+ CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
+ CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength;
+ CtrlSetup.bmRequestType.B = 0x81;
+
+ //
+ // submit setup packet
+ //
+ Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
+ ASSERT(Status == STATUS_SUCCESS);
+
+ //
+ // done
+ //
+ return Status;
+}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleGetDescriptor(
+ IN OUT PIRP Irp,
+ IN OUT PURB Urb)
+{
+ NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ PUCHAR Buffer;
+ PUSBDEVICE UsbDevice;
+ ULONG Length;
+
+ DPRINT("CHubController::HandleGetDescriptor\n");
+
+ //
+ // check descriptor type
+ //
+ switch(Urb->UrbControlDescriptorRequest.DescriptorType)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ {
+ //
+ // sanity check
+ //
+ PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
+ PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
+
+ if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+ {
+ //
+ // copy root hub device descriptor
+ //
+ RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleGetDescriptor invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // retrieve device descriptor from device
+ //
+ UsbDevice->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer);
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ }
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ {
+ //
+ // sanity checks
+ //
+ PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
+ PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
+
+ if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+ {
+ //
+ // request is for the root bus controller
+ //
+ RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR));
+
+ //
+ // get configuration descriptor, very retarded!
+ //
+ ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer;
+
+ //
+ // check if buffer can hold interface and endpoint descriptor
+ //
+ if (ConfigurationDescriptor->wTotalLength > Urb->UrbControlDescriptorRequest.TransferBufferLength)
+ {
+ //
+ // buffer too small
+ //
+ Status = STATUS_SUCCESS;
+ ASSERT(FALSE);
+ break;
+ }
+
+ //
+ // copy interface descriptor template
+ //
+ Buffer = (PUCHAR)(ConfigurationDescriptor + 1);
+ RtlCopyMemory(Buffer, &ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
+
+ //
+ // copy end point descriptor template
+ //
+ Buffer += sizeof(USB_INTERFACE_DESCRIPTOR);
+ RtlCopyMemory(Buffer, &ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
+
+ //
+ // done
+ //
+ Status = STATUS_SUCCESS;
+
+ }
+ else
+ {
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("USB_CONFIGURATION_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ if (sizeof(USB_CONFIGURATION_DESCRIPTOR) > Urb->UrbControlDescriptorRequest.TransferBufferLength)
+ {
+ //
+ // buffer too small
+ //
+ Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->GetConfigurationDescriptorsLength();
+
+ //
+ // bail out
+ //
+ Status = STATUS_SUCCESS;
+ break;
+ }
- return Status;
-}
-//-----------------------------------------------------------------------------------------
-NTSTATUS
-CHubController::HandleGetDescriptor(
- IN OUT PIRP Irp,
- IN OUT PURB Urb)
-{
- NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
- PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
- PUCHAR Buffer;
+ //
+ // perform work in IUSBDevice
+ //
+ UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength, &Length);
- //
- // check descriptor type
- //
- switch(Urb->UrbControlDescriptorRequest.DescriptorType)
- {
- case USB_DEVICE_DESCRIPTOR_TYPE:
- {
- //
- // sanity check
- //
- PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
+ //
+ // sanity check
+ //
+ PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= Length);
- if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
- {
//
- // copy root hub device descriptor
+ // store result size
//
- RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+ Urb->UrbControlDescriptorRequest.TransferBufferLength = Length;
Status = STATUS_SUCCESS;
- break;
}
break;
}
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ case USB_STRING_DESCRIPTOR_TYPE:
{
//
- // sanity checks
+ // sanity check
//
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
- PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
-
- //
- // FIXME: support devices
- //
- PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle == NULL);
+ PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength);
- //
- // copy configuration descriptor template
- //
- C_ASSERT(sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR) == sizeof(USB_CONFIGURATION_DESCRIPTOR));
- RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR));
-
- //
- // get configuration descriptor, very retarded!
- //
- ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer;
//
- // check if buffer can hold interface and endpoint descriptor
+ // check if this is a valid usb device handle
//
- if (ConfigurationDescriptor->wTotalLength > Urb->UrbControlDescriptorRequest.TransferBufferLength)
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
{
+ DPRINT1("USB_STRING_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
//
- // buffer too small
+ // invalid device handle
//
- Status = STATUS_SUCCESS;
- break;
+ return STATUS_DEVICE_NOT_CONNECTED;
}
//
- // copy interface descriptor template
+ // get device
//
- Buffer = (PUCHAR)(ConfigurationDescriptor + 1);
- C_ASSERT(sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR) == sizeof(USB_INTERFACE_DESCRIPTOR));
- RtlCopyMemory(Buffer, ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
//
- // copy end point descriptor template
+ // generate setup packet
//
- Buffer += sizeof(USB_INTERFACE_DESCRIPTOR);
- C_ASSERT(sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR) == sizeof(USB_ENDPOINT_DESCRIPTOR));
- RtlCopyMemory(Buffer, ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
+ CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+ CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
+ CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
+ CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
+ CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength;
+ CtrlSetup.bmRequestType.B = 0x80;
//
- // done
+ // submit setup packet
//
- Status = STATUS_SUCCESS;
+ Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
break;
}
default:
return Status;
}
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleClassEndpoint(
+ IN OUT PIRP Irp,
+ IN OUT PURB Urb)
+{
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ NTSTATUS Status;
+ PUSBDEVICE UsbDevice;
+
+ //
+ // sanity check
+ //
+ PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
+ PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
+ PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleClassEndpoint invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+ DPRINT1("URB_FUNCTION_CLASS_ENDPOINT\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);
+
+ //
+ // initialize setup packet
+ //
+ CtrlSetup.bmRequestType.B = 0xa2; //FIXME: Const.
+ CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
+ CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+ CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+ CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
+
+ //
+ // issue request
+ //
+ Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
+
+ //
+ // assert on failure
+ //
+ PC_ASSERT(NT_SUCCESS(Status));
+
+
+ //
+ // done
+ //
+ return Status;
+}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleClassInterface(
+ IN OUT PIRP Irp,
+ IN OUT PURB Urb)
+{
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ NTSTATUS Status;
+ PUSBDEVICE UsbDevice;
+
+ //
+ // sanity check
+ //
+ //ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer || Urb->UrbControlVendorClassRequest.TransferBufferMDL);
+ //ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
+ PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // check if this is a valid usb device handle
+ //
+ if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+ {
+ DPRINT1("HandleClassInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+ //
+ // invalid device handle
+ //
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // get device
+ //
+ 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);
+
+ //
+ // initialize setup packet
+ //
+ CtrlSetup.bmRequestType.B = 0xa1; //FIXME: Const.
+ CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
+ CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+ CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+ CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
+
+ //
+ // issue request
+ //
+ Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
+
+ //
+ // assert on failure
+ //
+ PC_ASSERT(NT_SUCCESS(Status));
+
+
+ //
+ // done
+ //
+ return Status;
+}
+
//-----------------------------------------------------------------------------------------
NTSTATUS
CHubController::HandleDeviceControl(
switch (Urb->UrbHeader.Function)
{
+ case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
+ Status = HandleGetDescriptorFromInterface(Irp, Urb);
+ break;
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
Status = HandleGetDescriptor(Irp, Urb);
break;
case URB_FUNCTION_SELECT_CONFIGURATION:
Status = HandleSelectConfiguration(Irp, Urb);
break;
+ case URB_FUNCTION_SELECT_INTERFACE:
+ Status = HandleSelectInterface(Irp, Urb);
+ break;
case URB_FUNCTION_CLASS_OTHER:
Status = HandleClassOther(Irp, Urb);
break;
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
Status = HandleBulkOrInterruptTransfer(Irp, Urb);
break;
+ case URB_FUNCTION_ISOCH_TRANSFER:
+ Status = HandleIsochronousTransfer(Irp, Urb);
+ break;
+ case URB_FUNCTION_CLASS_INTERFACE:
+ Status = HandleClassInterface(Irp, Urb);
+ break;
+ case URB_FUNCTION_CLASS_ENDPOINT:
+ Status = HandleClassEndpoint(Irp, Urb);
+ break;
default:
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
break;
}
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
{
- DPRINT("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
+ DPRINT("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %p\n", this);
if (IoStack->Parameters.Others.Argument1)
{
Irp->IoStatus.Information = sizeof(ULONG);
break;
}
+ case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
+ {
+ DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION UNIMPLEMENTED\n");
+ Status = STATUS_SUCCESS;
+ break;
+ }
default:
{
DPRINT1("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu NOT IMPLEMENTED\n",
break;
}
}
+ if (Status != STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//
// reserve address
//
- RtlSetBit(&m_DeviceAddressBitmap, DeviceAddress);
+ RtlSetBits(&m_DeviceAddressBitmap, DeviceAddress, 1);
//
// device addresses start from 0x1 - 0xFF
//
// clear bit
//
- RtlClearBit(&m_DeviceAddressBitmap, DeviceAddress);
+ RtlClearBits(&m_DeviceAddressBitmap, DeviceAddress, 1);
//
// release lock
//
// now set the device address
//
- Status = UsbDevice->SetDeviceAddress(DeviceAddress);
+ Status = UsbDevice->SetDeviceAddress((UCHAR)DeviceAddress);
if (NT_SUCCESS(Status))
break;
- }while(Index++ < 3 );
+ }while(Index++ < 3 );
//
// check for failure
{
PUSBDEVICE UsbDevice;
CHubController * Controller;
- NTSTATUS Status;
- PURB Urb;
DPRINT1("USBHI_GetUsbDescriptors\n");
// sanity check
//
PC_ASSERT(DeviceDescriptorBuffer);
+ PC_ASSERT(DeviceDescriptorBufferLength);
PC_ASSERT(*DeviceDescriptorBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
+ PC_ASSERT(ConfigDescriptorBufferLength);
+ PC_ASSERT(*ConfigDescriptorBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
//
// first get controller
*DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
//
- // allocate urb
- //
- Urb = (PURB)ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), TAG_USBEHCI);
- if (!Urb)
- {
- //
- // no memory
- //
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- //
- // zero request
- //
- RtlZeroMemory(Urb, sizeof(URB));
-
- //
- // initialize request
- //
- Urb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
- Urb->UrbHeader.Length = sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST);
- Urb->UrbControlDescriptorRequest.DescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE;
- Urb->UrbControlDescriptorRequest.TransferBuffer = ConfigDescriptorBuffer;
- Urb->UrbControlDescriptorRequest.TransferBufferLength = *ConfigDescriptorBufferLength;
-
- //
- // submit urb
- //
- Status = UsbDevice->SubmitUrb(Urb);
-
- if (NT_SUCCESS(Status))
- {
- //
- // TransferBufferLength holds the number of bytes transferred
- //
- *ConfigDescriptorBufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
- }
-
- //
- // free urb
+ // get configuration descriptor
//
- ExFreePoolWithTag(Urb, TAG_USBEHCI);
+ UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer, *ConfigDescriptorBufferLength, ConfigDescriptorBufferLength);
//
// complete the request
//
- return Status;
+ return STATUS_SUCCESS;
}
NTSTATUS
PUSB_DEVICE_HANDLE OldDeviceHandle,
PUSB_DEVICE_HANDLE NewDeviceHandle)
{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
+ PUSBDEVICE OldUsbDevice, NewUsbDevice;
+ CHubController * Controller;
-NTSTATUS
-USB_BUSIFFN
-USBHI_GetPortHackFlags(
- PVOID BusContext,
- PULONG Flags)
-{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ DPRINT1("USBHI_RestoreUsbDevice\n");
+
+ //
+ // first get controller
+ //
+ Controller = (CHubController *)BusContext;
+ PC_ASSERT(Controller);
+
+ //
+ // get device object
+ //
+ OldUsbDevice = (PUSBDEVICE)OldDeviceHandle;
+ NewUsbDevice = (PUSBDEVICE)NewDeviceHandle;
+ PC_ASSERT(OldUsbDevice);
+ PC_ASSERT(NewDeviceHandle);
+
+ //
+ // validate device handle
+ //
+ PC_ASSERT(Controller->ValidateUsbDevice(NewUsbDevice));
+ PC_ASSERT(Controller->ValidateUsbDevice(OldUsbDevice));
+
+ DPRINT1("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress());
+ DPRINT1("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress());
+
+ //
+ // remove old device handle
+ //
+ USBHI_RemoveUsbDevice(BusContext, OldDeviceHandle, 0);
+
+ return STATUS_SUCCESS;
}
NTSTATUS
DeviceInfo->NumberOfOpenPipes = 0; //FIXME
//
- // FIXME get device descriptor
+ // get device descriptor
//
+ RtlMoveMemory(&DeviceInfo->DeviceDescriptor, ROOTHUB2_DEVICE_DESCRIPTOR, sizeof(USB_DEVICE_DESCRIPTOR));
//
// FIXME return pipe information
//
// store result length
//
- *LengthReturned = sizeof(USB_DEVICE_INFORMATION_0);
-
+#ifdef _MSC_VER
+ *LengthReturned = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[DeviceInfo->NumberOfOpenPipes]);
+#else
+ *LengthReturned = sizeof(USB_DEVICE_INFORMATION_0) + (DeviceInfo->NumberOfOpenPipes > 1 ? (DeviceInfo->NumberOfOpenPipes - 1) * sizeof(USB_PIPE_INFORMATION_0) : 0);
+#endif
//
// done
//
// set length returned
//
*LengthReturned = ControllerInfo->ActualLength;
- return STATUS_NOT_IMPLEMENTED;
+
+ //
+ // done
+ //
+ return STATUS_SUCCESS;
}
NTSTATUS
PUSB_DEVICE_HANDLE HubDeviceHandle,
ULONG TtCount)
{
- UNIMPLEMENTED
+ DPRINT("USBHI_Initialize20Hub HubDeviceHandle %p UNIMPLEMENTED TtCount %lu\n", HubDeviceHandle, TtCount);
return STATUS_SUCCESS;
}
{
CHubController * Controller;
- DPRINT1("USBHI_RootHubInitNotification\n");
+ DPRINT("USBHI_RootHubInitNotification %p \n", CallbackContext);
//
// get controller object
//
return;
}
+ else
+ {
+ //
+ // usbhub sends this request as a part of the Pnp startup sequence
+ // looks like we need apply a dragon voodoo to fixup the device stack
+ // otherwise usbhub will cause a bugcheck
+ //
+ DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo);
- //
- // set device handle data
- //
- UsbDevice->SetDeviceHandleData(UsbDevicePdo);
+ //
+ // sanity check
+ //
+ PC_ASSERT(UsbDevicePdo->AttachedDevice);
+
+ //
+ // should be usbstor
+ // fixup device stack voodoo part #2
+ //
+ UsbDevicePdo->AttachedDevice->StackSize++;
+
+ //
+ // set device handle data
+ //
+ UsbDevice->SetDeviceHandleData(UsbDevicePdo);
+ }
}
//=================================================================================================
InterfaceHub->GetUsbDescriptors = USBHI_GetUsbDescriptors;
InterfaceHub->RemoveUsbDevice = USBHI_RemoveUsbDevice;
InterfaceHub->RestoreUsbDevice = USBHI_RestoreUsbDevice;
- InterfaceHub->GetPortHackFlags = USBHI_GetPortHackFlags;
InterfaceHub->QueryDeviceInformation = USBHI_QueryDeviceInformation;
}
//
// done
//
- return Status;
+ return STATUS_SUCCESS;
}
NTSTATUS
DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
+ //
+ // fixup device stack voodoo part #1
+ //
+ (*OutDeviceObject)->StackSize++;
+
/* done */
return Status;
}
//
return STATUS_SUCCESS;
}
+
+VOID StatusChangeEndpointCallBack(PVOID Context)
+{
+ CHubController* This;
+ PIRP Irp;
+ This = (CHubController*)Context;
+
+ ASSERT(This);
+
+ Irp = This->m_PendingSCEIrp;
+ if (!Irp)
+ {
+ DPRINT1("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n");
+ return;
+ }
+
+ This->m_PendingSCEIrp = NULL;
+ This->QueryStatusChageEndpoint(Irp);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}