예제 #1
0
static VOID threadHandle(IN PVOID pContext)
{
	PTHREAD_PARAM		pparam = (PTHREAD_PARAM)pContext;

	pparam->isThreadEnded = FALSE;
	SetEvent(pparam->syncthread);
	///pparam->ThreadStatus = THREAD_RUNNING;
	DBGPRINT(DBG_THREAD|DBG_HELP,(L"->Thread: Thread is running\n"));
	if (pparam->priority != DEFAULT_THREAD_PRIORITY) {
		CeSetThreadPriority(GetCurrentThread(), pparam->priority); 
	}
	
	while (pparam->EndOfThread == FALSE ) {
		WaitForSingleObject(pparam->hEvent, INFINITE);
		if (pparam->EndOfThread == TRUE) {
			DBGPRINT(DBG_THREAD|DBG_HELP,(L"->Thread: Thread is ending. Leave the loop now\n"));
			break;
		}
		///Call the real body of the thread handle
		if (pparam->threadHandleBody) {
			pparam->threadHandleBody(pparam->pContext);
		}
	}

	///SetEvent(pparam->syncthread);
	pparam->isThreadEnded = TRUE;
	DBGPRINT(DBG_THREAD|DBG_HELP,(L"->Thread: Thread is terminiated\n"));
	return;
}
예제 #2
0
static BOOL InitializeIST()
{
    BOOL r;

    gMfcIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!gMfcIntrEvent) {
        ERRORMSG(1, (L"Unable to create interrupt event"));
        return(FALSE);
    }

    if (!CreateInterruptNotification()) {
        ERRORMSG(1, (L"Unable to create interrupt notification"));
        CloseHandle(gMfcIntrEvent);
        return FALSE;
    }

    r = KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
                        &g_MfcIrq,     sizeof(UINT32),
                        &g_MfcSysIntr, sizeof(UINT32),
                        NULL);
    if (r != TRUE) {
        ERRORMSG(1, (L"Failed to request sysintr value for MFC interrupt.\r\n"));
        DeleteInterruptNotification();
        CloseHandle(gMfcIntrEvent);
        return FALSE;
    }


    r = InterruptInitialize(g_MfcSysIntr, gMfcIntrEvent, NULL, 0);
    if (r != TRUE) {
        ERRORMSG(1, (L"Unable to initialize output interrupt"));
        DeleteInterruptNotification();
        CloseHandle(gMfcIntrEvent);
        return FALSE;
    }

    gMfcIntrThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
                                  0,
                                  (LPTHREAD_START_ROUTINE)MFC_IntrThread,
                                  0,
                                  0,
                                  NULL);
    if (!gMfcIntrThread) {
        ERRORMSG(1, (L"Unable to create interrupt thread"));
        InterruptDisable(g_MfcSysIntr);
        DeleteInterruptNotification();
        CloseHandle(gMfcIntrEvent);
        return FALSE;
    }

    // Bump up the priority since the interrupt must be serviced immediately.
    CeSetThreadPriority(gMfcIntrThread, MFC_THREAD_PRIORITY_DEFAULT);

    RETAILMSG(1, (L"MFC Interrupt has been initialized.\n"));

    return TRUE;
}
예제 #3
0
void startPollThread(CF_DEVICE *cfDevice)
{
    HANDLE hThread;

    poll = 1;
    hThread = CreateThread(NULL, 0, 
		        cfPollThread, (LPVOID)cfDevice, 0, NULL);
    CeSetThreadPriority(hThread, 200);
    CloseHandle(hThread);
    
    return;
}
예제 #4
0
extern 
DWORD WINAPI DRG_Init(DWORD dwContext)
{
	PWCHAR*                         pRegPath = NULL;
    SDCARD_CLIENT_REGISTRATION_INFO ClientInfo;     // client into
    SD_API_STATUS                   Status;         // intermediate status
	HANDLE                          hThread;

    NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6K_SDIO: +DRG_Init by DiskImage !!! \r\n");

    // get the device handle from the bus driver
    hClientHandle = SDGetDeviceHandle(dwContext, pRegPath);
    if (NULL == hClientHandle) {
		NDIS_DEBUG_PRINTF(DBG_ERR, "-DRG_Init: Failed to get client handle \r\n");
        return 0;
    }

    memset(&ClientInfo, 0, sizeof(ClientInfo));

    // set client options and register as a client device
    _tcscpy(ClientInfo.ClientName, TEXT("Atheros AR6K SDIO Wifi Card"));

    // set the callback
    ClientInfo.pSlotEventCallBack = SlotEventCallBack;

    Status = SDRegisterClient(hClientHandle, 
                              NULL, 
                              &ClientInfo);

    if (!SD_API_SUCCESS(Status)) {
        NDIS_DEBUG_PRINTF(DBG_ERR, "-DRG_Init: Failed to register client : 0x%08X \r\n", Status);
        return 0;
    }

	drvInit();

    if (!createRegKeyValues()) {
        NDIS_DEBUG_PRINTF(DBG_ERR, "-DRG_Init: Failed to create ndis registryentries \r\n");
        return 0;
    }

	// Perform NDIS register adapter on a separate thread to avoid
	// blocking the SDIO bus driver
	hThread = CreateThread(NULL, 0, 
		NdisRegisterAdapterThread, NULL, 0, NULL);
	
	CeSetThreadPriority(hThread, 200);
	CloseHandle(hThread);
	
	NDIS_DEBUG_PRINTF(DBG_TRACE, "DRG_Init : Exit\r\n");
	return 1;
}
예제 #5
0
파일: CanThread.cpp 프로젝트: cl716/ips
BOOL enable_Can_RunThread()
{
	HANDLE hThread1,hThread2;
	//CanBandRate bandrate = BandRate_100kbps;
	BYTE cnfregdata[3];
	//DWORD ctrolcode = 0x1234567d;
	//SJW=1,SOC=8MHZ----->bandrate=100K			
	//cnfregdata[0] = 0x1;
	//cnfregdata[1] = 0xbe;
	//cnfregdata[2] = 0x3;
	//SJW=1,TBS1=SYN+PS1=7+7=14,TBS2=PS2=2,BRP=2*(brp+1)=8,SOC=8MHZ----->bandrate=58.82K
	cnfregdata[0] = 0x3;
	cnfregdata[1] = 0xb6;
	cnfregdata[2] = 0x1;

	hcan =  CreateFile(_T("CAN1:"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
	if(hcan == INVALID_HANDLE_VALUE)
	{
		printf("OPEN CAN1 device fail,error is %d \r\n",GetLastError());
		return FALSE;
	}

	//DeviceIoControl(hcan,CAN_IOCTL_SETBANDRATE,&bandrate,1,NULL,0,NULL,NULL);
	DeviceIoControl(hcan,CAN_IOCTL_SETBANDRATE,cnfregdata,3,NULL,0,NULL,NULL);

	hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Can_RunReadThread, NULL, 0,NULL);
	if(hThread1  == NULL)
		printf("CreateThread fail,error is %d",GetLastError());
	//CeSetThreadPriority(hThread1,95);
	CeSetThreadPriority(hThread1,202);
	CloseHandle(hThread1);
	
	hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Can_RunWriteThread, NULL, 0, NULL);
	if(hThread2  == NULL)
		printf("CreateThread fail,error is %d",GetLastError());
	CeSetThreadPriority(hThread2,201);
	CloseHandle(hThread2);
	return TRUE;
}
예제 #6
0
파일: ndshared.c 프로젝트: NemProjects/WLAN
static void
shared_dpc_thread(void *h)
{
	shared_info_t *sh = (shared_info_t *)h;

	/* Read the priority from registry */
	CeSetThreadPriority(GetCurrentThread(), sh->DPCPriority);

	while (TRUE) {
		NdisWaitEvent(&sh->dpc_event, 0);	/* wait forever */

		NdisResetEvent(&sh->dpc_event);		/* reset the event */

		(sh->dpc_cb)(sh->dpc_arg);
	}
}
예제 #7
0
// this thread is signaled when the system wakes from a suspend state
DWORD WINAPI
ResumeThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[2];
    BOOL fDone = FALSE;
    INT iPriority;
    SETFNAME(_T("ResumeThreadProc"));

    PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId()));

    // set the thread priority
    if(!GetPMThreadPriority(_T("ResumePriority256"), &iPriority)) {
        iPriority = DEF_RESUME_THREAD_PRIORITY;
    }
    CeSetThreadPriority(GetCurrentThread(), iPriority);

    // we're up and running
    SetEvent(hevReady);

    // wait for new devices to arrive
    hEvents[0] = ghevResume;
    hEvents[1] = ghevPmShutdown;
    while(!fDone) {
        dwStatus = WaitForMultipleObjects(dim(hEvents), hEvents, FALSE, INFINITE);
        switch(dwStatus) {
        case (WAIT_OBJECT_0 + 0):
            PMLOGMSG(ZONE_RESUME, (_T("%s: resume event signaled\r\n"), pszFname));
            PlatformResumeSystem();
            break;
        case (WAIT_OBJECT_0 + 1):
            PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname));
            fDone = TRUE;
            break;
        default:
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                                 pszFname, dwStatus, GetLastError()));
            fDone = TRUE;
            break;
        }
    }

    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}
예제 #8
0
// New function to Card detect thread of HSMMC ch1 on SMDK6410.
DWORD CSDHControllerCh1::CardDetectThread() {
    BOOL  bSlotStateChanged = FALSE;
    DWORD dwWaitResult  = WAIT_TIMEOUT;
    PCSDHCSlotBase pSlotZero = GetSlot(0);

    CeSetThreadPriority(GetCurrentThread(), 100);

    while(1) {
        // Wait for the next insertion/removal interrupt
        dwWaitResult = WaitForSingleObject(m_hevCardDetectEvent, INFINITE);

        Lock();
        pSlotZero->HandleInterrupt(SDSLOT_INT_CARD_DETECTED);
        Unlock();
        InterruptDone(m_dwSDDetectSysIntr);

        EnableCardDetectInterrupt();
    }

    return TRUE;
}
예제 #9
0
static DWORD SpiGpioIRQInterruptThread(LPVOID pContext)
{
    PSDHCD_HW_DEVICE pHWDevice = (PSDHCD_HW_DEVICE)pContext;

    DBG_PRINT(SDDBG_TRACE, ("SpiGpioIRQInterruptThread: Initializing. Context 0x%X \n",pContext));
    
    CeSetThreadPriority(GetCurrentThread(), SPI_IRQ_THREAD_PRIORITY);
    
    while (TRUE) {
        WaitForSingleObject(pHWDevice->hIstEventSPIGpioIRQ,INFINITE); 
        if (pHWDevice->ShutDown) {
            DBG_PRINT(SDDBG_TRACE, ("SpiGpioIRQInterruptThread: Shutting down \n"));            
            break;
        }
        
        HcdSpiInterrupt(pHWDevice->pDevice);
            
            /* ack kernel/OAL that interrupt has been acknowledged */
        InterruptDone(pHWDevice->SysIntrSPIGpioIRQ); 
    }

    return 0;
}
예제 #10
0
DWORD
CSDHCBase::IST()
{
    SETFNAME(_T("IST"));
    
    DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("%s Thread Starting\n"), pszFname));

    if (!CeSetThreadPriority(GetCurrentThread(), m_dwPriority)) {
        DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("%s Failed to set CEThreadPriority\n"),
            pszFname));
    }

    while (TRUE) {
        DEBUGCHK(m_hevInterrupt);
        DWORD dwWaitStatus = WaitForSingleObject(m_hevInterrupt, INFINITE);
        Validate();
        //InterruptDone(m_dwSysIntr);
        RETAILMSG(0,(TEXT("CSDHCBase::IST() Event is signaled [SYSINT = %x].\n"),m_dwSysIntr));
        if (WAIT_OBJECT_0 != dwWaitStatus) {
            DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("%s Wait Failed! 0x%08X\n"), 
                pszFname, dwWaitStatus));
            // bail out
            break;
        }
        else if (m_fDriverShutdown) {
            break;
        }
        else {
		  RETAILMSG(0,(TEXT("CSDHCBase::IST()\n")));			
            HandleInterrupt();
        }
    }

    DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("%s Thread Exiting\n"), pszFname));

    return 0;
}
예제 #11
0
void S3C2450DISP::SetVisibleSurface( GPESurf *pTempSurf, BOOL bWaitForVBlank)
{
	static int timeoutcnt=0;
    DWORD we;
#ifdef	HIGH_PRIORITY_INTR
	int iPriority;
	HANDLE hThread;

	hThread = GetCurrentThread();
	iPriority = CeGetThreadPriority(hThread);
	CeSetThreadPriority(hThread, DISPDRV_IST_PRIORITY);
#endif	
	S3C2450Surf *pSurf = (S3C2450Surf *) pTempSurf;
	EnterCriticalSection(&m_CS);
	// assume Synchronous to VSYNC

	EnableInterrupt();
	we = WaitForSingleObject(m_hVSYNCInterruptEvent,1000/*INFINITE*/);
	DisableInterrupt();
	InterruptDone(m_dwVSYNCSysIntr);

	if(we != WAIT_OBJECT_0)
	{
		timeoutcnt++;
		RETAILMSG(1,(TEXT("Surface Flipping Time Out  %d !!!\n"), timeoutcnt));
		for(int i=0;i<78;i++)
			RETAILMSG(1,(TEXT("0x%08X = 0x%08X\n"),(DWORD*)((DWORD*)m_pLCDReg + i),*(DWORD*)((DWORD*)m_pLCDReg + i)));
			
		RETAILMSG(1,(TEXT("saved_x=%d"),saved_x));
		RETAILMSG(1,(TEXT("saved_y=%d"),saved_y));
		RETAILMSG(1,(TEXT("saved_width=%d"),saved_width));
		RETAILMSG(1,(TEXT("saved_height=%d"),saved_height));				
		while(1);
	}

	if(pSurf->m_bIsOverlay == FALSE)
	{
		//RETAILMSG(1,(TEXT("pSurf->OffsetInVideoMemory()=0x%08X\n"),pSurf->OffsetInVideoMemory()));
		m_pVisibleSurface = pSurf;
		m_pLCDReg->VIDW00ADD0B0 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE);		
				// buffer end address
		m_pLCDReg->VIDW00ADD1B0 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE) + (LCD_XSIZE_TFT*LCD_YSIZE_TFT*2);
				// buffer size 
		m_pLCDReg->VIDW00ADD2B0 = (0<<VIDWxADD2_OFFSET_SIZE_S)|(LCD_XSIZE_TFT*2);
	}
	else
	{

		m_pLCDReg->VIDW01ADD0 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE);		
				// buffer end address
		m_pLCDReg->VIDW01ADD1 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE) + 
														(pSurf->Width()*pSurf->Height()*2);
				// buffer size 
		m_pLCDReg->VIDW01ADD2 = (0<<VIDWxADD2_OFFSET_SIZE_S)|(pSurf->Width()*2);		
	}
	RETAILMSG(DBGLCD, (TEXT("S3C2450DISP::SetVisibleSurface\r\n")));
	LeaveCriticalSection(&m_CS);

