[usb/usbehci]:

- Fix bug in InitializeUsbDevice that caused endpoints to be duplicated in internal config structure.
- Fix implementation of UsbRemoveDevice.
- Implement SetDeviceHandleData and RestoreUsbDevice.
- SubmitControlTransfer: Not all control request need data, in which case dont create a MDL and a PID_CODE_IN_TOKEN TD Descriptor.
- Fix bug in ReleaseMemory that caused memory not to be marked as free.
- Fix incorrect memory header size that resulted in memory corruption.

svn path=/trunk/; revision=50302
This commit is contained in:
Michael Martin 2011-01-06 17:46:59 +00:00
parent 6d1907d27b
commit 748ea2de6c
5 changed files with 169 additions and 61 deletions

View file

@ -31,7 +31,6 @@ AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress)
Size = ((Size + SMALL_ALLOCATION_SIZE - 1) / SMALL_ALLOCATION_SIZE) * SMALL_ALLOCATION_SIZE;
BlocksNeeded = Size / SMALL_ALLOCATION_SIZE;
do
{
if (MemoryPage->IsFull)
@ -52,6 +51,11 @@ AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress)
freeCount = 0;
}
if ((i-freeCount+1 + BlocksNeeded) > sizeof(MemoryPage->Entry))
{
freeCount = 0;
continue;
}
if (freeCount == BlocksNeeded)
{
for (j = 0; j < freeCount; j++)
@ -80,13 +84,13 @@ VOID
ReleaseMemory(ULONG Address)
{
PMEM_HEADER MemoryPage;
ULONG Index, i;
ULONG Index, i, BlockSize;
MemoryPage = (PMEM_HEADER)(Address & ~(PAGE_SIZE - 1));
Index = (Address - ((ULONG)MemoryPage + sizeof(MEM_HEADER))) / SMALL_ALLOCATION_SIZE;
for (i = 0; i < MemoryPage->Entry[Index].Blocks; i++)
BlockSize = MemoryPage->Entry[Index].Blocks;
for (i = 0; i < BlockSize; i++)
{
MemoryPage->Entry[Index + i].InUse = 0;
MemoryPage->Entry[Index + i].Blocks = 0;

View file

@ -11,7 +11,8 @@ typedef struct _MEM_ENTRY
typedef struct _MEM_HEADER
{
UCHAR IsFull;
MEM_ENTRY Entry[127];
MEM_ENTRY Entry[124];
UCHAR Reserved[3];
} MEM_HEADER, *PMEM_HEADER;
VOID

View file

@ -77,6 +77,9 @@ BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd, PURB Urb, PUSB_DEFAULT_PIPE_S
/* SET CONFIG */
case URB_FUNCTION_SELECT_CONFIGURATION:
CtrlSetup->bRequest = USB_REQUEST_SET_CONFIGURATION;
CtrlSetup->wValue.W = Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
CtrlSetup->wIndex.W = 0;
CtrlSetup->wLength = 0;
CtrlSetup->bmRequestType.B = 0x00;
break;
@ -111,7 +114,11 @@ BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd, PURB Urb, PUSB_DEFAULT_PIPE_S
/* SET INTERFACE*/
case URB_FUNCTION_SELECT_INTERFACE:
DPRINT1("Not implemented\n");
CtrlSetup->bRequest = USB_REQUEST_SET_INTERFACE;
CtrlSetup->wValue.W = Urb->UrbSelectInterface.Interface.AlternateSetting;
CtrlSetup->wIndex.W = Urb->UrbSelectInterface.Interface.InterfaceNumber;
CtrlSetup->wLength = 0;
CtrlSetup->bmRequestType.B = 0x01;
break;
/* SYNC FRAME */
@ -150,18 +157,21 @@ SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
KeInitializeEvent(Event, NotificationEvent, FALSE);
}
/* Allocate Mdl for Buffer */
pMdl = IoAllocateMdl(TransferBuffer,
TransferBufferLength,
FALSE,
FALSE,
NULL);
if (TransferBuffer)
{
/* Allocate Mdl for Buffer */
pMdl = IoAllocateMdl(TransferBuffer,
TransferBufferLength,
FALSE,
FALSE,
NULL);
/* Lock Physical Pages */
MmBuildMdlForNonPagedPool(pMdl);
//MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
/* Lock Physical Pages */
MmBuildMdlForNonPagedPool(pMdl);
//MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
MdlPhysicalAddr = MmGetPhysicalAddress((PVOID)TransferBuffer).LowPart;
MdlPhysicalAddr = MmGetPhysicalAddress((PVOID)TransferBuffer).LowPart;
}
QueueHead = CreateQueueHead(hcd);
@ -175,9 +185,12 @@ SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
/* Save the first descriptor */
QueueHead->TransferDescriptor = Descriptor[0];
Descriptor[1] = CreateDescriptor(hcd,
PID_CODE_IN_TOKEN,
TransferBufferLength);
if (TransferBuffer)
{
Descriptor[1] = CreateDescriptor(hcd,
PID_CODE_IN_TOKEN,
TransferBufferLength);
}
Descriptor[2] = CreateDescriptor(hcd,
PID_CODE_OUT_TOKEN,
@ -186,17 +199,34 @@ SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
Descriptor[1]->Token.Bits.InterruptOnComplete = FALSE;
/* Link the descriptors */
Descriptor[0]->NextDescriptor = Descriptor[1];
Descriptor[1]->NextDescriptor = Descriptor[2];
Descriptor[1]->PreviousDescriptor = Descriptor[0];
Descriptor[2]->PreviousDescriptor = Descriptor[1];
if (TransferBuffer)
{
Descriptor[0]->NextDescriptor = Descriptor[1];
Descriptor[1]->NextDescriptor = Descriptor[2];
Descriptor[1]->PreviousDescriptor = Descriptor[0];
Descriptor[2]->PreviousDescriptor = Descriptor[1];
}
else
{
Descriptor[0]->NextDescriptor = Descriptor[2];
Descriptor[2]->PreviousDescriptor = Descriptor[0];
}
/* Assign the descritors buffers */
Descriptor[0]->BufferPointer[0] = (ULONG)CtrlPhysicalPA;
Descriptor[1]->BufferPointer[0] = MdlPhysicalAddr;
Descriptor[0]->NextPointer = Descriptor[1]->PhysicalAddr;
Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr;
if (TransferBuffer)
{
Descriptor[1]->BufferPointer[0] = MdlPhysicalAddr;
Descriptor[0]->NextPointer = Descriptor[1]->PhysicalAddr;
Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr;
}
else
{
Descriptor[0]->NextPointer = Descriptor[2]->PhysicalAddr;
}
QueueHead->NextPointer = Descriptor[0]->PhysicalAddr;
QueueHead->IrpToComplete = IrpToComplete;

View file

@ -4,7 +4,7 @@
#include <ntifs.h>
#include <ntddk.h>
#include <stdio.h>
#define NDEBUG
#define NDEBUG
#include <debug.h>
#include <hubbusif.h>
#include <usbioctl.h>
@ -12,15 +12,16 @@
#define USB_POOL_TAG (ULONG)'ebsu'
#define DEVICEINTIALIZED 0x01
#define DEVICESTARTED 0x02
#define DEVICEBUSY 0x04
#define DEVICESTOPPED 0x08
#define DEVICESTALLED 0x10
#define DEVICEINTIALIZED 0x01
#define DEVICESTARTED 0x02
#define DEVICEBUSY 0x04
#define DEVICESTOPPED 0x08
#define DEVICESTALLED 0x10
#define DEVICEREMOVED 0x20
#define MAX_USB_DEVICES 127
#define EHCI_MAX_SIZE_TRANSFER 0x100000
#define MAX_USB_DEVICES 127
#define EHCI_MAX_SIZE_TRANSFER 0x100000
#define C_HUB_LOCAL_POWER 0
#define C_HUB_OVER_CURRENT 1
@ -71,6 +72,8 @@ typedef struct _USB_DEVICE
BOOLEAN IsHub;
USB_DEVICE_SPEED DeviceSpeed;
USB_DEVICE_TYPE DeviceType;
ULONG DeviceState;
PDEVICE_OBJECT UsbDevicePdo;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
UNICODE_STRING LanguageIDs;
UNICODE_STRING iManufacturer;

View file

@ -132,21 +132,21 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
CtrlSetup.wIndex.W = 0;
CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
CtrlSetup.bmRequestType.B = 0x80;
SubmitControlTransfer(&FdoDeviceExtension->hcd,
&CtrlSetup,
&UsbDevice->DeviceDescriptor,
sizeof(USB_DEVICE_DESCRIPTOR),
NULL);
//DumpDeviceDescriptor(&UsbDevice->DeviceDescriptor);
if (UsbDevice->DeviceDescriptor.bLength != 0x12)
{
DPRINT1("Failed to get Device Descriptor from device connected on port %d\n", UsbDevice->Port);
return STATUS_DEVICE_DATA_ERROR;
}
if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0)
{
DPRINT1("Device on port %d has no configurations!\n", UsbDevice->Port);
@ -171,7 +171,7 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
}
Ptr = Buffer;
for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++)
{
/* Get the Device Configuration Descriptor */
@ -184,7 +184,7 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
CtrlSetup.wIndex.W = 0;
CtrlSetup.wLength = PAGE_SIZE;
SubmitControlTransfer(&FdoDeviceExtension->hcd,
&CtrlSetup,
Buffer,
@ -223,14 +223,13 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT), USB_POOL_TAG);
RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]->EndPointDescriptor,
EndpointDesc, sizeof(USB_ENDPOINT_DESCRIPTOR));
Ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
}
}
}
UsbDevice->ActiveConfig = UsbDevice->Configs[0];
UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0];
return STATUS_SUCCESS;
/* Set the device address */
@ -244,13 +243,14 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
CtrlSetup.wLength = 0;
DPRINT1("Setting Address to %x\n", UsbDevice->Address);
SubmitControlTransfer(&FdoDeviceExtension->hcd,
&CtrlSetup,
NULL,
0,
NULL);
PdoDeviceExtension->UsbDevices[i]->DeviceState = DEVICEINTIALIZED;
return STATUS_SUCCESS;
}
@ -334,15 +334,12 @@ RemoveUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, ULONG Flags)
}
ExFreePool(UsbDevice);
/* DeConfig Device */
break;
case USBD_KEEP_DEVICE_DATA:
DPRINT1("USBD_KEEP_DEVICE_DATA Not implemented!\n");
break;
case USBD_MARK_DEVICE_BUSY:
DPRINT1("USBD_MARK_DEVICE_BUSY Not implemented!\n");
UsbDevice->DeviceState |= DEVICEBUSY;
/* Fall through */
case USBD_KEEP_DEVICE_DATA:
UsbDevice->DeviceState |= DEVICEREMOVED;
break;
default:
DPRINT1("Unknown Remove Flags %x\n", Flags);
@ -354,8 +351,60 @@ NTSTATUS
USB_BUSIFFN
RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle)
{
DPRINT1("Ehci: RestoreUsbDevice not implemented! %x, %x, %x\n", BusContext, OldDeviceHandle, NewDeviceHandle);
return STATUS_NOT_SUPPORTED;
PUSB_DEVICE OldUsbDevice;
PUSB_DEVICE NewUsbDevice;
DPRINT1("Ehci: RestoreUsbDevice %x, %x, %x\n", BusContext, OldDeviceHandle, NewDeviceHandle);
OldUsbDevice = DeviceHandleToUsbDevice(BusContext, OldDeviceHandle);
NewUsbDevice = DeviceHandleToUsbDevice(BusContext, NewDeviceHandle);
if (!OldUsbDevice)
{
DPRINT1("OldDeviceHandle is invalid\n");
return STATUS_DEVICE_NOT_CONNECTED;
}
if (!(OldUsbDevice->DeviceState & DEVICEREMOVED))
{
DPRINT1("UsbDevice is not marked as Removed!\n");
return STATUS_UNSUCCESSFUL;
}
if (!NewUsbDevice)
{
DPRINT1("NewDeviceHandle is invalid\n");
return STATUS_DEVICE_NOT_CONNECTED;
}
if ((OldUsbDevice->DeviceDescriptor.idVendor == NewUsbDevice->DeviceDescriptor.idVendor) &&
(OldUsbDevice->DeviceDescriptor.idProduct == NewUsbDevice->DeviceDescriptor.idProduct))
{
PUSB_CONFIGURATION ConfigToDelete;
int i;
NewUsbDevice->DeviceState &= ~DEVICEBUSY;
NewUsbDevice->DeviceState &= ~DEVICEREMOVED;
NewUsbDevice->ActiveConfig = OldUsbDevice->ActiveConfig;
NewUsbDevice->ActiveInterface = OldUsbDevice->ActiveInterface;
for (i = 0; i < NewUsbDevice->DeviceDescriptor.bNumConfigurations; i++)
{
ConfigToDelete = NewUsbDevice->Configs[i];
ASSERT(OldUsbDevice->Configs[i]);
NewUsbDevice->Configs[i] = OldUsbDevice->Configs[i];
OldUsbDevice->Configs[i] = ConfigToDelete;
}
RemoveUsbDevice(BusContext, OldDeviceHandle, 0);
return STATUS_SUCCESS;
}
else
{
DPRINT1("VendorId or ProductId did not match!\n");
return STATUS_DEVICE_NOT_CONNECTED;
}
}
NTSTATUS
@ -407,13 +456,24 @@ QueryDeviceInformation(PVOID BusContext,
return STATUS_INVALID_PARAMETER;
}
DeviceInfo->PortNumber = UsbDevice->Port;
DeviceInfo->HubAddress = 1;
DeviceInfo->HubAddress = 0;
DeviceInfo->DeviceAddress = UsbDevice->Address;
DeviceInfo->DeviceSpeed = UsbDevice->DeviceSpeed;
DeviceInfo->DeviceType = UsbDevice->DeviceType;
DeviceInfo->CurrentConfigurationValue = UsbDevice->ActiveConfig->ConfigurationDescriptor.bConfigurationValue;
DeviceInfo->NumberOfOpenPipes = UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints;
if (!UsbDevice->DeviceState)
{
DeviceInfo->CurrentConfigurationValue = 0;
DeviceInfo->NumberOfOpenPipes = 0;
DeviceInfo->PortNumber = 0;
}
else
{
DeviceInfo->CurrentConfigurationValue = UsbDevice->ActiveConfig->ConfigurationDescriptor.bConfigurationValue;
/* FIXME: Use correct number of open pipes instead of all available */
DeviceInfo->NumberOfOpenPipes = UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints;
DeviceInfo->PortNumber = UsbDevice->Port;
}
RtlCopyMemory(&DeviceInfo->DeviceDescriptor, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
@ -495,15 +555,15 @@ GetExtendedHubInformation(PVOID BusContext,
DPRINT1("InformationLevel should really be set to 0. Ignoring\n");
}
UsbExtHubInfo->NumberOfPorts = 8;
UsbExtHubInfo->NumberOfPorts = FdoDeviceExntension->hcd.ECHICaps.HCSParams.PortCount;
for (i=0; i < UsbExtHubInfo->NumberOfPorts; i++)
{
UsbExtHubInfo->Port[i].PhysicalPortNumber = i + 1;
UsbExtHubInfo->Port[i].PortLabelNumber = FdoDeviceExntension->hcd.ECHICaps.HCSParams.PortCount;
UsbExtHubInfo->Port[i].PortLabelNumber = i + 1;
UsbExtHubInfo->Port[i].VidOverride = 0;
UsbExtHubInfo->Port[i].PidOverride = 0;
UsbExtHubInfo->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2;
UsbExtHubInfo->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2;// | USB_PORTATTR_OWNED_BY_CC;
}
*LengthReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]);
@ -600,7 +660,17 @@ VOID
USB_BUSIFFN
SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo)
{
DPRINT1("Ehci: SetDeviceHandleData not implemented %x, %x, %x\n", BusContext, DeviceHandle, UsbDevicePdo);
PUSB_DEVICE UsbDevice;
DPRINT1("Ehci: SetDeviceHandleData %x, %x, %x\n", BusContext, DeviceHandle, UsbDevicePdo);
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
if (!UsbDevice)
{
DPRINT1("Invalid DeviceHandle or device not connected\n");
return;
}
UsbDevice->UsbDevicePdo = UsbDevicePdo;
}
@ -654,6 +724,6 @@ NTSTATUS
USB_BUSIFFN
EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2)
{
DPRINT1("Ehci: EnumLogEntry called\n");
DPRINT1("Ehci: EnumLogEntry called %x, %x, %x, %x\n", DriverTag, EnumTag, P1, P2);
return STATUS_SUCCESS;
}