static void trackWorkLoop(_DALSYSWorkLoopObj * newWL) { static unsigned int workLoopListIndex = (DALSYS_WL_TRACK_CNT-1); unsigned int index; DALSYS_SyncEnter(workLoopListSyncHdl); index = workLoopListIndex; do { index = (index + 1) % DALSYS_WL_TRACK_CNT; } while (PD_VAR(DALSYSWorkLoopList)[index] && index != workLoopListIndex); if (NULL == PD_VAR(DALSYSWorkLoopList)[index]) { PD_VAR(DALSYSWorkLoopList)[index] = newWL; workLoopListIndex = index; } else { DALSYS_LOG_ERROR_EVENT("WL tracking list is full"); } DALSYS_SyncLeave(workLoopListSyncHdl); }
static DALResult dequeue(_DALSYSWorkLoopEvent *pRemoveWorkLoopEvent) { _DALSYSWorkLoopObj * pWorkLoopObj = (_DALSYSWorkLoopObj *) pRemoveWorkLoopEvent->hWorkLoop; if(NULL == pWorkLoopObj) return DAL_ERROR; /* Check if the event is in Work Loop Queue */ if(WL_EVENT_ENQUEUED == pRemoveWorkLoopEvent->dwState) { DALSYS_SyncEnter(pWorkLoopObj->hSync); /* Work Loop queue update */ if (pWorkLoopObj->hWorkLoopEventHead) { if (pWorkLoopObj->hWorkLoopEventHead == pRemoveWorkLoopEvent) { // deleted event is at the head of the queue pWorkLoopObj->hWorkLoopEventHead = pRemoveWorkLoopEvent->nextEvent; if (pWorkLoopObj->hWorkLoopEventTail == pRemoveWorkLoopEvent) { // deleted event is the only event on queue pWorkLoopObj->hWorkLoopEventTail = NULL; } } else { _DALSYSWorkLoopEvent *pCurWorkLoopEvent = pWorkLoopObj->hWorkLoopEventHead; while (pCurWorkLoopEvent->nextEvent && pCurWorkLoopEvent->nextEvent != pRemoveWorkLoopEvent) { // iterate until the end of the list or the deleted event is found pCurWorkLoopEvent = pCurWorkLoopEvent->nextEvent; } if (pCurWorkLoopEvent->nextEvent == pRemoveWorkLoopEvent) { // found the deleted event pCurWorkLoopEvent->nextEvent = pRemoveWorkLoopEvent->nextEvent; if (pWorkLoopObj->hWorkLoopEventTail == pRemoveWorkLoopEvent) { // deleted event is at the end of the event queue pWorkLoopObj->hWorkLoopEventTail = pCurWorkLoopEvent; } } } } DALSYS_SyncLeave(pWorkLoopObj->hSync); pRemoveWorkLoopEvent->dwState = WL_EVENT_DEQUEUED; pRemoveWorkLoopEvent->nextEvent = NULL; } return DAL_SUCCESS; }
/*================================================================================================== @brief FTM driver Close This API can be used to Close the FTM driver. @param OpenHdl: Input - handle created in Audio_FTM_Open @return return code, AUDIO_FTM_SUCCESS on successful completion, error code otherwise ==================================================================================================*/ AUDIO_FTM_STS_T audio_ftm_toneplay_close ( AUDIO_FTM_CLIENT_HANDLE_T pOpenContext /* Input: client handle */ ) { Aud_FTM_ClientCtxt_T *pExplicitOpenContext; Aud_FTM_DrvCtxt_T *pDrvCtx; uint32 nClient_id; uint32 i; AUDIO_FTM_STS_T res; if (pOpenContext == NULL) { return AUDIO_FTM_ERR_INVALID_PARAM; } pExplicitOpenContext = (Aud_FTM_ClientCtxt_T *)pOpenContext; pDrvCtx = pExplicitOpenContext->pDrvCtxt; res=audio_ftm_hw_close(pDrvCtx->pDevCtxt); if(res != AUDIO_FTM_SUCCESS) return AUDIO_FTM_ERROR; nClient_id=pExplicitOpenContext->dwClientID; DALSYS_Free(pExplicitOpenContext); pExplicitOpenContext=NULL; DALSYS_SyncEnter(pDrvCtx->hClientSync); aud_ftm_cbuf_clear(&(pDrvCtx->fifo_data_buf)); for(i=nClient_id; i< DALSYS_atomic_read(&pDrvCtx->dwOpenCount)-1; i++) { pDrvCtx->apClientCtxt[i]=pDrvCtx->apClientCtxt[i+1]; pDrvCtx->apClientCtxt[i]->dwClientID--; } pDrvCtx->apClientCtxt[i]=NULL; // Decrease opened device counter Release(&pDrvCtx->dwOpenCount); if(DALSYS_atomic_read(&pDrvCtx->dwOpenCount) == 0) { pDrvCtx->bOpened=FALSE; aud_ftm_cbuf_deinit(&(pDrvCtx->fifo_data_buf)); DALSYS_Free(pTmpBuf); pTmpBuf=NULL; DALSYS_Free(pAud_ftm_rx_buf); pAud_ftm_rx_buf=NULL; } DALSYS_SyncLeave(pDrvCtx->hClientSync); return AUDIO_FTM_SUCCESS; }
static void untrackWorkLoop(_DALSYSWorkLoopObj * deletedWL) { unsigned int index; DALSYS_SyncEnter(workLoopListSyncHdl); for (index = 0; index < DALSYS_WL_TRACK_CNT; index++) { if (PD_VAR(DALSYSWorkLoopList)[index] == deletedWL) { PD_VAR(DALSYSWorkLoopList)[index] = NULL; break; } } DALSYS_SyncLeave(workLoopListSyncHdl); }
/*------------------------------------------------------------------------------ Internal API to insert Event into Work Loop queue -------------------------------------------------------------------------------*/ DALResult DALSYS_EnqueueAndTrigger(_DALSYSWorkLoopEvent *pWorkLoopEvent) { _DALSYSWorkLoopObj *pWorkLoopObj; if(!pWorkLoopEvent) { DALSYS_LOG_ERROR_EVENT("pWorkLoopEvent is NULL"); return DAL_ERROR; } pWorkLoopObj = (_DALSYSWorkLoopObj *)pWorkLoopEvent->hWorkLoop; if(NULL == pWorkLoopObj) { DALSYS_LOG_ERROR_EVENT("pWorkLoopObj is NULL"); return DAL_ERROR; } /* Check if the event is not already in Work Loop Queue */ if(WL_EVENT_ENQUEUED != pWorkLoopEvent->dwState) { DALSYS_SyncEnter(pWorkLoopObj->hSync); /* Work Loop queue update */ (!pWorkLoopObj->hWorkLoopEventHead) ? (pWorkLoopObj->hWorkLoopEventHead = pWorkLoopEvent) : (pWorkLoopObj->hWorkLoopEventTail->nextEvent = pWorkLoopEvent); pWorkLoopObj->hWorkLoopEventTail = pWorkLoopEvent; pWorkLoopEvent->dwState = WL_EVENT_ENQUEUED; pWorkLoopEvent->nextEvent = NULL; DALSYS_SyncLeave(pWorkLoopObj->hSync); } /* Trigger the Work Loop signal */ qurt_anysignal_set(&pWorkLoopObj->signal, SIGNAL_EVENT); return DAL_SUCCESS; }
/*------------------------------------------------------------------------------ Work Loops thread of execution ------------------------------------------------------------------------------*/ void _WorkLoopExecute(void *pArg) { _DALSYSWorkLoopObj *pWorkLoopObj = (_DALSYSWorkLoopObj *) pArg; trackWorkLoop(pWorkLoopObj); for(;;) { unsigned int signal; /*---------------------------------------------------------------------- Wait for commands ----------------------------------------------------------------------*/ signal = qurt_anysignal_wait(&pWorkLoopObj->signal, SIGNAL_EVENT | SIGNAL_EXIT ); qurt_anysignal_clear(&pWorkLoopObj->signal, SIGNAL_EVENT | SIGNAL_EXIT); if (signal & SIGNAL_EXIT) { untrackWorkLoop(pWorkLoopObj); DALSYS_WorkLoopThreadExit(pWorkLoopObj); // this thread is terminated // DALSYS_DestroyWorkLoopObject must be called to free the // workloop memory and resources } if (signal & SIGNAL_EVENT) { /* Process Work Loop queue */ for(;;) { DALSYSEventHandle hEvent; _DALSYSWorkLoopEvent *pWorkLoopEvent; DALResult ret; DALSYS_SyncEnter(pWorkLoopObj->hSync); if(!pWorkLoopObj->hWorkLoopEventHead) { /* Queue is empty */ DALSYS_SyncLeave(pWorkLoopObj->hSync); break; } /* Remove Event from queue head */ pWorkLoopEvent = pWorkLoopObj->hWorkLoopEventHead; pWorkLoopEvent->dwState = WL_EVENT_DEQUEUED; /* Adjust queue after the above removal */ pWorkLoopObj->hWorkLoopEventHead = pWorkLoopEvent->nextEvent; if(!pWorkLoopObj->hWorkLoopEventHead) /* There was just 1 Event */ pWorkLoopObj->hWorkLoopEventTail = NULL; DALSYS_SyncLeave(pWorkLoopObj->hSync); hEvent = DALSYSCMN_CONTAINEROF(pWorkLoopEvent, _DALSYSEventObj, p.wl); /* Process the event */ if(pWorkLoopEvent->hSync) DALSYS_SyncEnter(pWorkLoopEvent->hSync); ret = pWorkLoopEvent->pWorkLoopFunc(hEvent, pWorkLoopEvent->pArg); if(pWorkLoopEvent->hSync) DALSYS_SyncLeave(pWorkLoopEvent->hSync); if (DAL_WORK_LOOP_EXIT == ret) { untrackWorkLoop(pWorkLoopObj); DALSYS_WorkLoopThreadExit(pWorkLoopObj); // this thread is terminated // DALSYS_DestroyWorkLoopObject must be called to free the // workloop memory and resources } } } } }
/** @copydoc AxiCfgOs_MutexUnlock */ void AxiCfgOs_MutexUnlock( void ) { DALSYS_SyncLeave( Info.hMutex ); }
/*================================================================================================== @brief FTM driver open This API can be used to open the FTM driver. @param DriverHdl: Input - handle created in Audio_FTM_Attach AccessMode: Input - Read/Write/RD_WR ShareMode: Input - Exclusive or Share pClientHdl: Output - point to the returned Open handle @return return code, AUDIO_FTM_SUCCESS on successful completion, error code otherwise ==================================================================================================*/ AUDIO_FTM_STS_T audio_ftm_toneplay_open ( AUDIO_FTM_DRIVER_HANDLE_T pDriverContext , /* Input: driver handle */ AUD_FTM_ACCESS_MODE_T AccessMode, /* Input: Access mode */ AUD_FTM_SHARE_MODE_T ShareMode, /* Input: Share mode */ AUDIO_FTM_CLIENT_HANDLE_T * pClientContext /* Output: client handle */ ) { Aud_FTM_DrvCtxt_T * pDrvCxt = (Aud_FTM_DrvCtxt_T *)pDriverContext; Aud_FTM_ClientCtxt_T * pOpenContext = NULL; AUDIO_FTM_STS_T res; int16 i; uint32 dev_buf_size, fifo_buf_size; if (pDrvCxt == NULL) { DALSYS_Log_Err("%s: failed %d\n",__func__,__LINE__); return AUDIO_FTM_ERR_INVALID_PARAM; } DALSYS_SyncEnter(pDrvCxt->hClientSync); if((ShareMode == AUD_FTM_SHAREMODE_EXCLU ) && (DALSYS_atomic_read(&pDrvCxt->dwOpenCount) != 0)) /* ShareMode = 0: exclusive mode; =FILE_SHARE_READ: read only; =FILE_SHARE_WRITE: write only */ { DALSYS_SyncLeave(pDrvCxt->hClientSync); DALSYS_Log_Err("%s: failed %d\n",__func__,__LINE__); return AUDIO_FTM_ERROR; } if(DAL_SUCCESS != DALSYS_Malloc(sizeof(Aud_FTM_ClientCtxt_T), (void **)&pOpenContext)) { DALSYS_Log_Err("%s: failed %d\n",__func__,__LINE__); DALSYS_SyncLeave(pDrvCxt->hClientSync); return AUDIO_FTM_ERR_MEM_ALLOC_FAIL; } if (pOpenContext == NULL) { DALSYS_SyncLeave(pDrvCxt->hClientSync); DALSYS_Log_Err("%s: failed %d\n",__func__,__LINE__); return AUDIO_FTM_ERR_MEM_ALLOC_FAIL; } DALSYS_memset(pOpenContext,0,sizeof(Aud_FTM_ClientCtxt_T)); // Store device settings for future use pOpenContext->pDrvCtxt = pDrvCxt; pOpenContext->dwAccessCode = AccessMode; pOpenContext->dwShareMode = ShareMode; pOpenContext->dwClientID=DALSYS_atomic_read(&pDrvCxt->dwOpenCount); pDrvCxt->apClientCtxt[pOpenContext->dwClientID]=pOpenContext; #ifdef MSM8960_ALSA pDrvCxt->pDevCtxt->read_write_flag = PCM_OUT; #endif /***** open HW *****/ DALSYS_Log_Info("%s: open hw\n",__func__); pDrvCxt->pDevCtxt->playbackdevice = pDrvCxt->pDevCtxt->pDrvCtxt->client_param.device; res=audio_ftm_hw_open(pDrvCxt->pDevCtxt); if(res != AUDIO_FTM_SUCCESS) { DALSYS_Log_Err("%s: failed %d\n",__func__,__LINE__); DALSYS_SyncLeave(pDrvCxt->hClientSync); return AUDIO_FTM_ERROR; } audio_ftm_hw_iocontrol(pDrvCxt->pDevCtxt, IOCTL_AUDIO_FTM_RX_DEV_BUF_SIZE, NULL, 0, &dev_buf_size, sizeof(dev_buf_size), NULL); pDrvCxt->nRx_blk_convey_samples=dev_buf_size/sizeof(int16); /********* init circular buf ********/ fifo_buf_size=dev_buf_size*AUD_FTM_TONE_PLAY_FIFO_FACTOR+4; // reserve 4 bytes DALSYS_Log_Info("%s: init buf\n",__func__); aud_ftm_cbuf_init(&(pDrvCxt->fifo_data_buf), fifo_buf_size); if(DAL_SUCCESS != DALSYS_Malloc(dev_buf_size*AUD_FTM_TONE_PLAY_FIFO_FACTOR, (void **)&pTmpBuf)) /* buffer for DTMF data producing */ { DALSYS_SyncLeave(pDrvCxt->hClientSync); DALSYS_Log_Err(" pTmpBuf allocation fail\n"); return DAL_ERROR; } DALSYS_memset(pTmpBuf,0,dev_buf_size*AUD_FTM_TONE_PLAY_FIFO_FACTOR); if(DAL_SUCCESS != DALSYS_Malloc(dev_buf_size, (void **)&pAud_ftm_rx_buf)) /* buffer for fetch data from FIFO and pass to low layer driver for consuming */ { DALSYS_SyncLeave(pDrvCxt->hClientSync); DALSYS_Log_Err(" pAud_ftm_rx_buf allocation fail\n"); return DAL_ERROR; } DALSYS_memset(pAud_ftm_rx_buf,0,dev_buf_size); /***** prefill the circular buffer with DTMF data *****/ for(i=0; i<((dev_buf_size*AUD_FTM_TONE_PLAY_FIFO_FACTOR)/sizeof(int16)); i++) { *(pTmpBuf+i)=audio_ftm_dtmf_tone_sample_gen(&(pDrvCxt->dtmfGen),pDrvCxt->nDTMF_Gain); } aud_ftm_cbuf_write (&(pDrvCxt->fifo_data_buf),(uint8 *)pTmpBuf,(int32)(dev_buf_size*AUD_FTM_TONE_PLAY_FIFO_FACTOR)); // Increase opened device counter AddRef(&pDrvCxt->dwOpenCount); pDrvCxt->bOpened=TRUE; DALSYS_SyncLeave(pDrvCxt->hClientSync); *pClientContext= (AUDIO_FTM_CLIENT_HANDLE_T)pOpenContext; return AUDIO_FTM_SUCCESS; }
AUDIO_FTM_STS_T audio_ftm_toneplay_attach ( void *pParam, /* Input: parameters */ AUDIO_FTM_DRIVER_HANDLE_T *pDriverHdl /* Output: driver handle */ ) { /************* Context creation ***********/ Aud_FTM_DevCtxt_T *pDeviceCtxt; Aud_FTM_DrvCtxt_T *pDriverCtxt; Aud_FTM_HW_INIT_PARAM_T hw_param; int16 freq1,freq2, sampling_freq; AUDIO_FTM_STS_T sts; if (g_bDriverInitialized) { DALSYS_Log_Err("%s: error: already initialized\n", __func__); return AUDIO_FTM_ERROR; // already inited, } DALSYS_Log_Info("Attach TonePlay Driver\n"); /****************** create context object ******************/ if((DAL_SUCCESS != DALSYS_Malloc(sizeof(Aud_FTM_DevCtxt_T), (void **)&pDeviceCtxt)) || (pDeviceCtxt == NULL)) { DALSYS_Log_Err("Memory allocation fail\n"); return AUDIO_FTM_ERR_MEM_ALLOC_FAIL; } DALSYS_memset(pDeviceCtxt,0,sizeof(Aud_FTM_DevCtxt_T)); if((DAL_SUCCESS != DALSYS_Malloc(sizeof(Aud_FTM_DrvCtxt_T), (void **)&pDriverCtxt)) || (pDriverCtxt == NULL)) { DALSYS_Log_Err("Memory allocation fail\n"); DALSYS_Free(pDeviceCtxt); return AUDIO_FTM_ERR_MEM_ALLOC_FAIL; } DALSYS_memset(pDriverCtxt,0,sizeof(Aud_FTM_DevCtxt_T)); DALSYS_atomic_init(&pDriverCtxt->dwOpenCount); pDriverCtxt->pDevCtxt=pDeviceCtxt; pDeviceCtxt->pDrvCtxt=pDriverCtxt; /************* Create Critical Section ***********/ if(DAL_SUCCESS != DALSYS_SyncCreate(DALSYS_SYNC_ATTR_RESOURCE, &(pDriverCtxt->hClientSync), NULL)) { DALSYS_Log_Err("hClientSync creation fail\n"); return AUDIO_FTM_ERROR; } if(DAL_SUCCESS != DALSYS_EventCreate(DALSYS_EVENT_ATTR_WORKLOOP_EVENT, //Not used for work loops &(pDriverCtxt->hReq_Data_Event), //Return event handle NULL)) { DALSYS_Log_Err("%s: failed to create event\n", __func__); DALSYS_SyncLeave(pDriverCtxt->hClientSync); DALSYS_Free(pDriverCtxt->hClientSync); return AUDIO_FTM_ERROR; } /************* hardware initialization ***********/ DALSYS_memcpy((uint8*)&(pDriverCtxt->client_param), (uint8*)pParam, sizeof(AUD_FTM_TONE_PLAY_PARAM_T)); hw_param.inpath=AUDIO_FTM_IN_INVALID; hw_param.outpath=pDriverCtxt->client_param.path.outpath; hw_param.rate=AUDIO_FTM_PCM_RATE_8K; hw_param.width=AUDIO_FTM_BIT_WIDTH_16; hw_param.channel=AUDIO_FTM_CHN_1; hw_param.gain=pDriverCtxt->client_param.gain; hw_param.bLoopbackCase=FALSE; sts=aud_ftm_hw_init(pDeviceCtxt, &hw_param); if(sts != AUDIO_FTM_SUCCESS) { DALSYS_Log_Err("%s: failed to init hw\n", __func__); return AUDIO_FTM_ERROR; } /* Tone generator init */ freq1=((AUD_FTM_TONE_PLAY_PARAM_T*)pParam)->dtmf_low; freq2=((AUD_FTM_TONE_PLAY_PARAM_T*)pParam)->dtmf_hi; sampling_freq=8000; audio_ftm_dtmf_tone_init(&(pDriverCtxt->dtmfGen),freq1,freq2,sampling_freq); pDriverCtxt->nDTMF_Gain = vol_map[3]; /***** end of Init *****/ pDriverCtxt->bOpened=FALSE; g_bDriverInitialized=TRUE; *pDriverHdl=(AUDIO_FTM_DRIVER_HANDLE_T)pDriverCtxt; return AUDIO_FTM_SUCCESS; }
/** Leaves a synchronized context. Leaves a synchronized context. @param[in,out] sync Sync object to be used @return None. */ BAM_API_NON_PAGED void bam_osal_syncleave(bam_osal_sync_type *sync) { #ifndef BAM_MBA DALSYS_SyncLeave(*((DALSYSSyncHandle*)sync)); #endif // #ifndef BAM_MBA }
static void STMTrace_FreePort( DalDeviceHandle * h, uint32 uPort) { STMTraceClientCtxt *pClientCtxt = ((DalSTMTraceHandle *)h)->pClientCtxt; STMTraceDevCtxt *pDevCtxt = pClientCtxt->pSTMTraceDevCtxt; STMPortRangeItem * currRange = NULL; STMPortRangeItem * prevRange = NULL; uint32 uBitPos = 0; DALSYS_SyncEnter(pDevCtxt->hSync); currRange = pDevCtxt->listHead; while(NULL != currRange) { // does the uPort fall in the current range ? if(currRange->uBaseAddr <= uPort && uPort < currRange->uBaseAddr + STM_PORT_SIZE*currRange->portRange.uNumPorts) { goto free_port; } prevRange = currRange; currRange = currRange->next; } DALSYS_SyncLeave(pDevCtxt->hSync); return; free_port: uBitPos = (uPort-currRange->uBaseAddr)/STM_PORT_SIZE; if(DAL_SUCCESS != _FreeBit(currRange->portRange.pBitMask, MAX_STM_PORTS_PER_PAGE, uBitPos)) { DALSYS_SyncLeave(pDevCtxt->hSync); return; } currRange->uNumFreePorts++; if(currRange->uNumFreePorts == currRange->portRange.uNumPorts) { // all ports in this range have been freed so free the bit from // main mask if(DAL_SUCCESS != _FreeBit(currRange->mainPortRange->pBitMask, currRange->mainPortRange->uNumPorts/MAX_STM_PORTS_PER_PAGE, currRange->portRange.uBasePort/MAX_STM_PORTS_PER_PAGE)) { DALSYS_SyncLeave(pDevCtxt->hSync); return; } if(NULL != currRange->hMem) { DALSYS_DestroyObject(currRange->hMem); } if(NULL != prevRange) { prevRange->next = currRange->next; } else { pDevCtxt->listHead = pDevCtxt->listHead->next; } DALSYS_Free(currRange->portRange.pBitMask); DALSYS_Free(currRange); } DALSYS_SyncLeave(pDevCtxt->hSync); return; }
static DALResult STMTrace_NewPort( DalDeviceHandle * h, uint32 * uPort, uint32 * uPortDMA) { STMTraceClientCtxt *pClientCtxt = ((DalSTMTraceHandle *)h)->pClientCtxt; STMTraceDevCtxt *pDevCtxt = pClientCtxt->pSTMTraceDevCtxt; STMPortRange *pMainPortRange; STMPortRangeItem * currRange = NULL; STMPortRangeItem * prevRange = NULL; uint32 uBitPos; DALSYSMemInfo memInfo; if(NULL != uPortDMA) // DMA'able port requested ? { pMainPortRange = &pDevCtxt->portRangeDMA; if(!pMainPortRange->uNumPorts) { return DAL_ERROR; } } else { pMainPortRange = &pDevCtxt->portRange; } DALSYS_SyncEnter(pDevCtxt->hSync); currRange = pDevCtxt->listHead; while(NULL != currRange) { // previously allocated range has a free port? if(0 != currRange->uNumFreePorts) goto alloc_port; prevRange = currRange; currRange = currRange->next; } // carve out a new range from the master range now if(DAL_SUCCESS != DALSYS_Malloc(sizeof(STMPortRangeItem),(void **)&currRange)) { DALSYS_SyncLeave(pDevCtxt->hSync); return DAL_ERROR; } memset(currRange, 0, sizeof(STMPortRangeItem)); if(DAL_SUCCESS != _AllocBit(pMainPortRange->pBitMask, pMainPortRange->uNumPorts/MAX_STM_PORTS_PER_PAGE, &uBitPos)) { DALSYS_Free(currRange); DALSYS_SyncLeave(pDevCtxt->hSync); return DAL_ERROR; } currRange->portRange.uBasePort = pMainPortRange->uBasePort + (uBitPos * MAX_STM_PORTS_PER_PAGE); currRange->portRange.uNumPorts = MAX_STM_PORTS_PER_PAGE; currRange->uNumFreePorts = MAX_STM_PORTS_PER_PAGE; currRange->mainPortRange = pMainPortRange; if(DAL_SUCCESS != _AllocateMemForBitMasks(&currRange->portRange.pBitMask, MAX_STM_PORTS_PER_PAGE)) { _FreeBit(pMainPortRange->pBitMask, pMainPortRange->uNumPorts/MAX_STM_PORTS_PER_PAGE, uBitPos); DALSYS_Free(currRange); DALSYS_SyncLeave(pDevCtxt->hSync); return DAL_ERROR; } if(DAL_SUCCESS != DALSYS_MemRegionAlloc(DALSYS_MEM_PROPS_HWIO, DALSYS_MEM_ADDR_NOT_SPECIFIED, pDevCtxt->uSTMSPBaseAddr + (currRange->portRange.uBasePort * STM_PORT_SIZE), 4096, &currRange->hMem, NULL)) { _FreeBit(pMainPortRange->pBitMask, pMainPortRange->uNumPorts/MAX_STM_PORTS_PER_PAGE, uBitPos); DALSYS_Free(currRange->portRange.pBitMask); DALSYS_Free(currRange); DALSYS_SyncLeave(pDevCtxt->hSync); return DAL_ERROR; } DALSYS_MemInfo(currRange->hMem, &memInfo); currRange->uBaseAddr = memInfo.VirtualAddr; if(NULL != prevRange) { prevRange->next = currRange; } else { pDevCtxt->listHead = currRange; } alloc_port: if(DAL_SUCCESS != _AllocBit(currRange->portRange.pBitMask, MAX_STM_PORTS_PER_PAGE, &uBitPos)) { DALSYS_SyncLeave(pDevCtxt->hSync); return DAL_ERROR; } *uPort = currRange->uBaseAddr + (STM_PORT_SIZE * uBitPos); if(NULL != uPortDMA) { /* prepare a 32 bit int with 7 bits starting at 17th bit */ uint32 uPortOffset = ((currRange->portRange.uBasePort+uBitPos)&0x7F)<<17; /* first get the physical address of the allocated port */ *uPortDMA = pDevCtxt->uSTMSPBaseAddr + ((currRange->portRange.uBasePort + uBitPos) * STM_PORT_SIZE); /* then set the 7 bits starting at 17th bit pos to 0's */ *uPortDMA = *uPortDMA &(~(0x7F<<17)); /* finally set the lower 7 bits of the stimulus port number at the 17th bit pos */ *uPortDMA |= uPortOffset; } currRange->uNumFreePorts--; DALSYS_SyncLeave(pDevCtxt->hSync); return DAL_SUCCESS; }