#ifdef	HIGH_PRIORITY_INTR
	CeSetThreadPriority(hThread, iPriority);
#endif	
}
예제 #12
0
/*
* WMME capture and playback thread.
*/
static int PJ_THREAD_FUNC wmme_dev_thread(void *arg)
{
    pjmedia_snd_stream *strm = arg;
    HANDLE events[3];
    unsigned eventCount;
    unsigned bytes_per_frame;
    pj_status_t status = PJ_SUCCESS;


    eventCount = 0;
    events[eventCount++] = strm->thread_quit_event;
    if (strm->dir & PJMEDIA_DIR_PLAYBACK)
	events[eventCount++] = strm->play_strm.hEvent;
    if (strm->dir & PJMEDIA_DIR_CAPTURE)
	events[eventCount++] = strm->rec_strm.hEvent;


    /* Raise self priority. We don't want the audio to be distorted by
     * system activity.
     */
#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0
    if (strm->dir & PJMEDIA_DIR_PLAYBACK)
	CeSetThreadPriority(GetCurrentThread(), 153);
    else
	CeSetThreadPriority(GetCurrentThread(), 247);
#else
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
#endif

    /* Calculate bytes per frame */
    bytes_per_frame = strm->samples_per_frame * BYTES_PER_SAMPLE;

    /*
     * Loop while not signalled to quit, wait for event objects to be 
     * signalled by WMME capture and play buffer.
     */
    while (status == PJ_SUCCESS)
    {

	DWORD rc;
	pjmedia_dir signalled_dir;

	rc = WaitForMultipleObjects(eventCount, events, FALSE, INFINITE);
	if (rc < WAIT_OBJECT_0 || rc >= WAIT_OBJECT_0 + eventCount)
	    continue;

	if (rc == WAIT_OBJECT_0)
	    break;

	if (rc == (WAIT_OBJECT_0 + 1))
	{
	    if (events[1] == strm->play_strm.hEvent)
		signalled_dir = PJMEDIA_DIR_PLAYBACK;
	    else
		signalled_dir = PJMEDIA_DIR_CAPTURE;
	}
	else
	{
	    if (events[2] == strm->play_strm.hEvent)
		signalled_dir = PJMEDIA_DIR_PLAYBACK;
	    else
		signalled_dir = PJMEDIA_DIR_CAPTURE;
	}


	if (signalled_dir == PJMEDIA_DIR_PLAYBACK)
	{
	    struct wmme_stream *wmme_strm = &strm->play_strm;
	    MMRESULT mr = MMSYSERR_NOERROR;
	    status = PJ_SUCCESS;

	    /*
	    * Windows Multimedia has requested us to feed some frames to
	    * playback buffer.
	    */

	    while (wmme_strm->WaveHdr[wmme_strm->dwBufIdx].dwFlags & WHDR_DONE)
	    {
		void* buffer = wmme_strm->WaveHdr[wmme_strm->dwBufIdx].lpData;

		PJ_LOG(5,(THIS_FILE, "Finished writing buffer %d", 
			  wmme_strm->dwBufIdx));

		/* Get frame from application. */
		status = (*strm->play_cb)(strm->user_data, 
					  wmme_strm->timestamp.u32.lo,
					  buffer,
					  bytes_per_frame);

		if (status != PJ_SUCCESS)
		    break;

		/* Write to the device. */
		mr = waveOutWrite(wmme_strm->hWave.Out, 
				  &(wmme_strm->WaveHdr[wmme_strm->dwBufIdx]), 
				  sizeof(WAVEHDR));
		if (mr != MMSYSERR_NOERROR)
		{
		    status = PJ_STATUS_FROM_OS(mr);
		    break;
		}

		/* Increment position. */
		if (++wmme_strm->dwBufIdx >= wmme_strm->dwMaxBufIdx)
		    wmme_strm->dwBufIdx = 0;
		wmme_strm->timestamp.u64 += strm->samples_per_frame / 
					    strm->channel_count;
	    }
	}
	else
	{
	    struct wmme_stream *wmme_strm = &strm->rec_strm;
	    MMRESULT mr = MMSYSERR_NOERROR;
	    status = PJ_SUCCESS;

	    /*
	    * Windows Multimedia has indicated that it has some frames ready
	    * in the capture buffer. Get as much frames as possible to
	    * prevent overflows.
	    */
#if 0
	    {
		static DWORD tc = 0;
		DWORD now = GetTickCount();
		DWORD i = 0;
		DWORD bits = 0;

		if (tc == 0) tc = now;

		for (i = 0; i < wmme_strm->dwMaxBufIdx; ++i)
		{
		    bits = bits << 4;
		    bits |= wmme_strm->WaveHdr[i].dwFlags & WHDR_DONE;
		}
		PJ_LOG(5,(THIS_FILE, "Record Signal> Index: %d, Delta: %4.4d, "
			  "Flags: %6.6x\n",
			  wmme_strm->dwBufIdx,
			  now - tc,
			  bits));
		tc = now;
	    }
#endif

	    while (wmme_strm->WaveHdr[wmme_strm->dwBufIdx].dwFlags & WHDR_DONE)
	    {
		char* buffer = (char*)
			       wmme_strm->WaveHdr[wmme_strm->dwBufIdx].lpData;
		unsigned cap_len = 
			wmme_strm->WaveHdr[wmme_strm->dwBufIdx].dwBytesRecorded;

		/*
		PJ_LOG(5,(THIS_FILE, "Read %d bytes from buffer %d", cap_len, 
			  wmme_strm->dwBufIdx));
		*/

		if (cap_len < bytes_per_frame)
		    pj_bzero(buffer + cap_len, bytes_per_frame - cap_len);

		/* Copy the audio data out of the wave buffer. */
		pj_memcpy(strm->buffer, buffer, bytes_per_frame);

		/* Re-add the buffer to the device. */
		mr = waveInAddBuffer(wmme_strm->hWave.In, 
				     &(wmme_strm->WaveHdr[wmme_strm->dwBufIdx]), 
				     sizeof(WAVEHDR));
		if (mr != MMSYSERR_NOERROR) {
		    status = PJ_STATUS_FROM_OS(mr);
		    break;
		}

		/* Call callback */
		status = (*strm->rec_cb)(strm->user_data, 
					 wmme_strm->timestamp.u32.lo, 
					 strm->buffer, 
					 bytes_per_frame);

		if (status != PJ_SUCCESS)
		    break;

		/* Increment position. */
		if (++wmme_strm->dwBufIdx >= wmme_strm->dwMaxBufIdx)
		    wmme_strm->dwBufIdx = 0;
		wmme_strm->timestamp.u64 += strm->samples_per_frame / 
					    strm->channel_count;
	    }
	}
    }

    PJ_LOG(5,(THIS_FILE, "WMME: thread stopping.."));
    return 0;
}
예제 #13
0
//------------------------------------------------------------------------------
//
//  Function:  HDS_Init
//
//  Called by device manager to initialize device.
//
DWORD
HDS_Init(
    LPCTSTR szContext,
    LPCVOID pBusContext
    )
{
    DWORD rc = (DWORD)NULL;
    HeadsetDevice_t *pDevice = NULL;

	UNREFERENCED_PARAMETER(pBusContext);

    DEBUGMSG(ZONE_FUNCTION, (
        L"+HDS_Init(%s, 0x%08x)\r\n", szContext, pBusContext
        ));

    // Create device structure
    pDevice = (HeadsetDevice_t *)LocalAlloc(LPTR, sizeof(HeadsetDevice_t));
    if (pDevice == NULL)
        {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: HDS_Init: "
            L"Failed allocate HDS driver structure\r\n"
            ));
        goto cleanUp;
        }

    // initialize memory
    //
    memset(pDevice, 0, sizeof(HeadsetDevice_t));

    // Set cookie & initialize critical section
    pDevice->cookie = HDS_DEVICE_COOKIE;

    // Initialize crit section
    InitializeCriticalSection(&pDevice->cs);

    // Read device parameters
    if (GetDeviceRegistryParams(
            szContext, pDevice, dimof(s_deviceRegParams), s_deviceRegParams)
            != ERROR_SUCCESS)
        {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: HDS_Init: "
            L"Failed read HDS driver registry parameters\r\n"
            ));
        goto cleanUp;
        }

    // Open WAV device
    pDevice->hWAV = CreateFile(L"WAV1:", GENERIC_READ | GENERIC_WRITE, 0,
                        NULL, OPEN_EXISTING, 0, NULL);

    if (pDevice->hWAV == INVALID_HANDLE_VALUE)
        {
        pDevice->hWAV = NULL;
        DEBUGMSG(ZONE_WARN,
            (L"WARN: HDS_Init: Failed open WAV1: device driver\r\n"));
        }

    // Open GPIO bus
    pDevice->hGPIO = GPIOOpen();
    if (pDevice->hGPIO == NULL)
        {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: HDS_Init: "
            L"Failed open GPIO bus driver\r\n"
            ));
        goto cleanUp;
        }

    // Configure GPIO mute as output high
    GPIOSetMode(pDevice->hGPIO, pDevice->hdstMuteGpio, GPIO_DIR_OUTPUT);
    GPIOSetBit(pDevice->hGPIO, pDevice->hdstMuteGpio);

    // Note that the headset detect GPIO pullup and pulldown configuration
    // is not handled in the \src\boot\twl4030\bsp_twl4020.c file

    // Configure GPIO headset as input with both edge interrupts
    GPIOSetMode(pDevice->hGPIO, pDevice->hdstDetGpio,
        GPIO_DIR_INPUT | GPIO_INT_LOW_HIGH | GPIO_INT_HIGH_LOW);

    // update plugged-in field
    pDevice->bPluggedIn = (BOOL)GPIOGetBit(pDevice->hGPIO,
        pDevice->hdstDetGpio);

    // Create interrupt event
    pDevice->hIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (pDevice->hIntrEvent == NULL)
        {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: HDS_Init: "
            L"Failed create interrupt event\r\n"
            ));
        goto cleanUp;
        }

    // Associate event with TWL headset interrupt
    if (!GPIOInterruptInitialize(pDevice->hGPIO, pDevice->hdstDetGpio,
		&pDevice->dwSysIntr, pDevice->hIntrEvent))
        {
        DEBUGMSG (ZONE_ERROR, (L"ERROR: HDS_Init: "
            L"Failed associate event with TWL headset interrupt\r\n"
            ));
        goto cleanUp;
        }

    // Start interrupt service thread
    pDevice->intrThreadExit = FALSE;
    pDevice->hIntrThread = CreateThread(
        NULL, 0, HDS_IntrThread, pDevice, 0,NULL
        );
    if (!pDevice->hIntrThread)
        {
        DEBUGMSG (ZONE_ERROR, (L"ERROR: HDS_Init: "
            L"Failed create interrupt thread\r\n"
            ));
        goto cleanUp;
        }

    // Set thread priority
    CeSetThreadPriority(pDevice->hIntrThread, pDevice->priority256);

    // Return non-null value
    rc = (DWORD)pDevice;

