Author: mjmartin Date: Thu Dec 30 15:12:46 2010 New Revision: 50223
URL: http://svn.reactos.org/svn/reactos?rev=50223&view=rev Log: [usb/usbehci]: - Reorganization code to put hardware related structures and routines in own source files. - Modify ResetPort to correctly reset the port instead of the controller. - Implement allocating chunks of memory from the Common Buffer for use with the rest of source code.
Added: trunk/reactos/drivers/usb/usbehci/hardware.c (with props) trunk/reactos/drivers/usb/usbehci/hardware.h (with props) trunk/reactos/drivers/usb/usbehci/physmem.c (with props) trunk/reactos/drivers/usb/usbehci/physmem.h (with props)
Added: trunk/reactos/drivers/usb/usbehci/hardware.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/hardwar... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/hardware.c (added) +++ trunk/reactos/drivers/usb/usbehci/hardware.c [iso-8859-1] Thu Dec 30 15:12:46 2010 @@ -1,0 +1,275 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbehci/hardware.c + * PURPOSE: Hardware related routines. + * PROGRAMMERS: + * Michael Martin (michael.martin@reactos.org) + */ + +#include "hardware.h" +#define NDEBUG +#include <debug.h> + +//FORCEINLINE +VOID +SetAsyncListQueueRegister(PEHCI_HOST_CONTROLLER hcd, ULONG PhysicalAddr) +{ + ULONG OpRegisters = hcd->OpRegisters; + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_ASYNCLISTBASE), PhysicalAddr); +} + +//FORCEINLINE +ULONG +GetAsyncListQueueRegister(PEHCI_HOST_CONTROLLER hcd) +{ + ULONG OpRegisters = hcd->OpRegisters; + return READ_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_ASYNCLISTBASE)); +} + +//FORCEINLINE +VOID +SetPeriodicFrameListRegister(PEHCI_HOST_CONTROLLER hcd, ULONG PhysicalAddr) +{ + ULONG OpRegisters = hcd->OpRegisters; + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_PERIODICLISTBASE), PhysicalAddr); +} + +//FORCEINLINE +ULONG +GetPeriodicFrameListRegister(PEHCI_HOST_CONTROLLER hcd) +{ + ULONG OpRegisters = hcd->OpRegisters; + return READ_REGISTER_ULONG((PULONG) (OpRegisters + EHCI_PERIODICLISTBASE)); +} + +//FORCEINLINE +ULONG +ReadControllerStatus(PEHCI_HOST_CONTROLLER hcd) +{ + ULONG OpRegisters = hcd->OpRegisters; + return READ_REGISTER_ULONG ((PULONG) (OpRegisters + EHCI_USBSTS)); +} + +//FORCEINLINE +VOID +ClearControllerStatus(PEHCI_HOST_CONTROLLER hcd, ULONG Status) +{ + ULONG OpRegisters = hcd->OpRegisters; + WRITE_REGISTER_ULONG((PULONG) (OpRegisters + EHCI_USBSTS), Status); +} + +VOID +ResetPort(PEHCI_HOST_CONTROLLER hcd, UCHAR Port) +{ + ULONG tmp; + ULONG OpRegisters = hcd->OpRegisters; + DPRINT1("Reset Port %x\n", Port); + + tmp = READ_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * Port))); + if (tmp & 0x400) + { + DPRINT1("Non HighSpeed device connected. Releasing ownership.\n"); + WRITE_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * Port)), 0x2000); + } + + /* Get current port state */ + tmp = READ_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * Port))); + + /* Set reset and clear enable */ + tmp |= 0x100; + tmp &= ~0x04; + WRITE_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * Port)), tmp); + + /* USB 2.0 Spec 10.2.8.1, more than 50ms */ + KeStallExecutionProcessor(100); + + /* Clear reset */ + tmp &= ~0x100; + WRITE_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * Port)), tmp); + + KeStallExecutionProcessor(100); + + tmp = READ_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * Port))); + + if (tmp & 0x100) + { + DPRINT1("EHCI ERROR: Port Reset did not complete!\n"); + } +} + +VOID +StopEhci(PEHCI_HOST_CONTROLLER hcd) +{ + ULONG OpRegisters = hcd->OpRegisters; + PEHCI_USBCMD_CONTENT UsbCmd; + PEHCI_USBSTS_CONTEXT UsbSts; + LONG FailSafe; + LONG tmp; + + DPRINT1("Stopping Ehci controller\n"); + + WRITE_REGISTER_ULONG((PULONG) (OpRegisters + EHCI_USBINTR), 0); + + tmp = READ_REGISTER_ULONG((PULONG) (OpRegisters + EHCI_USBCMD)); + UsbCmd = (PEHCI_USBCMD_CONTENT) & tmp; + UsbCmd->Run = FALSE; + WRITE_REGISTER_ULONG((PULONG) (OpRegisters + EHCI_USBCMD), tmp); + + /* Wait for the device to stop */ + for (FailSafe = 100; FailSafe > 1; FailSafe++) + { + KeStallExecutionProcessor(10); + tmp = READ_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBSTS)); + UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp; + + if (UsbSts->HCHalted) + { + break; + } + } + if (!UsbSts->HCHalted) + DPRINT1("EHCI ERROR: Controller is not responding to Stop request!\n"); +} + +VOID +StartEhci(PEHCI_HOST_CONTROLLER hcd) +{ + ULONG OpRegisters = hcd->OpRegisters; + PEHCI_USBCMD_CONTENT UsbCmd; + PEHCI_USBSTS_CONTEXT UsbSts; + LONG FailSafe; + LONG tmp; + LONG tmp2; + + DPRINT("Starting Ehci controller\n"); + + tmp = READ_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBSTS)); + UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp; + + if (!UsbSts->HCHalted) + { + StopEhci(hcd); + } + + tmp = READ_REGISTER_ULONG ((PULONG)(OpRegisters + EHCI_USBCMD)); + + /* Reset the device */ + UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; + UsbCmd->HCReset = TRUE; + WRITE_REGISTER_ULONG ((PULONG)(OpRegisters + EHCI_USBCMD), tmp); + + /* Wait for the device to reset */ + for (FailSafe = 100; FailSafe > 1; FailSafe++) + { + KeStallExecutionProcessor(10); + tmp = READ_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBCMD)); + UsbCmd = (PEHCI_USBCMD_CONTENT)&tmp; + + if (!UsbCmd->HCReset) + { + break; + } + DPRINT("Waiting for reset, USBCMD: %x\n", READ_REGISTER_ULONG ((PULONG)(OpRegisters + EHCI_USBCMD))); + } + + if (UsbCmd->HCReset) + { + DPRINT1("EHCI ERROR: Controller failed to reset! Will attempt to continue.\n"); + } + + UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; + + /* Disable Interrupts on the device */ + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBINTR), 0); + /* Clear the Status */ + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBSTS), 0x0000001f); + + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_CTRLDSSEGMENT), 0); + + SetAsyncListQueueRegister(hcd, hcd->AsyncListQueue->PhysicalAddr | QH_TYPE_QH); + /* Set the ansync and periodic to disable */ + UsbCmd->PeriodicEnable = FALSE; + UsbCmd->AsyncEnable = TRUE; + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBCMD), tmp); + + /* Set the threshold */ + UsbCmd->IntThreshold = 1; + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBCMD), tmp); + + /* Turn back on interrupts */ + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBINTR), + EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR + /*| EHCI_USBINTR_FLROVR*/ | EHCI_USBINTR_PC); + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBINTR), + EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR + /*| EHCI_USBINTR_FLROVR*/ | EHCI_USBINTR_PC); + + UsbCmd->Run = TRUE; + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBCMD), tmp); + + /* Wait for the device to start */ + for (;;) + { + KeStallExecutionProcessor(10); + tmp2 = READ_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_USBSTS)); + UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp2; + + if (!UsbSts->HCHalted) + { + break; + } + DPRINT("Waiting for start, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(OpRegisters + EHCI_USBSTS))); + } + + /* Set all port routing to ECHI controller */ + WRITE_REGISTER_ULONG((PULONG)(OpRegisters + EHCI_CONFIGFLAG), 1); +} + +VOID +GetCapabilities(PEHCI_CAPS PCap, ULONG CapRegister) +{ + PEHCI_HCS_CONTENT PHCS; + LONG i; + + if (!PCap) + return; + + PCap->Length = READ_REGISTER_UCHAR((PUCHAR)CapRegister); + PCap->Reserved = READ_REGISTER_UCHAR((PUCHAR)(CapRegister + 1)); + PCap->HCIVersion = READ_REGISTER_USHORT((PUSHORT)(CapRegister + 2)); + PCap->HCSParamsLong = READ_REGISTER_ULONG((PULONG)(CapRegister + 4)); + PCap->HCCParams = READ_REGISTER_ULONG((PULONG)(CapRegister + 8)); + + DPRINT1("Length %d\n", PCap->Length); + DPRINT1("Reserved %d\n", PCap->Reserved); + DPRINT1("HCIVersion %x\n", PCap->HCIVersion); + DPRINT1("HCSParams %x\n", PCap->HCSParamsLong); + DPRINT1("HCCParams %x\n", PCap->HCCParams); + + if (PCap->HCCParams & 0x02) + DPRINT1("Frame list size is configurable\n"); + + if (PCap->HCCParams & 0x01) + DPRINT1("64bit address mode not supported!\n"); + + DPRINT1("Number of Ports: %d\n", PCap->HCSParams.PortCount); + + if (PCap->HCSParams.PortPowerControl) + DPRINT1("Port Power Control is enabled\n"); + + if (!PCap->HCSParams.CHCCount) + { + DPRINT1("Number of Companion Host controllers %x\n", PCap->HCSParams.CHCCount); + DPRINT1("Number of Ports Per CHC: %d\n", PCap->HCSParams.PortPerCHC); + } + + PHCS = (PEHCI_HCS_CONTENT)&PCap->HCSParams; + if (PHCS->PortRouteRules) + { + for (i = 0; i < PCap->HCSParams.PortCount; i++) + { + PCap->PortRoute[i] = READ_REGISTER_UCHAR((PUCHAR) (CapRegister + 12 + i)); + } + } +}
Propchange: trunk/reactos/drivers/usb/usbehci/hardware.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/usb/usbehci/hardware.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/hardwar... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/hardware.h (added) +++ trunk/reactos/drivers/usb/usbehci/hardware.h [iso-8859-1] Thu Dec 30 15:12:46 2010 @@ -1,0 +1,307 @@ +#pragma once + +#include <ntddk.h> + +/* USB Command Register */ +#define EHCI_USBCMD 0x00 +#define EHCI_USBSTS 0x04 +#define EHCI_USBINTR 0x08 +#define EHCI_FRINDEX 0x0C +#define EHCI_CTRLDSSEGMENT 0x10 +#define EHCI_PERIODICLISTBASE 0x14 +#define EHCI_ASYNCLISTBASE 0x18 +#define EHCI_CONFIGFLAG 0x40 +#define EHCI_PORTSC 0x44 + +/* USB Interrupt Register Flags 32 Bits */ +#define EHCI_USBINTR_INTE 0x01 +#define EHCI_USBINTR_ERR 0x02 +#define EHCI_USBINTR_PC 0x04 +#define EHCI_USBINTR_FLROVR 0x08 +#define EHCI_USBINTR_HSERR 0x10 +#define EHCI_USBINTR_ASYNC 0x20 +/* Bits 6:31 Reserved */ + +/* Status Register Flags 32 Bits */ +#define EHCI_STS_INT 0x01 +#define EHCI_STS_ERR 0x02 +#define EHCI_STS_PCD 0x04 +#define EHCI_STS_FLR 0x08 +#define EHCI_STS_FATAL 0x10 +#define EHCI_STS_IAA 0x20 +/* Bits 11:6 Reserved */ +#define EHCI_STS_HALT 0x1000 +#define EHCI_STS_RECL 0x2000 +#define EHCI_STS_PSS 0x4000 +#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 + +typedef struct _PERIODICFRAMELIST +{ + PULONG VirtualAddr; + PHYSICAL_ADDRESS PhysicalAddr; + ULONG Size; +} PERIODICFRAMELIST, *PPERIODICFRAMELIST; + + +/* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */ +typedef struct _QETD_TOKEN_BITS +{ + ULONG PingState:1; + ULONG SplitTransactionState:1; + ULONG MissedMicroFrame:1; + ULONG TransactionError:1; + ULONG BabbleDetected: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 +{ + //Hardware + ULONG NextPointer; + ULONG AlternateNextPointer; + union + { + QETD_TOKEN_BITS Bits; + ULONG DWord; + } Token; + ULONG BufferPointer[5]; + + //Software + ULONG PhysicalAddr; + struct _QUEUE_TRANSFER_DESCRIPTOR *PreviousDescriptor; + struct _QUEUE_TRANSFER_DESCRIPTOR *NextDescriptor; +} QUEUE_TRANSFER_DESCRIPTOR, *PQUEUE_TRANSFER_DESCRIPTOR; + +/* EndPointSpeeds of END_POINT_CHARACTERISTICS */ +#define QH_ENDPOINT_FULLSPEED 0x00 +#define QH_ENDPOINT_LOWSPEED 0x01 +#define QH_ENDPOINT_HIGHSPEED 0x02 + +typedef struct _END_POINT_CHARACTERISTICS +{ + 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_CHARACTERISTICS, *PEND_POINT_CHARACTERISTICS; + +typedef struct _END_POINT_CAPABILITIES +{ + ULONG InterruptScheduleMask:8; + ULONG SplitCompletionMask:8; + ULONG HubAddr:6; + ULONG PortNumber:6; + /* Multi */ + ULONG NumberOfTransactionPerFrame:2; +} END_POINT_CAPABILITIES, *PEND_POINT_CAPABILITIES; + + +/* 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 +{ + //Hardware + ULONG HorizontalLinkPointer; + END_POINT_CHARACTERISTICS EndPointCharacteristics; + END_POINT_CAPABILITIES EndPointCapabilities; + /* TERMINATE_POINTER not valid for this member */ + ULONG CurrentLinkPointer; + /* TERMINATE_POINTER valid */ + ULONG NextPointer; + /* 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]; + + //Software + ULONG PhysicalAddr; + struct _QUEUE_HEAD *PreviousQueueHead; + struct _QUEUE_HEAD *NextQueueHead; + PQUEUE_TRANSFER_DESCRIPTOR TransferDescriptor; + PIRP IrpToComplete; + PMDL MdlToFree; + PKEVENT Event; +} QUEUE_HEAD, *PQUEUE_HEAD; + +/* 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; + ULONG PortPowerControl: 1; + ULONG Reserved : 2; + ULONG PortRouteRules : 1; + ULONG PortPerCHC : 4; + ULONG CHCCount : 4; + ULONG PortIndicator : 1; + ULONG Reserved2 : 3; + ULONG DbgPortNum : 4; + ULONG Reserved3 : 8; + +} EHCI_HCS_CONTENT, *PEHCI_HCS_CONTENT; + +typedef struct _EHCI_HCC_CONTENT +{ + ULONG CurAddrBits : 1; + ULONG VarFrameList : 1; + ULONG ParkMode : 1; + ULONG Reserved : 1; + ULONG IsoSchedThreshold : 4; + ULONG EECPCapable : 8; + ULONG Reserved2 : 16; + +} EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT; + +typedef struct _EHCI_CAPS { + UCHAR Length; + UCHAR Reserved; + USHORT HCIVersion; + union + { + EHCI_HCS_CONTENT HCSParams; + ULONG HCSParamsLong; + }; + ULONG HCCParams; + UCHAR PortRoute [8]; +} EHCI_CAPS, *PEHCI_CAPS; + +typedef struct _EHCI_HOST_CONTROLLER +{ + ULONG OpRegisters; + EHCI_CAPS ECHICaps; + PVOID CommonBufferVA; + PHYSICAL_ADDRESS CommonBufferPA; + ULONG CommonBufferSize; + PQUEUE_HEAD AsyncListQueue; + KSPIN_LOCK Lock; +} EHCI_HOST_CONTROLLER, *PEHCI_HOST_CONTROLLER; + +ULONG +ReadControllerStatus(PEHCI_HOST_CONTROLLER hcd); + +VOID +ClearControllerStatus(PEHCI_HOST_CONTROLLER hcd, ULONG Status); + +VOID +GetCapabilities(PEHCI_CAPS PCap, ULONG CapRegister); + +VOID +ResetPort(PEHCI_HOST_CONTROLLER hcd, UCHAR Port); + +VOID +StartEhci(PEHCI_HOST_CONTROLLER hcd); + +VOID +StopEhci(PEHCI_HOST_CONTROLLER hcd); + +VOID +SetAsyncListQueueRegister(PEHCI_HOST_CONTROLLER hcd, ULONG PhysicalAddr); + +ULONG +GetAsyncListQueueRegister(PEHCI_HOST_CONTROLLER hcd); + +VOID +SetPeriodicFrameListRegister(PEHCI_HOST_CONTROLLER hcd, ULONG PhysicalAddr); + +ULONG +GetPeriodicFrameListRegister(PEHCI_HOST_CONTROLLER hcd); +
Propchange: trunk/reactos/drivers/usb/usbehci/hardware.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/usb/usbehci/physmem.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/physmem... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/physmem.c (added) +++ trunk/reactos/drivers/usb/usbehci/physmem.c [iso-8859-1] Thu Dec 30 15:12:46 2010 @@ -1,0 +1,94 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbehci/physmem.c + * PURPOSE: Common Buffer routines. + * PROGRAMMERS: + * Michael Martin (michael.martin@reactos.org) + */ + +#include "physmem.h" +#include "debug.h" + +#define SMALL_ALLOCATION_SIZE 32 + +VOID +DumpPages() +{ + //PMEM_HEADER MemBlock = (PMEM_HEADER)EhciSharedMemory.VirtualAddr; +} + +// Returns Virtual Address of Allocated Memory +ULONG +AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress) +{ + PMEM_HEADER MemoryPage = (PMEM_HEADER)hcd->CommonBufferVA; + ULONG PageCount = 0; + ULONG NumberOfPages = hcd->CommonBufferSize / PAGE_SIZE; + ULONG BlocksNeeded; + ULONG i,j, freeCount; + ULONG RetAddr = 0; + + Size = ((Size + SMALL_ALLOCATION_SIZE - 1) / SMALL_ALLOCATION_SIZE) * SMALL_ALLOCATION_SIZE; + BlocksNeeded = Size / SMALL_ALLOCATION_SIZE; + + do + { + if (MemoryPage->IsFull) + { + PageCount++; + MemoryPage = (PMEM_HEADER)((ULONG)MemoryPage + PAGE_SIZE); + continue; + } + freeCount = 0; + for (i = 0; i < sizeof(MemoryPage->Entry); i++) + { + if (!MemoryPage->Entry[i].InUse) + { + freeCount++; + } + else + { + freeCount = 0; + } + + if (freeCount == BlocksNeeded) + { + for (j = 0; j < freeCount; j++) + { + MemoryPage->Entry[i-j].InUse = 1; + MemoryPage->Entry[i-j].Blocks = 0; + } + + MemoryPage->Entry[i-freeCount + 1].Blocks = BlocksNeeded; + + RetAddr = (ULONG)MemoryPage + (SMALL_ALLOCATION_SIZE * (i - freeCount + 1)) + sizeof(MEM_HEADER); + + *PhysicalAddress = (ULONG)hcd->CommonBufferPA.LowPart + (RetAddr - (ULONG)hcd->CommonBufferVA); + return RetAddr; + } + } + + PageCount++; + MemoryPage = (PMEM_HEADER)((ULONG)MemoryPage + PAGE_SIZE); + } while (PageCount < NumberOfPages); + + return 0; +} + +VOID +ReleaseMemory(ULONG Address) +{ + PMEM_HEADER MemoryPage; + ULONG Index, i; + + 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++) + { + MemoryPage->Entry[Index + i].InUse = 0; + MemoryPage->Entry[Index + i].Blocks = 0; + } +}
Propchange: trunk/reactos/drivers/usb/usbehci/physmem.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/usb/usbehci/physmem.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/physmem... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/physmem.h (added) +++ trunk/reactos/drivers/usb/usbehci/physmem.h [iso-8859-1] Thu Dec 30 15:12:46 2010 @@ -1,0 +1,25 @@ +#pragma once + +#include "hardware.h" + +typedef struct _MEM_ENTRY +{ + UCHAR InUse:1; + UCHAR Blocks:7; +} MEM_ENTRY, *PMEM_ENTRY; + +typedef struct _MEM_HEADER +{ + UCHAR IsFull; + MEM_ENTRY Entry[127]; +} MEM_HEADER, *PMEM_HEADER; + +VOID +DumpPages(); + +ULONG +AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress); + +VOID +ReleaseMemory(ULONG Address); +
Propchange: trunk/reactos/drivers/usb/usbehci/physmem.h ------------------------------------------------------------------------------ svn:eol-style = native