2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbehci/physmem.c
5 * PURPOSE: Common Buffer routines.
7 * Michael Martin (michael.martin@reactos.org)
13 #define SMALL_ALLOCATION_SIZE 32
18 //PMEM_HEADER MemBlock = (PMEM_HEADER)EhciSharedMemory.VirtualAddr;
21 // Returns Virtual Address of Allocated Memory
23 AllocateMemory(PEHCI_HOST_CONTROLLER hcd
, ULONG Size
, ULONG
*PhysicalAddress
)
25 PMEM_HEADER MemoryPage
= NULL
;
27 ULONG NumberOfPages
= hcd
->CommonBufferSize
/ PAGE_SIZE
;
28 ULONG BlocksNeeded
= 0;
32 MemoryPage
= (PMEM_HEADER
)hcd
->CommonBufferVA
[0];
33 Size
= ((Size
+ SMALL_ALLOCATION_SIZE
- 1) / SMALL_ALLOCATION_SIZE
) * SMALL_ALLOCATION_SIZE
;
34 BlocksNeeded
= Size
/ SMALL_ALLOCATION_SIZE
;
38 if (MemoryPage
->IsFull
)
42 if (!(PMEM_HEADER
)hcd
->CommonBufferVA
[PageCount
])
44 hcd
->CommonBufferVA
[PageCount
] =
45 hcd
->pDmaAdapter
->DmaOperations
->AllocateCommonBuffer(hcd
->pDmaAdapter
,
47 &hcd
->CommonBufferPA
[PageCount
],
50 MemoryPage
= (PMEM_HEADER
)hcd
->CommonBufferVA
[PageCount
];
54 for (i
= 0; i
< sizeof(MemoryPage
->Entry
); i
++)
56 if (!MemoryPage
->Entry
[i
].InUse
)
65 if ((i
-freeCount
+1 + BlocksNeeded
) > sizeof(MemoryPage
->Entry
))
71 if (freeCount
== BlocksNeeded
)
73 for (j
= 0; j
< freeCount
; j
++)
75 MemoryPage
->Entry
[i
-j
].InUse
= 1;
76 MemoryPage
->Entry
[i
-j
].Blocks
= 0;
79 MemoryPage
->Entry
[i
-freeCount
+ 1].Blocks
= BlocksNeeded
;
81 RetAddr
= (ULONG
)MemoryPage
+ (SMALL_ALLOCATION_SIZE
* (i
- freeCount
+ 1)) + sizeof(MEM_HEADER
);
83 *(ULONG
*)PhysicalAddress
= (ULONG
)hcd
->CommonBufferPA
[PageCount
].LowPart
+ (RetAddr
- (ULONG
)hcd
->CommonBufferVA
[PageCount
]);
90 if (!(PMEM_HEADER
)hcd
->CommonBufferVA
[PageCount
])
93 hcd
->CommonBufferVA
[PageCount
] =
94 hcd
->pDmaAdapter
->DmaOperations
->AllocateCommonBuffer(hcd
->pDmaAdapter
,
96 &hcd
->CommonBufferPA
[PageCount
],
98 DPRINT1("Allocated CommonBuffer VA %x, PA %x\n", hcd
->CommonBufferVA
[PageCount
], hcd
->CommonBufferPA
[PageCount
]);
100 MemoryPage
= (PMEM_HEADER
)hcd
->CommonBufferVA
[PageCount
];
102 } while (PageCount
< NumberOfPages
);
104 if (PageCount
== NumberOfPages
)
111 ReleaseMemory(PEHCI_HOST_CONTROLLER hcd
, ULONG Address
)
113 PMEM_HEADER MemoryPage
;
114 ULONG Index
, i
, BlockSize
;
116 MemoryPage
= (PMEM_HEADER
)(Address
& ~(PAGE_SIZE
- 1));
118 Index
= (Address
- ((ULONG
)MemoryPage
+ sizeof(MEM_HEADER
))) / SMALL_ALLOCATION_SIZE
;
119 BlockSize
= MemoryPage
->Entry
[Index
].Blocks
;
121 for (i
= 0; i
< BlockSize
; i
++)
123 MemoryPage
->Entry
[Index
+ i
].InUse
= 0;
124 MemoryPage
->Entry
[Index
+ i
].Blocks
= 0;
127 if (MemoryPage
!= (PMEM_HEADER
)hcd
->CommonBufferVA
[0])
129 for (i
=0; i
< sizeof(MemoryPage
->Entry
) / 2; i
++)
131 if ((MemoryPage
->Entry
[i
].InUse
) || (MemoryPage
->Entry
[sizeof(MemoryPage
->Entry
) - i
].InUse
))
134 DPRINT1("Freeing CommonBuffer VA %x, PA %x\n", MemoryPage
, MmGetPhysicalAddress(MemoryPage
));
135 hcd
->pDmaAdapter
->DmaOperations
->FreeCommonBuffer(hcd
->pDmaAdapter
,
137 MmGetPhysicalAddress(MemoryPage
),