cleanUp:
    if (rc == 0)
        {
        HDS_Deinit((DWORD)pDevice);
        }
    DEBUGMSG(ZONE_FUNCTION, (L"-HDS_Init(rc = %d\r\n", rc));
    return rc;
}
예제 #14
0
BOOL KeyMatrix::IsrThreadProc()
{
    DWORD dwPriority;
    DWORD i, step;

    DWORD   rguiScanCode[SIZE_KEY];
    BOOL    rgfKeyUp[SIZE_KEY];
    UINT    cEvents;
    DWORD ret;
    DWORD timeout;
    HANDLE gEventIntr;
    DWORD irq, sysintr;

    ReadRegDWORD( TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("Priority256"), &dwPriority );
    if(dwPriority == 0)
    {
        dwPriority = DEFAULT_PRIORITY;
    }

    DEBUGMSG(ZONE_INIT, (TEXT("+[KEYBD]IsrThreadProc\r\n")));
    // update the IST priority
    CeSetThreadPriority(GetCurrentThread(), (int)dwPriority);

    irq = IRQ_KEYPAD;
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(UINT32), &sysintr, sizeof(UINT32), NULL))
    {
        ERRORMSG( 1, (TEXT("ERROR: Failed to request the IRQ_KEY sysintr.\r\n")));
        sysintr = SYSINTR_UNDEFINED;
        return(FALSE);
    }

    gEventIntr = CreateEvent(NULL, FALSE, FALSE, NULL);
    if( NULL == gEventIntr )
    {
        ERRORMSG( 1, (TEXT("Event is not created\r\n")));
        return(FALSE);
    }

    if( InterruptInitialize(sysintr, gEventIntr, NULL, 0) == FALSE )
    {
        ERRORMSG( 1, (TEXT("interrupt is not initialized\n\r")));
        return(FALSE);
    }


    timeout = INFINITE;
    DEBUGMSG(ZONE_INIT, (TEXT("+[KEYBD]Enter Infinite Loop\r\n")));
    while(1)    // INFINITE LOOP ____________________________________________________________________
    {
        ret = WaitForSingleObject(gEventIntr, timeout); // Wait for Interrupt Event ________________________

        if( ret == WAIT_OBJECT_0 )
        {
            RETAILMSG( FALSE,(TEXT("Object : WAIT_OBJECT_0\r\n")));
            timeout = TIME_KEYSCAN;
        }

        // Clear Pressed/Released Interrupt
        KEYIF_Status_Clear();
        // Read the Matrix
        KScan_ProcIO();

        for( i=0, step=0; i< SIZE_COLS; i++, step+=SIZE_ROWS)
        {
            cEvents = KScan_ProcState( i, step, rguiScanCode, rgfKeyUp);

            if( cEvents )
            {
                for (UINT iEvent = 0; iEvent < cEvents; ++iEvent)
                {
                    v_pfnKeybdEvent(v_uiPddId, rguiScanCode[iEvent], rgfKeyUp[iEvent]);
                    RETAILMSG(FALSE,(TEXT("PddID : %x, ScanCode : %x, KeyUp : %d\r\n"),v_uiPddId, rguiScanCode[iEvent], rgfKeyUp[iEvent]));
                }
            }
        }

        if( TRUE == AreAllKeysUp() )
        {
            RETAILMSG(0,(TEXT("Key all up\r\n")));
            timeout = INFINITE;
        }
        InterruptDone(sysintr);
    }// INFINITE LOOP ____________________________________________________________________
}
예제 #15
0
//------------------------------------------------------------------------------
//
//  Function:  KPD_Init
//
//  Called by device manager to initialize device.
//
DWORD KPD_Init(LPCTSTR szContext, LPCVOID pBusContext)
{
    DWORD rc = (DWORD)NULL;
    KPD_DEVICE *pDevice = NULL;
    PHYSICAL_ADDRESS pa;


    DEBUGMSG(ZONE_FUNCTION, (
        L"+KPD_Init(%s, 0x%08x)\r\n", szContext, pBusContext
    ));

    // Create device structure
    pDevice = (KPD_DEVICE *)LocalAlloc(LPTR, sizeof(KPD_DEVICE));
    if (pDevice == NULL) {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: "
            L"Failed allocate KDP driver structure\r\n"
        ));
        goto cleanUp;
    }

    // Set cookie & initialize critical section
    pDevice->cookie = KPD_DEVICE_COOKIE;
    InitializeCriticalSection(&pDevice->cs);

    // Read device parameters
    if (GetDeviceRegistryParams(
        szContext, pDevice, dimof(g_deviceRegParams), g_deviceRegParams
    ) != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: "
            L"Failed read KPD driver registry parameters\r\n"
        ));
        pDevice->irqs[0]= -1;
        pDevice->irqs[1]= 2;
        pDevice->irqs[2]=(DWORD)NULL;
        pDevice->irqs[3]=(DWORD)NULL;
        pDevice->irqs[4]=(DWORD)NULL;
        pDevice->irqs[5]=(DWORD)NULL;
        pDevice->irqs[6]=(DWORD)NULL;
        pDevice->priority256=100;
        pDevice->samplePeriod=40;
        pDevice->debounceTime=0x50;
        pDevice->firstRepeat=500;
        pDevice->nextRepeat=125;
//        goto cleanUp;
    }

    // map gpio memory space
    pa.QuadPart = OMAP2420_GPIO1_REGS_PA;
    pDevice->pGPIO1Regs = (OMAP2420_GPIO_REGS *) MmMapIoSpace(pa, sizeof(OMAP2420_GPIO_REGS), FALSE);
    if (pDevice->pGPIO1Regs == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Failed to map GPIO1 registers\r\n"));
        goto cleanUp;
    }

    pa.QuadPart = OMAP2420_GPIO2_REGS_PA;
    pDevice->pGPIO2Regs = (OMAP2420_GPIO_REGS *) MmMapIoSpace(pa, sizeof(OMAP2420_GPIO_REGS), FALSE);
    if (pDevice->pGPIO2Regs == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Failed to map GPIO2 registers\r\n"));
        goto cleanUp;
    }

    pa.QuadPart = OMAP2420_GPIO3_REGS_PA;
    pDevice->pGPIO3Regs = (OMAP2420_GPIO_REGS *) MmMapIoSpace(pa, sizeof(OMAP2420_GPIO_REGS), FALSE);
    if (pDevice->pGPIO3Regs == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Failed to map GPIO3 registers\r\n"));
        goto cleanUp;
    }

    pa.QuadPart = OMAP2420_GPIO4_REGS_PA;
    pDevice->pGPIO4Regs = (OMAP2420_GPIO_REGS *) MmMapIoSpace(pa, sizeof(OMAP2420_GPIO_REGS), FALSE);
    if (pDevice->pGPIO4Regs == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Failed to map GPIO4 registers\r\n"));
        goto cleanUp;
    }

    // Need to configure the row GPIO's as interrupt sources
    pDevice->irqs[0] = -1;
    pDevice->irqs[1] = 2;
    //pDevice->irqs[2] = IRQ_GPIO_0+88;	// row 0 = GPIO88
    //pDevice->irqs[3] = IRQ_GPIO_0+89;	// row 1 = GPIO89
    //pDevice->irqs[4] = IRQ_GPIO_0+124;	// row 2 = GPIO124
    //pDevice->irqs[5] = IRQ_GPIO_0+11;	// row 3 = GPIO11
    //pDevice->irqs[6] = IRQ_GPIO_0+6;	// row 4 = GPIO6


    // Map interrupts
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
        pDevice->irqs, sizeof(pDevice->irqs),
        &pDevice->sysIntr, sizeof(pDevice->sysIntr), NULL
    )) {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: "
            L"Failed map Keyboard Interrupt\r\n"
        ));
        goto cleanUp;
    } else DEBUGMSG(ZONE_INIT, (L"KPD_Init: sysintr = %d",pDevice->sysIntr));

    // Enable wakeup from keyboard if required
    if (pDevice->enableWake != 0) {
        DEBUGMSG(ZONE_ERROR, (L"Enable keyboard as wakeup source\r\n"));
        if (!KernelIoControl(
            IOCTL_HAL_ENABLE_WAKE, &pDevice->sysIntr, sizeof(pDevice->sysIntr),
            NULL, 0, NULL
        )) {
            DEBUGMSG(ZONE_WARN, (L"WARN: KPD_Init: "
                L"Failed enable keyboard as wakeup source\r\n"
            ));
        }
    }

    // Create interrupt event
    pDevice->hIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (pDevice->hIntrEvent == NULL) {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: "
            L"Failed create interrupt event\r\n"
        ));
        goto cleanUp;
    }

    // Initialize interrupt
    if (!InterruptInitialize(pDevice->sysIntr, pDevice->hIntrEvent, NULL, 0)) {
        DEBUGMSG (ZONE_ERROR, (L"ERROR: KPD_Init: "
            L"InterruptInitialize failed\r\n"
        ));
        goto cleanUp;
    }
    // Start interrupt service thread
    if ((pDevice->hIntrThread = CreateThread(
        NULL, 0, KPD_IntrThread, pDevice, 0,NULL
    )) == NULL) {
        DEBUGMSG (ZONE_ERROR, (L"ERROR: KPD_Init: "
            L"Failed create interrupt thread\r\n"
        ));
        goto cleanUp;
    }
    // Set thread priority
    CeSetThreadPriority(pDevice->hIntrThread, pDevice->priority256);

    // Return non-null value
    rc = (DWORD)pDevice;

