Beispiel #1
0
static int usb_hub_thread(void *__hub)
{
    DBG_HOST_HUB("### >>> Enter hub.c file --> usb_hub_thread function \n");
	lock_kernel();

	/*
	 * This thread doesn't need any user-level access,
	 * so get rid of all our resources
	 */

	daemonize();
	reparent_to_init();

	/* Setup a nice name */
	strcpy(current->comm, "khubd");

	/* Send me a signal to get me die (for debugging) */
	do {
		usb_hub_events();
		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
	} while (!signal_pending(current));

	dbg("usb_hub_thread exiting");

	unlock_kernel();
	complete_and_exit(&khubd_exited, 0);
}
Beispiel #2
0
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
{

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
    daemonize(pThreadName /*"%s",pAd->net_dev->name*/);

    allow_signal(SIGTERM);
    allow_signal(SIGKILL);
    current->flags |= PF_NOFREEZE;
#else
    unsigned long flags;

    daemonize();
    reparent_to_init();
    strcpy(current->comm, pThreadName);

    siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));

    /* Allow interception of SIGKILL only
     * Don't allow other signals to interrupt the transmission */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
    spin_lock_irqsave(&current->sigmask_lock, flags);
    flush_signals(current);
    recalc_sigpending(current);
    spin_unlock_irqrestore(&current->sigmask_lock, flags);
#endif
#endif

    /* signal that we've started the thread */
    complete(pNotify);

}
Beispiel #3
0
static int usb_hub_thread(void *startup)
{
    lock_kernel();

    /*
     * This thread doesn't need any user-level access,
     * so get rid of all our resources
     */

    daemonize();
    reparent_to_init();

    /* Block all signals */
    spin_lock_irq(&current->sigmask_lock);
    sigfillset(&current->blocked);
    recalc_sigpending(current);
    spin_unlock_irq(&current->sigmask_lock);

    /* Setup a nice name */
    strcpy(current->comm, "khubd");

    khubd_terminated = 0;
    complete((struct completion *)startup);

    /* Set khubd_terminated=1 to get me die */
    do {
        usb_hub_events();
        wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list) || khubd_terminated);
    } while (!khubd_terminated || !list_empty(&hub_event_list));

    dbg("usb_hub_thread exiting");

    unlock_kernel();
    complete_and_exit(&khubd_exited, 0);
}
Beispiel #4
0
/*
 * Thread execution entry point function
 */
DT_Mdep_Thread_Start_Routine_Return_Type
DT_Mdep_Thread_Start_Routine(void *thread_handle)
{
	Thread *thread_ptr;
	thread_ptr = (Thread *) thread_handle;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
	reparent_to_init();
#else
	daemonize(__func__);
#endif
	thread_ptr->function(thread_ptr->param);
	return 0;
}
int khvcd(void *unused)
{
	int i;

	daemonize();
	reparent_to_init();
	strcpy(current->comm, "khvcd");
	sigfillset(&current->blocked);

	for (;;) {
		for (i = 0; i < MAX_NR_HVC_CONSOLES; ++i)
			hvc_poll(i);
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(TIMEOUT);
	}
}
Beispiel #6
0
static int test_thread(void *x)
{
    reparent_to_init();

        /* Setup a nice name */
        strcpy(current->comm, "testd_usb");

    usbprintk("Thread started\n");

    test_usb_init();

    do {        
        test_usb_events();
        my_wait_ms(50);
    } while (!signal_pending(current));

    usbprintk("hub_thread exiting\n");
    complete_and_exit(&testd_exited, 0);    
}
Beispiel #7
0
void parse_cmd_line (int* argc_ptr, char*** argv_ptr)
{
    char*** subargv_ptr = argv_ptr;
    int     subargc     = (*argc_ptr);

    gboolean should_reparent = TRUE;
    gboolean enable_debug = FALSE;
    int i=0;
    for (;i<(*argc_ptr);i++)
    {
	if(!g_strcmp0 ((*argv_ptr)[i], "-f"))
	{
	    should_reparent=FALSE;
            //(*argv_ptr)[i]=NULL;
	    //(*argc_ptr)--;
            continue;
	}
	if(!g_strcmp0 ((*argv_ptr)[i], "-d"))
	{
            enable_debug = TRUE;
	    should_reparent=FALSE;
            //(*argv_ptr)[i]=NULL;
	    //(*argc_ptr)--;
            continue;
	}
    }
    //uncomment previous comments
    //consolidate *argv, remove NULL slots.
    _consolidate_cmd_line(subargc, subargv_ptr);

    if (should_reparent)
    {
        //FIXME: shall we exit?
        if (close_std_stream())
            return;
	reparent_to_init();
    }
    if (enable_debug)
    {
	g_setenv("G_MESSAGES_DEBUG", "all", FALSE);
    }
}
Beispiel #8
0
 static int usb_led_probe_task(void *x)
{
 	unsigned long flags;
 	
 	daemonize();
 	reparent_to_init();
 
 	strcpy(current->comm, "USBLEDprobe");
 
 	do {
 		usb_led_flag = 1;
 		interruptible_sleep_on(&usb_led_queue);
 		usb_led_flag = 0;
 		USB_SET_LED(USB_DISCONNECT);
 		interruptible_sleep_on_timeout(&usb_led_blink_queue, 50);
 		USB_SET_LED(USB_CONNECT);
 		interruptible_sleep_on_timeout(&usb_led_blink_queue, 50);
 	} while (!signal_pending(current));
 
 	return 0;
 }
