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// 43BYTE OsGetVersion() 44{ 45 // Use EngFindResource, for now hard code 46 return( 1 ); 47} // BYTE OsGetVersion() 48 49BYTE OsGetRevision() 50{ 51 // Use EngFindResource, for now hard code 52 return( 0 ); 53} // BYTE OsGetRevision() 54 55BYTE OsGetRelease() 56{ 57 // Use EngFindResource, for now hard code 58 return( 0 ); 59} // BYTE OsGetRelease() 60 61// 62// Global Memory Management Functions 63// 64DWORD gAllocNonPagedCount = 0; 65 66LIST_HEAD(mems, _echo_mem) mems; 67 68 69static echo_mem * 70echo_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", true); 78 mem->size = size; 79 if (mem->area < B_OK) { 80 free(mem); 81 return NULL; 82 } 83 return mem; 84} 85 86static void 87echo_mem_delete(echo_mem *mem) 88{ 89 if(mem->area > B_OK) 90 delete_area(mem->area); 91 free(mem); 92} 93 94echo_mem * 95echo_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 108void 109echo_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 123void 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 139ECHOSTATUS 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// *********************************************************************** 174ECHOSTATUS 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 204COsSupport::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 216COsSupport::~COsSupport() 217{ 218 ECHO_DEBUGPRINTF(("COsSupport is all gone - m_dwPageBlockCount %ld\n",m_dwPageBlockCount)); 219} 220 221// 222// Timer Methods 223// 224 225ECHOSTATUS 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 237ECHOSTATUS 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 268ECHOSTATUS 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 313ECHOSTATUS 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 337PVOID 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 354ECHOSTATUS 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// 377void COsSupport::EchoErrorMsg(const char* pszMsg, const char* pszTitle) 378{ 379} 380 381PVOID 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 401VOID COsSupport::operator delete(PVOID memory) 402{ 403 free(memory); 404} 405 406