cleanUp:
    if (rc == 0) KPD_Deinit((DWORD)pDevice);
    DEBUGMSG(ZONE_FUNCTION, (L"-KPD_Init(rc = %d\r\n", rc));

    return rc;
}
예제 #16
0
INLINE_FUNCTION tShbError  ShbIpcStartSignalingNewData (
    tShbInstance pShbInstance_p,
    tSigHndlrNewData pfnSignalHandlerNewData_p,
    tShbPriority ShbPriority_p)
{

tShbMemInst*    pShbMemInst;
tShbMemHeader*  pShbMemHeader;
const char*     pszObjectName;
HANDLE          hEventTermRequ;
HANDLE          hEventTermResp;
HANDLE          hThreadNewData;
unsigned long   ulThreadIDNewData;
tShbError       ShbError;
int             iPriority;
wchar_t			awcObjectName[MAX_PATH];
size_t			convertedChars = 0;

    if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL))
    {
        return (kShbInvalidArg);
    }


    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
    pShbMemHeader = ShbIpcGetShbMemHeader (pShbInstance_p);
    ShbError = kShbOk;

    if ( (pShbMemInst->m_hThreadNewData                      != INVALID_HANDLE_VALUE) ||
         (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != INVALID_HANDLE_VALUE) ||
         (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != INVALID_HANDLE_VALUE) ||
         (pShbMemInst->m_pfnSigHndlrNewData                  != NULL) )
    {
        ShbError = kShbAlreadySignaling;
        goto Exit;
    }


    pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;


    // Because the event <pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]>
    // is used for signaling of new data after a write operation too (using
    // SetEvent), it is always created here (see <ShbIpcAllocBuffer>).

    pszObjectName = ShbIpcGetUniformObjectName (NAME_EVENT_TERM_REQU, pShbMemHeader->m_szBufferID, FALSE);

	mbstowcs_s(&convertedChars, awcObjectName, strlen(pszObjectName)+1, pszObjectName, _TRUNCATE);

    hEventTermRequ = CreateEvent (NULL,                         // LPSECURITY_ATTRIBUTES lpEventAttributes
                                  FALSE,                        // BOOL bManualReset
                                  FALSE,                        // BOOL bInitialState
								  awcObjectName);
    pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = hEventTermRequ;
    ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != NULL);

    pszObjectName = ShbIpcGetUniformObjectName (NAME_EVENT_TERM_RESP, pShbMemHeader->m_szBufferID, FALSE);
	mbstowcs_s(&convertedChars, awcObjectName, strlen(pszObjectName)+1, pszObjectName, _TRUNCATE);
    hEventTermResp = CreateEvent (NULL,                         // LPSECURITY_ATTRIBUTES lpEventAttributes
                                  FALSE,                        // BOOL bManualReset
                                  FALSE,                        // BOOL bInitialState
								  awcObjectName);
    pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = hEventTermResp;
    ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != NULL);

    hThreadNewData = CreateThread (NULL,                        // LPSECURITY_ATTRIBUTES lpThreadAttributes
                                   0,                           // SIZE_T dwStackSize
                                   ShbIpcThreadSignalNewData,   // LPTHREAD_START_ROUTINE lpStartAddress
                                   pShbInstance_p,              // LPVOID lpParameter
                                   0,                           // DWORD dwCreationFlags
                                   &ulThreadIDNewData);         // LPDWORD lpThreadId

    switch (ShbPriority_p)
    {
        case kShbPriorityLow:
            //iPriority = THREAD_PRIORITY_BELOW_NORMAL;
			iPriority = CE_THREAD_PRIO_256_BELOW_NORMAL;
            break;

		default:
        case kShbPriorityNormal:
            //iPriority = THREAD_PRIORITY_NORMAL;
			iPriority = CE_THREAD_PRIO_256_NORMAL;
            break;

        case kShbPriorityHigh:
           // iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
			iPriority = CE_THREAD_PRIO_256_ABOVE_NORMAL;
            break;
    }

    ASSERT(pShbMemInst->m_hThreadNewData != NULL);

	CeSetThreadPriority( hThreadNewData,  iPriority );

  //  SetThreadPriority(hThreadNewData, iPriority);

    pShbMemInst->m_hThreadNewData = hThreadNewData;

    #ifndef NDEBUG
    {
        pShbMemInst->m_ulThreadIDNewData = ulThreadIDNewData;
    }
    #endif


Exit:

    return (ShbError);

}
예제 #17
0
// This routine is called during IOCTL_POWER_CAPABILITIES processing.  It 
// returns TRUE if successful and FALSE if not.  The caller is expected to
// destroy the CDiskPower object if this routine fails.
BOOL CDiskPower::Init(CDisk *pDiskParent)
{
    DWORD dwStatus;
    GUID gPMClass;
    int nPriority = 250;    // THREAD_PRIORITY_ABOVE_NORMAL
    HANDLE hActive = NULL;
    BOOL fOk = TRUE;

    PREFAST_DEBUGCHK(pDiskParent != NULL);
    DEBUGMSG(ZONE_INIT, (_T("+CDiskPower::Init(): parent is 0x%08x\r\n"), pDiskParent));

    // record the parent device
    m_pDisk = pDiskParent;

    // get a pointer to the PM APIs we need
    if(fOk) {
        HMODULE hmCoreDll = LoadLibrary(L"coredll.dll");
        if(hmCoreDll == NULL) {
            DEBUGMSG(ZONE_INIT || ZONE_ERROR, (_T("CDevicePower::Init: LoadLibrary('coredll.dll') failed %d\r\n"), GetLastError()));
            fOk = FALSE;
        } else {
            m_pfnDevicePowerNotify = (DWORD ((*)(PVOID, CEDEVICE_POWER_STATE, DWORD))) GetProcAddress(hmCoreDll, L"DevicePowerNotify");
            if(m_pfnDevicePowerNotify == NULL) {
                DEBUGMSG(ZONE_INIT || ZONE_ERROR, (_T("CDevicePower::Init: GetProcAddress('DevicePowerNotify') failed %d\r\n"), GetLastError()));
                fOk = FALSE;
            }
            // we're explicitly linked with coredll so we don't need the handle
            FreeLibrary(hmCoreDll);
        }
    }

    // read registry configuration
    if(fOk) {
        HKEY hk;
        BOOL fGotClass = FALSE;
        WCHAR szClass[64] = {0}; // big enough for a GUID

        // determine the power class we are advertising
        dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_pDisk->m_szDeviceKey, 0, 0, &hk);
        if(dwStatus == ERROR_SUCCESS) {
            // read the PM class
            DWORD dwSize = sizeof(szClass);
            dwStatus = RegQueryValueEx(hk, L"PowerClass", NULL, NULL, (LPBYTE) szClass, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                fGotClass = TRUE;
            }

            // get the inactivity timeout
            DWORD dwValue;
            dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, L"InactivityTimeout", NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                m_dwPowerTimeout = dwValue;
            }
            DEBUGMSG(ZONE_INIT, (_T("CDiskPower::Init: inactivity timeout is %u ms\r\n"), m_dwPowerTimeout));
            
            // get the inactivity timeout
            dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, L"TimeoutDx", NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                if(VALID_DX((CEDEVICE_POWER_STATE)dwValue) && dwValue != D3) {
                    m_timeoutDx = (CEDEVICE_POWER_STATE) dwValue;
                } else {
                    DEBUGMSG(ZONE_WARNING, (_T("CDiskPower::Init: invalid or unsupported timeout device power state %d (0x%x)\r\n"), dwValue, dwValue));
                }
            }
            DEBUGMSG(ZONE_INIT, (_T("CDiskPower::Init: timeout state is D%d\r\n"), m_timeoutDx));
            
            // get the inactivity timeout
            dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, L"InactivityPriority256", NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                nPriority = (int) dwValue;
            }
            DEBUGMSG(ZONE_INIT, (_T("CDiskPower::Init: inactivity timeout thread priority is %d\r\n"), nPriority));
            
            RegCloseKey(hk);
        }   

        // did we get a class string?
        if(!fGotClass) {
            // no, use the default disk class
            wcsncpy(szClass, PMCLASS_BLOCK_DEVICE, dim(szClass));
            szClass[dim(szClass) - 1] = 0;
        }

        // convert to a GUID
        fOk = GUIDFromString(szClass, &gPMClass);
        if(!fOk) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: invalid power management class '%s'\r\n"),
                szClass));
        }
    }

    // get our active key from the registry
    if(fOk) {
        HKEY hk;
        dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_pDisk->m_szActiveKey, 0, 0, &hk);
        if(dwStatus == ERROR_SUCCESS) {
            DWORD dwValue;
            DWORD dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, DEVLOAD_HANDLE_VALNAME, NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus != ERROR_SUCCESS) {
                DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: can't read '%s' from '%s'\r\n"),
                    DEVLOAD_HANDLE_VALNAME, m_pDisk->m_szActiveKey));
                fOk = FALSE;
            } else {
                DEBUGCHK(dwValue != 0);
                hActive = (HANDLE) dwValue;
            }
        }
    }

    // figure out the name we are using
    if(fOk) {
        WCHAR szName[MAX_PATH];
        DWORD dwIndex = 0;
        do {
            DWORD dwSize = sizeof(szName);
            GUID gClass;
            fOk = EnumDeviceInterfaces(hActive, dwIndex, &gClass, szName, &dwSize);
            if(fOk && gPMClass == gClass) {
                // we found the interface
                break;
            }
            dwIndex++;
        } while(fOk);
        DEBUGMSG(!fOk && (ZONE_WARNING || ZONE_INIT), (_T("CDiskPower::Init: can't find PM interface\r\n")));

        // did we find the name?
        if(fOk) {
            // yes, allocate a name buffer to use to talk to the power manager
            DWORD dwChars = wcslen(PMCLASS_BLOCK_DEVICE) + wcslen(szName) + 2;  // class + separator + name + null
            LPWSTR pszPMName = (LPWSTR) LocalAlloc(LPTR, dwChars * sizeof(WCHAR));
            fOk = FALSE;        // assume failure
            if(pszPMName) {
                HRESULT hr = StringCchPrintfW(pszPMName, dwChars, L"{%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x}\\%s",
                    gPMClass.Data1, gPMClass.Data2, gPMClass.Data3,
                    (gPMClass.Data4[0] << 8) + gPMClass.Data4[1], gPMClass.Data4[2], gPMClass.Data4[3], 
                    gPMClass.Data4[4], gPMClass.Data4[5], gPMClass.Data4[6], gPMClass.Data4[7],
                    szName);
                if(SUCCEEDED(hr)) {
                    m_pszPMName = (LPCWSTR) pszPMName;
                    fOk = TRUE;
                }
            }
            DEBUGMSG(!fOk && (ZONE_WARNING || ZONE_INIT), (_T("CDiskPower::Init: can't find PM interface\r\n")));
        }
    }

    // create an event to tell the timeout thread about activity
    if(fOk) {
        m_hevPowerSignal = CreateEvent(NULL, FALSE, FALSE, NULL);
        m_hevDummy = CreateEvent(NULL, FALSE, FALSE, NULL);
        if(!m_hevPowerSignal || !m_hevDummy) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: couldn't create status events\r\n")));
            fOk = FALSE;
        }
    }

    // create the timeout thread
    if(fOk) {
        m_htPower = CreateThread(NULL, 0, DiskPowerThreadStub, this, 0, NULL);
        if(!m_htPower) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: CreateThread() failed %d\r\n"), GetLastError()));
            fOk = FALSE;
        } else {
            BOOL fSuccess = CeSetThreadPriority(m_htPower, nPriority);
            DEBUGMSG(!fSuccess && (ZONE_WARNING || ZONE_INIT), (_T("CDiskPower::Init: CeSetThreadPriority(%d) failed %d\r\n"), nPriority, GetLastError()));
        }
    }

    // disable the standby timer, since the PM is going to be controlling
    // the disk power state
    if(fOk) {
        if(!m_pDisk->SendDiskPowerCommand(ATA_NEW_CMD_IDLE, 0)) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: disable standby timer failed\r\n")));
        }
    }

    // on error, cleanup will happen in the destructor
    DEBUGMSG(ZONE_INIT, (_T("-CDiskPower::Init(): returning %d\r\n"), fOk));
    return fOk;
}
예제 #18
0
// this thread handles activity timer events
DWORD WINAPI 
ActivityTimersThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus, dwNumEvents, dwWaitInterval;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
    BOOL fDone = FALSE;
    HANDLE hevDummy = NULL;
    INT iPriority;
    const DWORD cdwTimerBaseIndex = 2;

#ifndef SHIP_BUILD
    SETFNAME(_T("ActivityTimersThreadProc"));
