ASoC: Remove duplicate ADC/DAC widgets from wm_hubs.c
[linux/fpc-iii.git] / drivers / staging / epl / ShbIpc-LinuxKernel.c
blob12d1eccde252f784dd531cf72e84e0772dd1889d
1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
6 Project: Project independend shared buffer (linear + circular)
8 Description: Implementation of platform specific part for the
9 shared buffer
10 (Implementation for Linux KernelSpace)
12 License:
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions
16 are met:
18 1. Redistributions of source code must retain the above copyright
19 notice, this list of conditions and the following disclaimer.
21 2. Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in the
23 documentation and/or other materials provided with the distribution.
25 3. Neither the name of SYSTEC electronic GmbH nor the names of its
26 contributors may be used to endorse or promote products derived
27 from this software without prior written permission. For written
28 permission, please contact info@systec-electronic.com.
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 POSSIBILITY OF SUCH DAMAGE.
43 Severability Clause:
45 If a provision of this License is or becomes illegal, invalid or
46 unenforceable in any jurisdiction, that shall not affect:
47 1. the validity or enforceability in that jurisdiction of any other
48 provision of this License; or
49 2. the validity or enforceability in other jurisdictions of that or
50 any other provision of this License.
52 -------------------------------------------------------------------------
54 2006/06/28 -rs: V 1.00 (initial version)
56 ****************************************************************************/
58 #include "global.h"
59 #include "SharedBuff.h"
60 #include "ShbIpc.h"
61 #include "ShbLinuxKernel.h"
62 #include "Debug.h"
64 #include <linux/string.h>
65 #include <linux/module.h>
66 #include <asm/processor.h>
67 //#include <linux/vmalloc.h>
68 #include <linux/sched.h>
69 #include <linux/param.h>
70 #include <linux/spinlock.h>
71 #include <linux/wait.h>
72 #include <linux/completion.h>
74 /***************************************************************************/
75 /* */
76 /* */
77 /* G L O B A L D E F I N I T I O N S */
78 /* */
79 /* */
80 /***************************************************************************/
82 //---------------------------------------------------------------------------
83 // Configuration
84 //---------------------------------------------------------------------------
86 //---------------------------------------------------------------------------
87 // Constant definitions
88 //---------------------------------------------------------------------------
90 #define MAX_LEN_BUFFER_ID 256
92 #define TIMEOUT_ENTER_ATOMIC 1000 // (ms) for debgging: INFINITE
93 #define TIMEOUT_TERM_THREAD 1000
94 #define INFINITE 3600
96 #define SBI_MAGIC_ID 0x5342492B // magic ID ("SBI+")
97 #define SBH_MAGIC_ID 0x5342482A // magic ID ("SBH*")
99 #define INVALID_ID -1
101 #define TABLE_SIZE 10
103 //---------------------------------------------------------------------------
104 // Local types
105 //---------------------------------------------------------------------------
107 // This structure is the common header for the shared memory region used
108 // by all processes attached this shared memory. It includes common
109 // information to administrate/manage the shared buffer from a couple of
110 // separated processes (e.g. the refernce counter). This structure is
111 // located at the start of the shared memory region itself and exists
112 // consequently only one times per shared memory instance.
113 typedef struct {
115 unsigned long m_ulShMemSize;
116 unsigned long m_ulRefCount;
117 int m_iBufferId;
118 // int m_iUserSpaceMem; //0 for userspace mem !=0 kernelspace mem
119 spinlock_t m_SpinlockBuffAccess;
120 BOOL m_fNewData;
121 BOOL m_fJobReady;
122 wait_queue_head_t m_WaitQueueNewData;
123 wait_queue_head_t m_WaitQueueJobReady;
125 #ifndef NDEBUG
126 unsigned long m_ulOwnerProcID;
127 #endif
129 } tShbMemHeader;
131 // This structure is the "external entry point" from a separate process
132 // to get access to a shared buffer. This structure includes all platform
133 // resp. target specific information to administrate/manage the shared
134 // buffer from a separate process. Every process attached to the shared
135 // buffer has its own runtime instance of this structure with its individual
136 // runtime data (e.g. the scope of an event handle is limitted to the
137 // owner process only). The structure member <m_pShbMemHeader> points
138 // to the (process specific) start address of the shared memory region
139 // itself.
140 typedef struct {
141 unsigned long m_SbiMagicID; // magic ID ("SBI+")
142 // void* m_pSharedMem;
143 int m_tThreadNewDataId;
144 long m_lThreadNewDataNice; // nice value of the new data thread
145 int m_tThreadJobReadyId;
146 unsigned long m_ulFlagsBuffAccess; // d.k. moved from tShbMemHeader, because each
147 // process needs to store the interrupt flags separately
148 tSigHndlrNewData m_pfnSigHndlrNewData;
149 unsigned long m_ulTimeOutJobReady;
150 tSigHndlrJobReady m_pfnSigHndlrJobReady;
151 tShbMemHeader *m_pShbMemHeader;
152 int m_iThreadTermFlag;
153 struct completion m_CompletionNewData;
155 struct semaphore *m_pSemBuffAccess;
156 struct semaphore *m_pSemNewData;
157 struct semaphore *m_pSemStopSignalingNewData;
158 struct semaphore *m_pSemJobReady;
160 #ifndef NDEBUG
161 unsigned long m_ulThreadIDNewData;
162 unsigned long m_ulThreadIDJobReady;
163 #endif
164 } tShbMemInst;
166 //---------------------------------------------------------------------------
167 // Prototypes of internal functions
168 //---------------------------------------------------------------------------
170 //tShbMemInst* ShbIpcGetShbMemInst (tShbInstance pShbInstance_p);
171 //tShbMemHeader* ShbIpcGetShbMemHeader (tShbMemInst* pShbMemInst_p);
173 //---------------------------------------------------------------------------
174 // Get pointer to process local information structure
175 //---------------------------------------------------------------------------
177 static inline tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p)
180 tShbMemInst *pShbMemInst;
182 pShbMemInst = (tShbMemInst *) pShbInstance_p;
184 return (pShbMemInst);
188 //---------------------------------------------------------------------------
189 // Get pointer to shared memory header
190 //---------------------------------------------------------------------------
192 static inline tShbMemHeader *ShbIpcGetShbMemHeader(tShbMemInst * pShbMemInst_p)
195 tShbMemHeader *pShbMemHeader;
197 pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
199 return (pShbMemHeader);
203 // Get pointer to process local information structure
204 //#define ShbIpcGetShbMemInst(pShbInstance_p) ((tShbMemInst*)pShbInstance_p)
206 // Get pointer to shared memory header
207 //#define ShbIpcGetShbMemHeader(pShbMemInst_p) (pShbMemInst_p->m_pShbMemHeader)
209 // not inlined internal functions
210 int ShbIpcThreadSignalNewData(void *pvThreadParam_p);
211 int ShbIpcThreadSignalJobReady(void *pvThreadParam_p);
213 //---------------------------------------------------------------------------
214 // modul globale vars
215 //---------------------------------------------------------------------------
217 struct sShbMemTable *psMemTableElementFirst_g;
219 static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
220 static int ShbIpcFindListElement(int iBufferId,
221 struct sShbMemTable
222 **ppsReturnMemTableElement);
223 static void ShbIpcAppendListElement(struct sShbMemTable *sNewMemTableElement);
224 static void ShbIpcDeleteListElement(int iBufferId);
225 static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256]);
226 static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
227 unsigned long aulCrcTable[256]);
230 //=========================================================================//
231 // //
232 // P U B L I C F U N C T I O N S //
233 // //
234 //=========================================================================//
236 // not inlined external functions
238 //---------------------------------------------------------------------------
239 // Initialize IPC for Shared Buffer Module
240 //---------------------------------------------------------------------------
242 tShbError ShbIpcInit(void)
244 psMemTableElementFirst_g = NULL;
245 return (kShbOk);
249 //---------------------------------------------------------------------------
250 // Deinitialize IPC for Shared Buffer Module
251 //---------------------------------------------------------------------------
253 tShbError ShbIpcExit(void)
256 return (kShbOk);
260 //---------------------------------------------------------------------------
261 // Allocate Shared Buffer
262 //---------------------------------------------------------------------------
264 tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
265 const char *pszBufferID_p,
266 tShbInstance * ppShbInstance_p,
267 unsigned int *pfShbNewCreated_p)
269 tShbError ShbError;
270 int iBufferId = 0;
271 unsigned long ulCrc32 = 0;
272 unsigned int uiFirstProcess = 0;
273 unsigned long ulShMemSize;
274 tShbMemHeader *pShbMemHeader;
275 tShbMemInst *pShbMemInst = NULL;
276 tShbInstance pShbInstance;
277 unsigned int fShMemNewCreated = FALSE;
278 void *pSharedMem = NULL;
279 unsigned long aulCrcTable[256];
280 struct sShbMemTable *psMemTableElement;
282 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer \n");
283 ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader);
285 //create Buffer ID
286 ShbIpcCrc32GenTable(aulCrcTable);
287 ulCrc32 = ShbIpcCrc32GetCrc(pszBufferID_p, aulCrcTable);
288 iBufferId = ulCrc32;
289 DEBUG_LVL_29_TRACE2
290 ("ShbIpcAllocBuffer BufferSize:%d sizeof(tShb..):%d\n",
291 ulBufferSize_p, sizeof(tShbMemHeader));
292 DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferId:%d MemSize:%d\n",
293 iBufferId, ulShMemSize);
294 //---------------------------------------------------------------
295 // (1) open an existing or create a new shared memory
296 //---------------------------------------------------------------
297 //test if buffer already exists
298 if (ShbIpcFindListElement(iBufferId, &psMemTableElement) == 0) {
299 //Buffer already exists
300 fShMemNewCreated = FALSE;
301 pSharedMem = psMemTableElement->m_pBuffer;
302 DEBUG_LVL_29_TRACE1
303 ("ShbIpcAllocBuffer attach Buffer at:%p Id:%d\n",
304 pSharedMem);
305 uiFirstProcess = 1;
306 } else {
307 //create new Buffer
308 fShMemNewCreated = TRUE;
309 uiFirstProcess = 0;
310 pSharedMem = kmalloc(ulShMemSize, GFP_KERNEL);
311 DEBUG_LVL_29_TRACE2
312 ("ShbIpcAllocBuffer Create New Buffer at:%p Id:%d\n",
313 pSharedMem, iBufferId);
314 if (pSharedMem == NULL) {
315 //unable to create mem
316 ShbError = kShbOutOfMem;
317 goto Exit;
319 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer create semas\n");
320 // append Element to Mem Table
321 psMemTableElement =
322 kmalloc(sizeof(struct sShbMemTable), GFP_KERNEL);
323 psMemTableElement->m_iBufferId = iBufferId;
324 psMemTableElement->m_pBuffer = pSharedMem;
325 psMemTableElement->m_psNextMemTableElement = NULL;
326 ShbIpcAppendListElement(psMemTableElement);
329 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer update header\n");
330 //update header
331 pShbMemHeader = (tShbMemHeader *) pSharedMem;
332 DEBUG_LVL_29_TRACE1
333 ("ShbIpcAllocBuffer 0 pShbMemHeader->m_ulShMemSize: %d\n",
334 pShbMemHeader->m_ulShMemSize);
335 // allocate a memory block from process specific mempool to save
336 // process local information to administrate/manage the shared buffer
337 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer alloc private mem\n");
338 pShbMemInst =
339 (tShbMemInst *) ShbIpcAllocPrivateMem(sizeof(tShbMemInst));
340 if (pShbMemInst == NULL) {
341 ShbError = kShbOutOfMem;
342 goto Exit;
344 // reset complete header to default values
345 //pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID;
346 // pShbMemInst->m_pSharedMem = pSharedMem;
347 pShbMemInst->m_tThreadNewDataId = INVALID_ID;
348 pShbMemInst->m_tThreadJobReadyId = INVALID_ID;
349 pShbMemInst->m_pfnSigHndlrNewData = NULL;
350 pShbMemInst->m_ulTimeOutJobReady = 0;
351 pShbMemInst->m_pfnSigHndlrJobReady = NULL;
352 pShbMemInst->m_pShbMemHeader = pShbMemHeader;
353 pShbMemInst->m_iThreadTermFlag = 0;
355 // initialize completion etc.
356 init_completion(&pShbMemInst->m_CompletionNewData);
358 ShbError = kShbOk;
359 if (fShMemNewCreated) {
360 // this process was the first who wanted to use the shared memory,
361 // so a new shared memory was created
362 // -> setup new header information inside the shared memory region
363 // itself
364 pShbMemHeader->m_ulShMemSize = ulShMemSize;
365 pShbMemHeader->m_ulRefCount = 1;
366 pShbMemHeader->m_iBufferId = iBufferId;
367 // initialize spinlock
368 spin_lock_init(&pShbMemHeader->m_SpinlockBuffAccess);
369 // initialize wait queues
370 init_waitqueue_head(&pShbMemHeader->m_WaitQueueNewData);
371 init_waitqueue_head(&pShbMemHeader->m_WaitQueueJobReady);
372 } else {
373 // any other process has created the shared memory and this
374 // process only has to attach to it
375 // -> check and update existing header information inside the
376 // shared memory region itself
377 if (pShbMemHeader->m_ulShMemSize != ulShMemSize) {
378 ShbError = kShbOpenMismatch;
379 goto Exit;
381 pShbMemHeader->m_ulRefCount++;
384 Exit:
385 pShbInstance = (tShbInstance *) pShbMemInst;
386 *pfShbNewCreated_p = fShMemNewCreated;
387 *ppShbInstance_p = pShbInstance;
388 return (ShbError);
392 //---------------------------------------------------------------------------
393 // Release Shared Buffer
394 //---------------------------------------------------------------------------
396 tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
398 tShbMemInst *pShbMemInst;
399 tShbMemHeader *pShbMemHeader;
400 tShbError ShbError;
401 tShbError ShbError2;
403 DEBUG_LVL_26_TRACE1("ShbIpcReleaseBuffer(%p)\n", pShbInstance_p);
404 if (pShbInstance_p == NULL) {
405 return (kShbOk);
407 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
408 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
410 // stop threads in any case, because they are bound to that specific instance
411 ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p);
412 // d.k.: Whats up with JobReady thread?
413 // Just wake it up, but without setting the semaphore variable
414 wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
416 if (!--pShbMemHeader->m_ulRefCount) {
417 ShbError = kShbOk;
418 // delete mem table element
419 ShbIpcDeleteListElement(pShbMemHeader->m_iBufferId);
420 // delete shared mem
421 kfree(pShbMemInst->m_pShbMemHeader);
422 } else {
423 ShbError = kShbMemUsedByOtherProcs;
425 //delete privat mem
426 kfree(pShbMemInst);
427 return (ShbError);
430 //---------------------------------------------------------------------------
431 // Enter atomic section for Shared Buffer access
432 //---------------------------------------------------------------------------
434 tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
437 tShbMemInst *pShbMemInst;
438 tShbMemHeader *pShbMemHeader;
439 tShbError ShbError = kShbOk;
441 if (pShbInstance_p == NULL) {
442 ShbError = kShbInvalidArg;
443 goto Exit;
445 DEBUG_LVL_29_TRACE0("enter atomic\n");
446 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
447 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
449 // lock interrupts
450 spin_lock_irqsave(&pShbMemHeader->m_SpinlockBuffAccess,
451 pShbMemInst->m_ulFlagsBuffAccess);
453 Exit:
454 return ShbError;
458 //---------------------------------------------------------------------------
459 // Leave atomic section for Shared Buffer access
460 //---------------------------------------------------------------------------
462 tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
465 tShbMemInst *pShbMemInst;
466 tShbMemHeader *pShbMemHeader;
467 tShbError ShbError = kShbOk;
469 if (pShbInstance_p == NULL) {
470 ShbError = kShbInvalidArg;
471 goto Exit;
473 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
474 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
475 // unlock interrupts
476 spin_unlock_irqrestore(&pShbMemHeader->m_SpinlockBuffAccess,
477 pShbMemInst->m_ulFlagsBuffAccess);
479 Exit:
480 DEBUG_LVL_29_TRACE0("Leave Atomic \n");
481 return ShbError;
485 //---------------------------------------------------------------------------
486 // Start signaling of new data (called from reading process)
487 //---------------------------------------------------------------------------
489 tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p,
490 tSigHndlrNewData pfnSignalHandlerNewData_p,
491 tShbPriority ShbPriority_p)
493 tShbMemInst *pShbMemInst;
494 tShbMemHeader *pShbMemHeader;
495 tShbError ShbError;
497 DEBUG_LVL_29_TRACE0("------->ShbIpcStartSignalingNewData\n");
498 if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) {
499 return (kShbInvalidArg);
502 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
503 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
504 ShbError = kShbOk;
506 if ((pShbMemInst->m_tThreadNewDataId != INVALID_ID)
507 || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) {
508 ShbError = kShbAlreadySignaling;
509 goto Exit;
511 DEBUG_LVL_26_TRACE2
512 ("ShbIpcStartSignalingNewData(%p) m_pfnSigHndlrNewData = %p\n",
513 pShbInstance_p, pfnSignalHandlerNewData_p);
514 pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
515 pShbMemHeader->m_fNewData = FALSE;
516 pShbMemInst->m_iThreadTermFlag = 0;
518 switch (ShbPriority_p) {
519 case kShbPriorityLow:
520 pShbMemInst->m_lThreadNewDataNice = -2;
521 break;
523 case kShbPriorityNormal:
524 pShbMemInst->m_lThreadNewDataNice = -9;
525 break;
527 case kshbPriorityHigh:
528 pShbMemInst->m_lThreadNewDataNice = -20;
529 break;
533 //create thread for signalling new data
534 pShbMemInst->m_tThreadNewDataId =
535 kernel_thread(ShbIpcThreadSignalNewData, pShbInstance_p,
536 CLONE_FS | CLONE_FILES);
538 Exit:
539 return ShbError;
543 //---------------------------------------------------------------------------
544 // Stop signaling of new data (called from reading process)
545 //---------------------------------------------------------------------------
547 tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p)
549 tShbMemInst *pShbMemInst;
550 tShbMemHeader *pShbMemHeader;
551 tShbError ShbError;
553 DEBUG_LVL_29_TRACE0("------->ShbIpcStopSignalingNewData\n");
554 if (pShbInstance_p == NULL) {
555 return (kShbInvalidArg);
557 ShbError = kShbOk;
558 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
559 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
561 DEBUG_LVL_26_TRACE2
562 ("ShbIpcStopSignalingNewData(%p) pfnSignHndlrNewData=%p\n",
563 pShbInstance_p, pShbMemInst->m_pfnSigHndlrNewData);
564 if (pShbMemInst->m_pfnSigHndlrNewData != NULL) { // signal handler was set before
565 int iErr;
566 //set termination flag in mem header
567 pShbMemInst->m_iThreadTermFlag = 1;
569 // check if thread is still running at all by sending the null-signal to this thread
570 /* iErr = kill_proc(pShbMemInst->m_tThreadNewDataId, 0, 1); */
571 iErr = send_sig(0, pShbMemInst->m_tThreadNewDataId, 1);
572 if (iErr == 0) {
573 // wake up thread, because it is still running
574 wake_up_interruptible(&pShbMemHeader->
575 m_WaitQueueNewData);
577 //wait for termination of thread
578 wait_for_completion(&pShbMemInst->m_CompletionNewData);
581 pShbMemInst->m_pfnSigHndlrNewData = NULL;
582 pShbMemInst->m_tThreadNewDataId = INVALID_ID;
585 return ShbError;
589 //---------------------------------------------------------------------------
590 // Signal new data (called from writing process)
591 //---------------------------------------------------------------------------
593 tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
595 tShbMemHeader *pShbMemHeader;
597 if (pShbInstance_p == NULL) {
598 return (kShbInvalidArg);
600 pShbMemHeader =
601 ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
602 //set semaphore
603 pShbMemHeader->m_fNewData = TRUE;
604 DEBUG_LVL_29_TRACE0("ShbIpcSignalNewData set Sem -> New Data\n");
606 wake_up_interruptible(&pShbMemHeader->m_WaitQueueNewData);
607 return (kShbOk);
610 //---------------------------------------------------------------------------
611 // Start signaling for job ready (called from waiting process)
612 //---------------------------------------------------------------------------
614 tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
615 unsigned long ulTimeOut_p,
616 tSigHndlrJobReady pfnSignalHandlerJobReady_p)
618 tShbMemInst *pShbMemInst;
619 tShbMemHeader *pShbMemHeader;
620 tShbError ShbError;
622 if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) {
623 return (kShbInvalidArg);
625 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
626 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
628 ShbError = kShbOk;
629 if ((pShbMemInst->m_tThreadJobReadyId != INVALID_ID)
630 || (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) {
631 ShbError = kShbAlreadySignaling;
632 goto Exit;
634 pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p;
635 pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
636 pShbMemHeader->m_fJobReady = FALSE;
637 //create thread for signalling new data
638 pShbMemInst->m_tThreadJobReadyId =
639 kernel_thread(ShbIpcThreadSignalJobReady, pShbInstance_p,
640 CLONE_FS | CLONE_FILES);
641 Exit:
642 return ShbError;
645 //---------------------------------------------------------------------------
646 // Signal job ready (called from executing process)
647 //---------------------------------------------------------------------------
649 tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
651 tShbMemHeader *pShbMemHeader;
653 DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady\n");
654 if (pShbInstance_p == NULL) {
655 return (kShbInvalidArg);
657 pShbMemHeader =
658 ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
659 //set semaphore
660 pShbMemHeader->m_fJobReady = TRUE;
661 DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady set Sem -> Job Ready \n");
663 wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
664 return (kShbOk);
667 //---------------------------------------------------------------------------
668 // Get pointer to common used share memory area
669 //---------------------------------------------------------------------------
671 void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
674 tShbMemHeader *pShbMemHeader;
675 void *pShbShMemPtr;
677 pShbMemHeader =
678 ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
679 if (pShbMemHeader != NULL) {
680 pShbShMemPtr = (u8 *) pShbMemHeader + sizeof(tShbMemHeader);
681 } else {
682 pShbShMemPtr = NULL;
685 return (pShbShMemPtr);
689 //=========================================================================//
690 // //
691 // P R I V A T E F U N C T I O N S //
692 // //
693 //=========================================================================//
695 //---------------------------------------------------------------------------
696 // Get pointer to process local information structure
697 //---------------------------------------------------------------------------
699 /*tShbMemInst* ShbIpcGetShbMemInst (
700 tShbInstance pShbInstance_p)
703 tShbMemInst* pShbMemInst;
705 pShbMemInst = (tShbMemInst*)pShbInstance_p;
707 return (pShbMemInst);
712 //---------------------------------------------------------------------------
713 // Get pointer to shared memory header
714 //---------------------------------------------------------------------------
716 /*tShbMemHeader* ShbIpcGetShbMemHeader (
717 tShbMemInst* pShbMemInst_p)
720 tShbMemHeader* pShbMemHeader;
722 pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
724 return (pShbMemHeader);
729 //---------------------------------------------------------------------------
730 // Allocate a memory block from process specific mempool
731 //---------------------------------------------------------------------------
733 static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p)
735 tShbError ShbError;
736 void *pMem;
738 DEBUG_LVL_29_TRACE0("ShbIpcAllocPrivateMem \n");
739 //get private mem
740 pMem = kmalloc(ulMemSize_p, GFP_KERNEL);
741 if (pMem == NULL) {
742 //unable to create mem
743 ShbError = kShbOutOfMem;
744 goto Exit;
746 Exit:
747 return (pMem);
751 //---------------------------------------------------------------------------
752 // Thread for new data signaling
753 //---------------------------------------------------------------------------
755 int ShbIpcThreadSignalNewData(void *pvThreadParam_p)
757 tShbInstance pShbInstance;
758 tShbMemInst *pShbMemInst;
759 tShbMemHeader *pShbMemHeader;
760 int iRetVal = -1;
761 int fCallAgain;
763 daemonize("ShbND%p", pvThreadParam_p);
764 allow_signal(SIGTERM);
765 pShbInstance = (tShbMemInst *) pvThreadParam_p;
766 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
767 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
769 DEBUG_LVL_26_TRACE1("ShbIpcThreadSignalNewData(%p)\n", pvThreadParam_p);
771 set_user_nice(current, pShbMemInst->m_lThreadNewDataNice);
773 // DEBUG_LVL_29_TRACE1("ShbIpcThreadSignalNewData wait for New Data Sem %p\n",pShbMemInst->m_pSemNewData);
774 do {
775 iRetVal =
776 wait_event_interruptible(pShbMemHeader->m_WaitQueueNewData,
777 (pShbMemInst->m_iThreadTermFlag !=
779 || (pShbMemHeader->m_fNewData !=
780 FALSE));
782 if (iRetVal != 0) { // signal pending
783 break;
786 if (pShbMemHeader->m_fNewData != FALSE) {
787 pShbMemHeader->m_fNewData = FALSE;
788 do {
789 fCallAgain =
790 pShbMemInst->
791 m_pfnSigHndlrNewData(pShbInstance);
792 // call scheduler, which will execute any task with higher priority
793 schedule();
794 } while (fCallAgain != FALSE);
796 } while (pShbMemInst->m_iThreadTermFlag == 0);
797 DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalNewData terminated \n");
798 //set thread completed
799 complete_and_exit(&pShbMemInst->m_CompletionNewData, 0);
800 return 0;
803 //---------------------------------------------------------------------------
804 // Thread for new data Job Ready signaling
805 //---------------------------------------------------------------------------
807 int ShbIpcThreadSignalJobReady(void *pvThreadParam_p)
809 tShbInstance pShbInstance;
810 tShbMemInst *pShbMemInst;
811 tShbMemHeader *pShbMemHeader;
812 long lTimeOut;
813 int iRetVal = -1;
815 daemonize("ShbJR%p", pvThreadParam_p);
816 allow_signal(SIGTERM);
817 pShbInstance = (tShbMemInst *) pvThreadParam_p;
818 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
819 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
821 DEBUG_LVL_29_TRACE0
822 ("ShbIpcThreadSignalJobReady wait for job ready Sem\n");
823 if (pShbMemInst->m_ulTimeOutJobReady != 0) {
824 lTimeOut = (long)pShbMemInst->m_ulTimeOutJobReady;
825 //wait for job ready semaphore
826 iRetVal =
827 wait_event_interruptible_timeout(pShbMemHeader->
828 m_WaitQueueJobReady,
829 (pShbMemHeader->
830 m_fJobReady != FALSE),
831 lTimeOut);
832 } else {
833 //wait for job ready semaphore
834 iRetVal =
835 wait_event_interruptible(pShbMemHeader->m_WaitQueueJobReady,
836 (pShbMemHeader->m_fJobReady !=
837 FALSE));
840 if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) {
841 //call Handler
842 pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance,
843 !pShbMemHeader->m_fJobReady);
846 pShbMemInst->m_pfnSigHndlrJobReady = NULL;
847 return 0;
850 //Build the crc table
851 static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256])
853 unsigned long ulCrc, ulPoly;
854 int iIndexI, iIndexJ;
856 ulPoly = 0xEDB88320L;
857 for (iIndexI = 0; iIndexI < 256; iIndexI++) {
858 ulCrc = iIndexI;
859 for (iIndexJ = 8; iIndexJ > 0; iIndexJ--) {
860 if (ulCrc & 1) {
861 ulCrc = (ulCrc >> 1) ^ ulPoly;
862 } else {
863 ulCrc >>= 1;
866 aulCrcTable[iIndexI] = ulCrc;
870 //Calculate the crc value
871 static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
872 unsigned long aulCrcTable[256])
874 unsigned long ulCrc;
875 int iIndex;
877 ulCrc = 0xFFFFFFFF;
878 for (iIndex = 0; iIndex < strlen(pcString); iIndex++) {
879 ulCrc =
880 ((ulCrc >> 8) & 0x00FFFFFF) ^
881 aulCrcTable[(ulCrc ^ pcString[iIndex]) & 0xFF];
883 return (ulCrc ^ 0xFFFFFFFF);
887 static void ShbIpcAppendListElement(struct sShbMemTable *psNewMemTableElement)
889 struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
890 psNewMemTableElement->m_psNextMemTableElement = NULL;
892 if (psMemTableElementFirst_g != NULL) { /* sind Elemente vorhanden */
893 while (psMemTableElement->m_psNextMemTableElement != NULL) { /* suche das letzte Element */
894 psMemTableElement =
895 psMemTableElement->m_psNextMemTableElement;
897 psMemTableElement->m_psNextMemTableElement = psNewMemTableElement; /* Haenge das Element hinten an */
898 } else { /* wenn die liste leer ist, bin ich das erste Element */
899 psMemTableElementFirst_g = psNewMemTableElement;
903 static int ShbIpcFindListElement(int iBufferId,
904 struct sShbMemTable **ppsReturnMemTableElement)
906 struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
907 while (psMemTableElement != NULL) {
908 if (psMemTableElement->m_iBufferId == iBufferId) {
909 //printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",psMemTableElement->m_pBuffer,psMemTableElement->m_iBufferId);
910 *ppsReturnMemTableElement = psMemTableElement;
911 //printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",(*ppsReturnMemTableElement)->m_pBuffer,(*ppsReturnMemTableElement)->m_iBufferId);
912 return 0;
914 psMemTableElement = psMemTableElement->m_psNextMemTableElement;
916 return -1;
919 static void ShbIpcDeleteListElement(int iBufferId)
921 struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
922 struct sShbMemTable *psMemTableElementOld = psMemTableElementFirst_g;
923 if (psMemTableElement != NULL) {
924 while ((psMemTableElement != NULL)
925 && (psMemTableElement->m_iBufferId != iBufferId)) {
926 psMemTableElementOld = psMemTableElement;
927 psMemTableElement =
928 psMemTableElement->m_psNextMemTableElement;
930 if (psMemTableElement != NULL) {
931 if (psMemTableElement != psMemTableElementFirst_g) {
932 psMemTableElementOld->m_psNextMemTableElement =
933 psMemTableElement->m_psNextMemTableElement;
934 kfree(psMemTableElement);
935 } else {
936 kfree(psMemTableElement);
937 psMemTableElementFirst_g = NULL;