Beispiel #1
0
void handle_usb(u32 clkn)
{
	u8 epstat;

	/* write queued packets to USB if possible */
	epstat = USBHwEPGetStatus(BULK_IN_EP);
	if (!(epstat & EPSTAT_B1FULL)) {
		dequeue_send(clkn);
	}
	if (!(epstat & EPSTAT_B2FULL)) {
		dequeue_send(clkn);
	}

	/* polled "interrupt" */
	USBHwISR();
}
Beispiel #2
0
/* Send an IPC to another thread. */
NORETURN void
sys_ipc_recv(word_t src_thread, word_t operation)
{
    /* Ensure the thread exists. */
    if (EXPECT_FALSE(src_thread >= max_tcbs && src_thread != IPC_WAIT_ANY)) {
        syscall_return_error(IPC_ERROR, EINVAL);
    }

    spin_lock(&ipc_lock);

    /* Get first thread on send queue. */
    tcb_t *src = current_tcb->ipc_send_head;

    /* If there are no threads, go to sleep. */
    if (src == NULL) {
        current_tcb->ipc_waiting_for = src;
        tcb_t *next = deactivate_self_schedule(THREAD_STATE_WAIT_IPC_RECV);
        spin_unlock(&ipc_lock);
        switch_to(next);
    }

    /* Otherwise, dequeue the thread. */
    dequeue_send(current_tcb, src);

    /* Copy the message across and wake up the sender. */
    copy_message(src, current_tcb);

    /* Is the sender performing a call? */
    if (src->thread_state == THREAD_STATE_WAIT_IPC_CALL) {
        /* Move it into receive phase. 'ipc_waiting_for' should already be set
         * to us. */
        word_t tid = src->tid;
        ASSERT(src->ipc_waiting_for == current_tcb);
        src->thread_state = THREAD_STATE_WAIT_IPC_RECV;
        spin_unlock(&ipc_lock);
        syscall_return_success(tid);
        /* NOTREACHED */
    }

    /* If the sender was not performing a call, wake them up. */
    src->ipc_waiting_for = NULL;
    set_syscall_return_val_success(src, 0);
    set_syscall_return_val_success(current_tcb, src->tid);
    tcb_t *next = activate_schedule(src);
    spin_unlock(&ipc_lock);
    switch_to(next);
    /* NOTREACHED */
}