#endif

    PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId()));

    // set the thread priority
    if(!GetPMThreadPriority(_T("TimerPriority256"), &iPriority)) {
        iPriority = DEF_ACTIVITY_TIMER_THREAD_PRIORITY;
    }
    CeSetThreadPriority(GetCurrentThread(), iPriority);

    // initialize the list of activity timers
    if(ActivityTimerInitList() != ERROR_SUCCESS) {
        PMLOGMSG(ZONE_WARN, (_T("%s: ActivityTimerInitList() failed\r\n"), pszFname));
        goto done;
    }

    // create a dummy event that's never signaled
    hevDummy = CreateEvent(NULL, FALSE, FALSE, NULL);
    if(hevDummy == NULL) {
        PMLOGMSG(ZONE_WARN, (_T("%s: Couldn't create dummy event\r\n"), pszFname));
        goto done;
    }

    // set up the list of events
    dwNumEvents = 0;
    hEvents[dwNumEvents++] = ghevPmShutdown;
    hEvents[dwNumEvents++] = ghevTimerResume;
    PMLOCK();
    if(gppActivityTimers[0] == NULL) {
        // no activity timers defined
        PmFree(gppActivityTimers);
        gppActivityTimers = NULL;
    } else {
        // copy activity timer events into the event list
        while(dwNumEvents < dim(hEvents) && gppActivityTimers[dwNumEvents - cdwTimerBaseIndex] != NULL) {
            hEvents[dwNumEvents] = gppActivityTimers[dwNumEvents - cdwTimerBaseIndex]->hevReset;
            dwNumEvents++;
        }
    }
    PMUNLOCK();

    // we're up and running
    SetEvent(hevReady);

    // are there actually any timers to wait on?
    if(dwNumEvents <= cdwTimerBaseIndex) {
        // no timers defined, so we don't need this thread to wait on them.
        PMLOGMSG(ZONE_INIT || ZONE_WARN, (_T("%s: no activity timers defined, exiting\r\n"), pszFname));
        Sleep(1000);            // don't want PM initialization to fail when we exit
        goto done;
    }

    // wait for these events to get signaled
    PMLOGMSG(ZONE_TIMERS, (_T("%s: entering wait loop, %d timers total\r\n"),
        pszFname, dwNumEvents - cdwTimerBaseIndex));
    dwWaitInterval = 0;
    while(!fDone) {
        DWORD dwTimeout = GetNextInactivityTimeout(dwWaitInterval);
        DWORD dwWaitStart = GetTickCount();

        PMLOGMSG(ZONE_TIMERS, 
            (_T("%s: waiting %u (0x%08x) ms for next event, wait interval was %d\r\n"), pszFname,
            dwTimeout, dwTimeout, dwWaitInterval));
        dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, dwTimeout);
        dwWaitInterval = GetTickCount() - dwWaitStart;

        // figure out what caused the wakeup
        if(dwStatus == (WAIT_OBJECT_0 + 0)) {
            PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname));
            fDone = TRUE;
        } else if(dwStatus == (WAIT_OBJECT_0 + 1)) {
            DWORD dwIndex;
            PACTIVITY_TIMER pat;

            // we've resumed, so re-enable all activity timers that can be reset
            PMLOGMSG(ZONE_TIMERS, (_T("%s: resume event set\r\n"), pszFname));
            PMLOCK();
            for(dwIndex = 0; (pat = gppActivityTimers[dwIndex]) != NULL; dwIndex++) {
                DWORD dwEventIndex = dwIndex + cdwTimerBaseIndex;
                if(hEvents[dwEventIndex] == hevDummy) {
                    hEvents[dwEventIndex] = pat->hevReset;
                }
                pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
            }
            PMUNLOCK();
        } else if(dwStatus == WAIT_TIMEOUT) {
            DWORD dwIndex;
            PACTIVITY_TIMER pat;

            // figure out which event(s) timed out
            PMLOCK();
            for(dwIndex = 0; (pat = gppActivityTimers[dwIndex]) != NULL; dwIndex++) {
                if(pat->dwTimeLeft <= dwWaitInterval  && pat->dwTimeLeft != INFINITE) {
                    // has the timer really expired?
                    if(WaitForSingleObject(pat->hevReset, 0) == WAIT_OBJECT_0) {
                        // The timer was reset while we weren't looking at it, so we'll look
                        // at it again later.  Calculate the new timeout, compensating for the update
                        // that will occur in GetNextInactivityTimeout().
                        PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' reset after timeout\r\n"), pszFname,
                            pat->pszName));
                        pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
                        pat->dwResetCount++;
                    } else {
                        // the timer has really expired, update events appropriately
                        PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' has expired\r\n"), pszFname,
                            pat->pszName));
                        ResetEvent(pat->hevActive);
                        SetEvent(pat->hevInactive);

                        // start looking at the reset event for this timer again
                        hEvents[dwIndex + cdwTimerBaseIndex] = pat->hevReset;

                        // update counts
                        pat->dwTimeLeft = INFINITE;
                        pat->dwExpiredCount++;
                    }
                }
            }
            PMUNLOCK();
        } else if(dwStatus > (WAIT_OBJECT_0 + 0) && dwStatus < (WAIT_OBJECT_0 + dwNumEvents)) {
            PACTIVITY_TIMER pat;
            DWORD dwEventIndex = dwStatus - WAIT_OBJECT_0;

            PMLOCK();
            
            // get a pointer to the timer
            pat = gppActivityTimers[dwEventIndex - cdwTimerBaseIndex];

            // handle its events
            DEBUGCHK(pat != NULL);
            if(pat->dwTimeout == 0) {
                // we're not using the event, so ignore it
                pat->dwTimeLeft = INFINITE;
            } else {
                PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' reset\r\n"), pszFname, pat->pszName));

                // set events appropriately
                ResetEvent(pat->hevInactive);
                SetEvent(pat->hevActive);

                // don't look at this event again until it's about ready to time out
                hEvents[dwEventIndex] = hevDummy;

                // update time left on the timer, compensating for the update
                // that will occur in GetNextInactivityTimeout().
                pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
            }
            pat->dwResetCount++;
            PMUNLOCK();
        } else {
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                pszFname, dwStatus, GetLastError())); 
            fDone = TRUE;
        }
    }

done:
    // release resources
    if(hevDummy != NULL) CloseHandle(hevDummy);
    PMLOCK();
    if(gppActivityTimers != NULL) {
        DWORD dwIndex = 0;
        while(gppActivityTimers[dwIndex] != NULL) {
            ActivityTimerDestroy(gppActivityTimers[dwIndex]);
            dwIndex++;
        }
        PmFree(gppActivityTimers);
        gppActivityTimers = NULL;
    }
    PMUNLOCK();

    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}
예제 #19
0
DWORD
HW_Init(
    PI2C_CONTEXT pI2C
    )
{
    DWORD dwErr = ERROR_SUCCESS;
	UINT32 Irq;
    
//    RETAILMSG(1,(TEXT("I2C Init\r\n")));
    if ( !pI2C ) {
        return ERROR_INVALID_PARAMETER;
    }
    
    DEBUGMSG(ZONE_TRACE,(TEXT("+I2C_Init: %u, 0x%x, 0x%x \r\n"), 
        pI2C->Mode, pI2C->SlaveAddress));

    InitializeCriticalSection(&pI2C->RegCS);
    
    pI2C->Status    = 0;
    pI2C->Data      = NULL;
    pI2C->DataCount = INVALID_DATA_COUNT;
    pI2C->Flags.DropRxAddr = FALSE;

    pI2C->hProc = (HANDLE)GetCurrentProcessId();

    InitRegs(pI2C);

    // create I/O Done Event
    if ( (pI2C->DoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
    {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERR,(TEXT("I2C_Init ERROR: Unable to create Done event: %u \r\n"), dwErr));
        goto _init_error;
    }

    // setup Operating Mode
    if ( pI2C->Mode == INTERRUPT ) {
        // create IST event
        if ( (pI2C->ISTEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
        {
            dwErr = GetLastError();
            DEBUGMSG(ZONE_ERR,(TEXT("I2C_Init ERROR: Unable to create IST event: %u \r\n"), dwErr));
            goto _init_error;
        }

	// Obtain sysintr values from the OAL for the camera interrupt.
	//
	Irq = IRQ_I2C;
	if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(UINT32), &gIntrIIC, sizeof(UINT32), NULL))
	{
		DEBUGMSG(ZONE_ERR, (TEXT("ERROR: Failed to request the IIC sysintr.\r\n")));
		gIntrIIC = SYSINTR_UNDEFINED;
		return(FALSE);
	}
//	RETAILMSG(1, (TEXT("IIC IRQ mapping: [IRQ:%d->sysIRQ:%d].\r\n"), Irq, gIntrIIC));

        // initialize the interrupt
        if( !InterruptInitialize(gIntrIIC, pI2C->ISTEvent, NULL, 0) ) 
        {
            dwErr = GetLastError();
            DEBUGMSG(ZONE_ERR,(TEXT("I2C_Init ERROR: Unable to initialize interrupt: %u\r\n"), dwErr));
            goto _init_error;
        }

        InterruptDone(gIntrIIC);

        // create the IST
        if ( (pI2C->IST = CreateThread(NULL, 0, I2C_IST, (LPVOID)pI2C, 0, NULL)) == NULL)
        {
            dwErr = GetLastError();
            DEBUGMSG(ZONE_ERR,(TEXT("I2C_Init ERROR: Unable to create IST: %u\r\n"), dwErr));
            goto _init_error;
        }

        // TODO: registry override
        if ( !CeSetThreadPriority(pI2C->IST, I2C_THREAD_PRIORITY)) {
            dwErr = GetLastError();
            DEBUGMSG(ZONE_ERR, (TEXT("I2C_Init ERROR: CeSetThreadPriority ERROR:%d\n"), dwErr));
            goto _init_error;
        }
    }

    DEBUGMSG(ZONE_TRACE,(TEXT("-I2C_Init \r\n")));

    return dwErr;

_init_error:
    HW_Deinit(pI2C);

    return dwErr;
}
예제 #20
0
파일: hif.c 프로젝트: NemProjects/WLAN
BOOL
hifDeviceInserted(SD_DEVICE_HANDLE *handle)
{
    HIF_DEVICE                 *device;
    SD_API_STATUS               sdStatus;
	SDIO_CARD_INFO              sdioInfo;
	SD_HOST_BLOCK_CAPABILITY    blockCap;
	SD_CARD_RCA                 cardRCA;
	A_UCHAR                     rgucTuple[SD_CISTPLE_MAX_BODY_SIZE];
    PSD_CISTPL_FUNCE_FUNCTION   pFunce = (PSD_CISTPL_FUNCE_FUNCTION) rgucTuple;
    A_UINT32                    ulLength = 0;
	A_UCHAR                     ucRegVal;
	A_BOOL                      blockMode;
    SD_CARD_INTERFACE           ci;
    SD_IO_FUNCTION_ENABLE_INFO  fData;
	DWORD                       bData;
    //SDCONFIG_FUNC_SLOT_CURRENT_DATA slotCurrent;
#ifdef CEPC
	HANDLE                      hThread;
#endif //CEPC


    device = addHifDevice(handle);
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceInserted: Enter\n");

	/* Enable SDIO [dragon] function */
    fData.Interval = DEFAULT_SDIO_FUNCTION_RETRY_TIMEOUT;
    fData.ReadyRetryCount = DEFAULT_SDIO_FUNCTION_RETRIES;

    sdStatus = SDSetCardFeature (handle, SD_IO_FUNCTION_ENABLE,
                                  &fData, sizeof(fData));
    if (!SD_API_SUCCESS(sdStatus)) {
        return FALSE;
    }

    /* 
	 * Issue commands to get the manufacturer ID and stuff and compare it 
	 * against the rev Id derived from the ID registered during the 
	 * initialization process. Report the device only in the case there 
	 * is a match.
	 */

	sdStatus = SDCardInfoQuery(handle, SD_INFO_SDIO, 
							&sdioInfo, sizeof(sdioInfo));
    if (!SD_API_SUCCESS(sdStatus)) {
        return FALSE;
    }
    funcNo = sdioInfo.FunctionNumber;

	sdStatus = SDCardInfoQuery(handle, SD_INFO_REGISTER_RCA, 
		                        &cardRCA, sizeof(cardRCA));
    HIF_DEBUG_PRINTF(ATH_LOG_INF, "Card RCA  is 0x%x\n", cardRCA);

    /* Configure the SDIO Bus Width */
	memset(&ci, 0, sizeof(ci));
    if (sdio1bitmode) {
		ci.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT;
	} else {
		ci.InterfaceMode = SD_INTERFACE_SD_4BIT;
	}
	if (sdiobusspeedlow) {
		ci.ClockRate = SDIO_CLOCK_FREQUENCY_REDUCED;
	} else {
		ci.ClockRate = SDIO_CLOCK_FREQUENCY_DEFAULT;
	}
	sdStatus = SDSetCardFeature(handle, SD_SET_CARD_INTERFACE,
		                        &ci, sizeof(ci));

    if (!SD_API_SUCCESS(sdStatus)) {
		return FALSE;
	}
        
	/* Check if the target supports block mode */
	sdStatus = SDReadWriteRegistersDirect(handle, SD_IO_READ, 
					0, 0x08, FALSE, &ucRegVal, 1);
    if (!SD_API_SUCCESS(sdStatus)) {
        return FALSE;
    }
    blockMode = (ucRegVal & 0x2) >> 1; // SMB is bit 1
	if (!blockMode) {
		HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Function does not support block mode\n");
		return FALSE;
	} else {
		HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Function supports block mode\n");

		blockCap.ReadBlocks = blockCap.WriteBlocks = 8;
		blockCap.ReadBlockSize = blockCap.WriteBlockSize = HIF_MBOX_BLOCK_SIZE;

		sdStatus = SDCardInfoQuery(handle, SD_INFO_HOST_BLOCK_CAPABILITY, 
						&blockCap, sizeof(blockCap));

		if (blockCap.ReadBlockSize < blockCap.WriteBlockSize) {
			maxBlockSize = blockCap.ReadBlockSize;
		} else {
			maxBlockSize = blockCap.WriteBlockSize;
		}
		if (blockCap.ReadBlocks < blockCap.WriteBlocks) {
			maxBlocks = blockCap.ReadBlocks;
		} else {
			maxBlocks = blockCap.WriteBlocks;
		}

		sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, NULL, &ulLength, FALSE);
		if ((!SD_API_SUCCESS(sdStatus)) || (ulLength > sizeof(rgucTuple)) ) {
			return FALSE;
		}
		sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, rgucTuple, &ulLength, FALSE);
		if ((!SD_API_SUCCESS(sdStatus)) || 
			(pFunce->bType != SD_CISTPL_FUNCE_FUNCTION_TYPE) ) {
			return FALSE;
		}

		if (maxBlockSize > pFunce->wMaxBlkSize) {
			maxBlockSize = pFunce->wMaxBlkSize;
		}

		bData = (DWORD)maxBlockSize;
		sdStatus = SDSetCardFeature(handle, 
			SD_IO_FUNCTION_SET_BLOCK_SIZE, 
			&bData, sizeof(bData));

	}
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
		           "Bytes Per Block: %d bytes, Block Count:%d \n", 
                   maxBlockSize, maxBlocks);
    /* Allocate the slot current */
	/* Kowsalya : commenting as there is no equivalent for this in WINCE */
	/*
    status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent);
    if (SDIO_SUCCESS(status)) {
        HIF_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n", 
                                slotCurrent.SlotCurrent));         
        status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT,
                                   &slotCurrent, sizeof(slotCurrent));
        if (!SDIO_SUCCESS(status)) {
            HIF_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Failed to allocate slot current %d\n", status));
            return FALSE;
        }
    }
	*/

    /* Inform HTC */
    if ((htcCallbacks.deviceInsertedHandler(device)) != A_OK) {
        HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Device rejected\n");
        return FALSE;
    }

