⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncfwapi.c

📁 CE下 NET2778 NDIS Drivers, 在每个平台上都可以使用
💻 C
📖 第 1 页 / 共 5 页
字号:

        // See if the physical endpoint requires service
        if (IrqStat0 & (1<<PhysEp))
        {   // This physical endpoint has interrupted:
            //  - Service the endpoint's transfer requirements
            //  - Candidacy level may change depending on results of the transfer
            ASSERT(Endpoint->Priv.PhysEp == PhysEp);
            ASSERT(Endpoint->Transfer != NULL);

            // Call endpoint's transfer handler
            //  - USB packets will be received (OUT) or transmitted (IN)
            Endpoint->Priv.PioPacketHandler(Endpoint);
            EndpointActivity++;
        }

#if _NCVIRTUALENDPOINTS
        else if (Endpoint->Priv.SwapCandidate < SwapCandidate_NoBytesTransferred)
        {   // Endpoint does NOT require service, AND it currently has low chance of being re-assigned
            //  - Increase this endpoint's chances for re-assignment
            Endpoint->Priv.SwapCandidate = SwapCandidate_NoBytesTransferred;
        }

        if (Endpoint->Transfer->TransferFlags & (1<<NC_TRANSFER_FLAG_ENDPOINT_LOCK))
        {   // Locked endpoints stay locked, regardless of previous results!
            Endpoint->Priv.SwapCandidate = SwapCandidate_Locked;
            // No further processing
            continue;
        }

        if (Endpoint->Priv.SwapCandidate < SwapCandidate_TransferComplete)
        {   // Transfer did not complete, however endpoint may need to be relocked
            if (Endpoint->Transfer->TransferFlags & (1<<NC_TRANSFER_FLAG_TRANSFER_LOCK))
            {   // Client requested this transfer to remain assigned for the life of the transfer
                Endpoint->Priv.SwapCandidate = SwapCandidate_Locked;
            }
            else if (Endpoint->Priv.FrameCount < Endpoint->Ex.VirtualEp_MinLockTime)
            {   // Number of USB frames since this transfer started and locked is within a threshold
                //  - Relock the endpoint so it cannot be reassigned (at least for now) 
                //    to prevent unproductive re-assignment thrashing
                //  - Increment Frame Count: Next interrupt, endpoint may get reassigned!
                Endpoint->Priv.SwapCandidate = SwapCandidate_Locked;
                Endpoint->Priv.FrameCount += FramesSinceLastInterrupt;
            }
        }
#endif  // _NCVIRTUALENDPOINTS
    }

#if _NCVIRTUALENDPOINTS
#pragma message (_NC_MESSAGE"Virtualized endpoints support supported. (Up to 30 endpoints.)")
    // This implementation supports NET2272 virtualized endpoints. Virtualized endpoints
    // allows your USB device to have as many as 30 (15 IN plus 15 OUT) Bulk or Interrupt
    // endpoints. A significant amount of virtualization support firmware may be eliminated 
    // if the three physical endpoints (EPA, EPB, EPC) plus Endpoint Zero is sufficient 
    // for your device. This Virtualized Endpoint Interrupt section plus the following 
    // routines may be removed:
    //  - FindNextNakingVirtualEp()
    //  - ReassignBestEndpoint()
    //  - SaveTransfer()
    //  - RestartTransfer()
    // Recommendation: Discard unused sections *after* debugging!!

    IrqStat0 = NETCHIP_READ(IRQSTAT0) & NETCHIP_READ(IRQENB0);
    if (IrqStat0 & (1<<VIRTUALIZED_ENDPOINT_INTERRUPT))
    {   // At least one virtualized endpoint is requesting service (Host has sent a token)
        //  - NET2272 virtualization logic is NAKing tokens on virtualized endpoints
        Endpoint = FindNextNakingVirtualEp();
        if (Endpoint != NULL)
        {   // A virtualized transfer needs service. It must be assigned to a physical endpoint
            //  - Find the best physical endpoint to assign this transfer to:
            if (ReassignBestEndpoint(Endpoint) == NCSTATUS_SUCCESS)
            {   // Successfully re-assigned a transfer from one of the chip's physical endpoints
                //  - Start (or restart) this transfer on the same physical endpoint
                RestartTransfer(Endpoint);
            }
        }
        EndpointActivity++;
    }
