mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[usb/usbehci]
- Added numerous structures required for Asynchronous Lists used to communicate with controller. Needs much more work. - Implement initial retrieving Device and String Descriptors from USB devices. - Fixed improper handling of Queued IRPs that was causing crashes. - For now, always queue the Irp if the request is a Urb of type Get Descriptor. - Reorganized code to trim down source files. svn path=/trunk/; revision=45017
This commit is contained in:
parent
f1e6ecbc60
commit
ce0ab52c93
9 changed files with 696 additions and 208 deletions
|
@ -1,3 +1,11 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/common.c
|
||||
* PURPOSE: Common operations in FDO/PDO.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
#define INITGUID
|
||||
#include "usbehci.h"
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/fdo.c
|
||||
* PURPOSE: USB EHCI device driver.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
#include "usbehci.h"
|
||||
|
@ -73,7 +81,7 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
|
|||
tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
|
||||
|
||||
DPRINT("port tmp %x\n", tmp);
|
||||
|
||||
GetDeviceDescriptor(FdoDeviceExtension, 0);
|
||||
FdoDeviceExtension->ChildDeviceCount++;
|
||||
CompletePendingRequest(FdoDeviceExtension);
|
||||
|
||||
|
@ -145,7 +153,7 @@ InterruptService(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
|||
|
||||
if (CStatus & EHCI_STS_HALT)
|
||||
{
|
||||
DPRINT("EHCI: Host Controller unexpected halt.\n");
|
||||
DPRINT1("EHCI: Host Controller unexpected halt.\n");
|
||||
/* FIXME: Reset the controller */
|
||||
}
|
||||
|
||||
|
|
144
reactos/drivers/usb/usbehci/irp.c
Normal file
144
reactos/drivers/usb/usbehci/irp.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/irp.c
|
||||
* PURPOSE: IRP Handling.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
#include "usbehci.h"
|
||||
|
||||
VOID
|
||||
RequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
|
||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
|
||||
|
||||
KIRQL OldIrql = Irp->CancelIrql;
|
||||
IoReleaseCancelSpinLock(DISPATCH_LEVEL);
|
||||
|
||||
KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->IrpQueueLock);
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
|
||||
KeReleaseSpinLock(&FdoDeviceExtension->IrpQueueLock, OldIrql);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
VOID
|
||||
QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &OldIrql);
|
||||
|
||||
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertTailList(&DeviceExtension->IrpQueue, &Irp->Tail.Overlay.ListEntry);
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PLIST_ENTRY NextIrp = NULL;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
KIRQL oldIrql;
|
||||
PIRP Irp = NULL;
|
||||
URB *Urb;
|
||||
|
||||
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
|
||||
|
||||
while(!IsListEmpty(&DeviceExtension->IrpQueue))
|
||||
{
|
||||
NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
|
||||
Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
|
||||
|
||||
if (!Irp)
|
||||
break;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
ASSERT(Stack);
|
||||
|
||||
Urb = (PURB) Stack->Parameters.Others.Argument1;
|
||||
ASSERT(Urb);
|
||||
|
||||
/* FIXME: Fill in information for Argument1/URB */
|
||||
|
||||
DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||
DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||
DPRINT("Index %x\n", Urb->UrbControlDescriptorRequest.Index);
|
||||
DPRINT("DescriptorType %x\n", Urb->UrbControlDescriptorRequest.DescriptorType);
|
||||
DPRINT("LanguageId %x\n", Urb->UrbControlDescriptorRequest.LanguageId);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ArrivalNotificationCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID PContext)
|
||||
{
|
||||
IoFreeIrp(Irp);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
VOID
|
||||
DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
PIO_STACK_LOCATION IrpStack = NULL;
|
||||
PDEVICE_OBJECT PortDeviceObject = NULL;
|
||||
PIRP Irp = NULL;
|
||||
|
||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
|
||||
|
||||
PortDeviceObject = IoGetAttachedDeviceReference(FdoDeviceExtension->Pdo);
|
||||
|
||||
if (!PortDeviceObject)
|
||||
{
|
||||
DPRINT1("Unable to notify Pdos parent of device arrival.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Irp = IoAllocateIrp(PortDeviceObject->StackSize, FALSE);
|
||||
|
||||
if (!Irp)
|
||||
{
|
||||
DPRINT1("Unable to allocate IRP\n");
|
||||
}
|
||||
|
||||
IoSetCompletionRoutine(Irp,
|
||||
(PIO_COMPLETION_ROUTINE)ArrivalNotificationCompletion,
|
||||
NULL,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
IrpStack = IoGetNextIrpStackLocation(Irp);
|
||||
IrpStack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
|
||||
IrpStack->MajorFunction = IRP_MJ_PNP;
|
||||
IrpStack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
|
||||
|
||||
IoCallDriver(PortDeviceObject, Irp);
|
||||
}
|
||||
|
|
@ -1,122 +1,14 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/misc.c
|
||||
* PURPOSE: Misceallenous operations.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
#include "usbehci.h"
|
||||
|
||||
VOID
|
||||
QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
|
||||
InsertTailList(&DeviceExtension->IrpQueue, &Irp->Tail.Overlay.ListEntry);
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||
}
|
||||
|
||||
VOID
|
||||
CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PLIST_ENTRY NextIrp = NULL;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
KIRQL oldIrql;
|
||||
PIRP Irp = NULL;
|
||||
URB *Urb;
|
||||
|
||||
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
|
||||
|
||||
/* No Irps in Queue? */
|
||||
if (IsListEmpty(&DeviceExtension->IrpQueue))
|
||||
{
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||
return;
|
||||
}
|
||||
|
||||
NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
|
||||
while(TRUE)
|
||||
{
|
||||
Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
|
||||
|
||||
if (!Irp)
|
||||
break;
|
||||
|
||||
/* FIXME: Handle cancels */
|
||||
/*if (!IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Urb = (PURB) Stack->Parameters.Others.Argument1;
|
||||
|
||||
ASSERT(Urb);
|
||||
|
||||
/* FIXME: Fill in information for Argument1/URB */
|
||||
|
||||
DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||
DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||
DPRINT("Index %x\n", Urb->UrbControlDescriptorRequest.Index);
|
||||
DPRINT("DescriptorType %x\n", Urb->UrbControlDescriptorRequest.DescriptorType);
|
||||
DPRINT("LanguageId %x\n", Urb->UrbControlDescriptorRequest.LanguageId);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ArrivalNotificationCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID PContext)
|
||||
{
|
||||
IoFreeIrp(Irp);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
VOID
|
||||
DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
PIO_STACK_LOCATION IrpStack = NULL;
|
||||
PDEVICE_OBJECT PortDeviceObject = NULL;
|
||||
PIRP Irp = NULL;
|
||||
|
||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
|
||||
|
||||
PortDeviceObject = IoGetAttachedDeviceReference(FdoDeviceExtension->Pdo);
|
||||
|
||||
if (!PortDeviceObject)
|
||||
{
|
||||
DPRINT1("Unable to notify Pdos parent of device arrival.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Irp = IoAllocateIrp(PortDeviceObject->StackSize, FALSE);
|
||||
|
||||
if (!Irp)
|
||||
{
|
||||
DPRINT1("Unable to allocate IRP\n");
|
||||
}
|
||||
|
||||
IoSetCompletionRoutine(Irp,
|
||||
(PIO_COMPLETION_ROUTINE)ArrivalNotificationCompletion,
|
||||
NULL,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
IrpStack = IoGetNextIrpStackLocation(Irp);
|
||||
IrpStack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
|
||||
IrpStack->MajorFunction = IRP_MJ_PNP;
|
||||
IrpStack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
|
||||
|
||||
IoCallDriver(PortDeviceObject, Irp);
|
||||
}
|
||||
|
||||
/*
|
||||
Get SymblicName from Parameters in Registry Key
|
||||
Caller is responsible for freeing pool of returned pointer
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/pdo.c
|
||||
* PURPOSE: USB EHCI device driver.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
#define INITGUID
|
||||
|
@ -55,24 +63,14 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
Urb = (PURB) Stack->Parameters.Others.Argument1;
|
||||
Urb->UrbHeader.Status = 0;
|
||||
|
||||
/* Check for ChildDevices */
|
||||
if (!FdoDeviceExtension->ChildDeviceCount)
|
||||
{
|
||||
/* No device has been plugged in yet. So just queue
|
||||
the irp and complete it when a device is connected */
|
||||
if (FdoDeviceExtension->DeviceState)
|
||||
QueueRequest(FdoDeviceExtension, Irp);
|
||||
DPRINT1("Irp->CancelRoutine %x\n",Irp->CancelRoutine);
|
||||
QueueRequest(FdoDeviceExtension, Irp);
|
||||
|
||||
Information = 0;
|
||||
|
||||
Information = 0;
|
||||
IoMarkIrpPending(Irp);
|
||||
Status = STATUS_PENDING;
|
||||
|
||||
IoMarkIrpPending(Irp);
|
||||
Status = STATUS_PENDING;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Reporting of device connects not implemented yet.\n");
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FIXME: Handle all other Functions */
|
||||
|
@ -158,7 +156,7 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
}
|
||||
default:
|
||||
{
|
||||
DPRINT("Unhandled IoControlCode %x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
|
||||
DPRINT1("Unhandled IoControlCode %x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
299
reactos/drivers/usb/usbehci/urbreq.c
Normal file
299
reactos/drivers/usb/usbehci/urbreq.c
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/urbreq.c
|
||||
* PURPOSE: URB Related Functions.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
#include "usbehci.h"
|
||||
|
||||
/* QueueHead must point to the base address in common buffer */
|
||||
PVOID
|
||||
IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
|
||||
PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD1,
|
||||
PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD2,
|
||||
PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD3,
|
||||
PEHCI_SETUP_FORMAT *CtrlSetup,
|
||||
PVOID *CtrlData,
|
||||
ULONG Size)
|
||||
{
|
||||
QueueHead->HorizontalLinkPointer = (ULONG)QueueHead | QH_TYPE_QH;
|
||||
|
||||
/* Set NakCountReload to max value possible */
|
||||
QueueHead->EndPointCapabilities1.NakCountReload = 0xF;
|
||||
|
||||
/* 1 for non high speed, 0 for high speed device */
|
||||
QueueHead->EndPointCapabilities1.ControlEndPointFlag = 0;
|
||||
|
||||
QueueHead->EndPointCapabilities1.HeadOfReclamation = TRUE;
|
||||
QueueHead->EndPointCapabilities1.MaximumPacketLength = 64;
|
||||
|
||||
/* Get the Initial Data Toggle from the QEDT */
|
||||
QueueHead->EndPointCapabilities1.QEDTDataToggleControl = TRUE;
|
||||
|
||||
/* HIGH SPEED DEVICE */
|
||||
QueueHead->EndPointCapabilities1.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
|
||||
QueueHead->EndPointCapabilities1.EndPointNumber = 0;
|
||||
|
||||
/* Only used for Periodic Schedule and Not High Speed devices.
|
||||
Setting it to one result in undefined behavior for Async */
|
||||
QueueHead->EndPointCapabilities1.InactiveOnNextTransaction = 0;
|
||||
|
||||
QueueHead->EndPointCapabilities1.DeviceAddress = 0;
|
||||
QueueHead->EndPointCapabilities2.HubAddr = 0;
|
||||
QueueHead->EndPointCapabilities2.NumberOfTransactionPerFrame = 0x01;
|
||||
|
||||
/* 0 For Async, 1 for periodoc schedule */
|
||||
QueueHead->EndPointCapabilities2.InterruptScheduleMask = 0;
|
||||
|
||||
QueueHead->EndPointCapabilities2.PortNumber = 0;
|
||||
QueueHead->EndPointCapabilities2.SplitCompletionMask = 0;
|
||||
QueueHead->CurrentLinkPointer = 0;
|
||||
QueueHead->QETDPointer = TERMINATE_POINTER;
|
||||
QueueHead->AlternateNextPointer = TERMINATE_POINTER;
|
||||
QueueHead->Token.Bits.InterruptOnComplete = TRUE;
|
||||
QueueHead->BufferPointer[0] = 0;
|
||||
QueueHead->BufferPointer[1] = 0;
|
||||
QueueHead->BufferPointer[2] = 0;
|
||||
QueueHead->BufferPointer[3] = 0;
|
||||
QueueHead->BufferPointer[4] = 0;
|
||||
/* Queue Head Initialized */
|
||||
|
||||
/* Queue Transfer Descriptors must be 32 byte aligned and reside in continous physical memory */
|
||||
*CtrlTD1 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(QueueHead) + sizeof(QUEUE_HEAD) + 0x1F) & ~0x1F);
|
||||
*CtrlTD2 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(*CtrlTD1) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0x1F) & ~0x1F);
|
||||
*CtrlTD3 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(*CtrlTD2) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0x1F) & ~0x1F);
|
||||
|
||||
/* Must be Page aligned */
|
||||
*CtrlSetup = (PEHCI_SETUP_FORMAT) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF) & ~0xFFF);
|
||||
*CtrlData = (PSTANDARD_DEVICE_DESC) (( (ULONG)(*CtrlSetup) + sizeof(EHCI_SETUP_FORMAT) + 0xFFF) & ~0xFFF);
|
||||
|
||||
(*CtrlTD1)->NextPointer = TERMINATE_POINTER;
|
||||
(*CtrlTD1)->AlternateNextPointer = TERMINATE_POINTER;
|
||||
(*CtrlTD1)->BufferPointer[0] = (ULONG)MmGetPhysicalAddress((PVOID) (*CtrlSetup)).LowPart;
|
||||
(*CtrlTD1)->Token.Bits.DataToggle = FALSE;
|
||||
(*CtrlTD1)->Token.Bits.InterruptOnComplete = FALSE;
|
||||
(*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(EHCI_SETUP_FORMAT);
|
||||
(*CtrlTD1)->Token.Bits.ErrorCounter = 0x03;
|
||||
(*CtrlTD1)->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN;
|
||||
(*CtrlTD1)->Token.Bits.Active = TRUE;
|
||||
|
||||
(*CtrlTD2)->NextPointer = TERMINATE_POINTER;
|
||||
(*CtrlTD2)->AlternateNextPointer = TERMINATE_POINTER;
|
||||
(*CtrlTD2)->BufferPointer[0] = (ULONG)MmGetPhysicalAddress((PVOID) (*CtrlData)).LowPart;
|
||||
(*CtrlTD2)->Token.Bits.DataToggle = TRUE;
|
||||
(*CtrlTD2)->Token.Bits.InterruptOnComplete = TRUE;
|
||||
(*CtrlTD2)->Token.Bits.TotalBytesToTransfer = Size;
|
||||
(*CtrlTD2)->Token.Bits.ErrorCounter = 0x03;
|
||||
(*CtrlTD2)->Token.Bits.PIDCode = PID_CODE_IN_TOKEN;
|
||||
(*CtrlTD2)->Token.Bits.Active = TRUE;
|
||||
|
||||
(*CtrlTD1)->NextPointer = (ULONG)MmGetPhysicalAddress((PVOID)(*CtrlTD2)).LowPart;
|
||||
|
||||
(*CtrlTD3)->NextPointer = TERMINATE_POINTER;
|
||||
(*CtrlTD3)->AlternateNextPointer = TERMINATE_POINTER;
|
||||
(*CtrlTD3)->BufferPointer[0] = 0;
|
||||
(*CtrlTD3)->Token.Bits.Active = TRUE;
|
||||
(*CtrlTD3)->Token.Bits.PIDCode = PID_CODE_OUT_TOKEN;
|
||||
(*CtrlTD3)->Token.Bits.InterruptOnComplete = TRUE;
|
||||
(*CtrlTD3)->Token.Bits.DataToggle = TRUE;
|
||||
(*CtrlTD3)->Token.Bits.ErrorCounter = 0x03;
|
||||
(*CtrlTD2)->NextPointer = (ULONG) MmGetPhysicalAddress((PVOID)(*CtrlTD3)).LowPart;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
||||
{
|
||||
PEHCI_SETUP_FORMAT CtrlSetup = NULL;
|
||||
PSTANDARD_DEVICE_DESC CtrlData = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
|
||||
PQUEUE_HEAD QueueHead;
|
||||
PEHCI_USBCMD_CONTENT UsbCmd;
|
||||
PEHCI_USBSTS_CONTEXT UsbSts;
|
||||
LONG Base;
|
||||
LONG tmp;
|
||||
|
||||
Base = (ULONG) DeviceExtension->ResourceMemory;
|
||||
|
||||
/* Set up the QUEUE HEAD in memory */
|
||||
QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
|
||||
|
||||
IntializeHeadQueueForStandardRequest(QueueHead,
|
||||
&CtrlTD1,
|
||||
&CtrlTD2,
|
||||
&CtrlTD3,
|
||||
&CtrlSetup,
|
||||
(PVOID)&CtrlData,
|
||||
sizeof(STANDARD_DEVICE_DESC));
|
||||
|
||||
/* FIXME: Use defines and handle other than Device Desciptors */
|
||||
CtrlSetup->bmRequestType = 0x80;
|
||||
CtrlSetup->bRequest = 0x06;
|
||||
CtrlSetup->wValue = 0x0100;
|
||||
CtrlSetup->wIndex = 0;
|
||||
CtrlSetup->wLength = sizeof(STANDARD_DEVICE_DESC);
|
||||
|
||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
UsbCmd->Run = FALSE;
|
||||
WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD), tmp);
|
||||
|
||||
/* Wait for the controller to halt */
|
||||
for (;;)
|
||||
{
|
||||
KeStallExecutionProcessor(10);
|
||||
tmp = READ_REGISTER_ULONG((PULONG)(Base + EHCI_USBSTS));
|
||||
UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp;
|
||||
DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(Base + EHCI_USBSTS)));
|
||||
if (UsbSts->HCHalted)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set to TRUE on interrupt for async completion */
|
||||
DeviceExtension->AsyncComplete = FALSE;
|
||||
QueueHead->QETDPointer = (ULONG) MmGetPhysicalAddress((PVOID)(CtrlTD1)).LowPart;
|
||||
|
||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
UsbCmd->AsyncEnable = TRUE;
|
||||
|
||||
WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
|
||||
|
||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
|
||||
/* Interrupt on Async completion */
|
||||
UsbCmd->DoorBell = TRUE;
|
||||
UsbCmd->Run = TRUE;
|
||||
WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
KeStallExecutionProcessor(10);
|
||||
DPRINT("Waiting for completion!\n");
|
||||
if (DeviceExtension->AsyncComplete == TRUE)
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT1("bLength %d\n", CtrlData->bLength);
|
||||
DPRINT1("bDescriptorType %x\n", CtrlData->bDescriptorType);
|
||||
DPRINT1("bcdUSB %x\n", CtrlData->bcdUSB);
|
||||
DPRINT1("CtrlData->bDeviceClass %x\n", CtrlData->bDeviceClass);
|
||||
DPRINT1("CtrlData->bDeviceSubClass %x\n", CtrlData->bDeviceSubClass);
|
||||
DPRINT1("CtrlData->bDeviceProtocal %x\n", CtrlData->bDeviceProtocal);
|
||||
DPRINT1("CtrlData->bMaxPacketSize %x\n", CtrlData->bMaxPacketSize);
|
||||
DPRINT1("CtrlData->idVendor %x\n", CtrlData->idVendor);
|
||||
DPRINT1("CtrlData->idProduct %x\n", CtrlData->idProduct);
|
||||
DPRINT1("CtrlData->bcdDevice %x\n", CtrlData->bcdDevice);
|
||||
DPRINT1("CtrlData->iManufacturer %x\n", CtrlData->iManufacturer);
|
||||
DPRINT1("CtrlData->iProduct %x\n", CtrlData->iProduct);
|
||||
DPRINT1("CtrlData->iSerialNumber %x\n", CtrlData->iSerialNumber);
|
||||
DPRINT1("CtrlData->bNumConfigurations %x\n", CtrlData->bNumConfigurations);
|
||||
|
||||
/* Temporary: Remove */
|
||||
if (CtrlData->bLength > 0)
|
||||
{
|
||||
/* We got valid data, try for strings */
|
||||
UCHAR Manufacturer = CtrlData->iManufacturer;
|
||||
UCHAR Product = CtrlData->iManufacturer;
|
||||
UCHAR SerialNumber = CtrlData->iSerialNumber;
|
||||
|
||||
GetDeviceStringDescriptor(DeviceExtension, Manufacturer);
|
||||
GetDeviceStringDescriptor(DeviceExtension, Product);
|
||||
GetDeviceStringDescriptor(DeviceExtension, SerialNumber);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
||||
{
|
||||
PEHCI_SETUP_FORMAT CtrlSetup = NULL;
|
||||
PSTRING_DESCRIPTOR CtrlData = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
|
||||
PQUEUE_HEAD QueueHead;
|
||||
PEHCI_USBCMD_CONTENT UsbCmd;
|
||||
PEHCI_USBSTS_CONTEXT UsbSts;
|
||||
LONG Base;
|
||||
LONG tmp;
|
||||
|
||||
Base = (ULONG) DeviceExtension->ResourceMemory;
|
||||
DPRINT1("Index: %d\n", Index);
|
||||
/* Set up the QUEUE HEAD in memory */
|
||||
QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
|
||||
|
||||
IntializeHeadQueueForStandardRequest(QueueHead,
|
||||
&CtrlTD1,
|
||||
&CtrlTD2,
|
||||
&CtrlTD3,
|
||||
&CtrlSetup,
|
||||
(PVOID)&CtrlData,
|
||||
sizeof(STRING_DESCRIPTOR) + 256);
|
||||
|
||||
/* FIXME: Use defines and handle other than Device Desciptors */
|
||||
CtrlSetup->bmRequestType = 0x80;
|
||||
CtrlSetup->bRequest = 0x06;
|
||||
CtrlSetup->wValue = 0x0300 | Index;
|
||||
CtrlSetup->wIndex = 0;
|
||||
/* 256 pulled from thin air */
|
||||
CtrlSetup->wLength = sizeof(STRING_DESCRIPTOR) + 256;
|
||||
|
||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
UsbCmd->Run = FALSE;
|
||||
WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD), tmp);
|
||||
|
||||
/* Wait for the controller to halt */
|
||||
for (;;)
|
||||
{
|
||||
KeStallExecutionProcessor(10);
|
||||
tmp = READ_REGISTER_ULONG((PULONG)(Base + EHCI_USBSTS));
|
||||
UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp;
|
||||
DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(Base + EHCI_USBSTS)));
|
||||
if (UsbSts->HCHalted)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set to TRUE on interrupt for async completion */
|
||||
DeviceExtension->AsyncComplete = FALSE;
|
||||
QueueHead->QETDPointer = (ULONG) MmGetPhysicalAddress((PVOID)(CtrlTD1)).LowPart;
|
||||
|
||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
UsbCmd->AsyncEnable = TRUE;
|
||||
|
||||
WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
|
||||
|
||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
|
||||
/* Interrupt on Async completion */
|
||||
UsbCmd->DoorBell = TRUE;
|
||||
UsbCmd->Run = TRUE;
|
||||
WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
KeStallExecutionProcessor(10);
|
||||
DPRINT("Waiting for completion!\n");
|
||||
if (DeviceExtension->AsyncComplete == TRUE)
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT1("String %S\n", &CtrlData->bString);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1,21 +1,10 @@
|
|||
/*
|
||||
* ReactOS USB ehci driver
|
||||
* Copyright (C) 2009 Michael Martin
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/usbehci.c
|
||||
* PURPOSE: USB EHCI device driver.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
/* DEFINES *******************************************************************/
|
||||
|
|
|
@ -53,6 +53,205 @@
|
|||
#define EHCI_STS_ASS 0x8000
|
||||
#define EHCI_ERROR_INT ( EHCI_STS_FATAL | EHCI_STS_ERR )
|
||||
|
||||
|
||||
/* Last bit in QUEUE ELEMENT TRANSFER DESCRIPTOR Next Pointer */
|
||||
/* Used for Queue Element Transfer Descriptor Pointers
|
||||
and Queue Head Horizontal Link Pointers */
|
||||
#define TERMINATE_POINTER 0x01
|
||||
|
||||
/* QUEUE ELEMENT TRANSFER DESCRIPTOR, Token defines and structs */
|
||||
|
||||
/* PIDCodes for QETD_TOKEN
|
||||
OR with QUEUE_TRANSFER_DESCRIPTOR Token.PIDCode*/
|
||||
#define PID_CODE_OUT_TOKEN 0x00
|
||||
#define PID_CODE_IN_TOKEN 0x01
|
||||
#define PID_CODE_SETUP_TOKEN 0x02
|
||||
|
||||
/* Split Transaction States
|
||||
OR with QUEUE_TRANSFER_DESCRIPTOR Token.SplitTransactionState */
|
||||
#define DO_START_SPLIT 0x00
|
||||
#define DO_COMPLETE_SPLIT 0x01
|
||||
|
||||
/* Ping States, OR with QUEUE_TRANSFER_DESCRIPTOR Token. */
|
||||
#define PING_STATE_DO_OUT 0x00
|
||||
#define PING_STATE_DO_PING 0x01
|
||||
|
||||
/* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */
|
||||
typedef struct _QETD_TOKEN_BITS
|
||||
{
|
||||
ULONG PingState:1;
|
||||
ULONG SplitTransactionState:1;
|
||||
ULONG MissedMicroFrame:1;
|
||||
ULONG TransactionError:1;
|
||||
ULONG BabbelDetected:1;
|
||||
ULONG DataBufferError:1;
|
||||
ULONG Halted:1;
|
||||
ULONG Active:1;
|
||||
ULONG PIDCode:2;
|
||||
ULONG ErrorCounter:2;
|
||||
ULONG CurrentPage:3;
|
||||
ULONG InterruptOnComplete:1;
|
||||
ULONG TotalBytesToTransfer:15;
|
||||
ULONG DataToggle:1;
|
||||
} QETD_TOKEN_BITS, *PQETD_TOKEN_BITS;
|
||||
|
||||
|
||||
/* QUEUE ELEMENT TRANSFER DESCRIPTOR */
|
||||
typedef struct _QUEUE_TRANSFER_DESCRIPTOR
|
||||
{
|
||||
ULONG NextPointer;
|
||||
ULONG AlternateNextPointer;
|
||||
union
|
||||
{
|
||||
QETD_TOKEN_BITS Bits;
|
||||
ULONG DWord;
|
||||
} Token;
|
||||
ULONG BufferPointer[5];
|
||||
} QUEUE_TRANSFER_DESCRIPTOR, *PQUEUE_TRANSFER_DESCRIPTOR;
|
||||
|
||||
/* EndPointSpeeds of END_POINT_CAPABILITIES */
|
||||
#define QH_ENDPOINT_FULLSPEED 0x00
|
||||
#define QH_ENDPOINT_LOWSPEED 0x01
|
||||
#define QH_ENDPOINT_HIGHSPEED 0x02
|
||||
|
||||
typedef struct _END_POINT_CAPABILITIES1
|
||||
{
|
||||
ULONG DeviceAddress:7;
|
||||
ULONG InactiveOnNextTransaction:1;
|
||||
ULONG EndPointNumber:4;
|
||||
ULONG EndPointSpeed:2;
|
||||
ULONG QEDTDataToggleControl:1;
|
||||
ULONG HeadOfReclamation:1;
|
||||
ULONG MaximumPacketLength:11;
|
||||
ULONG ControlEndPointFlag:1;
|
||||
ULONG NakCountReload:4;
|
||||
} END_POINT_CAPABILITIES1, *PEND_POINT_CAPABILITIES1;
|
||||
|
||||
typedef struct _END_POINT_CAPABILITIES2
|
||||
{
|
||||
ULONG InterruptScheduleMask:8;
|
||||
ULONG SplitCompletionMask:8;
|
||||
ULONG HubAddr:6;
|
||||
ULONG PortNumber:6;
|
||||
/* Multi */
|
||||
ULONG NumberOfTransactionPerFrame:2;
|
||||
} END_POINT_CAPABILITIES2, *PEND_POINT_CAPABILITIES2;
|
||||
|
||||
|
||||
/* QUEUE HEAD defines and structs */
|
||||
|
||||
/* QUEUE HEAD Select Types, OR with QUEUE_HEAD HorizontalLinkPointer */
|
||||
#define QH_TYPE_IDT 0x00
|
||||
#define QH_TYPE_QH 0x02
|
||||
#define QH_TYPE_SITD 0x04
|
||||
#define QH_TYPE_FSTN 0x06
|
||||
|
||||
/* QUEUE HEAD */
|
||||
typedef struct _QUEUE_HEAD
|
||||
{
|
||||
ULONG HorizontalLinkPointer;
|
||||
END_POINT_CAPABILITIES1 EndPointCapabilities1;
|
||||
END_POINT_CAPABILITIES2 EndPointCapabilities2;
|
||||
/* TERMINATE_POINTER not valid for this member */
|
||||
ULONG CurrentLinkPointer;
|
||||
/* TERMINATE_POINTER valid */
|
||||
ULONG QETDPointer;
|
||||
/* TERMINATE_POINTER valid, bits 1:4 is NAK_COUNTER */
|
||||
ULONG AlternateNextPointer;
|
||||
/* Only DataToggle, InterruptOnComplete, ErrorCounter, PingState valid */
|
||||
union
|
||||
{
|
||||
QETD_TOKEN_BITS Bits;
|
||||
ULONG DWord;
|
||||
} Token;
|
||||
ULONG BufferPointer[5];
|
||||
} QUEUE_HEAD, *PQUEUE_HEAD;
|
||||
|
||||
typedef struct _EHCI_SETUP_FORMAT
|
||||
{
|
||||
UCHAR bmRequestType;
|
||||
UCHAR bRequest;
|
||||
USHORT wValue;
|
||||
USHORT wIndex;
|
||||
USHORT wLength;
|
||||
} EHCI_SETUP_FORMAT, *PEHCI_SETUP_FORMAT;
|
||||
|
||||
typedef struct _STANDARD_DEVICE_DESC
|
||||
{
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
USHORT bcdUSB;
|
||||
UCHAR bDeviceClass;
|
||||
UCHAR bDeviceSubClass;
|
||||
UCHAR bDeviceProtocal;
|
||||
UCHAR bMaxPacketSize;
|
||||
USHORT idVendor;
|
||||
USHORT idProduct;
|
||||
USHORT bcdDevice;
|
||||
UCHAR iManufacturer;
|
||||
UCHAR iProduct;
|
||||
UCHAR iSerialNumber;
|
||||
UCHAR bNumConfigurations;
|
||||
} STANDARD_DEVICE_DESC, *PSTANDARD_DEVICE_DESC;
|
||||
|
||||
typedef struct _STRING_DESCRIPTOR
|
||||
{
|
||||
UCHAR bLength; /* Size of this descriptor in bytes */
|
||||
UCHAR bDescriptorType; /* STRING Descriptor Type */
|
||||
UCHAR bString[0]; /* UNICODE encoded string */
|
||||
} STRING_DESCRIPTOR, *PSTRING_DESCRIPTOR;
|
||||
|
||||
/* USBCMD register 32 bits */
|
||||
typedef struct _EHCI_USBCMD_CONTENT
|
||||
{
|
||||
ULONG Run : 1;
|
||||
ULONG HCReset : 1;
|
||||
ULONG FrameListSize : 2;
|
||||
ULONG PeriodicEnable : 1;
|
||||
ULONG AsyncEnable : 1;
|
||||
ULONG DoorBell : 1;
|
||||
ULONG LightReset : 1;
|
||||
ULONG AsyncParkCount : 2;
|
||||
ULONG Reserved : 1;
|
||||
ULONG AsyncParkEnable : 1;
|
||||
ULONG Reserved1 : 4;
|
||||
ULONG IntThreshold : 8;
|
||||
ULONG Reserved2 : 8;
|
||||
|
||||
} EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
|
||||
|
||||
typedef struct _EHCI_USBSTS_CONTENT
|
||||
{
|
||||
ULONG USBInterrupt:1;
|
||||
ULONG ErrorInterrupt:1;
|
||||
ULONG DetectChangeInterrupt:1;
|
||||
ULONG FrameListRolloverInterrupt:1;
|
||||
ULONG HostSystemErrorInterrupt:1;
|
||||
ULONG AsyncAdvanceInterrupt:1;
|
||||
ULONG Reserved:6;
|
||||
ULONG HCHalted:1;
|
||||
ULONG Reclamation:1;
|
||||
ULONG PeriodicScheduleStatus:1;
|
||||
ULONG AsynchronousScheduleStatus:1;
|
||||
} EHCI_USBSTS_CONTEXT, *PEHCI_USBSTS_CONTEXT;
|
||||
|
||||
typedef struct _EHCI_USBPORTSC_CONTENT
|
||||
{
|
||||
ULONG CurrentConnectStatus:1;
|
||||
ULONG ConnectStatusChange:1;
|
||||
ULONG PortEnabled:1;
|
||||
ULONG PortEnableChanged:1;
|
||||
ULONG OverCurrentActive:1;
|
||||
ULONG OverCurrentChange:1;
|
||||
ULONG ForcePortResume:1;
|
||||
ULONG Suspend:1;
|
||||
ULONG PortReset:1;
|
||||
ULONG Reserved:1;
|
||||
ULONG LineStatus:2;
|
||||
ULONG PortPower:1;
|
||||
ULONG PortOwner:1;
|
||||
} EHCI_USBPORTSC_CONTENT, *PEHCI_USBPORTSC_CONTENT;
|
||||
|
||||
typedef struct _EHCI_HCS_CONTENT
|
||||
{
|
||||
ULONG PortCount : 4;
|
||||
|
@ -167,57 +366,6 @@ typedef struct _PDO_DEVICE_EXTENSION
|
|||
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* USBCMD register 32 bits */
|
||||
typedef struct _EHCI_USBCMD_CONTENT
|
||||
{
|
||||
ULONG Run : 1;
|
||||
ULONG HCReset : 1;
|
||||
ULONG FrameListSize : 2;
|
||||
ULONG PeriodicEnable : 1;
|
||||
ULONG AsyncEnable : 1;
|
||||
ULONG DoorBell : 1;
|
||||
ULONG LightReset : 1;
|
||||
ULONG AsyncParkCount : 2;
|
||||
ULONG Reserved : 1;
|
||||
ULONG AsyncParkEnable : 1;
|
||||
ULONG Reserved1 : 4;
|
||||
ULONG IntThreshold : 8;
|
||||
ULONG Reserved2 : 8;
|
||||
|
||||
} EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
|
||||
|
||||
typedef struct _EHCI_USBSTS_CONTENT
|
||||
{
|
||||
ULONG USBInterrupt:1;
|
||||
ULONG ErrorInterrupt:1;
|
||||
ULONG DetectChangeInterrupt:1;
|
||||
ULONG FrameListRolloverInterrupt:1;
|
||||
ULONG HostSystemErrorInterrupt:1;
|
||||
ULONG AsyncAdvanceInterrupt:1;
|
||||
ULONG Reserved:6;
|
||||
ULONG HCHalted:1;
|
||||
ULONG Reclamation:1;
|
||||
ULONG PeriodicScheduleStatus:1;
|
||||
ULONG AsynchronousScheduleStatus:1;
|
||||
} EHCI_USBSTS_CONTEXT, *PEHCI_USBSTS_CONTEXT;
|
||||
|
||||
typedef struct _EHCI_USBPORTSC_CONTENT
|
||||
{
|
||||
ULONG CurrentConnectStatus:1;
|
||||
ULONG ConnectStatusChange:1;
|
||||
ULONG PortEnabled:1;
|
||||
ULONG PortEnableChanged:1;
|
||||
ULONG OverCurrentActive:1;
|
||||
ULONG OverCurrentChange:1;
|
||||
ULONG ForcePortResume:1;
|
||||
ULONG Suspend:1;
|
||||
ULONG PortReset:1;
|
||||
ULONG Reserved:1;
|
||||
ULONG LineStatus:2;
|
||||
ULONG PortPower:1;
|
||||
ULONG PortOwner:1;
|
||||
} EHCI_USBPORTSC_CONTENT, *PEHCI_USBPORTSC_CONTENT;
|
||||
|
||||
NTSTATUS NTAPI
|
||||
GetBusInterface(PDEVICE_OBJECT pcifido, PBUS_INTERFACE_STANDARD busInterface);
|
||||
|
||||
|
@ -252,13 +400,10 @@ NTSTATUS NTAPI
|
|||
PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
||||
BOOLEAN
|
||||
GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, USHORT Port);
|
||||
GetDeviceDescriptor (PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index);
|
||||
|
||||
BOOLEAN
|
||||
GetDeviceDescriptor2(PFDO_DEVICE_EXTENSION DeviceExtension, USHORT Port);
|
||||
|
||||
BOOLEAN
|
||||
GetStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, ULONG DecriptorStringNumber);
|
||||
GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index);
|
||||
|
||||
VOID
|
||||
CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension);
|
||||
|
@ -275,4 +420,7 @@ CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension);
|
|||
VOID
|
||||
DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context);
|
||||
|
||||
VOID
|
||||
RequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,4 +8,6 @@
|
|||
<file>pdo.c</file>
|
||||
<file>common.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>irp.c</file>
|
||||
<file>urbreq.c</file>
|
||||
</module>
|
||||
|
|
Loading…
Reference in a new issue