#ifdef CEPC
	NdisInitializeEvent(&hifIRQEvent);
	hThread = CreateThread(NULL, 0, 
		hifIRQThread, (LPVOID)handle, 0, NULL);
	CeSetThreadPriority(hThread, 200);
	CloseHandle(hThread);
#endif //CEPC
	return TRUE;
}
예제 #21
0
파일: platform.cpp 프로젝트: gardhi/PM
EXTERN_C DWORD WINAPI
PlatformSetSystemPowerState (LPCTSTR pszName, BOOL fForce, BOOL fInternal)
{
	DWORD dwStatus = ERROR_SUCCESS;
	PSYSTEM_POWER_STATE pNewSystemPowerState = NULL;
	PDEVICE_POWER_RESTRICTION pNewCeilingDx = NULL;
	BOOL fDoTransition = FALSE;
	INT iPreSuspendPriority = 0;
	static BOOL fFirstCall = TRUE;

	SETFNAME (_T ("PlatformSetSystemPowerState"));

	// Read system power state variables and construct new lists:

	if (gfFileSystemsAvailable)
		PmUpdateSystemPowerStatesIfChanged ();
	dwStatus = RegReadSystemPowerState (pszName, &pNewSystemPowerState, &pNewCeilingDx);

	// Did we get registry information about the new power state?

	if (dwStatus == ERROR_SUCCESS)
	{
		BOOL fSuspendSystem = FALSE;
		static BOOL fWantStartupScreen = FALSE;
		DWORD dwNewStateFlags = pNewSystemPowerState->dwFlags;

		// Assume we will update the system power state:
		fDoTransition = TRUE;

		// Are we going to suspend the system as a whole?
		if ((dwNewStateFlags &
			 (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL | POWER_STATE_RESET)) != 0)
		{
			fSuspendSystem = TRUE;
		}

		// A "critical" suspend might mean we have totally lost battery power and need
		// to suspend really quickly.  Depending on the platform, OEMs may be able
		// to bypass driver notification entirely and rely on xxx_PowerDown() notifications
		// to suspend gracefully.  Or they may be able to implement a critical suspend
		// kernel ioctl.  This sample implementation is very generic and simply sets the
		// POWER_FORCE flag, which is not used.

		if (dwNewStateFlags & (POWER_STATE_CRITICAL | POWER_STATE_OFF | POWER_STATE_RESET))
		{
			fForce = TRUE;
		}

		// If everything seems OK, do the set operation:

		if (fDoTransition)
		{
			POWER_BROADCAST_BUFFER pbb;
			PDEVICE_LIST pdl;
			BOOL fResumeSystem = FALSE;

			// Send out system power state change notifications:
			pbb.Message = PBT_TRANSITION;
			pbb.Flags = pNewSystemPowerState->dwFlags;
			pbb.Length = _tcslen (pNewSystemPowerState->pszName) + 1;	// Char count not byte count for now
			if (pbb.Length > MAX_PATH)
			{
				// Truncate the system power state name -- note, we actually have MAX_PATH + 1
				// characters available.
				pbb.Length = MAX_PATH;
			}
			_tcsncpy_s (pbb.SystemPowerState, _countof (pbb.SystemPowerState),
						pNewSystemPowerState->pszName, pbb.Length);
			pbb.Length *= sizeof (pbb.SystemPowerState[0]);	           // Convert to byte count
			GenerateNotifications ((PPOWER_BROADCAST) & pbb);

			// Is GWES ready?
			if (!gfGwesReady)
			{
				if (WaitForAPIReady (SH_GDI, 0) == WAIT_OBJECT_0)
				{
					gfGwesReady = TRUE;
				}
			}

			// Are we suspending?
			if (fSuspendSystem && gpfnGwesPowerDown != NULL)
			{
				// Start the process of suspending GWES:
				if (gfGwesReady)
				{
					fWantStartupScreen = gpfnGwesPowerDown ();
				}
			}

			// Update global system state variables:
			PMLOCK ();
			PSYSTEM_POWER_STATE pOldSystemPowerState = gpSystemPowerState;
			PDEVICE_POWER_RESTRICTION pOldCeilingDx = gpCeilingDx;

			if (gpSystemPowerState != NULL
				&& (gpSystemPowerState->
					dwFlags & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL)) != 0)
			{
				// We are exiting a suspended state:
				fResumeSystem = TRUE;
			}
			gpSystemPowerState = pNewSystemPowerState;
			gpCeilingDx = pNewCeilingDx;
			PMUNLOCK ();

			// Are we suspending, resuming, or neither?
			if (fSuspendSystem)
			{
				INT iCurrentPriority;

				// We're suspending: update all devices other than block devices,
				// in case any of them need to access the registry or write files.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: suspending - notifying non-block drivers\r\n"), pszFname));
				for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
				{
					if (*pdl->pGuid != idBlockDevices)
					{
						UpdateClassDeviceStates (pdl);
					}
				}

				// Notify the kernel that we are about to suspend.  This gives the
				// kernel an opportunity to clear wake source flags before we initiate
				// the suspend process.  If we don't do this and a wake source interrupt
				// occurs between the time we call PowerOffSystem() and the time
				// OEMPowerOff() is invoked, it is hard for the kernel to know whether or
				// not to suspend.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: calling KernelIoControl(IOCTL_HAL_PRESUSPEND)\r\n"), pszFname));
				KernelIoControl (IOCTL_HAL_PRESUSPEND, NULL, 0, NULL, 0, NULL);
				iCurrentPriority = CeGetThreadPriority (GetCurrentThread ());
				DEBUGCHK (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN);
				if (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN)
				{
					CeSetThreadPriority (GetCurrentThread (), giPreSuspendPriority);
					Sleep (0);
					CeSetThreadPriority (GetCurrentThread (), iCurrentPriority);
				}

				// Notify file systems that their block drivers will soon go away.
				// After making this call, this thread is the only one that can access
				// the file system (including registry and device drivers) without
				// blocking.  Unfortunately, this API takes and holds the file system
				// critical section, so other threads attempting to access the registry
				// or files may cause priority inversions.  To avoid priority problem
				// that may starve the Power Manager, we may raise our own priority to a
				// high level.  Do this if giSuspendPriority is non-zero.

				if (giSuspendPriority != 0)
				{
					iPreSuspendPriority = CeGetThreadPriority (GetCurrentThread ());
					DEBUGCHK (iPreSuspendPriority != THREAD_PRIORITY_ERROR_RETURN);
					PMLOGMSG (ZONE_PLATFORM,
							  (_T
							   ("%s: suspending: raising thread priority for 0x%08x from %d to %d\r\n"),
							   pszFname, GetCurrentThreadId (), iPreSuspendPriority,
							   giSuspendPriority));
					CeSetThreadPriority (GetCurrentThread (), giSuspendPriority);
				}

                // Discard code pages from drivers.  This is a diagnostic tool to
                // forcibly expose paging-related bugs that could cause apparently
                // random system crashes or hangs.  Optionally, OEMs can disable this
                // for production systems to speed up resume times.  We have to call
                // PageOutMode before FileSys Shutdown. Otherwise, it cause dead lock
                // between filesystem and loader.

				if (gfPageOutAllModules)
				{
					ForcePageout ();
				}

				if (g_pSysRegistryAccess)
					g_pSysRegistryAccess->EnterLock ();
				gfFileSystemsAvailable = FALSE;

				if ((dwNewStateFlags & POWER_STATE_RESET) != 0)
				{
					// Is this to be a cold boot?
					if (_tcscmp (pszName, _T ("coldreboot")) == 0)
					{
						SetCleanRebootFlag ();
					}
				}

				FileSystemPowerFunction (FSNOTIFY_POWER_OFF);

				// Update block device power states:
				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: suspending - notifying block drivers\r\n"), pszFname));
				pdl = GetDeviceListFromClass (&idBlockDevices);
				if (pdl != NULL)
				{
					UpdateClassDeviceStates (pdl);
				}

				// Handle resets and shutdowns here, after flushing files.  Since Windows CE does
				// not define a standard mechanism for handling shutdown (via POWER_STATE_OFF),
				// OEMs will need to fill in the appropriate code here.  Similarly, if an OEM does
				// not support IOCTL_HAL_REBOOT, they should not support POWER_STATE_RESET.

				if ((dwNewStateFlags & POWER_STATE_RESET) != 0)
				{
					// Should not return from this call, but if we do just suspend the system:
					KernelLibIoControl ((HANDLE) KMOD_OAL, IOCTL_HAL_REBOOT, NULL, 0, NULL, 0,
										NULL);
					RETAILMSG (TRUE,
							   (_T
								("PM: PlatformSetSystemPowerState: KernelIoControl(IOCTL_HAL_REBOOT) returned!\r\n")));
					DEBUGCHK (FALSE);	// Break into the debugger.
				}
			}
			else if (fResumeSystem)
			{
				// We're waking up from a resume -- update block device power states
				// so we can access the registry and/or files.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: resuming - notifying block drivers\r\n"), pszFname));
				pdl = GetDeviceListFromClass (&idBlockDevices);
				if (pdl != NULL)
				{
					UpdateClassDeviceStates (pdl);
				}

				// Notify file systems that their block drivers are back.

				FileSystemPowerFunction (FSNOTIFY_POWER_ON);
				gfFileSystemsAvailable = TRUE;
				if (g_pSysRegistryAccess)
					g_pSysRegistryAccess->LeaveLock ();

				// Update all devices other than block devices:

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: resuming - notifying block drivers\r\n"), pszFname));
				for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
				{
					if (*pdl->pGuid != idBlockDevices)
					{
						UpdateClassDeviceStates (pdl);
					}
				}

				// Tell GWES to wake up:
				if (gpfnGwesPowerUp != NULL && gfGwesReady)
				{
					gpfnGwesPowerUp (fWantStartupScreen);
					fWantStartupScreen = FALSE;
				}

				// Send out resume notification:
				pbb.Message = PBT_RESUME;
				pbb.Flags = 0;
				pbb.Length = 0;
				pbb.SystemPowerState[0] = 0;
				GenerateNotifications ((PPOWER_BROADCAST) & pbb);
			}
			else
			{
				// Update all devices without any particular ordering:
				UpdateAllDeviceStates ();
			}

			// Release the old state information:
			SystemPowerStateDestroy (pOldSystemPowerState);
			while (pOldCeilingDx != NULL)
			{
				PDEVICE_POWER_RESTRICTION pdpr = pOldCeilingDx->pNext;

				PowerRestrictionDestroy (pOldCeilingDx);
				pOldCeilingDx = pdpr;
			}

			// Are we suspending?
			if (fSuspendSystem)
			{
				// Set a flag to notify the resume thread that this was a controlled suspend.
				gfSystemSuspended = TRUE;

				PMLOGMSG (ZONE_PLATFORM
						  || ZONE_RESUME, (_T ("%s: calling PowerOffSystem()\r\n"), pszFname));
				PowerOffSystem ();	    // Sets a flag in the kernel for the scheduler.
				Sleep (0);	            // Force the scheduler to run.
				PMLOGMSG (ZONE_PLATFORM
						  || ZONE_RESUME, (_T ("%s: back from PowerOffSystem()\r\n"), pszFname));

				// Clear the suspend flag:
				gfSystemSuspended = FALSE;
			}
		}
		else
		{
			// Release the unused new state information:
			SystemPowerStateDestroy (pNewSystemPowerState);
			while (pNewCeilingDx != NULL)
			{
				PDEVICE_POWER_RESTRICTION pdpr = pNewCeilingDx->pNext;

				PowerRestrictionDestroy (pNewCeilingDx);
				pNewCeilingDx = pdpr;
			}
		}
	}

	// Restore our priority if we updated it during a suspend transition:
	if (giSuspendPriority != 0 && iPreSuspendPriority != 0)
	{
		PMLOGMSG (ZONE_PLATFORM, (_T ("%s: restoring thread priority to %d\r\n"),
								  pszFname, iPreSuspendPriority));
		CeSetThreadPriority (GetCurrentThread (), iPreSuspendPriority);
	}

	return dwStatus;
}
예제 #22
0
//------------------------------------------------------------------------------
//
//  Function:  Device_ListenerThread
//
//  Listener thread for devices supporting a particular class interface.
//
DWORD
Device_ListenerThread(
    void *pData
    )
{
    int             idx;
    DWORD           code;
    MSGQUEUEOPTIONS msgOptions;
    int             queueCount = 0;
    HANDLE          rgAdvertiseClass[MAX_NOTIFY_INTERFACES];
    HANDLE          rgMsgQueues[MAX_NOTIFY_INTERFACES + 1];

    UNREFERENCED_PARAMETER(pData);

    // Set thread priority
    //
    CeSetThreadPriority(GetCurrentThread(), s_Device.priority256);

    // loop through and create the msgQueue's and register for 
    // advertised interfaces
    //
    memset(&msgOptions, 0, sizeof(msgOptions));
    msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
    msgOptions.dwFlags = 0;
    msgOptions.cbMaxMessage = PNP_QUEUE_SIZE;
    msgOptions.bReadAccess = TRUE;
    memset(rgMsgQueues, 0, sizeof(HANDLE) * (MAX_NOTIFY_INTERFACES + 1));
    memset(rgAdvertiseClass, 0, sizeof(HANDLE) * (MAX_NOTIFY_INTERFACES));    
    
    for (queueCount = 0; queueCount < MAX_NOTIFY_INTERFACES; ++queueCount)
        {
        if (s_rgAdvertisedInfo[queueCount].iid == -1) break;

        // Get handle to msg queues
        //
        rgMsgQueues[queueCount] = ::CreateMsgQueue(NULL, &msgOptions);
        if (rgMsgQueues[queueCount] == NULL)
            {
            goto cleanUp;
            }

        // Get handle to advertised interfaces
        rgAdvertiseClass[queueCount] = ::RequestDeviceNotifications(
            s_rgAdvertisedInfo[queueCount].pguid, rgMsgQueues[queueCount],
            TRUE
            );

        if (rgAdvertiseClass[queueCount] == NULL)
            {
            goto cleanUp;
            }
        }

    // insert private event at end of array
    //
    rgMsgQueues[queueCount] = s_Device.hMsgSync;

    // done with initialiation
    //
    for(;;)
        {
        code = ::WaitForMultipleObjects(queueCount + 1, rgMsgQueues, FALSE, INFINITE);
        idx = code - WAIT_OBJECT_0;
        if (idx < queueCount)
            {
            ProcessMsgQueueSignal(idx, rgMsgQueues[idx], s_rgAdvertisedInfo[idx].iid);
            continue;
            }
        else if (idx == queueCount)
            {
            break;
            }
        else 
            {
            continue;
            }
        }

cleanUp:

    // free all allocated handles
    //
    for (idx = 0; idx < MAX_NOTIFY_INTERFACES; ++idx)
        {
        if (rgAdvertiseClass[idx] == NULL)   break;
        ::StopDeviceNotifications(rgAdvertiseClass[idx]);
        ::CloseMsgQueue(rgMsgQueues[idx]);
        }  
    return 0;
}
//-----------------------------------------------------------------------------
//
//  Function:  SmartReflexSensingThread
//
//  thread in charge of changing the optimized voltage values
//
DWORD
WINAPI
SmartReflexSensingThread(
    LPVOID pvParam
    )
{
    DWORD code;
    DWORD dwTimeout;

    UNREFERENCED_PARAMETER(pvParam);

    // set thread priority to lowest to prevent possible thread inversion
    CeSetThreadPriority(s_SmartReflexLoadPolicyInfo.hSmartReflexSensingThread, 255);

    // events
    // -----------------
    //
    // abort - when currently not in OPM0 or
    //         a device is active which causes smartreflex to be enabled
    //
    // signal - currently at opm 0 and
    //          no device active to trigger smartreflex
    //
    // timeout - wait time expired
    //

    // states
    //--------
    //
    // Inactive - not waiting to calibrate or
    //            not currently calibrating
    //
    // Waiting  - currently waiting to calibrate
    //
    // Sensing  - currently calibrating
    //

    // current state   |       abort       |       signal       |       timeout     |
    //--------------------------------------------------------------------------------
    //
    // Inactive               Inactive             Waiting              Inactive
    //
    // Waiting                Inactive             Waiting              Sensing
    //
    // Sensing                Inactive             Waiting              Inactive
    //

    dwTimeout = INFINITE;
    for(;;)
        {
        code = WaitForSingleObject(s_SmartReflexLoadPolicyInfo.hSmartReflexSensingEvent, dwTimeout);

        // check for exit thread
        if (s_SmartReflexLoadPolicyInfo.bExitThread == TRUE) goto cleanUp;

        // identify event
        if (s_currentOpm != kOpm0 || s_SmartReflexLoadPolicyInfo.dwActiveDevices != 0)
            {
            // Event: abort
            dwTimeout = INFINITE;
            switch (s_SmartReflexLoadPolicyInfo.nSensingState)
                {
                case STATE_INACTIVE:
                    break;

                case STATE_WAITING:
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_INACTIVE;
                    break;

                case STATE_SENSING:
                    // check if smartreflex should be disabled
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_INACTIVE;
                    UpdateSmartReflex();
                    break;
                }
            }
        else if (code == WAIT_OBJECT_0)
            {
            // Event: signal
            switch (s_SmartReflexLoadPolicyInfo.nSensingState)
                {
                case STATE_INACTIVE:
                    dwTimeout = s_SmartReflexLoadPolicyInfo.dwSensingDelay;
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_WAITING;
                    break;

                case STATE_WAITING:
                    dwTimeout = s_SmartReflexLoadPolicyInfo.dwSensingDelay;
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_WAITING;
                    break;

                case STATE_SENSING:
                    dwTimeout = s_SmartReflexLoadPolicyInfo.dwSensingDelay;
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_WAITING;
                    UpdateSmartReflex();
                    break;
                }
            }
        else
            {
            // Event: timeout
            switch (s_SmartReflexLoadPolicyInfo.nSensingState)
                {
                case STATE_INACTIVE:
                    dwTimeout = INFINITE;
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_INACTIVE;
                    break;

                case STATE_WAITING:
                    dwTimeout = s_SmartReflexLoadPolicyInfo.dwSensingPeriod;
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_SENSING;
                    UpdateSmartReflex();
                    break;

                case STATE_SENSING:
                    dwTimeout = INFINITE;
                    s_SmartReflexLoadPolicyInfo.nSensingState = STATE_INACTIVE;
                    SaveCalibratedVoltages();
                    UpdateSmartReflex();
                    FlushCalibratedVoltages();
                    break;
                }
            }
        }

cleanUp:
    return 0;
}
예제 #24
0
DWORD WINAPI 
PnpThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus;
    HANDLE hnGeneric = NULL;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
    DWORD dwNumEvents = 0;
    BOOL fDone = FALSE;
    BOOL fOk;
    INT iPriority;
    PDEVICE_LIST pdl;
    SETFNAME(_T("PnpThreadProc"));

    PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId()));

    // set the thread priority
    if(!GetPMThreadPriority(_T("PnPPriority256"), &iPriority)) {
        iPriority = DEF_PNP_THREAD_PRIORITY;
    }
    CeSetThreadPriority(GetCurrentThread(), iPriority);

    // first list entry is the exit event
    hEvents[dwNumEvents++] = ghevPmShutdown;

    // set up device notifications
    for(pdl = gpDeviceLists; pdl != NULL && dwNumEvents < dim(hEvents); pdl = pdl->pNext) {
        hEvents[dwNumEvents++] = pdl->hMsgQ;
        pdl->hnClass = RequestDeviceNotifications(pdl->pGuid, pdl->hMsgQ, TRUE);
        if(pdl->hnClass == NULL) {
            PMLOGMSG(ZONE_WARN, (_T("%s: RequestDeviceNotifications() failed %d\r\n"),
                pszFname, GetLastError()));
        }
    }
    DEBUGCHK(dwNumEvents > 1);
    // we're up and running
    SetEvent(hevReady);
    
    // Wait for Initalization complete.
    HANDLE hInit[2] = {ghevPowerManagerReady, ghevPmShutdown};
    fDone = (WaitForMultipleObjects(_countof(hInit), hInit, FALSE, INFINITE)!= WAIT_OBJECT_0);

    // wait for new devices to arrive
    while(!fDone) {
        dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, INFINITE);
        if(dwStatus == (WAIT_OBJECT_0 + 0)) {
            PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname));
            fDone = TRUE;
        } else if(dwStatus > WAIT_OBJECT_0 && dwStatus <= (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { 
            dwStatus -= WAIT_OBJECT_0;
            fOk = ProcessPnPMsgQueue(hEvents[dwStatus]);
            if(!fOk) {
                PMLOGMSG(ZONE_WARN, (_T("%s: ProcessPnPMsgQueue(0x%08x) failed\r\n"), pszFname,
                    hEvents[dwStatus]));
            }
        } else {
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                pszFname, dwStatus, GetLastError())); 
            fDone = TRUE;
            break;
        }
    }

    // release resources
    for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) {
        if(pdl->hnClass != NULL) StopDeviceNotifications(pdl->hnClass);
    }

    // all done
    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}
