Ejemplo n.º 1
0
// === CODE ===
void Timer_CallbackThread(void *Unused)
{
	Threads_SetName("Timer Callback Thread");
	Workqueue_Init(&gTimers_CallbackQueue, "Timer Callbacks", offsetof(tTimer, Next));

	for(;;)
	{
		tTimer *timer = Workqueue_GetWork(&gTimers_CallbackQueue);
	
		if( !timer->Callback ) {
			LOG("Timer %p doesn't have a callback", timer);
			ASSERT( timer->Callback );
		}

		// Save callback and argument (because once the mutex is released
		// the timer may no longer be valid)
		tTimerCallback	*cb = timer->Callback;
		void	*arg = timer->Argument;
		
		LOG("Callback fire %p", timer);
	
		// Allow Time_RemoveTimer to be called safely
		timer->bActive = 0;
		
		// Fire callback
		cb(arg);

		// Mark timer as no longer needed
	}
}
Ejemplo n.º 2
0
void USB_PortCtl_Worker(void *Unused)
{
	Threads_SetName("USB PortCtl Worker");
	for(;;)
	{
		tUSBHubPort *port;
		tUSBHub	*hub;
	       
		port = Workqueue_GetWork(&gUSB_PortCtl_WorkQueue);
		if( !port ) {
			Log_Warning("USB", "PortCtl Workqueue returned NULL");
			break;
		}
	       	hub = (tUSBHub*)(port - port->PortNum) - 1;

		LOG("port = %p, hub = %p", port, hub);

		switch(port->Status)
		{
		case 1:
			// Assert reset
			USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_RESET);
			LOG("Port reset starting");
			// Wait 50 ms
			Time_Delay(50);
			USB_PortCtl_ClearPortFeature(hub, port->PortNum, PORT_RESET);
			Time_Delay(10);	// May take up to 2ms for reset to clear
			// Enable port
			LOG("Port enabling");
			USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_ENABLE);
			// Begin connect processing
			port->Status = 2;
			USB_DeviceConnected(hub, port->PortNum);
			break;
		}
	}
}