Beispiel #9
0
void ral_task_customize(
	IN KTHREAD *pTask)
{
	RTBT_OS_TASK *pOSTask = (RTBT_OS_TASK *)pTask->pOSThread;

	
#ifndef KTHREAD_SUPPORT
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
	daemonize((PSTRING)&pOSTask->taskName[0]);

	allow_signal(SIGTERM);
	allow_signal(SIGKILL);
	current->flags |= PF_NOFREEZE;
#else
	unsigned long flags;

	daemonize();
	reparent_to_init();
	strcpy(current->comm, &pOSTask->taskName[0]);

	siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));	
	
	/* Allow interception of SIGKILL only
	 * Don't allow other signals to interrupt the transmission */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
	spin_lock_irqsave(&current->sigmask_lock, flags);
	flush_signals(current);
	recalc_sigpending(current);
	spin_unlock_irqrestore(&current->sigmask_lock, flags);
#endif
#endif
	
	RTMP_GET_OS_PID(pOSTask->taskPID, current->pid);

    /* signal that we've started the thread */
	complete(&pOSTask->taskComplete);
#endif
}
static int
kthread(void *_create)
{
    struct kthread_create_info *create = _create;
    int (*threadfn)(void *data);
    void *data;

//    printk("kthread: create %p\n", create);

    threadfn = create->threadfn;
    data = create->data;
//    printk("kthread: threadfn %p data %p\n", threadfn, data);

    lock_kernel();
    daemonize();
    reparent_to_init();
    spin_lock_irq(&current->sigmask_lock);
    sigfillset(&current->blocked);
    recalc_sigpending(current);
    spin_unlock_irq(&current->sigmask_lock);
    unlock_kernel();

    set_current_state(TASK_INTERRUPTIBLE);
    complete(&create->started);

//    printk("kthread: about to call thread function\n");

    if (!kthread_should_stop())
	threadfn(data);

//    printk("kthread: thread function done\n");

    if (kthread_should_stop())
	complete(&kthread_stop_complete);

    return 0;
}
Beispiel #11
0
/*!
 * @brief Implements the kernel thread for KeyV "bottom half" interrupt handling.
 *
 * The function that implements the kernel thread for interrupt handling.  This
 * is used to "simulate" a bottom half because the I2C driver only works in task
 * context, not in interrupt or bottom half context.  The function simply executes
 * the same bottom half function that would normally run in the bottom half tasklet.
 *
 * @param unused An unused parameter
 *
 * @return 0, but the function will only return upon receiving an abort signal.
 */
