📄 driver.cpp
字号:
/******************************************************************************** * * $Id: driver.cpp,v 1.1.1.1 2004/12/08 08:38:43 hychu Exp $ * * File: Main.cpp * * Copyright (c) 2000-2002 Davicom Inc. All rights reserved. * ********************************************************************************/#include "common.h"#include "driver.h"#include "device.h"#if defined(PERF_TEST)#include <winbase.h>ULONG fnCallback( PVOID pVoid){ NIC_DRIVER_OBJECT * pobj; pobj = (NIC_DRIVER_OBJECT*)pVoid; // Set to highest priority // BOOL ret; // ret = CeSetThreadPriority(GetCurrentThread(), 0); // wait 2 seconds... NdisMSleep(2*1000*1000); // one forever loop to trigger device interrupt handler // period: 1 mS for(;;) { pobj->m_pLower->DeviceInterruptEventHandler(0); NdisMSleep(1000); } return 0;} void SpawnPerfThread( PVOID pVoid){ HANDLE h; h = CreateThread( 0,0, fnCallback, pVoid, 0,0); }#endif#if defined(DM9601)/* * About the wrapper handle and the intermediate handle... * The wrapper handle, obtained from NDIS, is the original of the driver. * Without this wrapper handle, we cannot do anything. * Unfortunately, we cannot get sufficient argument from USB loader to * ask one wrapper handle. * Current alternative is, to put this driver into NDIS registry as * it is a 'static' driver, thus, we can get the wrapper handle. * This wrapper handle should not be cleared even the USB device is plug'd * out. Or we cannot restart the NDIS function anymore. * */NDIS_HANDLE ghNdisIntermediateHandle=NULL;UNICODE_STRING guniRegistryPath;int gnInstance=0;USB_HANDLE ghDevice;LPCUSB_FUNCS glpUsbFuncs;LPCUSB_DEVICE glpUsbDevice;LPCUSB_INTERFACE glpInterface;class USB_NIC_DRIVER : public NIC_DRIVER_OBJECT{public: USB_NIC_DRIVER::USB_NIC_DRIVER( NDIS_HANDLE MiniportHandle, NDIS_HANDLE WrapperConfigHandle, USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs, LPCUSB_DEVICE lpUsbDevice, LPCUSB_INTERFACE lpInterface) : NIC_DRIVER_OBJECT(MiniportHandle,WrapperConfigHandle) { m_usbHandle = hDevice; m_usbpFuncs = lpUsbFuncs; m_usbpDevice = lpUsbDevice; m_usbpInterface = lpInterface; } USB_NIC_DRIVER::~USB_NIC_DRIVER(void) { PUTS(("usb deconstructor.\n")); } virtual void EDriverInitialize( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediaIndex, IN PNDIS_MEDIUM MediaArray, IN UINT MediaArraySize); virtual void DriverOnUsbNotify(U32); public: USB_HANDLE m_usbHandle; LPCUSB_DEVICE m_usbpDevice; LPCUSB_FUNCS m_usbpFuncs; LPCUSB_INTERFACE m_usbpInterface;};void USB_NIC_DRIVER::EDriverInitialize( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediaIndex, IN PNDIS_MEDIUM MediaArray, IN UINT MediaArraySize){ m_pLower = DeviceEntry(this,NULL); m_pLower->EDeviceSetUsbParameters( m_usbHandle,m_usbpFuncs,m_usbpInterface); NIC_DRIVER_OBJECT::EDriverInitialize( OpenErrorStatus, SelectedMediaIndex, MediaArray, MediaArraySize); m_pLower->DeviceInitializeTimer();}void USB_NIC_DRIVER::DriverOnUsbNotify( U32 uCode){ NdisIMDeInitializeDeviceInstance(m_NdisHandle);}extern "C" BOOL WINAPI USBNotificationRoutine( LPVOID lpNotifyParam, DWORD dwCode, LPDWORD pdw1, LPDWORD pdw2, LPDWORD pdw3, LPDWORD pdw4){ ((USB_NIC_DRIVER*)lpNotifyParam)->DriverOnUsbNotify(dwCode); gnInstance--; return TRUE;}#endif /**************************************************************************************** * * Driver-wide global data declaration * ****************************************************************************************/NDIS_OID gszNICSupportedOid[] = { OID_GEN_SUPPORTED_LIST, OID_GEN_HARDWARE_STATUS, OID_GEN_MEDIA_SUPPORTED, OID_GEN_MEDIA_IN_USE, OID_GEN_MEDIA_CONNECT_STATUS, OID_GEN_MAXIMUM_SEND_PACKETS, OID_GEN_VENDOR_DRIVER_VERSION, OID_GEN_MAXIMUM_LOOKAHEAD, OID_GEN_MAXIMUM_FRAME_SIZE, 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_ID, OID_GEN_VENDOR_DESCRIPTION, OID_GEN_CURRENT_PACKET_FILTER, OID_GEN_CURRENT_LOOKAHEAD, OID_GEN_DRIVER_VERSION, OID_GEN_XMIT_OK, OID_GEN_RCV_OK, OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR, OID_GEN_RCV_NO_BUFFER, OID_GEN_RCV_CRC_ERROR, OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS, OID_802_3_MULTICAST_LIST, OID_802_3_MAXIMUM_LIST_SIZE, OID_802_3_RCV_ERROR_ALIGNMENT, OID_802_3_XMIT_ONE_COLLISION, OID_802_3_XMIT_MORE_COLLISIONS, OID_802_3_XMIT_DEFERRED, OID_802_3_XMIT_MAX_COLLISIONS, OID_802_3_XMIT_UNDERRUN, OID_802_3_XMIT_HEARTBEAT_FAILURE, OID_802_3_XMIT_TIMES_CRS_LOST, OID_802_3_XMIT_LATE_COLLISIONS, };/******************************************************************************************** * * NIC_DRIVER_OBJECT Implementation * ********************************************************************************************/void NIC_DRIVER_OBJECT::DriverStart(void){#if defined(PERF_TEST) RETAILMSG(TRUE,( TEXT("DriverStart, <tx=%d(%d)>\n") , m_pLower->m_szConfigures[CID_TXBUFFER_NUMBER], m_TQueue.Size() ));#endif m_pLower->DeviceStart();#if !defined(PERF_TEST) return;#else // of PERF_TEST#error no perf mode PCQUEUE_GEN_HEADER pobj; PU8 pcurr; PU16 pshort;#if defined(PERF_TX_MODE) int loop; for(loop=0;(pobj = m_TQueue.Dequeue());loop++) { pcurr = (PU8)CQueueGetUserPointer(pobj); memset((void*)pcurr,0xff,pobj->nLength=ETH_MAX_FRAME_SIZE); pshort=(PU16)pcurr; *(pshort+0) = MAKE_WORD(0x91,0x02); *(pshort+1) = MAKE_WORD(0xCE,0xCE); *(pshort+2) = MAKE_WORD(0xCE,0xCE); *(long*)(pshort+6) = loop; m_pLower->DeviceSend(pobj); } // of sending loop RETAILMSG(TRUE,(TEXT("TX_MODE:end of submission"))); #endif // of PERF_TX_MODE SpawnPerfThread((PVOID)this);#endif // of PERF_TEST}void NIC_DRIVER_OBJECT::EDriverInitialize( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediaIndex, IN PNDIS_MEDIUM MediaArray, IN UINT MediaArraySize){ m_uRecentInterruptStatus = 0; if(!m_pLower) m_pLower = DeviceEntry(this,NULL); if(!m_pLower) THROW((ERR_STRING("Error in creating device"))); UINT i; NDIS_STATUS status; NDIS_HANDLE hconfig; // Determinate media type for(i=0; i<MediaArraySize; i++) if(MediaArray[i] == NdisMedium802_3) break; if (i == MediaArraySize) THROW((ERR_STRING("Unsupported media"),NDIS_STATUS_UNSUPPORTED_MEDIA)); *SelectedMediaIndex = i; // Read registry configurations NdisOpenConfiguration( &status, &hconfig, m_NdisWrapper); if(status != NDIS_STATUS_SUCCESS) THROW((ERR_STRING("Error in opening configuration"),status)); C_Exception *pexp; TRY { m_pLower->DeviceSetDefaultSettings(); m_pLower->DeviceSetEepromFormat(); m_pLower->DeviceRetriveConfigurations(hconfig); m_pLower->EDeviceValidateConfigurations(); FI; } CATCH(pexp) { pexp->PrintErrorMessage(); CLEAN(pexp); NdisCloseConfiguration(hconfig); THROW((ERR_STRING("*** Error in retriving configurations.\n"))); } NdisCloseConfiguration(hconfig); m_pLower->DeviceRegisterAdapter(); /* init tx buffers */ U32 m,uaddr; if(!(uaddr = (U32)malloc(sizeof(DATA_BLOCK)* (m=m_pLower->m_szConfigures[CID_TXBUFFER_NUMBER]*2)))) THROW((ERR_STRING("Insufficient memory"))); for(;m--;uaddr+=sizeof(DATA_BLOCK)) m_TQueue.Enqueue((PCQUEUE_GEN_HEADER)uaddr); TRY { m_pLower->EDeviceRegisterIoSpace(); m_pLower->EDeviceLoadEeprom(); m_pLower->EDeviceInitialize(m_pLower->m_nResetCounts=0); m_pLower->EDeviceRegisterInterrupt(); FI; } CATCH(pexp) { pexp->PrintErrorMessage(); CLEAN(pexp); THROW((ERR_STRING("Device error"))); } m_pLower->DeviceOnSetupFilter(0);}PVOID NIC_DRIVER_OBJECT::DriverBindAddress( U32 uPhysicalAddress, U32 uLength){ void *pvoid; // allocate memory for the work space if(!(pvoid = VirtualAlloc( NULL, uLength, MEM_RESERVE, PAGE_NOACCESS))) return NULL; /* binding this virtual addr to physical location */ VirtualCopy( pvoid, (PVOID)uPhysicalAddress, uLength, PAGE_READWRITE | PAGE_NOCACHE); return pvoid;}void NIC_DRIVER_OBJECT::DriverIndication( U32 uIndication){ switch (uIndication) { case NIC_IND_TX_IDLE: if(m_bOutofResources) { m_bOutofResources = 0; NdisMSendResourcesAvailable(m_NdisHandle); } break; case AID_ERROR: case AID_LARGE_INCOME_PACKET: m_bSystemHang = 1; default: break; } // of switch }void NIC_DRIVER_OBJECT::DriverIsr( OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueInterrupt) { PERF_PROBE_ON(PROBE_ISR);#ifdef PERFORMANCE_LOG if(!_gnPerfLogPos) { DumpPerfmanceLogs(); BREAK; }#endif m_pLower->DeviceDisableInterrupt(); U32 intstat; if(!(intstat = m_pLower->DeviceGetInterruptStatus())) { *InterruptRecognized = *QueueInterrupt = FALSE; m_pLower->DeviceEnableInterrupt(); PERF_PROBE_OFF(PROBE_ISR); return; } /* clear it immediately */ m_pLower->DeviceSetInterruptStatus( m_uRecentInterruptStatus = intstat); *InterruptRecognized = TRUE; *QueueInterrupt = TRUE;#ifdef IMPL_DEVICE_ISR m_pLower->DeviceIsr(intstat);#endif PERF_PROBE_OFF(PROBE_ISR);}void NIC_DRIVER_OBJECT::DriverInterruptHandler(void){ PERF_PROBE_ON(PROBE_HANLDER); m_pLower->DeviceInterruptEventHandler(m_uRecentInterruptStatus); m_pLower->DeviceEnableInterrupt(); PERF_PROBE_OFF(PROBE_HANLDER);}#define HANDLE_QUERY(event,ptr,len) \ case event: if(InfoBufferLength < (*BytesNeeded=len)) \ { status = NDIS_STATUS_INVALID_LENGTH; break; } \ panswer = (void*)(ptr); *BytesWritten = len; break;NDIS_STATUS NIC_DRIVER_OBJECT::DriverQueryInformation( IN NDIS_OID Oid, IN PVOID InfoBuffer, IN ULONG InfoBufferLength, OUT PULONG BytesWritten, OUT PULONG BytesNeeded){ NDIS_STATUS status = NDIS_STATUS_SUCCESS; PVOID panswer; U8 szbuffer[32]; U32 tmp32; // pass to lower object, to see if it can handle this query, // if it can, return TRUE and set status. if(m_pLower->DeviceQueryInformation( &status, Oid, InfoBuffer, InfoBufferLength, BytesWritten, BytesNeeded)) return status; switch (Oid) { HANDLE_QUERY( OID_GEN_SUPPORTED_LIST, &gszNICSupportedOid,sizeof(gszNICSupportedOid)); HANDLE_QUERY( OID_GEN_HARDWARE_STATUS, &m_pLower->m_szCurrentSettings[SID_HW_STATUS],sizeof(U32)); HANDLE_QUERY( OID_GEN_MEDIA_IN_USE, &m_pLower->m_szCurrentSettings[SID_MEDIA_IN_USE],sizeof(U32)); HANDLE_QUERY( OID_GEN_MEDIA_SUPPORTED, &m_pLower->m_szCurrentSettings[SID_MEDIA_SUPPORTED],sizeof(U32)); HANDLE_QUERY( OID_GEN_MEDIA_CONNECT_STATUS, &m_pLower->m_szCurrentSettings[SID_MEDIA_CONNECTION_STATUS],sizeof(U32)); HANDLE_QUERY( OID_GEN_MAXIMUM_LOOKAHEAD, &m_pLower->m_szCurrentSettings[SID_MAXIMUM_LOOKAHEAD],sizeof(U32)); HANDLE_QUERY( OID_GEN_MAXIMUM_FRAME_SIZE, &m_pLower->m_szCurrentSettings[SID_MAXIMUM_FRAME_SIZE],sizeof(U32)); HANDLE_QUERY( OID_GEN_MAXIMUM_TOTAL_SIZE, &m_pLower->m_szCurrentSettings[SID_MAXIMUM_TOTAL_SIZE],sizeof(U32)); HANDLE_QUERY( OID_GEN_MAXIMUM_SEND_PACKETS, &m_pLower->m_szCurrentSettings[SID_MAXIMUM_SEND_PACKETS],sizeof(U32)); HANDLE_QUERY( OID_GEN_LINK_SPEED, &m_pLower->m_szCurrentSettings[SID_LINK_SPEED],sizeof(U32)); HANDLE_QUERY( OID_GEN_XMIT_OK, &m_pLower->m_szStatistics[TID_GEN_XMIT_OK],sizeof(U32)); HANDLE_QUERY( OID_GEN_RCV_OK, &m_pLower->m_szStatistics[TID_GEN_RCV_OK],sizeof(U32)); HANDLE_QUERY( OID_GEN_XMIT_ERROR, &m_pLower->m_szStatistics[TID_GEN_XMIT_ERROR],sizeof(U32)); HANDLE_QUERY( OID_GEN_RCV_ERROR, &m_pLower->m_szStatistics[TID_GEN_RCV_ERROR],sizeof(U32)); HANDLE_QUERY( OID_GEN_RCV_NO_BUFFER, &m_pLower->m_szStatistics[TID_GEN_RCV_NO_BUFFER],sizeof(U32)); HANDLE_QUERY( OID_GEN_RCV_CRC_ERROR, &m_pLower->m_szStatistics[TID_GEN_RCV_CRC_ERROR],sizeof(U32)); HANDLE_QUERY( OID_802_3_RCV_ERROR_ALIGNMENT, &m_pLower->m_szStatistics[TID_802_3_RCV_ERROR_ALIGNMENT],sizeof(U32)); HANDLE_QUERY( OID_802_3_RCV_OVERRUN, &m_pLower->m_szStatistics[TID_802_3_RCV_OVERRUN],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_ONE_COLLISION, &m_pLower->m_szStatistics[TID_802_3_XMIT_ONE_COLLISION],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_MORE_COLLISIONS, &m_pLower->m_szStatistics[TID_802_3_XMIT_MORE_COLLISIONS],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_DEFERRED, &m_pLower->m_szStatistics[TID_802_3_XMIT_DEFERRED],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_MAX_COLLISIONS, &m_pLower->m_szStatistics[TID_802_3_XMIT_MAX_COLLISIONS],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_UNDERRUN, &m_pLower->m_szStatistics[TID_802_3_XMIT_UNDERRUN],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_HEARTBEAT_FAILURE, &m_pLower->m_szStatistics[TID_802_3_XMIT_HEARTBEAT_FAILURE],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_TIMES_CRS_LOST, &m_pLower->m_szStatistics[TID_802_3_XMIT_TIMES_CRS_LOST],sizeof(U32)); HANDLE_QUERY( OID_802_3_XMIT_LATE_COLLISIONS, &m_pLower->m_szStatistics[TID_802_3_XMIT_LATE_COLLISIONS],sizeof(U32)); HANDLE_QUERY( OID_GEN_MAC_OPTIONS, &m_pLower->m_szCurrentSettings[SID_GEN_MAC_OPTIONS],sizeof(U32)); HANDLE_QUERY( OID_802_3_PERMANENT_ADDRESS, m_pLower->DeviceMacAddress(&szbuffer[0]),ETH_ADDRESS_LENGTH); HANDLE_QUERY( OID_802_3_CURRENT_ADDRESS, m_pLower->DeviceMacAddress(&szbuffer[0]),ETH_ADDRESS_LENGTH); HANDLE_QUERY( OID_802_3_MAXIMUM_LIST_SIZE, &m_pLower->m_szCurrentSettings[SID_802_3_MAXIMUM_LIST_SIZE],sizeof(U32)); HANDLE_QUERY( OID_802_3_MULTICAST_LIST, &m_pLower->m_szMulticastList[0][0], m_pLower->m_nMulticasts*ETH_ADDRESS_LENGTH); HANDLE_QUERY( OID_GEN_CURRENT_PACKET_FILTER, &m_pLower->m_szCurrentSettings[SID_GEN_CURRENT_PACKET_FILTER],sizeof(U32)); HANDLE_QUERY( OID_GEN_TRANSMIT_BUFFER_SPACE, &m_pLower->m_szCurrentSettings[SID_GEN_TRANSMIT_BUFFER_SPACE],sizeof(U32)); HANDLE_QUERY( OID_GEN_RECEIVE_BUFFER_SPACE, &m_pLower->m_szCurrentSettings[SID_GEN_RECEIVE_BUFFER_SPACE],sizeof(U32)); HANDLE_QUERY( OID_GEN_TRANSMIT_BLOCK_SIZE, &m_pLower->m_szCurrentSettings[SID_GEN_TRANSMIT_BLOCK_SIZE],sizeof(U32)); HANDLE_QUERY( OID_GEN_RECEIVE_BLOCK_SIZE, &m_pLower->m_szCurrentSettings[SID_GEN_RECEIVE_BLOCK_SIZE],sizeof(U32)); HANDLE_QUERY( OID_GEN_VENDOR_ID, (tmp32=(U32)m_pLower->DeviceVendorID(),&tmp32),sizeof(U32)); HANDLE_QUERY( OID_GEN_VENDOR_DESCRIPTION, VENDOR_DESC,strlen(VENDOR_DESC)); HANDLE_QUERY( OID_GEN_CURRENT_LOOKAHEAD, &m_pLower->m_szCurrentSettings[SID_GEN_CURRENT_LOOKAHEAD],sizeof(U32)); HANDLE_QUERY( OID_GEN_DRIVER_VERSION, &m_pLower->m_szCurrentSettings[SID_GEN_DRIVER_VERSION],sizeof(U32)); HANDLE_QUERY( OID_GEN_VENDOR_DRIVER_VERSION, &m_pLower->m_szCurrentSettings[SID_GEN_VENDOR_DRIVER_VERSION],sizeof(U32)); HANDLE_QUERY( OID_GEN_PROTOCOL_OPTIONS, &m_pLower->m_szCurrentSettings[SID_GEN_PROTOCOL_OPTIONS],sizeof(U32)); default: status = NDIS_STATUS_INVALID_OID; break; } // of switch if(status == NDIS_STATUS_SUCCESS) { NdisMoveMemory(InfoBuffer,panswer,*BytesWritten); } return status;}#define HANDLE_SET(event,len) \ case event: if(InfoBufferLength < (*BytesNeeded=len)) \ { status = NDIS_STATUS_INVALID_LENGTH; break; } \ *BytesRead = len; HANDLE_SET_##event(); break;#define HANDLE_SET_OID_GEN_CURRENT_PACKET_FILTER() \ m_pLower->DeviceOnSetupFilter(*(U32*)InfoBuffer) NDIS_STATUS NIC_DRIVER_OBJECT::DriverSetInformation( IN NDIS_OID Oid, IN PVOID InfoBuffer, IN ULONG InfoBufferLength, OUT PULONG BytesRead, OUT PULONG BytesNeeded){ NDIS_STATUS status = NDIS_STATUS_SUCCESS; // pass to lower object, to see if it can handle this request, // if it can, return TRUE and set status. if(m_pLower->DeviceSetInformation( &status, Oid, InfoBuffer, InfoBufferLength, BytesRead, BytesNeeded)) return status; switch (Oid) { HANDLE_SET( OID_GEN_CURRENT_PACKET_FILTER,sizeof(U32)); case OID_802_3_MULTICAST_LIST: NdisMoveMemory( &m_pLower->m_szMulticastList[0][0], InfoBuffer, InfoBufferLength); m_pLower->m_nMulticasts = InfoBufferLength / ETH_ADDRESS_LENGTH;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -