xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/OsSupportBeOS.cpp (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
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