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

📄 nsc.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:

    if (PacketToComplete != NULL) {

        if (thisDev->lastPacketAtOldSpeed == PacketToComplete) {

            thisDev->lastPacketAtOldSpeed=NULL;

            SpeedChange=TRUE;

            DBGERR(("defered set speed\n"));

            SetSpeed(thisDev);
        }
    }

    NdisDprReleaseSpinLock(&thisDev->QueueLock);

    if (PacketToComplete != NULL) {

        ProcessSendQueue(thisDev);
        NdisMSendComplete(thisDev->ndisAdapterHandle, PacketToComplete, PacketStatus);

    }
    //
    //  send any received packets to irda.sys
    //
    DeliverFullBuffers(thisDev);

    SyncSetInterruptMask(thisDev, TRUE);

    LOG("<== MiniportHandleInterrupt");
    DBGOUT(("<== MiniportHandleInterrupt"));

}

/*
 *************************************************************************
 *  GetPnPResources
 *************************************************************************
 *
 *
 */
BOOLEAN GetPnPResources(IrDevice *thisDev, NDIS_HANDLE WrapperConfigurationContext)
{
	NDIS_STATUS stat;
    BOOLEAN result = FALSE;

    /*
     *  We should only need 2 adapter resources (2 IO and 1 interrupt),
     *  but I've seen devices get extra resources.
     *  So give the NdisMQueryAdapterResources call room for 10 resources.
     */
    #define RESOURCE_LIST_BUF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))

    UCHAR buf[RESOURCE_LIST_BUF_SIZE];
    PNDIS_RESOURCE_LIST resList = (PNDIS_RESOURCE_LIST)buf;
    UINT bufSize = RESOURCE_LIST_BUF_SIZE;

    NdisMQueryAdapterResources(&stat, WrapperConfigurationContext, resList, &bufSize);
    if (stat == NDIS_STATUS_SUCCESS){
        PCM_PARTIAL_RESOURCE_DESCRIPTOR resDesc;
        BOOLEAN     haveIRQ = FALSE,
                    haveIOAddr = FALSE,
                    haveDma = FALSE;
        UINT i;

        for (resDesc = resList->PartialDescriptors, i = 0;
             i < resList->Count;
             resDesc++, i++){

            switch (resDesc->Type){
                case CmResourceTypePort:
                    if (thisDev->CardType==PC87108 &&
                        (resDesc->u.Port.Start.LowPart==0xEA ||
                         resDesc->u.Port.Start.LowPart==0x398 ||
                         resDesc->u.Port.Start.LowPart==0x150))
                    {
                        // This is an eval board and this is the config io base address

                        thisDev->portInfo.ConfigIoBasePhysAddr = resDesc->u.Port.Start.LowPart;
                    }
                    else if (thisDev->CardType==PC87308 &&
                             (resDesc->u.Port.Start.LowPart==0x2E ||
                              resDesc->u.Port.Start.LowPart==0x15C))
                    {
                        // This is an eval board and this is the config io base address

                        thisDev->portInfo.ConfigIoBasePhysAddr = resDesc->u.Port.Start.LowPart;
                    }
                    else if (thisDev->CardType==PC87338 &&
                             (resDesc->u.Port.Start.LowPart==0x2E ||
                              resDesc->u.Port.Start.LowPart==0x398 ||
                              resDesc->u.Port.Start.LowPart==0x15C))
                    {
                        // This is an eval board and this is the config io base address

                        thisDev->portInfo.ConfigIoBasePhysAddr = resDesc->u.Port.Start.LowPart;
                    }
                    else
                    {
                        if (haveIOAddr){
                            /*
                             *  The *PNP0510 chip on the IBM ThinkPad 760EL
                             *  gets an extra IO range assigned to it.
                             *  So only pick up the first IO port range;
                             *  ignore this subsequent one.
                             */
                            DBGERR(("Ignoring extra PnP IO base %xh because already using %xh.",
                                      (UINT)resDesc->u.Port.Start.LowPart,
                                      (UINT)thisDev->portInfo.ioBasePhys));
                        }
                        else {
                            thisDev->portInfo.ioBasePhys = resDesc->u.Port.Start.LowPart;
                            haveIOAddr = TRUE;
                            DBGOUT(("Got UART IO addr: %xh.", thisDev->portInfo.ioBasePhys));
                        }
                    }
                    break;

                case CmResourceTypeInterrupt:
                    if (haveIRQ){
                        DBGERR(("Ignoring second PnP IRQ %xh because already using %xh.",
                                (UINT)resDesc->u.Interrupt.Level, thisDev->portInfo.irq));
                    }
                    else {
	                    thisDev->portInfo.irq = resDesc->u.Interrupt.Level;
                        haveIRQ = TRUE;
                        DBGOUT(("Got PnP IRQ: %d.", thisDev->portInfo.irq));
                    }
                    break;

                case CmResourceTypeDma:
                    if (haveDma){
                        DBGERR(("Ignoring second DMA address %d because already using %d.",
                                (UINT)resDesc->u.Dma.Channel, (UINT)thisDev->portInfo.DMAChannel));
                    }
                    else {
                        ASSERT(!(resDesc->u.Dma.Channel&0xffffff00));
                        thisDev->portInfo.DMAChannel = (UCHAR)resDesc->u.Dma.Channel;
                        haveDma = TRUE;
                        DBGOUT(("Got DMA channel: %d.", thisDev->portInfo.DMAChannel));
                    }
                    break;
            }
        }

        result = (haveIOAddr && haveIRQ && haveDma);
    }

    return result;
}


