1 // **************************************************************************** 2 // 3 // OsSupportBeOS.cpp 4 // 5 // Implementation file for BeOS support services to the CEchoGals 6 // generic driver class 7 // Set editor tabs to 3 for your viewing pleasure. 8 // 9 // ---------------------------------------------------------------------------- 10 // 11 // This file is part of Echo Digital Audio's generic driver library. 12 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005 13 // All rights reserved 14 // www.echoaudio.com 15 // 16 // This library is free software; you can redistribute it and/or 17 // modify it under the terms of the GNU Lesser General Public 18 // License as published by the Free Software Foundation; either 19 // version 2.1 of the License, or (at your option) any later version. 20 // 21 // This library is distributed in the hope that it will be useful, 22 // but WITHOUT ANY WARRANTY; without even the implied warranty of 23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 // Lesser General Public License for more details. 25 // 26 // You should have received a copy of the GNU Lesser General Public 27 // License along with this library; if not, write to the Free Software 28 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29 // 30 // **************************************************************************** 31 32 #include "OsSupportBeOS.h" 33 34 #include "EchoGalsXface.h" 35 36 #include <KernelExport.h> 37 #include "util.h" 38 39 // 40 // Version information. 41 // In NT, we want to get this from a resource 42 // 43 BYTE OsGetVersion() 44 { 45 // Use EngFindResource, for now hard code 46 return( 1 ); 47 } // BYTE OsGetVersion() 48 49 BYTE OsGetRevision() 50 { 51 // Use EngFindResource, for now hard code 52 return( 0 ); 53 } // BYTE OsGetRevision() 54 55 BYTE OsGetRelease() 56 { 57 // Use EngFindResource, for now hard code 58 return( 0 ); 59 } // BYTE OsGetRelease() 60 61 // 62 // Global Memory Management Functions 63 // 64 DWORD gAllocNonPagedCount = 0; 65 66 LIST_HEAD(mems, _echo_mem) mems; 67 68 69 static echo_mem * 70 echo_mem_new(size_t size) 71 { 72 echo_mem *mem = NULL; 73 74 if ((mem = (echo_mem*)malloc(sizeof(*mem))) == NULL) 75 return (NULL); 76 77 mem->area = alloc_mem(&mem->phy_base, &mem->log_base, size, "echo buffer"); 78 mem->size = size; 79 if (mem->area < B_OK) { 80 free(mem); 81 return NULL; 82 } 83 return mem; 84 } 85 86 static void 87 echo_mem_delete(echo_mem *mem) 88 { 89 if(mem->area > B_OK) 90 delete_area(mem->area); 91 free(mem); 92 } 93 94 echo_mem * 95 echo_mem_alloc(size_t size) 96 { 97 echo_mem *mem = NULL; 98 99 mem = echo_mem_new(size); 100 if (mem == NULL) 101 return (NULL); 102 103 LIST_INSERT_HEAD(&mems, mem, next); 104 105 return mem; 106 } 107 108 void 109 echo_mem_free(void *ptr) 110 { 111 echo_mem *mem = NULL; 112 113 LIST_FOREACH(mem, &mems, next) { 114 if (mem->log_base != ptr) 115 continue; 116 LIST_REMOVE(mem, next); 117 118 echo_mem_delete(mem); 119 break; 120 } 121 } 122 123 void OsAllocateInit() 124 { 125 gAllocNonPagedCount = 0; 126 127 /* Init mems list */ 128 LIST_INIT(&mems); 129 } 130 131 // *********************************************************************** 132 // 133 // Allocate locked, non-pageable block of memory. Does not have to be 134 // physically contiguous. Primarily used to implement the overloaded 135 // new operator. 136 // 137 // *********************************************************************** 138 139 ECHOSTATUS OsAllocateNonPaged 140 ( 141 DWORD dwByteCt, // Block size in bytes 142 PPVOID ppMemAddr // Where to return memory ptr 143 ) 144 { 145 146 147 echo_mem * mem = echo_mem_alloc( dwByteCt ); 148 if(mem) 149 *ppMemAddr = mem->log_base; 150 151 if ( NULL == *ppMemAddr ) 152 { 153 ECHO_DEBUGPRINTF( ("OsAllocateNonPaged : Failed on %ld bytes\n", 154 dwByteCt) ); 155 ECHO_DEBUGBREAK(); 156 return ECHOSTATUS_NO_MEM; 157 } 158 159 OsZeroMemory( *ppMemAddr, dwByteCt ); 160 161 gAllocNonPagedCount++; 162 ECHO_DEBUGPRINTF(("gAllocNonPagedCount %ld\n",gAllocNonPagedCount)); 163 164 return ECHOSTATUS_OK; 165 166 } // ECHOSTATUS OsAllocateNonPaged 167 168 169 // *********************************************************************** 170 // 171 // Unlock and free, non-pageable block of memory. 172 // 173 // *********************************************************************** 174 ECHOSTATUS OsFreeNonPaged 175 ( 176 PVOID pMemAddr 177 ) 178 { 179 echo_mem_free( pMemAddr ); 180 181 gAllocNonPagedCount--; 182 ECHO_DEBUGPRINTF(("gAllocNonPagedCount %ld\n",gAllocNonPagedCount)); 183 184 return ECHOSTATUS_OK; 185 186 } // ECHOSTATUS OsFreeNonPaged 187 188 189 190 // *********************************************************************** 191 // 192 // This class is optional and uniquely defined for each OS. It provides 193 // information that other components may require. 194 // For example, in Windows NT it contains a device object used by various 195 // memory management methods. 196 // Since static variables are used in place of globals, an instance must 197 // be constructed and initialized by the OS Interface object prior to 198 // constructing the CEchoGals derived object. The CEchoGals and 199 // CDspCommObject classes must have access to it during their respective 200 // construction times. 201 // 202 // *********************************************************************** 203 204 COsSupport::COsSupport 205 ( 206 WORD wDeviceId, // PCI bus device ID 207 WORD wCardRev // Card revision number 208 ) 209 { 210 ECHO_DEBUGPRINTF(("COsSupport::COsSupport born, device id = 0x%x.\n", wDeviceId)); 211 212 m_wDeviceId = wDeviceId; 213 m_wCardRev = wCardRev; 214 } 215 216 COsSupport::~COsSupport() 217 { 218 ECHO_DEBUGPRINTF(("COsSupport is all gone - m_dwPageBlockCount %ld\n",m_dwPageBlockCount)); 219 } 220 221 // 222 // Timer Methods 223 // 224 225 ECHOSTATUS COsSupport::OsGetSystemTime 226 ( 227 PULONGLONG pullTime // Where to return system time 228 ) 229 { 230 *pullTime = ULONGLONG(system_time()); 231 232 return ECHOSTATUS_OK; 233 234 } // ECHOSTATUS COsSupport::OsGetSystemTime 235 236 237 ECHOSTATUS COsSupport::OsSnooze 238 ( 239 DWORD dwTime // Duration in micro seconds 240 ) 241 { 242 status_t status; 243 status = snooze(bigtime_t(dwTime)); 244 switch (status) { 245 case B_OK: 246 return ECHOSTATUS_OK; 247 break; 248 case B_INTERRUPTED: 249 return ECHOSTATUS_OPERATION_CANCELED; // maybe not appropriate, but anyway 250 break; 251 default: 252 return ECHOSTATUS_NOT_SUPPORTED; // no generic error? 253 break; 254 } 255 } 256 257 258 // 259 // Memory Management Methods 260 // 261 262 //--------------------------------------------------------------------------- 263 // 264 // Allocate a physical page block that can be used for DSP bus mastering. 265 // 266 //--------------------------------------------------------------------------- 267 268 ECHOSTATUS COsSupport::AllocPhysPageBlock 269 ( 270 DWORD dwBytes, 271 PPAGE_BLOCK &pPageBlock 272 ) 273 { 274 DWORD dwRoundedBytes; 275 276 // 277 // Allocate 278 // 279 dwRoundedBytes = (dwBytes + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); 280 ECHO_DEBUGPRINTF(("COsSupport::AllocPhysPageBlock - dwBytes %ld dwRoundedBytes %ld\n", 281 dwBytes,dwRoundedBytes)); 282 283 pPageBlock = echo_mem_alloc ( dwRoundedBytes ); 284 285 if (NULL == pPageBlock) 286 { 287 ECHO_DEBUGPRINTF(("AllocPhysPageBlock failed for %ld bytes\n",dwBytes)); 288 289 pPageBlock = NULL; 290 return ECHOSTATUS_NO_MEM; 291 } 292 293 ECHO_DEBUGPRINTF(("\tIOBufferMemoryDescriptor is OK\n")); 294 295 OsZeroMemory( pPageBlock->log_base, dwRoundedBytes ); 296 297 #ifdef _DEBUG 298 m_dwPageBlockCount++; 299 ECHO_DEBUGPRINTF(("\tm_dwPageBlockCount %ld\n",m_dwPageBlockCount)); 300 #endif 301 302 return ECHOSTATUS_OK; 303 304 } // AllocPageBlock 305 306 307 //--------------------------------------------------------------------------- 308 // 309 // Free a physical page block 310 // 311 //--------------------------------------------------------------------------- 312 313 ECHOSTATUS COsSupport::FreePhysPageBlock 314 ( 315 DWORD dwBytes, 316 PPAGE_BLOCK pPageBlock 317 ) 318 { 319 echo_mem_free(pPageBlock->log_base); 320 321 #ifdef _DEBUG 322 m_dwPageBlockCount--; 323 ECHO_DEBUGPRINTF(("\tm_dwPageBlockCount %ld\n",m_dwPageBlockCount)); 324 #endif 325 326 return ECHOSTATUS_OK; 327 328 } // FreePageBlock 329 330 331 //--------------------------------------------------------------------------- 332 // 333 // Get the virtual address for the buffer corresponding to the MDL 334 // 335 //--------------------------------------------------------------------------- 336 337 PVOID COsSupport::GetPageBlockVirtAddress 338 ( 339 PPAGE_BLOCK pPageBlock 340 ) 341 { 342 343 return pPageBlock->log_base; 344 345 } // GetPageBlockVirtAddress 346 347 348 //--------------------------------------------------------------------------- 349 // 350 // Get the physical address for part of the buffer corresponding to the MDL 351 // 352 //--------------------------------------------------------------------------- 353 354 ECHOSTATUS COsSupport::GetPageBlockPhysSegment 355 ( 356 PPAGE_BLOCK pPageBlock, // pass in a previously allocated block 357 DWORD dwOffset, // pass in the offset into the block 358 PHYS_ADDR &PhysAddr, // returns the physical address 359 DWORD &dwSegmentSize // and the length of the segment 360 ) 361 { 362 363 PhysAddr = ((PHYS_ADDR)pPageBlock->phy_base + dwOffset); 364 365 return ECHOSTATUS_OK; 366 367 } // GetPageBlockPhysSegment 368 369 370 // 371 // Add additional methods here 372 // 373 374 // 375 // Display an error message w/title 376 // 377 void COsSupport::EchoErrorMsg(PCHAR pszMsg, PCHAR pszTitle) 378 { 379 } 380 381 PVOID COsSupport::operator new(size_t size) 382 { 383 PVOID pMemory; 384 385 pMemory = malloc(size); 386 387 if ( NULL == pMemory ) 388 { 389 ECHO_DEBUGPRINTF(("COsSupport::operator new - memory allocation failed\n")); 390 391 pMemory = NULL; 392 } 393 else 394 { 395 memset( pMemory, 0, size ); 396 } 397 398 return pMemory; 399 } 400 401 VOID COsSupport::operator delete(PVOID memory) 402 { 403 free(memory); 404 } 405 406