- // Cache all of the relevant information on the stack for use
- // after we call super::free()!
- IOOptionBits flags = _flags;
- IOOptionBits options = _options;
- vm_size_t size = _capacity;
- void * buffer = _buffer;
- IOVirtualAddress source = _singleRange.v.address;
- vm_map_t vmmap = 0;
- vm_offset_t alignment = _alignment;
-
- if (reserved)
- {
- vmmap = reserved->map;
- IODelete( reserved, ExpansionData, 1 );
- }
-
- /* super::free may unwire - deallocate buffer afterwards */
- super::free();
-
- if (options & kIOMemoryPageable)
- {
+ // Cache all of the relevant information on the stack for use
+ // after we call super::free()!
+ IOOptionBits flags = _flags;
+ IOOptionBits internalFlags = _internalFlags;
+ IOOptionBits options = _options;
+ vm_size_t size = _capacity;
+ void * buffer = _buffer;
+ IOMemoryMap * map = NULL;
+ IOAddressRange * range = _ranges.v64;
+ vm_offset_t alignment = _alignment;
+
+ if (alignment >= page_size) {
+ size = round_page(size);
+ }
+
+ if (reserved) {
+ map = reserved->map;
+ IODelete( reserved, ExpansionData, 1 );
+ if (map) {
+ map->release();
+ }
+ }
+
+ if ((options & kIOMemoryPageable)
+ || (kInternalFlagPageSized & internalFlags)) {
+ size = round_page(size);
+ }
+
+#if IOTRACKING
+ if (!(options & kIOMemoryPageable)
+ && buffer
+ && (kInternalFlagInit & _internalFlags)) {
+ trackingAccumSize(-size);
+ }
+#endif /* IOTRACKING */
+
+ /* super::free may unwire - deallocate buffer afterwards */
+ super::free();
+
+ if (options & kIOMemoryPageable) {
+#if IOALLOCDEBUG
+ OSAddAtomicLong(-size, &debug_iomallocpageable_size);
+#endif
+ } else if (buffer) {
+ if (kInternalFlagPhysical & internalFlags) {
+ IOKernelFreePhysical((mach_vm_address_t) buffer, size);
+ } else if (kInternalFlagPageAllocated & internalFlags) {
+ uintptr_t page;
+ page = iopa_free(&gIOBMDPageAllocator, (uintptr_t) buffer, size);
+ if (page) {
+ kmem_free(kernel_map, page, page_size);
+ }