IOMapper * IOMapper::copyMapperForDeviceWithIndex(IOService * device, unsigned int index) { OSData *data; OSObject * obj; IOMapper * mapper = NULL; OSDictionary * matching; obj = device->copyProperty("iommu-parent"); if (!obj) return (NULL); if ((mapper = OSDynamicCast(IOMapper, obj))) goto found; if ((data = OSDynamicCast(OSData, obj))) { if (index >= data->getLength() / sizeof(UInt32)) goto done; data = OSData::withBytesNoCopy((UInt32 *)data->getBytesNoCopy() + index, sizeof(UInt32)); if (!data) goto done; matching = IOService::propertyMatching(gIOMapperIDKey, data); data->release(); } else matching = IOService::propertyMatching(gIOMapperIDKey, obj); if (matching) { mapper = OSDynamicCast(IOMapper, IOService::waitForMatchingService(matching)); matching->release(); } done: if (obj) obj->release(); found: if (mapper) { if (!mapper->fAllocName) { char name[MACH_ZONE_NAME_MAX_LEN]; char kmodname[KMOD_MAX_NAME]; vm_tag_t tag; uint32_t kmodid; tag = IOMemoryTag(kernel_map); if (!(kmodid = vm_tag_get_kext(tag, &kmodname[0], KMOD_MAX_NAME))) { snprintf(kmodname, sizeof(kmodname), "%d", tag); } snprintf(name, sizeof(name), "%s.DMA.%s", kmodname, device->getName()); mapper->fAllocName = kern_allocation_name_allocate(name, 16); } } return (mapper); }
bool OSSerialize::initWithCapacity(unsigned int inCapacity) { if (!super::init()) return false; tags = OSArray::withCapacity(256); if (!tags) { return false; } length = 1; if (!inCapacity) { inCapacity = 1; } if (round_page_overflow(inCapacity, &capacity)) { tags->release(); tags = 0; return false; } capacityIncrement = capacity; // allocate from the kernel map so that we can safely map this data // into user space (the primary use of the OSSerialize object) kern_return_t rc = kmem_alloc(kernel_map, (vm_offset_t *)&data, capacity, IOMemoryTag(kernel_map)); if (rc) { tags->release(); tags = 0; return false; } bzero((void *)data, capacity); OSCONTAINER_ACCUMSIZE(capacity); return true; }