Beispiel #1
0
static irqreturn_t lkl_disk_irq(int irq, void *dev_id)
{
	struct pt_regs *regs=get_irq_regs();

	complete_request(regs->irq_data);

	return IRQ_HANDLED;
}
Beispiel #2
0
void ResourceManager::complete_requests()
{
	TempAllocator1024 ta;
	Array<ResourceData> loaded(ta);
	m_loader.get_loaded(loaded);

	for (uint32_t i = 0; i < array::size(loaded); i++)
		complete_request(loaded[i].id, loaded[i].data);
}
Beispiel #3
0
void ResourceManager::complete_requests()
{
	TempAllocator1024 ta;
	Array<ResourceRequest> loaded(ta);
	_loader->get_loaded(loaded);

	for (u32 i = 0; i < array::size(loaded); ++i)
		complete_request(loaded[i].type, loaded[i].name, loaded[i].data);
}
Beispiel #4
0
void USBTester::callback_request(const setup_packet_t *setup)
{
    /* Called in ISR context */
    RequestResult result = PassThrough;
    uint8_t *data = NULL;
    uint32_t size = 0;
    uint32_t delay = 0;

    /* Process vendor-specific requests */
    if (setup->bmRequestType.Type == VENDOR_TYPE) {
        switch (setup->bRequest) {
            case VENDOR_TEST_CTRL_IN:
                result = Send;
                data = ctrl_buf;
                size = setup->wValue < sizeof(ctrl_buf) ? setup->wValue : sizeof(ctrl_buf);
                break;
            case VENDOR_TEST_CTRL_OUT:
                result = Receive;
                data = ctrl_buf;
                size = setup->wValue < 8 ? setup->wValue : 8;
                break;
            case VENDOR_TEST_CTRL_NONE:
                result = Success;
                break;
            case VENDOR_TEST_CTRL_NONE_DELAY:
                result = Success;
                delay = 2000;
                break;
            case VENDOR_TEST_CTRL_IN_SIZES:
                result = Send;
                data = ctrl_buf;
                size = setup->wLength;
                break;
            case VENDOR_TEST_CTRL_OUT_SIZES:
                result = Receive;
                data = ctrl_buf;
                size = setup->wValue;
                break;
            default:
                result = PassThrough;
                break;
        }
    }

    if (delay) {
        queue->call_in(delay, static_cast<USBDevice *>(this), &USBTester::complete_request, Success, data, size);
    } else {
        complete_request(result, data, size);
    }
}
/*==============================================================================
 *
 */
void abort_current_cmd(void)
{
    if(g_request_in_progress)
    {
        uint32_t flush_in_progress;
        
        /*
         * Call completion handler just in case we are in a multi threaded system
         * to avoid a task lockup.
         */
        complete_request(g_comblk_response_idx);
        
        /*
         * Flush the FIFOs
         */
        COMBLK->CONTROL |= CR_FLUSHOUT_MASK;
        do {
            flush_in_progress = COMBLK->CONTROL & CR_FLUSHOUT_MASK;
        } while(flush_in_progress);
    }
}
/*==============================================================================
 *
 */
void handle_rx_okay_irq(void)
{
    uint16_t data16;
    uint16_t is_command;
    
    data16 = COMBLK->DATA8;
    is_command = data16 & DATA8_COMMAND_MASK;
            
    switch(g_comblk_state)
    {
        /*----------------------------------------------------------------------
         * The RCV_OKAY interrupt should only be enabled for states
         * COMBLK_WAIT_RESPONSE and COMBLK_RX_RESPONSE. 
         */
        case COMBLK_WAIT_RESPONSE:
            if(is_command)
            {
                uint8_t rxed_opcode;
                rxed_opcode = (uint8_t)data16;
                if(rxed_opcode == g_comblk_cmd_opcode)
                {
                    g_comblk_response_idx = 0;
                    g_comblk_p_response[g_comblk_response_idx] = rxed_opcode;
                    ++g_comblk_response_idx;
                    g_comblk_state = COMBLK_RX_RESPONSE;
                }
                else
                {
                    /*
                     * Unexpected command response.
                     * Call the command completion handler with the response
                     * size set to zero to indicate a problem.
                     */
                    complete_request(0u);
                }
            }
            break;
            
        case COMBLK_RX_RESPONSE:
            if(is_command)
            {
                /*
                 * Unexpected command response.
                 * Call the command completion handler with the response size
                 * set to the number of response bytes received so far.
                 * The caller may simply have set a response buffer which is
                 * not large enough for the full response.
                 */
                complete_request(0u);
                g_comblk_state = COMBLK_WAIT_RESPONSE;
            }
            else
            {
                if(g_comblk_response_idx < g_comblk_response_size)
                {
                    uint8_t rxed_data;
                    
                    rxed_data = (uint8_t)data16;
                    g_comblk_p_response[g_comblk_response_idx] = rxed_data;
                    ++g_comblk_response_idx;
                }
                
                if(g_comblk_response_idx == g_comblk_response_size)
                {
                    complete_request(g_comblk_response_idx);
                    g_comblk_state = COMBLK_IDLE;
                }
            }
            break;
            
        /*----------------------------------------------------------------------
         * The RCV_OKAY interrupt should NOT be enabled for states
         * COMBLK_IDLE, COMBLK_TX_CMD and COMBLK_TX_DATA. 
         */
        case COMBLK_IDLE:
            /* Fall through */
        case COMBLK_TX_CMD:
            /* Fall through */
        case COMBLK_TX_DATA:
            /* Fall through */
        default:
            COMBLK->INT_ENABLE &= ~RCVOKAY_MASK;
            g_comblk_state = COMBLK_IDLE;
            break;
    }
}
/*==============================================================================
 *
 */
