BOOL PXA271_USB_Driver::StartOutput( USB_CONTROLLER_STATE* State, int endpoint )
{
    ASSERT( State );
    ASSERT(endpoint < c_Used_Endpoints);

    GLOBAL_LOCK(irq);

    // If endpoint is not an output
    if( State->Queues[endpoint] == NULL || !State->IsTxQueue[endpoint] )
        return FALSE;

    /* if the halt feature for this endpoint is set, then just
       clear all the characters */
    if(State->EndpointStatus[endpoint] & USB_STATUS_ENDPOINT_HALT)
    {
        ClearTxQueue( State, endpoint );
        return TRUE;
    }
    

    //If TxRunning, interrupts will drain the queue
    if(!g_PXA271_USB_Driver.TxRunning[endpoint])
    {
        g_PXA271_USB_Driver.TxRunning[endpoint] = TRUE;

        // Calling both TxPacket & EP_TxISR in this routine could cause a TX FIFO overflow
        TxPacket( State, endpoint );
    }
    else if(irq.WasDisabled())
    {                        
        PXA271_USB& USB = PXA271::USB();
        
        // This could be called during Flush with all interrupts off.  Just taking care of the endpoint
        // in question may cause a logjam if the host is expecting a response from another endpoint.
        // All endpoints must be examined for activity.
        if( USB.UDCISR0 & USB.UDCICR0 & USB.UDCICR__BOTH )        // If endpoint 0 needs attention
            EP0_ISR( 0 );
        for( int ep = 1; ep < c_Used_Endpoints; ep++ )
        {
            // If no interrupt for this endpoint
            if( (((USB.UDCISR0 & USB.UDCICR0) >> (ep * 2)) & USB.UDCICR__BOTH) == 0 )
                continue;
            
            if(State->Queues[ep])
            {
                if( State->IsTxQueue[endpoint] )
                    EP_TxISR( endpoint );
                else
                    EP_RxISR( endpoint );
            }
        }
    }
BOOL AT91_USBHS_Driver::StartOutput( USB_CONTROLLER_STATE* State, int endpoint )
{
    
    ASSERT(State);
    ASSERT(endpoint < c_Used_Endpoints);
    
    GLOBAL_LOCK(irq);
    
    struct AT91_UDPHS *pUdp = (struct AT91_UDPHS *) AT91C_BASE_UDP;

   // If endpoint is not an output
    if( State->Queues[endpoint] == NULL || !State->IsTxQueue[endpoint] )
        return FALSE;

    pUdp->UDPHS_IEN |= 1 << SHIFT_INTERUPT << endpoint;
    pUdp->UDPHS_EPT[endpoint].UDPHS_EPTCTLENB = AT91C_UDPHS_TX_PK_RDY;
    

    /* if the halt feature for this endpoint is set, then just
            clear all the characters */
    if(g_AT91_USBHS_Driver.EndpointStatus[endpoint] & USB_STATUS_ENDPOINT_HALT)
    {
        ClearTxQueue( State, endpoint );
        return TRUE;
    }

    //If TxRunning, interrupts will drain the queue

    if(!(BOOL)((UINT8)g_AT91_USBHS_Driver.TxRunning[endpoint]))
    {

        num_ep_int1++;
        g_AT91_USBHS_Driver.TxRunning[endpoint] = TRUE;

        TxPacket( State, endpoint );
    }
    else if(irq.WasDisabled()) // We should not call EP_TxISR after calling TxPacket becuase it can cause a TX FIFO overflow error.
    {
        Endpoint_ISR(endpoint);
    }

    return TRUE;
}