/*
 *************************************************************************
 *  Configure
 *************************************************************************
 *
 *  Read configurable parameters out of the system registry.
 *
 */
BOOLEAN Configure(
                 IrDevice *thisDev,
                 NDIS_HANDLE WrapperConfigurationContext
                 )
{
    //
    // Status of Ndis calls.
    //
    NDIS_STATUS Status;

    //
    // The handle for reading from the registry.
    //
    NDIS_HANDLE ConfigHandle;


    //
    // The value read from the registry.
    //
    PNDIS_CONFIGURATION_PARAMETER ReturnedValue;

    //
    // String names of all the parameters that will be read.
    //
    NDIS_STRING CardTypeStr         = CARDTYPE;
    NDIS_STRING Dongle_A_TypeStr	= DONGLE_A_TYPE;
    NDIS_STRING Dongle_B_TypeStr	= DONGLE_B_TYPE;
    NDIS_STRING MaxConnectRateStr   = MAXCONNECTRATE;


    UINT Valid_DongleTypes[] = VALID_DONGLETYPES;

    DBGOUT(("Configure(0x%x)", thisDev));
    NdisOpenConfiguration(&Status, &ConfigHandle, WrapperConfigurationContext);

    if (Status != NDIS_STATUS_SUCCESS){
        DBGERR(("NdisOpenConfiguration failed in Configure()"));
        return FALSE;
    }
    //
    // Read Ir108 Configuration I/O base Address
    //
    //DbgBreakPoint();
    NdisReadConfiguration(
                         &Status,
                         &ReturnedValue,
                         ConfigHandle,
                         &CardTypeStr,
                         NdisParameterHexInteger
                         );
    if (Status != NDIS_STATUS_SUCCESS){
        DBGERR(("NdisReadConfiguration failed in accessing CardType."));
        NdisCloseConfiguration(ConfigHandle);
        return FALSE;
    }
    thisDev->CardType = (UCHAR)ReturnedValue->ParameterData.IntegerData;


    if (!GetPnPResources(thisDev, WrapperConfigurationContext)){

        DBGERR(("GetPnPResources failed\n"));

        NdisCloseConfiguration(ConfigHandle);
        return FALSE;
    }





    // Read Dongle type constant Number.
    //
    NdisReadConfiguration(&Status,
			  &ReturnedValue,
			  ConfigHandle,
			  &Dongle_A_TypeStr,
			  NdisParameterInteger);

    if (Status != NDIS_STATUS_SUCCESS){
    	DBGERR(("NdisReadConfiguration failed in accessing DongleType (0x%x).",Status));
    }
    thisDev->DonglesSupported = 1;
    thisDev->DongleTypes[0] =
	(UCHAR)Valid_DongleTypes[(UCHAR)ReturnedValue->ParameterData.IntegerData];

    // Read Dongle type constant Number.
    //
    NdisReadConfiguration(&Status,
			  &ReturnedValue,
			  ConfigHandle,
			  &Dongle_B_TypeStr,
			  NdisParameterInteger);

    if (Status != NDIS_STATUS_SUCCESS){
    	 DBGERR(("NdisReadConfiguration failed in accessing DongleType (0x%x).",
		  Status));
    }
    thisDev->DongleTypes[1] = (UCHAR)Valid_DongleTypes[(UCHAR)ReturnedValue->ParameterData.IntegerData];
    thisDev->DonglesSupported++;

    // Read MaxConnectRate.
    //
    NdisReadConfiguration(&Status,
			  &ReturnedValue,
			  ConfigHandle,
			  &MaxConnectRateStr,
			  NdisParameterInteger);

    if (Status != NDIS_STATUS_SUCCESS){
    	DBGERR(("NdisReadConfiguration failed in accessing MaxConnectRate (0x%x).",Status));
        thisDev->AllowedSpeedMask = ALL_IRDA_SPEEDS;
    }
    else
    {
        thisDev->AllowedSpeedMask = 0;

        switch (ReturnedValue->ParameterData.IntegerData)
        {
            default:
            case 4000000:
                thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_4M;
            case 1152000:
                thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_1152K;
            case 115200:
                thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_115200;
            case 57600:
                thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_57600;
            case 38400:
                thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_38400;
            case 19200:
                thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_19200;
            case 9600:
                thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_9600 | NDIS_IRDA_SPEED_2400;
                break;
        }

    }


    NdisCloseConfiguration(ConfigHandle);


    DBGOUT(("Configure done: ConfigIO=0x%x UartIO=0x%x irq=%d DMA=%d",
            thisDev->portInfo.ConfigIoBaseAddr,thisDev->portInfo.ioBase,
            thisDev->portInfo.irq,thisDev->portInfo.DMAChannel));

    return TRUE;
}