static void handle_rx_okay_irq(void)
{
    uint16_t data16;
    uint16_t is_command;

    data16 = (uint16_t)COMBLK->DATA8;
    is_command = data16 & DATA8_COMMAND_MASK;

    switch(g_comblk_state)
    {
    /*----------------------------------------------------------------------
     * The RCV_OKAY interrupt should only be enabled for states
     * COMBLK_WAIT_RESPONSE and COMBLK_RX_RESPONSE.
     */
    case COMBLK_WAIT_RESPONSE:
        if(is_command)
        {
            uint8_t rxed_opcode;
            rxed_opcode = (uint8_t)data16;
            if(rxed_opcode == g_comblk_cmd_opcode)
            {
                g_comblk_response_idx = 0u;
                g_comblk_p_response[g_comblk_response_idx] = rxed_opcode;
                ++g_comblk_response_idx;
                g_comblk_state = COMBLK_RX_RESPONSE;
            }
            else
            {
                process_sys_ctrl_command(rxed_opcode);
            }
        }
        break;

    case COMBLK_RX_RESPONSE:
        if(is_command)
        {
            uint8_t rxed_opcode;
            rxed_opcode = (uint8_t)data16;
            process_sys_ctrl_command(rxed_opcode);
        }
        else
        {
            if(g_comblk_response_idx < g_comblk_response_size)
            {
                uint8_t rxed_data;

                rxed_data = (uint8_t)data16;
                g_comblk_p_response[g_comblk_response_idx] = rxed_data;
                ++g_comblk_response_idx;
            }

            if(g_comblk_response_idx == g_comblk_response_size)
            {
                complete_request(g_comblk_response_idx);
                g_comblk_state = COMBLK_IDLE;
            }
        }
        break;

    /*----------------------------------------------------------------------
     * The RCV_OKAY interrupt should NOT be enabled for states
     * COMBLK_IDLE, COMBLK_TX_CMD and COMBLK_TX_DATA.
     */
    case COMBLK_TX_PAGED_DATA:
        /* This is needed because when there is an error, we need to terminate loading the data */
        if(!is_command)
        {
            g_comblk_p_response[1] = (uint8_t)data16;
            complete_request(2u);
            g_comblk_state = COMBLK_IDLE;
        }
        break;
    case COMBLK_IDLE:
    /* Fall through */
    case COMBLK_TX_CMD:
    /* Fall through */
    case COMBLK_TX_DATA:
        /* Fall through */
        if(is_command)
        {
            uint8_t rxed_opcode;
            rxed_opcode = (uint8_t)data16;
            process_sys_ctrl_command(rxed_opcode);
        }
        break;

    default:
        complete_request(0u);
        g_comblk_state = COMBLK_IDLE;
        break;
    }
}
/*==============================================================================
 *
 */
