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

View file

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

View file

@ -77,6 +77,9 @@ BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd, PURB Urb, PUSB_DEFAULT_PIPE_S
/* SET CONFIG */ /* SET CONFIG */
case URB_FUNCTION_SELECT_CONFIGURATION: case URB_FUNCTION_SELECT_CONFIGURATION:
CtrlSetup->bRequest = USB_REQUEST_SET_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; CtrlSetup->bmRequestType.B = 0x00;
break; break;
@ -111,7 +114,11 @@ BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd, PURB Urb, PUSB_DEFAULT_PIPE_S
/* SET INTERFACE*/ /* SET INTERFACE*/
case URB_FUNCTION_SELECT_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; break;
/* SYNC FRAME */ /* SYNC FRAME */
@ -150,18 +157,21 @@ SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
KeInitializeEvent(Event, NotificationEvent, FALSE); KeInitializeEvent(Event, NotificationEvent, FALSE);
} }
/* Allocate Mdl for Buffer */ if (TransferBuffer)
pMdl = IoAllocateMdl(TransferBuffer, {
TransferBufferLength, /* Allocate Mdl for Buffer */
FALSE, pMdl = IoAllocateMdl(TransferBuffer,
FALSE, TransferBufferLength,
NULL); FALSE,
FALSE,
NULL);
/* Lock Physical Pages */ /* Lock Physical Pages */
MmBuildMdlForNonPagedPool(pMdl); MmBuildMdlForNonPagedPool(pMdl);
//MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess); //MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
MdlPhysicalAddr = MmGetPhysicalAddress((PVOID)TransferBuffer).LowPart; MdlPhysicalAddr = MmGetPhysicalAddress((PVOID)TransferBuffer).LowPart;
}
QueueHead = CreateQueueHead(hcd); QueueHead = CreateQueueHead(hcd);
@ -175,9 +185,12 @@ SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
/* Save the first descriptor */ /* Save the first descriptor */
QueueHead->TransferDescriptor = Descriptor[0]; QueueHead->TransferDescriptor = Descriptor[0];
Descriptor[1] = CreateDescriptor(hcd, if (TransferBuffer)
PID_CODE_IN_TOKEN, {
TransferBufferLength); Descriptor[1] = CreateDescriptor(hcd,
PID_CODE_IN_TOKEN,
TransferBufferLength);
}
Descriptor[2] = CreateDescriptor(hcd, Descriptor[2] = CreateDescriptor(hcd,
PID_CODE_OUT_TOKEN, PID_CODE_OUT_TOKEN,
@ -186,17 +199,34 @@ SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
Descriptor[1]->Token.Bits.InterruptOnComplete = FALSE; Descriptor[1]->Token.Bits.InterruptOnComplete = FALSE;
/* Link the descriptors */ /* Link the descriptors */
Descriptor[0]->NextDescriptor = Descriptor[1];
Descriptor[1]->NextDescriptor = Descriptor[2]; if (TransferBuffer)
Descriptor[1]->PreviousDescriptor = Descriptor[0]; {
Descriptor[2]->PreviousDescriptor = Descriptor[1]; 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 */ /* Assign the descritors buffers */
Descriptor[0]->BufferPointer[0] = (ULONG)CtrlPhysicalPA; Descriptor[0]->BufferPointer[0] = (ULONG)CtrlPhysicalPA;
Descriptor[1]->BufferPointer[0] = MdlPhysicalAddr;
Descriptor[0]->NextPointer = Descriptor[1]->PhysicalAddr; if (TransferBuffer)
Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr; {
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->NextPointer = Descriptor[0]->PhysicalAddr;
QueueHead->IrpToComplete = IrpToComplete; QueueHead->IrpToComplete = IrpToComplete;

View file

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

View file

@ -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); UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT), USB_POOL_TAG);
RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]->EndPointDescriptor, RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]->EndPointDescriptor,
EndpointDesc, sizeof(USB_ENDPOINT_DESCRIPTOR)); EndpointDesc, sizeof(USB_ENDPOINT_DESCRIPTOR));
Ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
} }
} }
} }
UsbDevice->ActiveConfig = UsbDevice->Configs[0]; UsbDevice->ActiveConfig = UsbDevice->Configs[0];
UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0]; UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0];
return STATUS_SUCCESS; return STATUS_SUCCESS;
/* Set the device address */ /* Set the device address */
@ -251,6 +250,7 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
0, 0,
NULL); NULL);
PdoDeviceExtension->UsbDevices[i]->DeviceState = DEVICEINTIALIZED;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -334,15 +334,12 @@ RemoveUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, ULONG Flags)
} }
ExFreePool(UsbDevice); ExFreePool(UsbDevice);
/* DeConfig Device */
break; break;
case USBD_KEEP_DEVICE_DATA:
DPRINT1("USBD_KEEP_DEVICE_DATA Not implemented!\n");
break;
case USBD_MARK_DEVICE_BUSY: 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; break;
default: default:
DPRINT1("Unknown Remove Flags %x\n", Flags); DPRINT1("Unknown Remove Flags %x\n", Flags);
@ -354,8 +351,60 @@ NTSTATUS
USB_BUSIFFN USB_BUSIFFN
RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle) RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle)
{ {
DPRINT1("Ehci: RestoreUsbDevice not implemented! %x, %x, %x\n", BusContext, OldDeviceHandle, NewDeviceHandle); PUSB_DEVICE OldUsbDevice;
return STATUS_NOT_SUPPORTED; 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 NTSTATUS
@ -407,13 +456,24 @@ QueryDeviceInformation(PVOID BusContext,
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
DeviceInfo->PortNumber = UsbDevice->Port; DeviceInfo->HubAddress = 0;
DeviceInfo->HubAddress = 1;
DeviceInfo->DeviceAddress = UsbDevice->Address; DeviceInfo->DeviceAddress = UsbDevice->Address;
DeviceInfo->DeviceSpeed = UsbDevice->DeviceSpeed; DeviceInfo->DeviceSpeed = UsbDevice->DeviceSpeed;
DeviceInfo->DeviceType = UsbDevice->DeviceType; 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)); 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"); 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++) for (i=0; i < UsbExtHubInfo->NumberOfPorts; i++)
{ {
UsbExtHubInfo->Port[i].PhysicalPortNumber = i + 1; 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].VidOverride = 0;
UsbExtHubInfo->Port[i].PidOverride = 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]); *LengthReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]);
@ -600,7 +660,17 @@ VOID
USB_BUSIFFN USB_BUSIFFN
SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo) 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 USB_BUSIFFN
EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2) 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; return STATUS_SUCCESS;
} }