예제 #25
0
파일: platform.cpp 프로젝트: gardhi/PM
EXTERN_C VOID WINAPI
PlatformResumeSystem (void)
{
	SETFNAME (_T ("PlatformResumeSystem"));

	PMLOGMSG (ZONE_RESUME, (_T ("+%s: suspend flag is %d\r\n"), pszFname, gfSystemSuspended));

	// Was this an unexpected resume event?  If so, there may be a thread priority problem
	// or some piece of software suspended the system without calling SetSystemPowerState().

	DEBUGCHK (gfSystemSuspended);
	if (!gfSystemSuspended)
	{
		// Unexpected resume -- go to the resuming state.  This should not happen unless
		// somebody is illegally calling PowerOffSystem() directly.

		PMLOGMSG (ZONE_WARN || ZONE_RESUME, (_T ("%s: WARNING: unexpected resume!\r\n"), pszFname));

		// Go into the new state.  OEMs that choose to support unexpected resumes may want to
		// lock PM variables with PMLOCK(), then set the curDx and actualDx values for all
		// devices to PwrDeviceUnspecified before calling PmSetSystemPowerState_I().  This will
		// force an update IOCTL to all devices.

		DEBUGCHK (ghevRestartTimers != NULL);
		SetEvent (ghevRestartTimers);
	}
	else
	{
		DWORD dwWakeSource, dwBytesReturned;
		BOOL fOk;

		// Get the system wake source to help determine which power state we resume into:
		fOk = KernelIoControl (IOCTL_HAL_GET_WAKE_SOURCE, NULL, 0, &dwWakeSource,
							   sizeof (dwWakeSource), &dwBytesReturned);
		if (fOk)
		{
			// IOCTL succeeded (not all platforms necessarily support it), but sanity check
			// the return value, just in case.

			if (dwBytesReturned != sizeof (dwWakeSource))
			{
				PMLOGMSG (ZONE_WARN, (_T ("%s: KernelIoControl() returned an invalid size %d\r\n"),
									  pszFname, dwBytesReturned));
			}
			else
			{
				// Look for an activity timer corresponding to this wake source.
				PACTIVITY_TIMER pat = ActivityTimerFindByWakeSource (dwWakeSource);

				if (pat != NULL)
				{
					PMLOGMSG (ZONE_RESUME, (_T ("%s: signaling '%s' activity at resume\r\n"),
											pszFname, pat->pszName));

					// Is there an activity timer we need to reset?
					if (pat->hevReset != NULL)
					{
						// Found a timer, elevate the timer management priority thread so that it
						// executes before the suspending thread.

						DWORD dwOldPriority = CeGetThreadPriority (ghtActivityTimers);
						DWORD dwNewPriority = (CeGetThreadPriority (GetCurrentThread ()) - 1);

						DEBUGCHK (dwNewPriority >= 0);
						SetEvent (pat->hevReset);
						CeSetThreadPriority (ghtActivityTimers, dwNewPriority);
						CeSetThreadPriority (ghtActivityTimers, dwOldPriority);
					}
				}
			}
		}
	}
	PMLOGMSG (ZONE_RESUME, (_T ("-%s\r\n"), pszFname));
}
예제 #26
0
파일: hif.c 프로젝트: NemProjects/WLAN
BOOL
hifDeviceInserted(SD_DEVICE_HANDLE *handle)
{
	HIF_DEVICE                 *device;
#if 0
	SD_API_STATUS               sdStatus;
	SDIO_CARD_INFO              sdioInfo;
	SD_HOST_BLOCK_CAPABILITY    blockCap;
	SD_CARD_RCA                 cardRCA;
	A_UCHAR                     rgucTuple[SD_CISTPLE_MAX_BODY_SIZE];
	PSD_CISTPL_FUNCE_FUNCTION   pFunce = (PSD_CISTPL_FUNCE_FUNCTION) rgucTuple;
	A_UINT32                    ulLength = 0;
	A_UCHAR                     ucRegVal;
	A_BOOL                      blockMode;
	SD_CARD_INTERFACE           ci;
	SD_IO_FUNCTION_ENABLE_INFO  fData;
	DWORD                       bData;
	//SDCONFIG_FUNC_SLOT_CURRENT_DATA slotCurrent;
	//HANDLE                      hIrqThread;


#endif

	HANDLE                      hThread;

	device = addHifDevice(handle);
	NDIS_DEBUG_PRINTF(1, "hifDeviceInserted: Enter\r\n");

#if 0

	/* Enable SDIO [dragon] function */
	fData.Interval = DEFAULT_SDIO_FUNCTION_RETRY_TIMEOUT;
	fData.ReadyRetryCount = DEFAULT_SDIO_FUNCTION_RETRIES;

	sdStatus = SDSetCardFeature (handle, SD_IO_FUNCTION_ENABLE, &fData, sizeof(fData));
	if (!SD_API_SUCCESS(sdStatus)) 
	{
		return FALSE;
	}


	/* 
	* Issue commands to get the manufacturer ID and stuff and compare it 
	* against the rev Id derived from the ID registered during the 
	* initialization process. Report the device only in the case there 
	* is a match.
	*/

	sdStatus = SDCardInfoQuery(handle, SD_INFO_SDIO, &sdioInfo, sizeof(sdioInfo));
	if (!SD_API_SUCCESS(sdStatus)) 
	{
		return FALSE;
	}
	
	funcNo = sdioInfo.FunctionNumber;

	sdStatus = SDCardInfoQuery(handle, SD_INFO_REGISTER_RCA, &cardRCA, sizeof(cardRCA));
	NDIS_DEBUG_PRINTF(1, " Card RCA  is 0x%x \r\n", cardRCA);

	/* Configure the SDIO Bus Width */
	memset(&ci, 0, sizeof(ci));
	if (sdio1bitmode) {
		ci.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT;
	} else {
		ci.InterfaceMode = SD_INTERFACE_SD_4BIT;
	}
	
	if (sdiobusspeedlow) {
		ci.ClockRate = SDIO_CLOCK_FREQUENCY_REDUCED;
	} else {
		ci.ClockRate = SDIO_CLOCK_FREQUENCY_DEFAULT;
	}
	
	sdStatus = SDSetCardFeature(handle, SD_SET_CARD_INTERFACE, &ci, sizeof(ci));

	if (!SD_API_SUCCESS(sdStatus)) {
		return FALSE;
	}
        
	/* Check if the target supports block mode */
	sdStatus = SDReadWriteRegistersDirect(handle, SD_IO_READ, 0, 0x08, FALSE, &ucRegVal, 1);
    if (!SD_API_SUCCESS(sdStatus)) {
        return FALSE;
    }
	
    blockMode = (ucRegVal & 0x2) >> 1; // SMB is bit 1
    
	if (!blockMode) 
	{
		NDIS_DEBUG_PRINTF(DBG_ERR, "[HIF] Function does not support block mode \r\n");
		return FALSE;
	} 
	else 
	{
		NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, "[HIF] Function supports block mode \r\n");

		blockCap.ReadBlocks = blockCap.WriteBlocks = 8;
		blockCap.ReadBlockSize = blockCap.WriteBlockSize = HIF_MBOX_BLOCK_SIZE;

		sdStatus = SDCardInfoQuery(handle, SD_INFO_HOST_BLOCK_CAPABILITY, 
						&blockCap, sizeof(blockCap));

		if (blockCap.ReadBlockSize < blockCap.WriteBlockSize) {
			maxBlockSize = blockCap.ReadBlockSize;
		} else {
			maxBlockSize = blockCap.WriteBlockSize;
		}
		
		if (blockCap.ReadBlocks < blockCap.WriteBlocks) {
			maxBlocks = blockCap.ReadBlocks;
		} else {
			maxBlocks = blockCap.WriteBlocks;
		}

		sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, NULL, &ulLength, FALSE);
		
		if ((!SD_API_SUCCESS(sdStatus)) || (ulLength > sizeof(rgucTuple)) ) {
			return FALSE;
		}
		
		sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, rgucTuple, &ulLength, FALSE);
		if ((!SD_API_SUCCESS(sdStatus)) || (pFunce->bType != SD_CISTPL_FUNCE_FUNCTION_TYPE) ) {
			return FALSE;
		}

		if (maxBlockSize > pFunce->wMaxBlkSize) {
			maxBlockSize = pFunce->wMaxBlkSize;
		}

		bData = (DWORD)maxBlockSize;
		sdStatus = SDSetCardFeature(handle,	SD_IO_FUNCTION_SET_BLOCK_SIZE, &bData, sizeof(bData));

	}
	
    NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF,
						"Bytes Per Block: %d bytes, Block Count:%d \r\n", 
                   		maxBlockSize, maxBlocks);
	/* Allocate the slot current */
	/* Kowsalya : commenting as there is no equivalent for this in WINCE */
	/*
    status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent);
    if (SDIO_SUCCESS(status)) {
        HIF_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n", 
                                slotCurrent.SlotCurrent));         
        status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT,
                                   &slotCurrent, sizeof(slotCurrent));
        if (!SDIO_SUCCESS(status)) {
            HIF_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Failed to allocate slot current %d\n", status));
            return FALSE;
        }
    }
	*/

    /* Initialize the bus requests to be used later */
    A_MEMZERO(device->busRequest, sizeof(device->busRequest));
    for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
		NdisInitializeEvent(&device->busRequest[count].sem_req);
		hifFreeBusRequest(device, &device->busRequest[count]);
    }	