#endif

    if (EndpointActivity == 0)
    {   // No data transfers
        //  - Check for less time-critical events

        // Check for changes in these USB conditions:
        if (NETCHIP_READ(IRQSTAT1) & (
            (1<<ROOT_PORT_RESET_INTERRUPT) |        // Root Port Reset
            (1<<RESUME_INTERRUPT) |                 // Chip wakeup
            (1<<SUSPEND_REQUEST_CHANGE_INTERRUPT) | // Host is suspending or resuming
            (1<<VBUS_INTERRUPT) |                   // VBUS went FALSE or TRUE
            0))
        {   // Handle changes in USB conditions
            NcDev_UsbState(PrivDeviceObject);
            // Tip: The NET2272 may now be suspended. If the chip's I/O Wakeup Enable 
            // is TRUE, then care must be taken to NOT access the chip, or it will wakeup!
        }
        else if (PrivDeviceObject->UsbPowerState == NC_USB_POWER_ON)
        {   // The chip is connected and running
            //  - Check for USB Setup Requests
            NcDev_ControlHandler(PrivDeviceObject);
        }
    }

    // Histo tip: Be careful about accessing the chip in this HISTO(). If it is
    // suspended and its I/O Wakeup Enable is TRUE, a register access will wake it!
    HISTO(DEFAULT_HISTORY, ")Int", 0, 0, 0);
    ASSERT(NcDebug_InterruptContext);
    NCDEBUG(NcDebug_InterruptContext = FALSE;)
    
    /*
    // Debugging tip: If this interrupt handler loops forever unproductively, it 
    // usually means:
    //   - An interrupt is enabled but not handled: Disable or write a handler for
    //     the interrupt. 
    //   - An interrupt is enabled and handled, but the interrupting bit is not 
    //     cleared: The NetChip #IRQ pin remains asserted as long as an interrupt 
    //     bit is enabled and set. (For instance, if VBUS Interrupt is set, the 
    //     chip's #IRQ remains asserted as long as VBUS Interrupt Enable is set. The
    //     #IRQ pin deasserts when VBUS Interrupt is cleared OR VBUS Interrupt Enable
    //     is cleared.)
    //   - The chip's #IRQ pin is stuck low. Note that the #IRQ pin may be shared
    //     by other chips; it may be another chip that is asserting its interrupt 
    //     pin. Also, there should be a pull-up resister on the interrupt line.
    //
    // The following code fragment can help expose problematic interrupts:
    IrqStat0 = NETCHIP_READ(IRQSTAT0);
    IrqEnb0 = NETCHIP_READ(IRQENB0);
    IrqStat1 = NETCHIP_READ(IRQSTAT1);
    IrqEnb1 = NETCHIP_READ(IRQENB1);

    NCPRINTF(VOLUME_MINIMUM, ("NcDev_InterruptHandler(): Unhandled interrupt... \n")); 
    if (IrqStat0 & IrqEnb0)
    {
        NCPRINTF(VOLUME_MINIMUM, ("IRQSTAT0(%2.2x) AND IRQENB0(%2.2x): %2.2x\n", 
            IrqStat0, IrqEnb0, (IrqStat0 & IrqEnb0)));
    }
    else if (IrqStat0 & IrqEnb0)
    {
        NCPRINTF(VOLUME_MINIMUM, ("IRQSTAT1(%2.2x) AND IRQENB1(%2.2x): %2.2x\n", 
            IrqStat1, IrqEnb1, (IrqStat1 & IrqEnb1)));
    }
    else
    {   // Unknown *and* unhandled interrupt
        //  - We should never *ever* get here!
        //  - (It can occur if Suspend Request Interrupt Enable is accidentally 
        //     set when writing 1 to Suspend Request Interrupt)
        NCPRINTF(VOLUME_MINIMUM, (" - <Unknown source>\n")); 
    }
    */

}

