网络驱动开发

源代码在线查看: request.c

软件大小: 2967 K
上传用户: bi_yangfeng
关键词: 网络 驱动开发
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*
				 ************************************************************************
				 *
				 *	REQUEST.c
				 *
				 *
				 *		(C) Copyright 1996 National Semiconductor Corp.
				 *		(C) Copyright 1996 Microsoft Corp.
				 *
				 *
				 *		(ep)
				 *
				 *************************************************************************
				 */
				
				#include "nsc.h"
				#include "request.tmh"
				#include "newdong.h"
				
				
				
				const  NDIS_OID NSCGlobalSupportedOids[] = {
					OID_GEN_SUPPORTED_LIST,
				    OID_GEN_HARDWARE_STATUS,
					OID_GEN_MEDIA_SUPPORTED,
					OID_GEN_MEDIA_IN_USE,
					OID_GEN_MAXIMUM_LOOKAHEAD,
					OID_GEN_MAXIMUM_FRAME_SIZE,
				    OID_GEN_MAXIMUM_SEND_PACKETS,
					OID_GEN_MAXIMUM_TOTAL_SIZE,
					OID_GEN_MAC_OPTIONS,
					OID_GEN_PROTOCOL_OPTIONS,
					OID_GEN_LINK_SPEED,
					OID_GEN_TRANSMIT_BUFFER_SPACE,
					OID_GEN_RECEIVE_BUFFER_SPACE,
					OID_GEN_TRANSMIT_BLOCK_SIZE,
					OID_GEN_RECEIVE_BLOCK_SIZE,
					OID_GEN_VENDOR_DESCRIPTION,
				    OID_GEN_VENDOR_DRIVER_VERSION,
					OID_GEN_DRIVER_VERSION,
					OID_GEN_CURRENT_PACKET_FILTER,
					OID_GEN_CURRENT_LOOKAHEAD,
				    OID_GEN_MEDIA_CONNECT_STATUS,
					OID_IRDA_RECEIVING,
					OID_IRDA_SUPPORTED_SPEEDS,
					OID_IRDA_LINK_SPEED,
					OID_IRDA_MEDIA_BUSY,
					OID_IRDA_TURNAROUND_TIME,
					OID_IRDA_MAX_RECEIVE_WINDOW_SIZE,
					OID_IRDA_EXTRA_RCV_BOFS,
				    OID_IRDA_MAX_SEND_WINDOW_SIZE
				    };
				
				
				//////////////////////////////////////////////////////////////////////////
				//									//
				//  Function:	    MiniportQueryInformation				//
				//									//
				//  Description:							//
				//  Query the capabilities and status of the miniport driver.		//
				//									//
				//////////////////////////////////////////////////////////////////////////
				
				NDIS_STATUS MiniportQueryInformation (
				    IN NDIS_HANDLE MiniportAdapterContext,
				    IN NDIS_OID Oid,
				    IN PVOID InformationBuffer,
				    IN ULONG InformationBufferLength,
				    OUT PULONG BytesWritten,
				    OUT PULONG BytesNeeded)
				{
				    NDIS_STATUS result = NDIS_STATUS_SUCCESS;
				    IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
				    INT i, speeds, speedSupported;
				    UINT *infoPtr;
				
				    NDIS_MEDIUM Medium = NdisMediumIrda;
				    ULONG GenericUlong;
				    PVOID SourceBuffer = (PVOID) (&GenericUlong);
				    ULONG SourceLength = sizeof(ULONG);
				
				
				    ULONG BaudRateTable[NUM_BAUDRATES];
				
				
				    switch (Oid){
				
					case OID_GEN_SUPPORTED_LIST:
					    SourceBuffer = (PVOID) (NSCGlobalSupportedOids);
					    SourceLength = sizeof(NSCGlobalSupportedOids);
					    break;
				
				    case OID_GEN_HARDWARE_STATUS:
				        GenericUlong = thisDev->hardwareStatus;
				        break;
				
					case OID_GEN_MEDIA_SUPPORTED:
					case OID_GEN_MEDIA_IN_USE:
					    SourceBuffer = (PVOID) (&Medium);
					    SourceLength = sizeof(NDIS_MEDIUM);
					    break;
				
					case OID_IRDA_RECEIVING:
					    DBGOUT(("MiniportQueryInformation(OID_IRDA_RECEIVING)"));
					    GenericUlong = (ULONG)thisDev->nowReceiving;
					    break;
							
					case OID_IRDA_SUPPORTED_SPEEDS:
					    DBGOUT(("MiniportQueryInformation(OID_IRDA_SUPPORTED_SPEEDS)"));
				
					    speeds = thisDev->portInfo.hwCaps.supportedSpeedsMask &
				                            thisDev->AllowedSpeedMask &
											ALL_IRDA_SPEEDS;
				
				        for (i = 0, infoPtr = (PUINT)BaudRateTable, SourceLength=0;
				             (i < NUM_BAUDRATES) && speeds;
				             i++){
				
				            if (supportedBaudRateTable[i].ndisCode & speeds){
				                *infoPtr++ = supportedBaudRateTable[i].bitsPerSec;
				                SourceLength += sizeof(UINT);
				                speeds &= ~supportedBaudRateTable[i].ndisCode;
				                DBGOUT((" - supporting speed %d bps", supportedBaudRateTable[i].bitsPerSec));
				            }
				        }
				
					    SourceBuffer = (PVOID) BaudRateTable;
					    break;
				
					case OID_GEN_LINK_SPEED:
					    // The maximum speed of NIC is 4Mbps
					    GenericUlong = 40000;  // 100bps increments
					    break;
				
					case OID_IRDA_LINK_SPEED:
					    DBGOUT(("MiniportQueryInformation(OID_IRDA_LINK_SPEED)"));
					    if (thisDev->linkSpeedInfo){
				    		GenericUlong = (ULONG)thisDev->linkSpeedInfo->bitsPerSec;
					    }
					    else {
					    	GenericUlong = DEFAULT_BAUD_RATE;
					    }
					    break;
				
					case OID_IRDA_MEDIA_BUSY:
					    DBGOUT(("MiniportQueryInformation(OID_IRDA_MEDIA_BUSY)"));
					    GenericUlong = (UINT)thisDev->mediaBusy;
					    break;
				
					case OID_GEN_CURRENT_LOOKAHEAD:
					case OID_GEN_MAXIMUM_LOOKAHEAD:
					    DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)"));
					    GenericUlong = MAX_I_DATA_SIZE;
					    break;
				
				    case OID_GEN_MAXIMUM_TOTAL_SIZE:
				    case OID_GEN_TRANSMIT_BLOCK_SIZE:
				    case OID_GEN_RECEIVE_BLOCK_SIZE:
					case OID_GEN_MAXIMUM_FRAME_SIZE:
					    DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)"));
				
				        // Normally there's some difference in these values, based on the
				        // MAC header, but IrDA doesn't have one.
				
					    GenericUlong = MAX_I_DATA_SIZE;
					    break;
				
					case OID_GEN_RECEIVE_BUFFER_SPACE:
					case OID_GEN_TRANSMIT_BUFFER_SPACE:
					    GenericUlong = (ULONG) (MAX_IRDA_DATA_SIZE * 8);
					    break;
				
					case OID_GEN_MAC_OPTIONS:
					    DBGOUT(("MiniportQueryInformation(OID_GEN_MAC_OPTIONS)"));
					    GenericUlong = 0;
					    break;
				
					case OID_GEN_MAXIMUM_SEND_PACKETS:
					    DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_SEND_PACKETS)"));
					    GenericUlong = 16;
					    break;
				
					case OID_IRDA_TURNAROUND_TIME:
					    // Indicate the amount of time that the transceiver needs
					    // to recuperate after a send.
					    DBGOUT(("MiniportQueryInformation(OID_IRDA_TURNAROUND_TIME)"));
					    GenericUlong =
						      (ULONG)thisDev->portInfo.hwCaps.turnAroundTime_usec;
					    break;
				
					case OID_IRDA_EXTRA_RCV_BOFS:
					    // Pass back the number of _extra_ BOFs to be prepended
					    // to packets sent to this unit at 115.2 baud, the
					    // maximum Slow IR speed.  This will be scaled for other
					    // speed according to the table in the
					    // Infrared Extensions to NDIS' spec.
					    DBGOUT(("MiniportQueryInformation(OID_IRDA_EXTRA_RCV_BOFS)"));
					    GenericUlong = (ULONG)thisDev->portInfo.hwCaps.extraBOFsRequired;
					    break;
				
					case OID_GEN_CURRENT_PACKET_FILTER:
					    DBGOUT(("MiniportQueryInformation(OID_GEN_CURRENT_PACKET_FILTER)"));
					    GenericUlong = NDIS_PACKET_TYPE_PROMISCUOUS;
					    break;
				
					case OID_IRDA_MAX_RECEIVE_WINDOW_SIZE:
					    DBGOUT(("MiniportQueryInformation(OID_IRDA_MAX_RECEIVE_WINDOW_SIZE)"));
					    GenericUlong = MAX_RX_PACKETS;
					    //GenericUlong = 1;
					    break;
				
					case OID_GEN_VENDOR_DESCRIPTION:
					    SourceBuffer = (PVOID)"NSC Infrared Port";
					    SourceLength = 18;
					    break;
				
				    case OID_GEN_VENDOR_DRIVER_VERSION:
				        // This value is used to know whether to update driver.
				        GenericUlong = (NSC_MAJOR_VERSION 				                       (NSC_MINOR_VERSION 				                       NSC_LETTER_VERSION;
				        break;
				
					case OID_GEN_DRIVER_VERSION:
				        GenericUlong = (NDIS_MAJOR_VERSION 				        SourceLength = 2;
					    break;
				
				    case OID_IRDA_MAX_SEND_WINDOW_SIZE:
				        GenericUlong = 7;
				        break;
				
				    case OID_GEN_MEDIA_CONNECT_STATUS:
				        GenericUlong = (ULONG) NdisMediaStateConnected;
				        break;
				
				
					default:
					    DBGERR(("MiniportQueryInformation(%d=0x%x), unsupported OID", Oid, Oid));
					    result = NDIS_STATUS_NOT_SUPPORTED;
					    break;
				    }
				
				    if (result == NDIS_STATUS_SUCCESS) {
				
				     	if (SourceLength > InformationBufferLength) {
				
				    	    *BytesNeeded = SourceLength;
				    	    result = NDIS_STATUS_INVALID_LENGTH;
				
				    	} else {
				
				    	    *BytesNeeded = 0;
				    	    *BytesWritten = SourceLength;
				    	    NdisMoveMemory(InformationBuffer, SourceBuffer, SourceLength);
				            DBGOUT(("MiniportQueryInformation succeeded (info 				    	}
				    }
				
				
				    return result;
				
				}
				
				
				//////////////////////////////////////////////////////////////////////////
				//									//
				//  Function:	    MiniportSetInformation				//
				//									//
				//  Description:							//
				//  Allow other layers of the network software (e.g., a transport	//
				//  driver) to control the miniport driver by changing information that //
				//  the miniport driver maintains in its OIDs, such as the packet	//
				//  or multicast addresses.						//
				//									//
				//////////////////////////////////////////////////////////////////////////
				
				NDIS_STATUS MiniportSetInformation (
				    IN NDIS_HANDLE MiniportAdapterContext,
				    IN NDIS_OID Oid,
				    IN PVOID InformationBuffer,
				    IN ULONG InformationBufferLength,
				    OUT PULONG BytesRead,
				    OUT PULONG BytesNeeded)
				{
				    NDIS_STATUS result = NDIS_STATUS_SUCCESS;
				    IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
				    UINT i,speedSupported;
				    const baudRateInfo *    CurrentLinkSpeed;
				
				    if (InformationBufferLength >= sizeof(UINT)){
				
					UINT info = *(UINT *)InformationBuffer;
					*BytesRead = sizeof(UINT);
					*BytesNeeded = 0;
				
					switch (Oid){
					    case OID_IRDA_LINK_SPEED:
						DBGOUT(("MiniportSetInformation(OID_IRDA_LINK_SPEED, %xh)",
							 info));
						result = NDIS_STATUS_INVALID_DATA;
				
				        CurrentLinkSpeed=thisDev->linkSpeedInfo;
				
						// Find the appropriate speed  and  set it
						speedSupported = NUM_BAUDRATES;
						for (i = 0; i < speedSupported; i++){
						    if (supportedBaudRateTable[i].bitsPerSec == info){
							thisDev->linkSpeedInfo = &supportedBaudRateTable[i];
							result = NDIS_STATUS_SUCCESS;
							break;
						    }
						}
						if (result == NDIS_STATUS_SUCCESS){
				
				            if (CurrentLinkSpeed != thisDev->linkSpeedInfo) {
				                //
				                //  different from the current
				                //
				                BOOLEAN    DoItNow=TRUE;
				
				                NdisAcquireSpinLock(&thisDev->QueueLock);
				
				                if (!IsListEmpty(&thisDev->SendQueue)){
				                    //
				                    //  packets queued, change after this one
				                    //
				                    thisDev->lastPacketAtOldSpeed = CONTAINING_RECORD(thisDev->SendQueue.Blink,
				                                                                          NDIS_PACKET,
				                                                                          MiniportReserved);
				            		DBGOUT(("delaying set-speed because send pkts queued"));
				                    DoItNow=FALSE;
				
				
				                } else {
				                    //
				                    //  no packets in the queue
				                    //
				                    if (thisDev->CurrentPacket != NULL) {
				                        //
				                        //  the current packet is the only one
				                        //
				                        thisDev->lastPacketAtOldSpeed=thisDev->CurrentPacket;
				                        thisDev->setSpeedAfterCurrentSendPacket = TRUE;
				
				                		DBGOUT(("delaying set-speed because send pkts queued"));
				                        DoItNow=FALSE;
				
				                    }
				
				                }
				
				                if (DoItNow) {
				
				    		        if (!SetSpeed(thisDev)){
				        	    		result = NDIS_STATUS_FAILURE;
				    		        }
				
				                    thisDev->TransmitIsIdle=FALSE;
				                }
				
				                NdisReleaseSpinLock(&thisDev->QueueLock);
				
				                if (DoItNow) {
				
				                    ProcessSendQueue(thisDev);
				                }
				            }
						}
						else {
						    *BytesRead = 0;
						    *BytesNeeded = 0;
						}
						break;
				
					    case OID_IRDA_MEDIA_BUSY:
						DBGOUT(("MiniportSetInformation(OID_IRDA_MEDIA_BUSY, %xh)",
							 info));
				
						//  The protocol can use this OID to reset the busy field
						//  in order to check it later for intervening activity.
						//
						thisDev->mediaBusy = (BOOLEAN)info;
				        InterlockedExchange(&thisDev->RxInterrupts,0);
						result = NDIS_STATUS_SUCCESS;
						break;
				
					    case OID_GEN_CURRENT_PACKET_FILTER:
						DBGOUT(
						 ("MiniportSetInformation(OID_GEN_CURRENT_PACKET_FILTER, %xh)",
						  info));
						result = NDIS_STATUS_SUCCESS;
						break;
				
				
				        case OID_GEN_CURRENT_LOOKAHEAD:
				        result = (info				        break;
				
					    //	 We don't support these
					    //
					    case OID_IRDA_RATE_SNIFF:
					    case OID_IRDA_UNICAST_LIST:
				
					     // These are query-only parameters.
					     //
					    case OID_IRDA_SUPPORTED_SPEEDS:
					    case OID_IRDA_MAX_UNICAST_LIST_SIZE:
					    case OID_IRDA_TURNAROUND_TIME:
				
					    default:
						DBGERR(("MiniportSetInformation(OID=%d=0x%x, value=%xh) - unsupported OID", Oid, Oid, info));
						*BytesRead = 0;
						*BytesNeeded = 0;
						result = NDIS_STATUS_NOT_SUPPORTED;
						break;
					}
				    }
				    else {
					*BytesRead = 0;
					*BytesNeeded = sizeof(UINT);
					result = NDIS_STATUS_INVALID_LENGTH;
				    }
				
				    DBGOUT(("MiniportSetInformation succeeded"));
				    return result;
				}
				
							

相关资源