+ * \fn tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
+ * \brief Allocates DMA physical memory
+ * \param Pages Number of pages required
+ * \param MaxBits Maximum number of bits the physical address can have
+ * \param PhysAddr Pointer to the location to place the physical address allocated
+ * \return Virtual address allocate
+ */
+tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
+{
+ tPAddr maxCheck = (1 << MaxBits);
+ tPAddr phys;
+ tVAddr ret;
+
+ ENTER("iPages iMaxBits pPhysAddr", Pages, MaxBits, PhysAddr);
+
+ // Sanity Check
+ if(MaxBits < 12 || !PhysAddr) {
+ LEAVE('i', 0);
+ return 0;
+ }
+
+ // Bound
+ if(MaxBits >= PHYS_BITS) maxCheck = -1;
+
+ // Fast Allocate
+ if(Pages == 1 && MaxBits >= PHYS_BITS)
+ {
+ phys = MM_AllocPhys();
+ *PhysAddr = phys;
+ ret = MM_MapHWPage(phys, 1);
+ if(ret == 0) {
+ MM_DerefPhys(phys);
+ LEAVE('i', 0);
+ return 0;
+ }
+ LEAVE('x', ret);
+ return ret;
+ }
+
+ // Slow Allocate
+ phys = MM_AllocPhysRange(Pages, MaxBits);
+ // - Was it allocated?
+ if(phys == 0) {
+ LEAVE('i', 0);
+ return 0;
+ }
+
+ // Allocated successfully, now map
+ ret = MM_MapHWPage(phys, Pages);
+ if( ret == 0 ) {
+ // If it didn't map, free then return 0
+ for(;Pages--;phys+=0x1000)
+ MM_DerefPhys(phys);
+ LEAVE('i', 0);
+ return 0;
+ }
+
+ *PhysAddr = phys;
+ LEAVE('x', ret);
+ return ret;
+}
+
+/**
+ * \fn void MM_UnmapHWPage(tVAddr VAddr, Uint Number)