///////////////////////////////////////////////////////////////////////////////
void
NcResetDataEp(
    PNC_DEVICE_OBJECT DeviceObject
    )
{   // Reset all endpoints (except endpoint zero)
    //  - Effectively undoes the API Endpoint Create function for all data endpoints
    //  - Calls client's Completion Handler (with error) on endpoints with Pending transfers
    //  - Calls client's Endpoint Event handler
    //  - Deprograms all endpoints and endpoint state information
    //  - Expected to be called on initialization, USB reset and de-configuration
    NCBYTE EpIndex;

    HISTO(DEFAULT_HISTORY, "DsEp", DeviceObject->ConfigurationEndpointCount, 0, 0);

    NETCHIP_WRITE(IRQENB0, NETCHIP_READ(IRQENB0) & ~(
        (1<<ENDPOINT_A_INTERRUPT_ENABLE) |
        (1<<ENDPOINT_B_INTERRUPT_ENABLE) |
        (1<<ENDPOINT_C_INTERRUPT_ENABLE) |
        (1<<VIRTUALIZED_ENDPOINT_INTERRUPT_ENABLE) |
        0));

    for (EpIndex = 1; EpIndex <= DeviceObject->ConfigurationEndpointCount; EpIndex++)
    {   // For all logical endpoints in the configuration (Except Endpoint Zero!)
        // call the client's endpoint closing function. (This allows the client
        // to do per-endpoint shutdown, such as freeing endpoint transfer buffers.)
        // Call client's endpoint closing function for this endpoint
        //  - Client can free this endpoint's buffers, etc.
        PNC_ENDPOINT_OBJECT Endpoint = &LogicalEndpoints[EpIndex];

        if (Endpoint->CompletionStatus == NCSTATUS_PENDING)
        {   // This endpoint's transfer did not complete
            //  - To slightly improve performance, call the endpoint event handler
            //    rather than the transfer object's completion handler. That way,
            //    the completion handler can process transfers faster.
            Endpoint->EventCode = NC_ENDPOINT_EVENT_SURPRISE_CANCEL_TRANSFER;
            ASSERT(Endpoint->EndpointEventHandler != NULL);
            Endpoint->EndpointEventHandler(Endpoint);
        }

        // Close the endpoint
        Endpoint->EventCode = NC_ENDPOINT_EVENT_SURPRISE_CLOSE;
        ASSERT(Endpoint->EndpointEventHandler != NULL);
        Endpoint->EndpointEventHandler(Endpoint);
    }

    // Clear all endpoint structures except Endpoint Zero
    memset(&LogicalEndpoints[1], 0x00, (NCAPI_MAX_ENDPOINT_COUNT - 1)*(sizeof(LogicalEndpoints[0])));
    DeviceObject->ConfigurationEndpointCount = 0;

    for (EpIndex = 1; EpIndex < NCAPI_MAX_ENDPOINT_COUNT; EpIndex++)
    {   // Set starting values for all possible logical endpoints (not including Endpoint Zero):
        //  - Client may optionally override these handlers
        LogicalEndpoints[EpIndex].EndpointEventHandler = (NCSTATUS(*)(PNC_ENDPOINT_OBJECT))DoNothing_MoreProcessingRequired;
    }

    for (EpIndex = FIRST_PHYSICAL_ENDPOINT; EpIndex < PHYSICAL_ENDPOINT_COUNT; EpIndex++)
    {   // Virtualize and disable interrupts for all physical endpoints (except Endpoint Zero)
        NETCHIP_WRITE(PAGESEL, EpIndex);
        NETCHIP_WRITE(EP_CFG, 0);
        NETCHIP_WRITE(EP_IRQENB, 0);

        // Map physical endpoint to a logical transfer structure
        LogicalEndpoints[EpIndex].Transfer = &LogicalEndpoints[EpIndex].DefaultTransferObject;
        PhysicalEndpoints[EpIndex] = &LogicalEndpoints[EpIndex];
        PhysicalEndpoints[EpIndex]->Priv.PhysEp = (BYTE)EpIndex;
        NC_VIRT_EP(PhysicalEndpoints[EpIndex]->Priv.SwapCandidate = SwapCandidate_TransferComplete;)
    }

    NETCHIP_WRITE(USBCTL1, NETCHIP_READ(USBCTL1) & ~(1<<VIRTUAL_ENDPOINT_ENABLE));
}

///////////////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
NCSTATUS
NcApi_OneTimeInit(
    PNC_DEVICE_OBJECT DeviceObject
    )
{   // One-time initialization of the NetChip API and the NetChip device (NET2272)
    //  - The caller passes a Device Object to this routine. The Device Object is a
    //    structure created by the client. It specifies virtually everything about
    //    the device to the API. It references USB descriptors, dynamic variables
    //    as well as evnet handlers:
    //  - USB Descriptors: Before calling here, the client should specify USB descriptors
    //    and strings in the Device Object.
    //  - Event Handlers: This routine populates event handlers in the Device Object
    //    with its own default routines. If the client wants to replace any handler,
    //    it should do so *after* this routine returns.
    //  - Other Device Object entries, such as the current configuration, will be updated 
    //    dynamically by NcApi. (For instance soon after connecting to a High-Speed 
    //    USB host, the Device Object's current configuration will reference the client's 
    //    High-Speed configuration.)
    //  - This routine should NOT be called from an interrupt context. 

    //XXXXXXXXXXXXXXXXXXXX Add PRINTF regarding 8/16 bit mode
    //XXXXXXXXXXXXXXXXXXXX Add PRINTF regarding Virtualization On/Off
    NCBYTE StringIndex;

    ASSERT(!NcDebug_InterruptContext)
    ASSERT(DeviceObject->ConfigurationEndpointCount == 0);
    
    // Copy a private pointer to the client's Device Object
    //  - This private pointer is for INTERNAL USE ONLY by the device and API software.
    PrivDeviceObject = DeviceObject;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -