+ /* Do we want a physical address? */
+ if (address && physicalAddress)
+ {
+ do
+ {
+ /* Get the physical page */
+ pagenum = pmap_find_phys(kernel_pmap, (addr64_t) address);
+ if(pagenum)
+ {
+ IOByteCount offset;
+ ppnum_t base;
+
+ base = IOMapperIOVMAlloc((size + PAGE_MASK) >> PAGE_SHIFT);
+ if (base)
+ {
+ _IOMallocContiguousEntry *
+ entry = IONew(_IOMallocContiguousEntry, 1);
+ if (!entry)
+ {
+ IOFreeContiguous((void *) address, size);
+ address = 0;
+ break;
+ }
+ entry->virtual = (void *) address;
+ entry->ioBase = base;
+ mutex_lock(gIOMallocContiguousEntriesLock);
+ queue_enter( &gIOMallocContiguousEntries, entry,
+ _IOMallocContiguousEntry *, link );
+ mutex_unlock(gIOMallocContiguousEntriesLock);
+
+ *physicalAddress = (IOPhysicalAddress)((base << PAGE_SHIFT) | (address & PAGE_MASK));
+ for (offset = 0; offset < ((size + PAGE_MASK) >> PAGE_SHIFT); offset++, pagenum++)
+ IOMapperInsertPage( base, offset, pagenum );
+ }
+ else
+ *physicalAddress = (IOPhysicalAddress)((pagenum << PAGE_SHIFT) | (address & PAGE_MASK));
+ }
+ else
+ /* Did not find, return 0 */
+ *physicalAddress = (IOPhysicalAddress) 0;
+ }
+ while (false);
+ }