static void handle_tx_okay_irq(void)
{
    switch(g_comblk_state)
    {
    /*----------------------------------------------------------------------
     * The TX_OKAY interrupt should only be enabled for states COMBLK_TX_CMD
     * and COMBLK_TX_DATA.
     */
    case COMBLK_TX_CMD:
        if(g_comblk_cmd_size > 0u)
        {
            uint32_t size_sent;
            size_sent = fill_tx_fifo(g_comblk_p_cmd, g_comblk_cmd_size);
            if(size_sent < g_comblk_cmd_size)
            {
                g_comblk_cmd_size = g_comblk_cmd_size - (uint16_t)size_sent;
                g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];
            }
            else
            {
                g_comblk_cmd_size = 0u;
                if(g_comblk_data_size > 0u)
                {
                    g_comblk_state = COMBLK_TX_DATA;
                }
                else
                {
                    g_comblk_state = COMBLK_WAIT_RESPONSE;
                }
            }
        }
        else
        {
            /*
             * This is an invalid situation indicating a bug in the driver
             * or corrupted memory.
             */
            ASSERT(0);
            abort_current_cmd();
        }
        break;

    case COMBLK_TX_DATA:
        if(g_comblk_data_size > 0u)
        {
            uint32_t size_sent;
            size_sent = fill_tx_fifo(g_comblk_p_data, g_comblk_data_size);
            if(size_sent < g_comblk_data_size)
            {
                g_comblk_data_size = g_comblk_data_size - size_sent;
                g_comblk_p_data = &g_comblk_p_data[size_sent];
            }
            else
            {
                COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
                g_comblk_state = COMBLK_WAIT_RESPONSE;
            }
        }
        else
        {
            /*
             * This is an invalid situation indicating a bug in the driver
             * or corrupted memory.
             */
            ASSERT(0);
            abort_current_cmd();
        }
        break;

    case COMBLK_TX_PAGED_DATA:
        /*
         * Read a page of data if required.
         */
        if(0u == g_comblk_data_size)
        {
            if(g_comblk_page_handler != 0)
            {
                g_comblk_data_size = g_comblk_page_handler(&g_comblk_p_data);
                if(0u == g_comblk_data_size)
                {
                    COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
                    g_comblk_state = COMBLK_WAIT_RESPONSE;
                }
            }
            else
            {
                ASSERT(0);
                abort_current_cmd();
            }
        }

        /*
         * Transmit the page data or move to COMBLK_WAIT_RESPONSE state if
         * no further page data could be obtained by the call to the page
         * handler above.
         */
        if(0u == g_comblk_data_size)
        {
            COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
            g_comblk_state = COMBLK_WAIT_RESPONSE;
        }
        else
        {
            uint32_t size_sent;
            size_sent = fill_tx_fifo(g_comblk_p_data, g_comblk_data_size);
            g_comblk_data_size = g_comblk_data_size - size_sent;
            g_comblk_p_data = &g_comblk_p_data[size_sent];
        }
        break;

    /*----------------------------------------------------------------------
     * The TX_OKAY interrupt should NOT be enabled for states COMBLK_IDLE,
     * COMBLK_WAIT_RESPONSE and COMBLK_RX_RESPONSE.
     */
    case COMBLK_IDLE:
    /* Fall through */
    case COMBLK_WAIT_RESPONSE:
    /* Fall through */
    case COMBLK_RX_RESPONSE:
    /* Fall through */
    default:
        COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
        complete_request(0u);
        g_comblk_state = COMBLK_IDLE;
        break;
    }
}
Beispiel #9
0
static irqreturn_t cc_isr(int irq, void *dev_id)
{
	struct cc_drvdata *drvdata = (struct cc_drvdata *)dev_id;
	struct device *dev = drvdata_to_dev(drvdata);
	u32 irr;
	u32 imr;

	/* STAT_OP_TYPE_GENERIC STAT_PHASE_0: Interrupt */

	/* read the interrupt status */
	irr = cc_ioread(drvdata, CC_REG(HOST_IRR));
	dev_dbg(dev, "Got IRR=0x%08X\n", irr);
	if (irr == 0) { /* Probably shared interrupt line */
		dev_err(dev, "Got interrupt with empty IRR\n");
		return IRQ_NONE;
	}
	imr = cc_ioread(drvdata, CC_REG(HOST_IMR));

	/* clear interrupt - must be before processing events */
	cc_iowrite(drvdata, CC_REG(HOST_ICR), irr);

	drvdata->irq = irr;
	/* Completion interrupt - most probable */
	if (irr & CC_COMP_IRQ_MASK) {
		/* Mask AXI completion interrupt - will be unmasked in
		 * Deferred service handler
		 */
		cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | CC_COMP_IRQ_MASK);
		irr &= ~CC_COMP_IRQ_MASK;
		complete_request(drvdata);
	}
#ifdef CONFIG_CRYPTO_FIPS
	/* TEE FIPS interrupt */
	if (irr & CC_GPR0_IRQ_MASK) {
		/* Mask interrupt - will be unmasked in Deferred service
		 * handler
		 */
		cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | CC_GPR0_IRQ_MASK);
		irr &= ~CC_GPR0_IRQ_MASK;
		fips_handler(drvdata);
	}
#endif
	/* AXI error interrupt */
	if (irr & CC_AXI_ERR_IRQ_MASK) {
		u32 axi_err;

		/* Read the AXI error ID */
		axi_err = cc_ioread(drvdata, CC_REG(AXIM_MON_ERR));
		dev_dbg(dev, "AXI completion error: axim_mon_err=0x%08X\n",
			axi_err);

		irr &= ~CC_AXI_ERR_IRQ_MASK;
	}

	if (irr) {
		dev_dbg(dev, "IRR includes unknown cause bits (0x%08X)\n",
			irr);
		/* Just warning */
	}

	return IRQ_HANDLED;
}