if (UsbDevice == NULL)
UsbDevice = DeviceExtension->UsbDevices[0];
+ /* Assume URB success */
+ Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
+ /* Set the DeviceHandle to the Internal Device */
+ Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
+
switch (Urb->UrbHeader.Function)
{
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
{
- /* Are we suppose to only return on this request when a device is connected
- or is it the RootHubInitNotification Callback */
DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
DPRINT1("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
DPRINT1("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
DPRINT1("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
+ DPRINT1("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->EndPointDescriptor);
DPRINT1("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
- /* FIXME */
+
RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
- ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1;
- /* Turn off Irp handling as nothing is handled beyond this */
- DeviceExtension->HaltUrbHandling = TRUE;
+ if (UsbDevice == DeviceExtension->UsbDevices[0])
+ {
+ if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
+ {
+ LONG i;
+ for (i = 0; i < 8; i++)
+ {
+ if (DeviceExtension->Ports[i].PortChange)
+ {
+ DPRINT1("Inform hub driver that port %d has changed\n", i+1);
+ ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << (i + 1);
+ }
+ }
+ }
+ else
+ {
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ }
break;
}
case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
{
- DPRINT1("Get Status from Device\n");
+ DPRINT("Get Status from Device\n");
+ DPRINT("Index : %d\n", Urb->UrbControlGetStatusRequest.Index);
+
+ /* Copied from pvdrivers */
+ if (Urb->UrbControlGetStatusRequest.Index == 0)
+ {
+ *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
+ }
+ else
+ {
+ DPRINT1("Uknown identifier\n");
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ Status = STATUS_UNSUCCESSFUL;
+ }
break;
}
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
{
- Urb->UrbHeader.Function = 0x08;
- Urb->UrbHeader.UsbdFlags = 0;
- Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
-
switch(Urb->UrbControlDescriptorRequest.DescriptorType)
{
case USB_DEVICE_DESCRIPTOR_TYPE:
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
&UsbDevice->DeviceDescriptor,
Urb->UrbControlDescriptorRequest.TransferBufferLength);
-
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
-
break;
}
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
&UsbDevice->ConfigurationDescriptor,
Urb->UrbControlDescriptorRequest.TransferBufferLength);
-
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
-
break;
}
case USB_STRING_DESCRIPTOR_TYPE:
}
InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
}
-
- Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
- Urb->UrbHeader.UsbdFlags = 0;
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
}
else
{
DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n", Urb->UrbControlVendorClassRequest.Value);
-
switch (Urb->UrbControlVendorClassRequest.Value >> 8)
{
case USB_DEVICE_CLASS_AUDIO:
DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
}
}
- Urb->UrbHeader.Function = 0x08;
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
- Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
- Urb->UrbHeader.UsbdFlags = 0;
+ break;
+ }
+ case USB_REQUEST_GET_STATUS:
+ {
+ DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
+
+ if (Urb->UrbControlVendorClassRequest.Index == 1)
+ {
+ ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0;
+ }
break;
}
default:
{
case USB_REQUEST_GET_STATUS:
{
- DPRINT1("USB_REQUEST_GET_STATUS\n");
+ DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
+
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
break;
}
case USB_REQUEST_CLEAR_FEATURE:
{
- DPRINT1("USB_REQUEST_CLEAR_FEATURE\n");
+ DPRINT1("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+ switch (Urb->UrbControlVendorClassRequest.Value)
+ {
+ case C_PORT_CONNECTION:
+ DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT;
+ break;
+ case C_PORT_RESET:
+ DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET;
+ break;
+ default:
+ DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value);
+ break;
+ }
break;
}
case USB_REQUEST_SET_FEATURE:
{
- DPRINT1("USB_REQUEST_SET_FEATURE value %x\n", Urb->UrbControlVendorClassRequest.Value);
+ DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+
switch(Urb->UrbControlVendorClassRequest.Value)
{
- /* FIXME: Needs research */
- case 0x01:
+ case PORT_RESET:
{
+ DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |= USB_PORT_STATUS_RESET;
+ break;
+ }
+ case PORT_ENABLE:
+ {
+ DPRINT1("Unhandled Set Feature\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Set Feature!\n");
+ break;
}
}
break;
case USB_REQUEST_SET_ADDRESS:
{
DPRINT1("USB_REQUEST_SET_ADDRESS\n");
+ ASSERT(FALSE);
break;
}
case USB_REQUEST_GET_DESCRIPTOR:
DPRINT1("USB_REQUEST_SYNC_FRAME\n");
break;
}
+ default:
+ {
+ DPRINT1("Unknown Function Class Unknown request\n");
+ ASSERT(FALSE);
+ break;
+ }
}
break;
}
{
DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ ASSERT(FALSE);
}
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
+ if (Urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
+ {
+ /* Fake a successful Control Transfer */
+ Urb->UrbHeader.Function = 0x08;
+ Urb->UrbHeader.UsbdFlags = 0;
+ }
+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
}
}
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
+ DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE);
+ if (Stack->Parameters.Others.Argument1)
+ {
+ /* Return the root hubs devicehandle */
+ *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)PdoDeviceExtension->UsbDevices[0];
+ }
+ else
+ Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT\n");
-
+ DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
if (Stack->Parameters.Others.Argument1)
{
/* FIXME: Determine the number of hubs between the usb device and root hub */
- /* For now return 0 */
- *(PVOID *)Stack->Parameters.Others.Argument1 = 0;
+ /* For now return 1, the root hub */
+ *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)1;
}
break;
}
if (Stack->Parameters.Others.Argument2)
*(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDevice(FdoDeviceExtension->DeviceObject);
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- return STATUS_SUCCESS;
+ Information = 0;
+ Status = STATUS_SUCCESS;
break;
}
case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
}
}
- /* Lifted from hpoussin */
Status = DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&SourceString,
&String);
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
UNICODE_STRING InterfaceSymLinkName;
+ LONG i;
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
/* Create the root hub */
RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
+ for (i = 0; i < 8; i++)
+ {
+ PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_ENABLE;
+ PdoDeviceExtension->Ports[i].PortChange = 0;
+ }
+
RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
ROOTHUB2_DEVICE_DESCRIPTOR,
sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));
break;
}
case BusRelations:
+ DPRINT1("BusRelations!!!!!\n");
case RemovalRelations:
case EjectionRelations:
+ {
+ /* Ignore the request */
+ Information = Irp->IoStatus.Information;
+ Status = Irp->IoStatus.Status;
+ break;
+
+ }
default:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
else
{
DPRINT1("Not Supported\n");
- Status = STATUS_NOT_SUPPORTED;
+ Status = Irp->IoStatus.Status;
+ Information = Irp->IoStatus.Information;
}
break;
}
#define PING_STATE_DO_OUT 0x00
#define PING_STATE_DO_PING 0x01
+#define C_HUB_LOCAL_POWER 0
+#define C_HUB_OVER_CURRENT 1
+#define PORT_CONNECTION 0
+#define PORT_ENABLE 1
+#define PORT_SUSPEND 2
+#define PORT_OVER_CURRENT 3
+#define PORT_RESET 4
+#define PORT_POWER 8
+#define PORT_LOW_SPEED 9
+#define PORT_HIGH_SPEED 9
+#define C_PORT_CONNECTION 16
+#define C_PORT_ENABLE 17
+#define C_PORT_SUSPEND 18
+#define C_PORT_OVER_CURRENT 19
+#define C_PORT_RESET 20
+#define PORT_TEST 21
+#define PORT_INDICATOR 22
+#define USB_PORT_STATUS_CHANGE 0x4000
+
/* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */
typedef struct _QETD_TOKEN_BITS
{
} EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT;
typedef struct _EHCI_CAPS {
- UCHAR Length;
- UCHAR Reserved;
- USHORT HCIVersion;
+ UCHAR Length;
+ UCHAR Reserved;
+ USHORT HCIVersion;
union
{
- EHCI_HCS_CONTENT HCSParams;
- ULONG HCSParamsLong;
+ EHCI_HCS_CONTENT HCSParams;
+ ULONG HCSParamsLong;
};
- ULONG HCCParams;
- UCHAR PortRoute [8];
+ ULONG HCCParams;
+ UCHAR PortRoute [8];
} EHCI_CAPS, *PEHCI_CAPS;
typedef struct _COMMON_DEVICE_EXTENSION
PDEVICE_OBJECT DeviceObject;
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+typedef struct _EHCIPORTS
+{
+ ULONG PortNumber;
+ ULONG PortType;
+ USHORT PortStatus;
+ USHORT PortChange;
+} EHCIPORTS, *PEHCIPORTS;
+
typedef struct _FDO_DEVICE_EXTENSION
{
COMMON_DEVICE_EXTENSION Common;
PULONG PeriodicFramList;
PULONG AsyncListQueueHeadPtr;
- PHYSICAL_ADDRESS PeriodicFramListPhysAddr;
- PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr;
+ PHYSICAL_ADDRESS PeriodicFramListPhysAddr;
+ PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr;
BOOLEAN AsyncComplete;
BOOLEAN HaltUrbHandling;
PVOID CallbackContext;
PRH_INIT_CALLBACK CallbackRoutine;
+ ULONG NumberOfPorts;
+ EHCIPORTS Ports[32];
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
typedef struct _WORKITEM_DATA