#else

	SetupSlotPowerControl(device);

	if (!SetupSDIOInterface(device)) {
		return FALSE;
	}

#endif


		
	InitializeCriticalSection(&gCriticalSection); //ÃʱâÈ­
	
	device->async_shutdown	= 0;
		
	hThread = CreateThread(NULL, 0, async_task, (void *)device, 0, NULL);
	CeSetThreadPriority(hThread, 200);
	CloseHandle(hThread);
		
	NdisInitializeEvent(&device->sem_async);
	
#if USE_IRQ_THREAD
	hThread = CreateThread(NULL, 0, hifIRQThread, (void *)device, 0, NULL);
	CeSetThreadPriority(hThread, 200);
	CloseHandle(hThread);	
	
	NdisInitializeEvent(&hifIRQEvent);
#endif



	/* start  up inform DRV layer */
	if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK) 	{
		NDIS_DEBUG_PRINTF(DBG_ERR, "[HIF] AR6000: Device rejected \r\n");
	}
	
	NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, " %s() -Exit \r\n",__FUNCTION__);
	return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance,      // handle to current instance
                   HINSTANCE hPrevInstance,  // handle to previous instance
                   LPWSTR lpCmdLine,          // pointer to command line
                   int nCmdShow)             // show state of window
{

    HANDLE tRx, tTx;
    BOOL dma_enable = FALSE;

    NKDbgPrintfW(L"******************************************\n\r");
    NKDbgPrintfW(L"*********    Program Start  **************\n\r");
    NKDbgPrintfW(L"******************************************\n\r");

    dma_enable = FALSE;

    bufferTx = sbufferTx;
    bufferRx = sbufferRx;

    if ((bufferRx == NULL) || (bufferTx == NULL))
    {
        printf("Could not alloc buffers");
        return FALSE;
    }

    //Initialize SSP1 (Master)
    //-----------------------------
    if (!SPIInit(txSSPport, DATABITS, SPI_CLOCK_812_KHZ, SPI_MASTER, SPI_MODE_3, NULL))
    {
        printf("Error in InitSPI");
        return FALSE;
    }

    //Initialize SSP2 (Slave)
    //-----------------------------
    if (!SPIInit(rxSSPport, DATABITS, SPI_CLOCK_812_KHZ, SPI_SLAVE, SPI_MODE_3, NULL))
    {
        printf("Error in InitSPI");
        return FALSE;
    }

    //Create and start transmit/receive threads
    //-----------------------------
    tRx = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) RXThread, 0, 0, NULL);
    CeSetThreadPriority(tRx,10);  //Set receive thread to a high priority to avoid buffer overflows

    //Sleep(100);
    tTx = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TXThread, 0, 0, NULL);

    printf("\r\nPress ENTER to leave the application.\r\n");
    getchar();

    TerminateThread(tRx, 0);
    TerminateThread(tTx, 0);
    Sleep(20);

    CloseHandle(tRx);
    CloseHandle(tTx);

    //Deinit
    //Very Important
    //if you forget to Deinit a SPI and Init the SPI new the spi interrupts will not work.
    //In this case you have to reset the System
    DeinitSPI(txSSPport);
    DeinitSPI(rxSSPport);

    return TRUE;

}