static int interrupt_thread_loop (void *unused)
{
    struct sched_param thread_sched_params = {.sched_priority = (MAX_RT_PRIO - 1)};
    unsigned int value;
    int i;
    static unsigned int init_start = 0;
        
    /* Usual thread setup. */
    lock_kernel();
    daemonize("kkeyvd");
    strcpy(current->comm, "kkeyvd");

    reparent_to_init();
    /* Ignore all signals, but those which terminate the thread. */
    siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
    unlock_kernel();
    /* Sets a realtime thread's priority */
    sched_setscheduler(current, SCHED_FIFO, &thread_sched_params);
         
    /*
     * Loop unless an abort signal is received.  All signals, but the abort signals are
     * masked off in the common setup.  As a result only abort signals can be pending.
     */
    while(!signal_pending(current))
    {
        value = 0;

        /* Sleep if an interrupt isn't pending again */
        if (wait_event_interruptible (interrupt_thread_wait, interrupt_flag) < 0)
        {
            break;
        }
                
        /* Reset the interrupt flag */
        interrupt_flag = 0;
        
        /* Handle the interrupt */
        if(keyv_reg_read(&value) != 0)
        {
            interrupt_fail = true;
                
            /* If a key is previously pressed, and enabled, then report a key release */
            for(i = 0; i < KEYV_KEY_MAX; i++)
            {
                if((KEYV_BITMASK_ISSET(previous_key, i)) && (KEYV_BITMASK_ISSET(key_value, i)))
                {
                     generate_key_event(key_states[i].keycode, KEYUP);
                }
            }
            
            previous_key = KEYV_KEY_NONE;

            continue;                
        }
            
        /* If the interrupt is for an initialization start of the KeyV part, then set
         * the variable to monitor */
        if((value & KEYV_MODE0) == KEYV_MODE0)
        {
            init_start = 1;
                
            /* If a key is previously pressed, and enabled, then report a key release */
            for(i = 0; i < KEYV_KEY_MAX; i++)
            {
                if((KEYV_BITMASK_ISSET(previous_key, i)) && (KEYV_BITMASK_ISSET(key_value, i)))
                {
                     generate_key_event(key_states[i].keycode, KEYUP);
                }
            }
            
            previous_key = KEYV_KEY_NONE;
        }
        else
        {
            /* If the KeyV part was previously initializing, see if it is done */
            if(init_start)
            {
                /* If initialization is complete, clear variable and be done */
                if((value >> 4) == KEYV_DONE)
                {
                    init_start = 0;
                        
                    /* Wait at least 100ms for reset and calibration to really finish */
                    msleep(100);
                        
                    keyv_reg_write(key_value);
                    keyv_mode_set(); 
                }
         
                /* If initialization was previously happening but the upper 4 bits do not match
                 * 0x4, then the 4 KeyV keys are not ready to be used.  At this point
                 * there would be a mechanical issue so the keys should be disabled and the part
                 * should be placed in the appropriate mode. */
                else
                {
                    /* Wait at least 100ms for reset and calibration to really finish */
                    msleep(100);
                    key_value = KEYV_KEY_NONE;
                    keyv_mode_set();  
                }
            }
            /* If KeyV part was not previously initializing, start to check key presses */
            else
            {
                
                /* If a key is currently released, previously pressed, 
                 * and enabled, then report a key release */
                for(i = 0; i < KEYV_KEY_MAX; i++)
                {
                    if(!(KEYV_BITMASK_ISSET(value, i)) && (KEYV_BITMASK_ISSET(previous_key, i)) &&
                        (KEYV_BITMASK_ISSET(key_value, i)))
                    {
                        generate_key_event(key_states[i].keycode, KEYUP);
                    }
                }
                
                    /* If a key is currently pressed, previously not pressed,
                     * and enabled, then report keypress */
                for(i = 0; i < KEYV_KEY_MAX; i++)
                {
                    if((KEYV_BITMASK_ISSET(value, i)) && !(KEYV_BITMASK_ISSET(previous_key, i)) &&
                       (KEYV_BITMASK_ISSET(key_value, i)))
                    {
                        generate_key_event(key_states[i].keycode, KEYDOWN);
                    }
                }
                                
                previous_key = value;
            }
        }
    }
Beispiel #12
0
/*
 * This is the lockd kernel thread
 */
static void
lockd(struct svc_rqst *rqstp)
{
	struct svc_serv	*serv = rqstp->rq_server;
	int		err = 0;
	unsigned long grace_period_expire;

	/* Lock module and set up kernel thread */
	MOD_INC_USE_COUNT;
	lock_kernel();

	/*
	 * Let our maker know we're running.
	 */
	nlmsvc_pid = current->pid;
	up(&lockd_start);

	daemonize();
	reparent_to_init();
	sprintf(current->comm, "lockd");

	/* Process request with signals blocked.  */
	spin_lock_irq(&current->sighand->siglock);
	siginitsetinv(&current->blocked, sigmask(SIGKILL));
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	/* kick rpciod */
	rpciod_up();

	dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");

	if (!nlm_timeout)
		nlm_timeout = LOCKD_DFLT_TIMEO;
	nlmsvc_timeout = nlm_timeout * HZ;

	grace_period_expire = set_grace_period();

	/*
	 * The main request loop. We don't terminate until the last
	 * NFS mount or NFS daemon has gone away, and we've been sent a
	 * signal, or else another process has taken over our job.
	 */
	while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid)
	{
		long timeout = MAX_SCHEDULE_TIMEOUT;
		if (signalled()) {
			spin_lock_irq(&current->sighand->siglock);
			flush_signals(current);
			spin_unlock_irq(&current->sighand->siglock);
			if (nlmsvc_ops) {
				nlmsvc_ops->detach();
				grace_period_expire = set_grace_period();
			}
		}

		/*
		 * Retry any blocked locks that have been notified by
		 * the VFS. Don't do this during grace period.
		 * (Theoretically, there shouldn't even be blocked locks
		 * during grace period).
		 */
		if (!nlmsvc_grace_period)
			timeout = nlmsvc_retry_blocked();

		/*
		 * Find a socket with data available and call its
		 * recvfrom routine.
		 */
		err = svc_recv(serv, rqstp, timeout);
		if (err == -EAGAIN || err == -EINTR)
			continue;
		if (err < 0) {
			printk(KERN_WARNING
			       "lockd: terminating on error %d\n",
			       -err);
			break;
		}

		dprintk("lockd: request from %08x\n",
			(unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr));

		/*
		 * Look up the NFS client handle. The handle is needed for
		 * all but the GRANTED callback RPCs.
		 */
		rqstp->rq_client = NULL;
		if (nlmsvc_ops) {
			nlmsvc_ops->exp_readlock();
			rqstp->rq_client =
				nlmsvc_ops->exp_getclient(&rqstp->rq_addr);
		}

		if (nlmsvc_grace_period &&
		    time_before(grace_period_expire, jiffies))
			nlmsvc_grace_period = 0;
		svc_process(serv, rqstp);

		/* Unlock export hash tables */
		if (nlmsvc_ops)
			nlmsvc_ops->exp_unlock();
	}

	/*
	 * Check whether there's a new lockd process before
	 * shutting down the hosts and clearing the slot.
	 */
	if (!nlmsvc_pid || current->pid == nlmsvc_pid) {
		if (nlmsvc_ops)
			nlmsvc_ops->detach();
		nlm_shutdown_hosts();
		nlmsvc_pid = 0;
	} else
		printk(KERN_DEBUG
			"lockd: new process, skipping host shutdown\n");
	wake_up(&lockd_exit);
		
	/* Exit the RPC thread */
	svc_exit_thread(rqstp);

	/* release rpciod */
	rpciod_down();

	/* Release module */
	MOD_DEC_USE_COUNT;
}
Beispiel #13
0
static int w99685_thread(void *arg)
{
	int ret = 0;
	UINT32 imglen = 0;;
	UINT16 blocks = 0;
	UINT8 choice = 0;
	w685cf_t *priv = arg;
	ImageContainer_t *imgcontainerp = priv->images;
	/*
	 * This thread doesn't need any user-level access,
	 * so get rid of all our resources..
	 */
	daemonize();
	reparent_to_init();
//	exit_files(current);
//	current->files = init_task.files;
//	atomic_inc(&current->files->count);
//	daemonize();
//	reparent_to_init();

	/* avoid getting signals */
//	spin_lock_irq(&current->sigmask_lock);
//	flush_signals(current);
//	sigfillset(&current->blocked);
//	recalc_sigpending(current);
//	spin_unlock_irq(&current->sigmask_lock);

	/* set our name for identification purposes */
	sprintf(current->comm, "W99685CFI_thread");

//Get Image Data, :P	
	for(;;) {
		if(priv->user) { // Someone open the camera, get the data.
			W99685CMD_GetImageLen(&imglen);
			TDEBUG("imagelen: %d", imglen);
			if(imglen > 0&& imglen <= W685BUF_SIZE)
			{
				blocks = (imglen-1+DATABLOCKSIZE)/DATABLOCKSIZE;
				if(blocks < W685BUF_SIZE/DATABLOCKSIZE) {
					choice = imgcontainerp->which;
					TDEBUG("Write choice: %d, and choicelen: %d", choice, IMAGELEN(imgcontainerp, choice));
					down( &((IMAGEHOLD(imgcontainerp, choice)).ilock) );
					if(IMAGELEN(imgcontainerp, choice) > 0) //Have had data, don't overwrite it.
						goto do_next;
					W99685_GetData(IMAGEDATA(imgcontainerp, choice) ,blocks);
					(IMAGEHOLD(imgcontainerp, choice)).len = imglen;
do_next:
					imgcontainerp->which = (++(imgcontainerp->which))%IMGCONTAINERSIZE;
					up( &((IMAGEHOLD(imgcontainerp, choice)).ilock) );
				}
			TDEBUG("Sleep...");
			wait_ms(20);
			}
			else if(imglen < 0)  //can't recover, it crazy :(
			{
				W685_ERR("Get image length error: %d\n", imglen);
				break;
			}
			else {
				wait_ms(500);
				continue;
			}
		}
		else
			sleep_on_timeout(&priv->waitq, 10);
	}
out:
	return ret;
}
Beispiel #14
0
/*
 * This task waits until at least one touchscreen is touched.  It then loops
 * digitizing and generating events until no touchscreens are being touched.
 */