/*
 *************************************************************************
 *  MiniportInitialize
 *************************************************************************
 *
 *
 *  Initializes the network interface card.
 *
 *
 *
 */
NDIS_STATUS MiniportInitialize  (   PNDIS_STATUS OpenErrorStatus,
                                    PUINT SelectedMediumIndex,
                                    PNDIS_MEDIUM MediumArray,
                                    UINT MediumArraySize,
                                    NDIS_HANDLE NdisAdapterHandle,
                                    NDIS_HANDLE WrapperConfigurationContext
                                )
{
    UINT mediumIndex;
    IrDevice *thisDev = NULL;
    NDIS_STATUS retStat, result = NDIS_STATUS_SUCCESS;

    DBGOUT(("MiniportInitialize()"));

    /*
     *  Search the passed-in array of supported media for the IrDA medium.
     */
    for (mediumIndex = 0; mediumIndex < MediumArraySize; mediumIndex++){
        if (MediumArray[mediumIndex] == NdisMediumIrda){
            break;
        }
    }
    if (mediumIndex < MediumArraySize){
        *SelectedMediumIndex = mediumIndex;
    }
    else {
        /*
         *  Didn't see the IrDA medium
         */
        DBGERR(("Didn't see the IRDA medium in MiniportInitialize"));
        result = NDIS_STATUS_UNSUPPORTED_MEDIA;
        return result;
    }

    /*
     *  Allocate a new device object to represent this connection.
     */
    thisDev = NewDevice();
    if (!thisDev){
        return NDIS_STATUS_NOT_ACCEPTED;
    }

    thisDev->hardwareStatus = NdisHardwareStatusInitializing;
    /*
     *  Allocate resources for this connection.
     */
    if (!OpenDevice(thisDev)){
        DBGERR(("OpenDevice failed"));
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }

    /*
     *  Record the NDIS wrapper's handle for this adapter, which we use
     *  when we call up to the wrapper.
     *  (This miniport's adapter handle is just thisDev, the pointer to the device object.).
     */
    DBGOUT(("NDIS handle: %xh <-> IRMINI handle: %xh", NdisAdapterHandle, thisDev));
    thisDev->ndisAdapterHandle = NdisAdapterHandle;

    /*
     *  Read the system registry to get parameters like COM port number, etc.
     */
    if (!Configure(thisDev, WrapperConfigurationContext)){
        DBGERR(("Configure failed"));
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }

    /*
     *  This call will associate our adapter handle with the wrapper's
     *  adapter handle.  The wrapper will then always use our handle
     *  when calling us.  We use a pointer to the device object as the context.
     */
    NdisMSetAttributesEx(NdisAdapterHandle,
                         (NDIS_HANDLE)thisDev,
                         0,
                         NDIS_ATTRIBUTE_DESERIALIZE,
                         NdisInterfaceInternal);


    /*
     *  Tell NDIS about the range of IO space that we'll be using.
     *  Puma uses Chip-select mode, so the ConfigIOBase address actually
     *  follows the regular io, so get both in one shot.
     */
    retStat = NdisMRegisterIoPortRange( (PVOID)&thisDev->portInfo.ioBase,
                                        NdisAdapterHandle,
                                        thisDev->portInfo.ioBasePhys,
                                        ((thisDev->CardType==PUMA108)?16:8));

    if (retStat != NDIS_STATUS_SUCCESS){
        DBGERR(("NdisMRegisterIoPortRange failed"));
        thisDev->portInfo.ioBase=NULL;
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }

    if (thisDev->portInfo.ConfigIoBasePhysAddr)
    {
        /*
         *  Eval boards require a second IO range.
         *
         */
        retStat = NdisMRegisterIoPortRange( (PVOID)&thisDev->portInfo.ConfigIoBaseAddr,
                                            NdisAdapterHandle,
                                            thisDev->portInfo.ConfigIoBasePhysAddr,
                                            2);

⌨️ 快捷键说明

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