static int
xts_thread(void *arg)
{
	int any_pens_down;
	struct xts_dev *dev;
	struct task_struct *tsk = current;
	DECLARE_WAITQUEUE(wait, tsk);
	xts_task = tsk;

	daemonize();
	reparent_to_init();
	strcpy(xts_task->comm, XTS_NAME);
	xts_task->tty = NULL;

	/* only want to receive SIGKILL */
	spin_lock_irq(&xts_task->sigmask_lock);
	siginitsetinv(&xts_task->blocked, sigmask(SIGKILL));
	recalc_sigpending(xts_task);
	spin_unlock_irq(&xts_task->sigmask_lock);

	complete(&task_sync);

	add_wait_queue(&irq_wait, &wait);
	any_pens_down = 0;
	for (;;) {
		/*
		 * Block waiting for interrupt or if any pens are down, either
		 * an interrupt or timeout to sample again.
		 */
		set_current_state(TASK_INTERRUPTIBLE);
		if (any_pens_down)
			schedule_timeout(HZ / 100);
		while (signal_pending(tsk)) {
			siginfo_t info;

			/* Only honor the signal if we're cleaning up */
			if (task_shutdown)
				goto exit;
			/*
			 * Someone else sent us a kill (probably the
			 * shutdown scripts "Sending all processes the
			 * KILL signal").  Just dequeue it and ignore
			 * it.
			 */
			spin_lock_irq(&current->sigmask_lock);
			(void)dequeue_signal(&current->blocked, &info);
			spin_unlock_irq(&current->sigmask_lock);
		}
		schedule();

		any_pens_down = 0;
		for (dev = dev_list; dev; dev = dev->next_dev) {
			if (dev->pen_is_down) {
				u32 x, y;
				XTouchscreen_GetPosition_2D(&dev->Touchscreen,
							    &x, &y);
				event_add(dev, 255, (u16) x, (u16) y);
				dev->pen_was_down = 1;
				any_pens_down = 1;
			} else if (dev->pen_was_down) {
				event_add(dev, 0, 0, 0);
				dev->pen_was_down = 0;
			}
		}
	}

exit:
	remove_wait_queue(&irq_wait, &wait);

	xts_task = NULL;
	complete_and_exit(&task_sync, 0);
}