Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmain.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Novell Eagle 2000 driver 00004 * FILE: ne2000/main.c 00005 * PURPOSE: Driver entry point 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * REVISIONS: 00008 * CSH 27/08-2000 Created 00009 */ 00010 #include <ne2000.h> 00011 00012 NTSTATUS 00013 NTAPI 00014 DriverEntry( 00015 PDRIVER_OBJECT DriverObject, 00016 PUNICODE_STRING RegistryPath); 00017 00018 00019 #if DBG 00020 00021 /* See debug.h for debug/trace constants */ 00022 ULONG DebugTraceLevel = 0; 00023 00024 #endif /* DBG */ 00025 00026 00027 /* List of supported OIDs */ 00028 static ULONG MiniportOIDList[] = { 00029 OID_GEN_SUPPORTED_LIST, 00030 OID_GEN_HARDWARE_STATUS, 00031 OID_GEN_MEDIA_SUPPORTED, 00032 OID_GEN_MEDIA_IN_USE, 00033 OID_GEN_MAXIMUM_LOOKAHEAD, 00034 OID_GEN_MAXIMUM_FRAME_SIZE, 00035 OID_GEN_LINK_SPEED, 00036 OID_GEN_TRANSMIT_BUFFER_SPACE, 00037 OID_GEN_RECEIVE_BUFFER_SPACE, 00038 OID_GEN_TRANSMIT_BLOCK_SIZE, 00039 OID_GEN_RECEIVE_BLOCK_SIZE, 00040 OID_GEN_VENDOR_ID, 00041 OID_GEN_VENDOR_DESCRIPTION, 00042 OID_GEN_VENDOR_DRIVER_VERSION, 00043 OID_GEN_CURRENT_PACKET_FILTER, 00044 OID_GEN_CURRENT_LOOKAHEAD, 00045 OID_GEN_DRIVER_VERSION, 00046 OID_GEN_MAXIMUM_TOTAL_SIZE, 00047 OID_GEN_PROTOCOL_OPTIONS, 00048 OID_GEN_MAC_OPTIONS, 00049 OID_GEN_MEDIA_CONNECT_STATUS, 00050 OID_GEN_MAXIMUM_SEND_PACKETS, 00051 OID_802_3_PERMANENT_ADDRESS, 00052 OID_802_3_CURRENT_ADDRESS, 00053 OID_802_3_MULTICAST_LIST, 00054 OID_802_3_MAXIMUM_LIST_SIZE, 00055 OID_802_3_MAC_OPTIONS 00056 }; 00057 00058 DRIVER_INFORMATION DriverInfo = { NULL, NULL, { NULL, NULL } }; 00059 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1); 00060 00061 00062 static BOOLEAN NTAPI MiniportCheckForHang( 00063 IN NDIS_HANDLE MiniportAdapterContext) 00064 /* 00065 * FUNCTION: Examines if an adapter has hung 00066 * ARGUMENTS: 00067 * MiniportAdapterContext = Pointer to adapter context area 00068 * RETURNS: 00069 * TRUE if the adapter has hung, FALSE if not 00070 */ 00071 { 00072 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00073 00074 return FALSE; 00075 } 00076 00077 00078 static VOID NTAPI MiniportDisableInterrupt( 00079 IN NDIS_HANDLE MiniportAdapterContext) 00080 /* 00081 * FUNCTION: Disables interrupts from an adapter 00082 * ARGUMENTS: 00083 * MiniportAdapterContext = Pointer to adapter context area 00084 */ 00085 { 00086 NDIS_DbgPrint(MAX_TRACE, ("Called. (MiniportDisableInterrupt).\n")); 00087 #ifndef NOCARD 00088 NICDisableInterrupts((PNIC_ADAPTER)MiniportAdapterContext); 00089 #endif 00090 } 00091 00092 00093 static VOID NTAPI MiniportEnableInterrupt( 00094 IN NDIS_HANDLE MiniportAdapterContext) 00095 /* 00096 * FUNCTION: Enables interrupts from an adapter 00097 * ARGUMENTS: 00098 * MiniportAdapterContext = Pointer to adapter context area 00099 */ 00100 { 00101 NDIS_DbgPrint(MAX_TRACE, ("Called. (MiniportEnableInterrupt).\n")); 00102 #ifndef NOCARD 00103 NICEnableInterrupts((PNIC_ADAPTER)MiniportAdapterContext); 00104 #endif 00105 } 00106 00107 00108 static VOID NTAPI MiniportHalt( 00109 IN NDIS_HANDLE MiniportAdapterContext) 00110 /* 00111 * FUNCTION: Deallocates resources for and halts an adapter 00112 * ARGUMENTS: 00113 * MiniportAdapterContext = Pointer to adapter context area 00114 */ 00115 { 00116 PNIC_ADAPTER Adapter = (PNIC_ADAPTER)MiniportAdapterContext; 00117 00118 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00119 00120 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00121 #ifndef NOCARD 00122 /* Stop the NIC */ 00123 NICStop(Adapter); 00124 #endif 00125 /* Wait for any DPCs to complete. FIXME: Use something else */ 00126 NdisStallExecution(250000); 00127 00128 if (Adapter->InterruptRegistered) 00129 /* Deregister interrupt */ 00130 NdisMDeregisterInterrupt(&Adapter->Interrupt); 00131 00132 if (Adapter->IOPortRangeRegistered) 00133 /* Deregister I/O port range */ 00134 NdisMDeregisterIoPortRange( 00135 Adapter->MiniportAdapterHandle, 00136 Adapter->IoBaseAddress, 00137 0x20, 00138 Adapter->IOBase); 00139 00140 if (Adapter->ShutdownHandlerRegistered) 00141 NdisMDeregisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle); 00142 00143 /* Remove adapter from global adapter list */ 00144 if ((&Adapter->ListEntry)->Blink != NULL) { 00145 RemoveEntryList(&Adapter->ListEntry); 00146 } 00147 00148 /* Free adapter context area */ 00149 NdisFreeMemory(Adapter, sizeof(NIC_ADAPTER), 0); 00150 } 00151 00152 00153 static VOID NTAPI MiQueryResources( 00154 OUT PNDIS_STATUS Status, 00155 IN PNIC_ADAPTER Adapter, 00156 IN NDIS_HANDLE WrapperConfigurationContext) 00157 { 00158 PNDIS_RESOURCE_LIST AssignedResources; 00159 UINT BufferSize = 0; 00160 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; 00161 UINT i; 00162 00163 NdisMQueryAdapterResources(Status, 00164 WrapperConfigurationContext, 00165 NULL, 00166 &BufferSize); 00167 if (*Status == NDIS_STATUS_SUCCESS) 00168 return; 00169 00170 *Status = NdisAllocateMemory((PVOID)&AssignedResources, 00171 BufferSize, 00172 0, 00173 HighestAcceptableMax); 00174 if (*Status != NDIS_STATUS_SUCCESS) 00175 return; 00176 00177 NdisMQueryAdapterResources(Status, 00178 WrapperConfigurationContext, 00179 AssignedResources, 00180 &BufferSize); 00181 if (*Status != NDIS_STATUS_SUCCESS) 00182 return; 00183 00184 for (i = 0; i < AssignedResources->Count; i++) 00185 { 00186 Descriptor = AssignedResources->PartialDescriptors + i; 00187 switch (Descriptor->Type) 00188 { 00189 case CmResourceTypeInterrupt: 00190 Adapter->InterruptLevel = Descriptor->u.Interrupt.Level; 00191 Adapter->InterruptVector = Descriptor->u.Interrupt.Vector; 00192 Adapter->InterruptShared = (Descriptor->ShareDisposition == CmResourceShareShared); 00193 Adapter->InterruptMode = Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED ? 00194 NdisInterruptLatched : NdisInterruptLevelSensitive; 00195 break; 00196 case CmResourceTypePort: 00197 Adapter->IoBaseAddress = Descriptor->u.Port.Start.LowPart; 00198 break; 00199 } 00200 } 00201 } 00202 00203 VOID 00204 NTAPI 00205 MiniportShutdown(PVOID Context) 00206 { 00207 #ifndef NOCARD 00208 NICStop((PNIC_ADAPTER)Context); 00209 #endif 00210 } 00211 00212 static NDIS_STATUS NTAPI MiniportInitialize( 00213 OUT PNDIS_STATUS OpenErrorStatus, 00214 OUT PUINT SelectedMediumIndex, 00215 IN PNDIS_MEDIUM MediumArray, 00216 IN UINT MediumArraySize, 00217 IN NDIS_HANDLE MiniportAdapterHandle, 00218 IN NDIS_HANDLE WrapperConfigurationContext) 00219 /* 00220 * FUNCTION: Adapter initialization function 00221 * ARGUMENTS: 00222 * OpenErrorStatus = Address of buffer to place additional status information 00223 * SelectedMediumIndex = Address of buffer to place selected medium index 00224 * MediumArray = Pointer to an array of NDIS_MEDIUMs 00225 * MediaArraySize = Number of elements in MediumArray 00226 * MiniportAdapterHandle = Miniport adapter handle assigned by NDIS 00227 * WrapperConfigurationContext = Handle used to identify configuration context 00228 * RETURNS: 00229 * Status of operation 00230 */ 00231 { 00232 UINT i; 00233 NDIS_STATUS Status; 00234 PNIC_ADAPTER Adapter; 00235 NDIS_HANDLE ConfigurationHandle; 00236 UINT *RegNetworkAddress = 0; 00237 UINT RegNetworkAddressLength = 0; 00238 00239 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00240 00241 NDIS_DbgPrint(MAX_TRACE, ("Called (Adapter %X).\n", MiniportAdapterHandle)); 00242 00243 /* Search for 802.3 media which is the only one we support */ 00244 for (i = 0; i < MediumArraySize; i++) { 00245 if (MediumArray[i] == NdisMedium802_3) 00246 break; 00247 } 00248 00249 if (i == MediumArraySize) { 00250 NDIS_DbgPrint(MIN_TRACE, ("No supported media.\n")); 00251 return NDIS_STATUS_UNSUPPORTED_MEDIA; 00252 } 00253 00254 *SelectedMediumIndex = i; 00255 00256 Status = NdisAllocateMemory((PVOID)&Adapter, 00257 sizeof(NIC_ADAPTER), 00258 0, 00259 HighestAcceptableMax); 00260 if (Status != NDIS_STATUS_SUCCESS) { 00261 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00262 return Status; 00263 } 00264 00265 NdisZeroMemory(Adapter, sizeof(NIC_ADAPTER)); 00266 Adapter->MiniportAdapterHandle = MiniportAdapterHandle; 00267 Adapter->IoBaseAddress = DRIVER_DEFAULT_IO_BASE_ADDRESS; 00268 Adapter->InterruptLevel = DRIVER_DEFAULT_INTERRUPT_NUMBER; 00269 Adapter->InterruptVector = DRIVER_DEFAULT_INTERRUPT_NUMBER; 00270 Adapter->InterruptShared = DRIVER_DEFAULT_INTERRUPT_SHARED; 00271 Adapter->InterruptMode = DRIVER_DEFAULT_INTERRUPT_MODE; 00272 Adapter->MaxMulticastListSize = DRIVER_MAX_MULTICAST_LIST_SIZE; 00273 Adapter->InterruptMask = DRIVER_INTERRUPT_MASK; 00274 Adapter->LookaheadSize = DRIVER_MAXIMUM_LOOKAHEAD; 00275 00276 /* Query the resources from PnP. */ 00277 MiQueryResources(&Status, Adapter, WrapperConfigurationContext); 00278 00279 /* Get the port, irq, and MAC address from registry if the PnP 00280 failed. */ 00281 if (Status != NDIS_STATUS_SUCCESS) 00282 { 00283 PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter; 00284 UNICODE_STRING Keyword; 00285 00286 NdisOpenConfiguration(&Status, &ConfigurationHandle, WrapperConfigurationContext); 00287 if (Status == NDIS_STATUS_SUCCESS) 00288 { 00289 NdisInitUnicodeString(&Keyword, L"Irq"); 00290 NdisReadConfiguration(&Status, &ConfigurationParameter, ConfigurationHandle, &Keyword, NdisParameterHexInteger); 00291 if(Status == NDIS_STATUS_SUCCESS) 00292 { 00293 NDIS_DbgPrint(MID_TRACE,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n", 00294 ConfigurationParameter->ParameterData.IntegerData)); 00295 Adapter->InterruptLevel = 00296 Adapter->InterruptVector = ConfigurationParameter->ParameterData.IntegerData; 00297 } 00298 00299 NdisInitUnicodeString(&Keyword, L"Port"); 00300 NdisReadConfiguration(&Status, &ConfigurationParameter, ConfigurationHandle, &Keyword, NdisParameterHexInteger); 00301 if(Status == NDIS_STATUS_SUCCESS) 00302 { 00303 NDIS_DbgPrint(MID_TRACE,("NdisReadConfiguration for Port returned successfully, port 0x%x\n", 00304 ConfigurationParameter->ParameterData.IntegerData)); 00305 Adapter->IoBaseAddress = ConfigurationParameter->ParameterData.IntegerData; 00306 } 00307 00308 NdisCloseConfiguration(ConfigurationHandle); 00309 } 00310 else 00311 { 00312 NDIS_DbgPrint(MIN_TRACE,("NdisOpenConfiguration returned error 0x%x\n", Status)); 00313 } 00314 } 00315 00316 /* find the nic */ 00317 if (!NICCheck(Adapter)) { 00318 NDIS_DbgPrint(MID_TRACE, ("No adapter found at (0x%X).\n", Adapter->IoBaseAddress)); 00319 NdisFreeMemory(Adapter, sizeof(NIC_ADAPTER), 0); 00320 return NDIS_STATUS_ADAPTER_NOT_FOUND; 00321 } else 00322 NDIS_DbgPrint(MID_TRACE, ("Adapter found at (0x%X).\n", Adapter->IoBaseAddress)); 00323 00324 NdisMSetAttributes( 00325 MiniportAdapterHandle, 00326 (NDIS_HANDLE)Adapter, 00327 FALSE, 00328 NdisInterfaceIsa); 00329 00330 Status = NdisMRegisterIoPortRange( 00331 (PVOID*)&Adapter->IOBase, 00332 MiniportAdapterHandle, 00333 Adapter->IoBaseAddress, 00334 0x20); 00335 00336 if (Status != NDIS_STATUS_SUCCESS) { 00337 NDIS_DbgPrint(MIN_TRACE, ("Cannot register port range. Status (0x%X).\n", Status)); 00338 MiniportHalt((NDIS_HANDLE)Adapter); 00339 return Status; 00340 } 00341 00342 Adapter->IOPortRangeRegistered = TRUE; 00343 00344 /* Initialize NIC */ 00345 #ifndef NOCARD 00346 Status = NICInitialize(Adapter); 00347 if (Status != NDIS_STATUS_SUCCESS) { 00348 NDIS_DbgPrint(MIN_TRACE,("No NE2000 or compatible network adapter found at address 0x%X.\n", 00349 Adapter->IOBase)); 00350 00351 NDIS_DbgPrint(MID_TRACE, ("Status (0x%X).\n", Status)); 00352 MiniportHalt((NDIS_HANDLE)Adapter); 00353 return Status; 00354 } 00355 00356 NdisOpenConfiguration(&Status, &ConfigurationHandle, WrapperConfigurationContext); 00357 if (Status == NDIS_STATUS_SUCCESS) 00358 { 00359 NdisReadNetworkAddress(&Status, (PVOID *)&RegNetworkAddress, &RegNetworkAddressLength, ConfigurationHandle); 00360 if(Status == NDIS_STATUS_SUCCESS && RegNetworkAddressLength == DRIVER_LENGTH_OF_ADDRESS) 00361 { 00362 int i; 00363 NDIS_DbgPrint(MID_TRACE,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n", 00364 RegNetworkAddress[0], RegNetworkAddress[1], RegNetworkAddress[2], RegNetworkAddress[3], 00365 RegNetworkAddress[4], RegNetworkAddress[5])); 00366 for(i = 0; i < DRIVER_LENGTH_OF_ADDRESS; i++) 00367 Adapter->StationAddress[i] = RegNetworkAddress[i]; 00368 } 00369 00370 NdisCloseConfiguration(ConfigurationHandle); 00371 } 00372 00373 if (Status != NDIS_STATUS_SUCCESS || RegNetworkAddressLength != DRIVER_LENGTH_OF_ADDRESS) 00374 { 00375 int i; 00376 for (i = 0; i < DRIVER_LENGTH_OF_ADDRESS; i++) 00377 Adapter->StationAddress[i] = Adapter->PermanentAddress[i]; 00378 } 00379 00380 NDIS_DbgPrint(MID_TRACE, ("BOARDDATA:\n")); 00381 for (i = 0; i < 4; i++) { 00382 NDIS_DbgPrint(MID_TRACE, ("%02X %02X %02X %02X\n", 00383 Adapter->SAPROM[i*4+0], 00384 Adapter->SAPROM[i*4+1], 00385 Adapter->SAPROM[i*4+2], 00386 Adapter->SAPROM[i*4+3])); 00387 } 00388 00389 /* Setup adapter structure */ 00390 Adapter->TXStart = ((ULONG_PTR)Adapter->RamBase >> 8); 00391 Adapter->TXCount = DRIVER_DEFAULT_TX_BUFFER_COUNT; 00392 Adapter->TXFree = DRIVER_DEFAULT_TX_BUFFER_COUNT; 00393 Adapter->TXCurrent = -1; 00394 Adapter->PageStart = Adapter->TXStart + Adapter->TXCount; 00395 Adapter->PageStop = Adapter->TXStart + (Adapter->RamSize >> 8); 00396 00397 /* Initialize multicast address mask to accept all */ 00398 for (i = 0; i < 8; i++) 00399 Adapter->MulticastAddressMask[i] = 0xFF; 00400 00401 /* Setup the NIC */ 00402 NICSetup(Adapter); 00403 00404 NDIS_DbgPrint(MID_TRACE, ("TXStart (0x%X) TXCount (0x%X) PageStart (0x%X)\n", 00405 Adapter->TXStart, 00406 Adapter->TXCount, 00407 Adapter->PageStart)); 00408 00409 NDIS_DbgPrint(MID_TRACE, ("PageStop (0x%X) CurrentPage (0x%X) NextPacket (0x%X).\n", 00410 Adapter->PageStop, 00411 Adapter->CurrentPage, 00412 Adapter->NextPacket)); 00413 #endif 00414 /* Register the interrupt */ 00415 Status = NdisMRegisterInterrupt( 00416 &Adapter->Interrupt, 00417 MiniportAdapterHandle, 00418 Adapter->InterruptVector, 00419 Adapter->InterruptLevel, 00420 FALSE, 00421 Adapter->InterruptShared, 00422 Adapter->InterruptMode); 00423 if (Status != NDIS_STATUS_SUCCESS) { 00424 NDIS_DbgPrint(MIN_TRACE, ("Cannot register interrupt. Status (0x%X).\n", Status)); 00425 MiniportHalt((NDIS_HANDLE)Adapter); 00426 return Status; 00427 } 00428 00429 Adapter->InterruptRegistered = TRUE; 00430 #ifndef NOCARD 00431 /* Start the NIC */ 00432 NICStart(Adapter); 00433 #endif 00434 00435 /* Register the shutdown handler */ 00436 NdisMRegisterAdapterShutdownHandler(MiniportAdapterHandle, Adapter, MiniportShutdown); 00437 00438 Adapter->ShutdownHandlerRegistered = TRUE; 00439 00440 /* Add adapter to the global adapter list */ 00441 InsertTailList(&DriverInfo.AdapterListHead, &Adapter->ListEntry); 00442 00443 NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n")); 00444 00445 return NDIS_STATUS_SUCCESS; 00446 } 00447 00448 00449 static VOID NTAPI MiniportISR( 00450 OUT PBOOLEAN InterruptRecognized, 00451 OUT PBOOLEAN QueueMiniportHandleInterrupt, 00452 IN NDIS_HANDLE MiniportAdapterContext) 00453 /* 00454 * FUNCTION: Interrupt Service Routine for controlled adapters 00455 * ARGUMENTS: 00456 * InterruptRecognized = Address of buffer to place wether 00457 * the adapter generated the interrupt 00458 * QueueMiniportHandleInterrupt = Address of buffer to place wether 00459 * MiniportHandleInterrupt should be called 00460 * MiniportAdapterContext = Pointer to adapter context area 00461 * NOTES: 00462 * All pending interrupts are handled 00463 */ 00464 { 00465 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00466 00467 NICDisableInterrupts((PNIC_ADAPTER)MiniportAdapterContext); 00468 00469 *InterruptRecognized = TRUE; 00470 *QueueMiniportHandleInterrupt = TRUE; 00471 } 00472 00473 00474 static NDIS_STATUS NTAPI MiniportQueryInformation( 00475 IN NDIS_HANDLE MiniportAdapterContext, 00476 IN NDIS_OID Oid, 00477 IN PVOID InformationBuffer, 00478 IN ULONG InformationBufferLength, 00479 OUT PULONG BytesWritten, 00480 OUT PULONG BytesNeeded) 00481 /* 00482 * FUNCTION: Handler to process queries 00483 * ARGUMENTS: 00484 * MiniportAdapterContext = Pointer to adapter context area 00485 * Oid = OID code designating query operation 00486 * InformationBuffer = Address of return buffer 00487 * InformationBufferLength = Length of return buffer 00488 * BytesWritten = Address of buffer to place number of bytes returned 00489 * BytesNeeded = Address of buffer to place number of bytes needed 00490 * in InformationBuffer for specified OID 00491 * RETURNS: 00492 * Status of operation 00493 */ 00494 { 00495 NDIS_STATUS Status; 00496 PVOID CopyFrom; 00497 UINT CopySize; 00498 ULONG GenericULONG; 00499 USHORT GenericUSHORT; 00500 NDIS_MEDIUM Medium = NdisMedium802_3; 00501 PNIC_ADAPTER Adapter = (PNIC_ADAPTER)MiniportAdapterContext; 00502 00503 NDIS_DbgPrint(MAX_TRACE, ("Called. Oid (0x%X).\n", Oid)); 00504 00505 Status = NDIS_STATUS_SUCCESS; 00506 CopyFrom = (PVOID)&GenericULONG; 00507 CopySize = sizeof(ULONG); 00508 00509 switch (Oid) { 00510 case OID_GEN_SUPPORTED_LIST: 00511 CopyFrom = (PVOID)&MiniportOIDList; 00512 CopySize = sizeof(MiniportOIDList); 00513 break; 00514 case OID_GEN_HARDWARE_STATUS: 00515 GenericULONG = (ULONG)NdisHardwareStatusReady; 00516 break; 00517 case OID_GEN_MEDIA_SUPPORTED: 00518 case OID_GEN_MEDIA_IN_USE: 00519 CopyFrom = (PVOID)&Medium; 00520 CopySize = sizeof(NDIS_MEDIUM); 00521 break; 00522 case OID_GEN_MAXIMUM_LOOKAHEAD: 00523 GenericULONG = DRIVER_MAXIMUM_LOOKAHEAD; 00524 break; 00525 case OID_GEN_MAXIMUM_FRAME_SIZE: 00526 GenericULONG = DRIVER_FRAME_SIZE - DRIVER_HEADER_SIZE; 00527 break; 00528 case OID_GEN_LINK_SPEED: 00529 GenericULONG = 100000; /* 10Mbps */ 00530 break; 00531 case OID_GEN_TRANSMIT_BUFFER_SPACE: 00532 GenericULONG = Adapter->TXCount * DRIVER_BLOCK_SIZE; 00533 break; 00534 case OID_GEN_RECEIVE_BUFFER_SPACE: 00535 GenericULONG = Adapter->RamSize - 00536 (ULONG_PTR)Adapter->RamBase - 00537 (Adapter->TXCount * DRIVER_BLOCK_SIZE); 00538 break; 00539 case OID_GEN_TRANSMIT_BLOCK_SIZE: 00540 GenericULONG = DRIVER_BLOCK_SIZE; 00541 break; 00542 case OID_GEN_RECEIVE_BLOCK_SIZE: 00543 GenericULONG = DRIVER_BLOCK_SIZE; 00544 break; 00545 case OID_GEN_VENDOR_ID: 00546 NdisMoveMemory(&GenericULONG, &Adapter->PermanentAddress, 3); 00547 GenericULONG &= 0xFFFFFF00; 00548 GenericULONG |= 0x01; 00549 break; 00550 case OID_GEN_VENDOR_DESCRIPTION: 00551 CopyFrom = (PVOID)&DRIVER_VENDOR_DESCRIPTION; 00552 CopySize = sizeof(DRIVER_VENDOR_DESCRIPTION); 00553 break; 00554 case OID_GEN_VENDOR_DRIVER_VERSION: 00555 GenericUSHORT = (USHORT)DRIVER_VENDOR_DRIVER_VERSION; 00556 CopyFrom = (PVOID)&GenericUSHORT; 00557 CopySize = sizeof(USHORT); 00558 break; 00559 case OID_GEN_CURRENT_PACKET_FILTER: 00560 GenericULONG = Adapter->PacketFilter; 00561 break; 00562 case OID_GEN_CURRENT_LOOKAHEAD: 00563 GenericULONG = Adapter->LookaheadSize; 00564 break; 00565 case OID_GEN_DRIVER_VERSION: 00566 GenericUSHORT = ((USHORT)DRIVER_NDIS_MAJOR_VERSION << 8) | DRIVER_NDIS_MINOR_VERSION; 00567 CopyFrom = (PVOID)&GenericUSHORT; 00568 CopySize = sizeof(USHORT); 00569 break; 00570 case OID_GEN_MAXIMUM_TOTAL_SIZE: 00571 GenericULONG = DRIVER_FRAME_SIZE; 00572 break; 00573 case OID_GEN_PROTOCOL_OPTIONS: 00574 NDIS_DbgPrint(MID_TRACE, ("OID_GEN_PROTOCOL_OPTIONS.\n")); 00575 Status = NDIS_STATUS_NOT_SUPPORTED; 00576 break; 00577 case OID_GEN_MAC_OPTIONS: 00578 GenericULONG = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 00579 NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 00580 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | 00581 NDIS_MAC_OPTION_NO_LOOPBACK; 00582 break; 00583 case OID_GEN_MEDIA_CONNECT_STATUS: 00584 GenericULONG = (ULONG)NdisMediaStateConnected; 00585 break; 00586 case OID_GEN_MAXIMUM_SEND_PACKETS: 00587 GenericULONG = 1; 00588 break; 00589 case OID_802_3_PERMANENT_ADDRESS: 00590 CopyFrom = (PVOID)&Adapter->PermanentAddress; 00591 CopySize = DRIVER_LENGTH_OF_ADDRESS; 00592 break; 00593 case OID_802_3_CURRENT_ADDRESS: 00594 CopyFrom = (PVOID)&Adapter->StationAddress; 00595 CopySize = DRIVER_LENGTH_OF_ADDRESS; 00596 break; 00597 case OID_802_3_MULTICAST_LIST: 00598 NDIS_DbgPrint(MID_TRACE, ("OID_802_3_MULTICAST_LIST.\n")); 00599 Status = NDIS_STATUS_NOT_SUPPORTED; 00600 break; 00601 case OID_802_3_MAXIMUM_LIST_SIZE: 00602 GenericULONG = Adapter->MaxMulticastListSize; 00603 break; 00604 case OID_802_3_MAC_OPTIONS: 00605 NDIS_DbgPrint(MID_TRACE, ("OID_802_3_MAC_OPTIONS.\n")); 00606 Status = NDIS_STATUS_NOT_SUPPORTED; 00607 break; 00608 default: 00609 NDIS_DbgPrint(MIN_TRACE, ("Unknown OID (0x%X).\n", Oid)); 00610 Status = NDIS_STATUS_INVALID_OID; 00611 break; 00612 } 00613 00614 if (Status == NDIS_STATUS_SUCCESS) { 00615 if (CopySize > InformationBufferLength) { 00616 *BytesNeeded = (CopySize - InformationBufferLength); 00617 *BytesWritten = 0; 00618 Status = NDIS_STATUS_INVALID_LENGTH; 00619 } else { 00620 NdisMoveMemory(InformationBuffer, CopyFrom, CopySize); 00621 *BytesWritten = CopySize; 00622 *BytesNeeded = 0; 00623 } 00624 } 00625 00626 NDIS_DbgPrint(MAX_TRACE, ("Leaving. Status is (0x%X).\n", Status)); 00627 00628 return Status; 00629 } 00630 00631 00632 static NDIS_STATUS NTAPI MiniportReconfigure( 00633 OUT PNDIS_STATUS OpenErrorStatus, 00634 IN NDIS_HANDLE MiniportAdapterContext, 00635 IN NDIS_HANDLE WrapperConfigurationContext) 00636 /* 00637 * FUNCTION: Reconfigures an adapter 00638 * ARGUMENTS: 00639 * OpenErrorStatus = Address of buffer to place additional status information 00640 * MiniportAdapterContext = Pointer to adapter context area 00641 * WrapperConfigurationContext = Handle used to identify configuration context 00642 * RETURNS: 00643 * Status of operation 00644 * NOTES: 00645 * Never called by NDIS library 00646 */ 00647 { 00648 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00649 00650 return NDIS_STATUS_FAILURE; 00651 } 00652 00653 00654 00655 static NDIS_STATUS NTAPI MiniportReset( 00656 OUT PBOOLEAN AddressingReset, 00657 IN NDIS_HANDLE MiniportAdapterContext) 00658 /* 00659 * FUNCTION: Resets an adapter 00660 * ARGUMENTS: 00661 * AddressingReset = Address of a buffer to place value indicating 00662 * wether NDIS library should call MiniportSetInformation 00663 * to restore addressing information 00664 * MiniportAdapterContext = Pointer to adapter context area 00665 * RETURNS: 00666 * Status of operation 00667 */ 00668 { 00669 NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; 00670 00671 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00672 00673 #ifndef NOCARD 00674 NdisStatus = NICReset((PNIC_ADAPTER)MiniportAdapterContext); 00675 #endif 00676 00677 *AddressingReset = TRUE; 00678 00679 return NdisStatus; 00680 } 00681 00682 00683 static NDIS_STATUS NTAPI MiniportSend( 00684 IN NDIS_HANDLE MiniportAdapterContext, 00685 IN PNDIS_PACKET Packet, 00686 IN UINT Flags) 00687 /* 00688 * FUNCTION: Transmits a packet 00689 * ARGUMENTS: 00690 * MiniportAdapterContext = Pointer to adapter context area 00691 * Packet = Pointer to a packet descriptor specifying 00692 * the data to be transmitted 00693 * Flags = Specifies optional packet flags 00694 * RETURNS: 00695 * Status of operation 00696 */ 00697 { 00698 PNIC_ADAPTER Adapter = (PNIC_ADAPTER)MiniportAdapterContext; 00699 00700 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL); 00701 00702 #ifndef NOCARD 00703 NDIS_DbgPrint(MID_TRACE, ("Queueing packet.\n")); 00704 00705 /* Queue the packet on the transmit queue */ 00706 RESERVED(Packet)->Next = NULL; 00707 if (Adapter->TXQueueHead == NULL) { 00708 Adapter->TXQueueHead = Packet; 00709 } else { 00710 RESERVED(Adapter->TXQueueTail)->Next = Packet; 00711 } 00712 00713 Adapter->TXQueueTail = Packet; 00714 00715 /* Transmit the packet */ 00716 NICTransmit(Adapter); 00717 00718 return NDIS_STATUS_PENDING; 00719 #else 00720 return NDIS_STATUS_SUCCESS; 00721 #endif 00722 } 00723 00724 00725 static NDIS_STATUS NTAPI MiniportSetInformation( 00726 IN NDIS_HANDLE MiniportAdapterContext, 00727 IN NDIS_OID Oid, 00728 IN PVOID InformationBuffer, 00729 IN ULONG InformationBufferLength, 00730 OUT PULONG BytesRead, 00731 OUT PULONG BytesNeeded) 00732 /* 00733 * FUNCTION: Changes state information in the driver 00734 * ARGUMENTS: 00735 * MiniportAdapterContext = Pointer to adapter context area 00736 * Oid = OID code designating set operation 00737 * InformationBuffer = Pointer to buffer with state information 00738 * InformationBufferLength = Length of InformationBuffer 00739 * BytesRead = Address of buffer to place number of bytes read 00740 * BytesNeeded = Address of buffer to place number of extra bytes 00741 * needed in InformationBuffer for specified OID 00742 * RETURNS: 00743 * Status of operation 00744 */ 00745 { 00746 ULONG GenericULONG; 00747 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 00748 PNIC_ADAPTER Adapter = (PNIC_ADAPTER)MiniportAdapterContext; 00749 00750 NDIS_DbgPrint(MAX_TRACE, ("Called. Oid (0x%X).\n", Oid)); 00751 00752 switch (Oid) { 00753 case OID_GEN_CURRENT_PACKET_FILTER: 00754 /* Verify length */ 00755 if (InformationBufferLength < sizeof(ULONG)) { 00756 *BytesRead = 0; 00757 *BytesNeeded = sizeof(ULONG) - InformationBufferLength; 00758 Status = NDIS_STATUS_INVALID_LENGTH; 00759 break; 00760 } 00761 00762 NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG)); 00763 /* Check for properties the driver don't support */ 00764 if (GenericULONG & 00765 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL | 00766 NDIS_PACKET_TYPE_FUNCTIONAL | 00767 NDIS_PACKET_TYPE_GROUP | 00768 NDIS_PACKET_TYPE_MAC_FRAME | 00769 NDIS_PACKET_TYPE_SMT | 00770 NDIS_PACKET_TYPE_SOURCE_ROUTING)) { 00771 *BytesRead = 4; 00772 *BytesNeeded = 0; 00773 Status = NDIS_STATUS_NOT_SUPPORTED; 00774 break; 00775 } 00776 00777 Adapter->PacketFilter = GenericULONG; 00778 00779 /* FIXME: Set filter on hardware */ 00780 00781 break; 00782 case OID_GEN_CURRENT_LOOKAHEAD: 00783 /* Verify length */ 00784 if (InformationBufferLength < sizeof(ULONG)) { 00785 *BytesRead = 0; 00786 *BytesNeeded = sizeof(ULONG) - InformationBufferLength; 00787 Status = NDIS_STATUS_INVALID_LENGTH; 00788 break; 00789 } 00790 00791 NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG)); 00792 if (GenericULONG > DRIVER_MAXIMUM_LOOKAHEAD) 00793 Status = NDIS_STATUS_INVALID_LENGTH; 00794 else 00795 Adapter->LookaheadSize = GenericULONG; 00796 break; 00797 case OID_802_3_MULTICAST_LIST: 00798 /* Verify length. Must be multiplum of hardware address length */ 00799 if ((InformationBufferLength % DRIVER_LENGTH_OF_ADDRESS) != 0) { 00800 *BytesRead = 0; 00801 *BytesNeeded = 0; 00802 Status = NDIS_STATUS_INVALID_LENGTH; 00803 break; 00804 } 00805 00806 /* Set new multicast address list */ 00807 NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength); 00808 00809 /* FIXME: Update hardware */ 00810 00811 break; 00812 default: 00813 NDIS_DbgPrint(MIN_TRACE, ("Invalid object ID (0x%X).\n", Oid)); 00814 *BytesRead = 0; 00815 *BytesNeeded = 0; 00816 Status = NDIS_STATUS_INVALID_OID; 00817 break; 00818 } 00819 00820 if (Status == NDIS_STATUS_SUCCESS) { 00821 *BytesRead = InformationBufferLength; 00822 *BytesNeeded = 0; 00823 } 00824 00825 NDIS_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status)); 00826 00827 return Status; 00828 } 00829 00830 00831 static NDIS_STATUS NTAPI MiniportTransferData( 00832 OUT PNDIS_PACKET Packet, 00833 OUT PUINT BytesTransferred, 00834 IN NDIS_HANDLE MiniportAdapterContext, 00835 IN NDIS_HANDLE MiniportReceiveContext, 00836 IN UINT ByteOffset, 00837 IN UINT BytesToTransfer) 00838 /* 00839 * FUNCTION: Transfers data from a received frame into an NDIS packet 00840 * ARGUMENTS: 00841 * Packet = Address of packet to copy received data into 00842 * BytesTransferred = Address of buffer to place number of bytes transmitted 00843 * MiniportAdapterContext = Pointer to adapter context area 00844 * MiniportReceiveContext = Pointer to receive context area (actually NULL) 00845 * ByteOffset = Offset within received packet to begin copying 00846 * BytesToTransfer = Number of bytes to copy into packet 00847 * RETURNS: 00848 * Status of operation 00849 */ 00850 { 00851 PNDIS_BUFFER DstBuffer; 00852 UINT BytesCopied, BytesToCopy, DstSize; 00853 ULONG SrcData; 00854 PUCHAR DstData; 00855 UINT RecvStart; 00856 UINT RecvStop; 00857 PNIC_ADAPTER Adapter = (PNIC_ADAPTER)MiniportAdapterContext; 00858 00859 NDIS_DbgPrint(MAX_TRACE, ("Called. Packet (0x%X) ByteOffset (0x%X) BytesToTransfer (%d).\n", 00860 Packet, ByteOffset, BytesToTransfer)); 00861 00862 if (BytesToTransfer == 0) { 00863 *BytesTransferred = 0; 00864 return NDIS_STATUS_SUCCESS; 00865 } 00866 00867 RecvStart = Adapter->PageStart * DRIVER_BLOCK_SIZE; 00868 RecvStop = Adapter->PageStop * DRIVER_BLOCK_SIZE; 00869 00870 NdisQueryPacket(Packet, NULL, NULL, &DstBuffer, NULL); 00871 NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 00872 00873 SrcData = Adapter->PacketOffset + sizeof(DISCARD_HEADER) + ByteOffset; 00874 if (ByteOffset + sizeof(DISCARD_HEADER) + BytesToTransfer > 00875 Adapter->PacketHeader.PacketLength) 00876 BytesToTransfer = Adapter->PacketHeader.PacketLength - 00877 sizeof(DISCARD_HEADER) - ByteOffset; 00878 00879 /* Start copying the data */ 00880 BytesCopied = 0; 00881 for (;;) { 00882 BytesToCopy = (DstSize < BytesToTransfer) ? DstSize : BytesToTransfer; 00883 if (SrcData + BytesToCopy > RecvStop) 00884 BytesToCopy = (RecvStop - SrcData); 00885 00886 NICReadData(Adapter, DstData, SrcData, BytesToCopy); 00887 00888 BytesCopied += BytesToCopy; 00889 SrcData += BytesToCopy; 00890 DstData = (PUCHAR)((ULONG_PTR) DstData + BytesToCopy); 00891 BytesToTransfer -= BytesToCopy; 00892 if (BytesToTransfer == 0) 00893 break; 00894 00895 DstSize -= BytesToCopy; 00896 if (DstSize == 0) { 00897 /* No more bytes in destination buffer. Proceed to 00898 the next buffer in the destination buffer chain */ 00899 NdisGetNextBuffer(DstBuffer, &DstBuffer); 00900 if (!DstBuffer) 00901 break; 00902 00903 NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 00904 } 00905 00906 if (SrcData == RecvStop) 00907 SrcData = RecvStart; 00908 } 00909 00910 NDIS_DbgPrint(MID_TRACE, ("Transferred (%d) bytes.\n", BytesToTransfer)); 00911 00912 *BytesTransferred = BytesCopied; 00913 00914 return NDIS_STATUS_SUCCESS; 00915 } 00916 00917 00918 NTSTATUS 00919 NTAPI 00920 DriverEntry( 00921 PDRIVER_OBJECT DriverObject, 00922 PUNICODE_STRING RegistryPath) 00923 /* 00924 * FUNCTION: Main driver entry point 00925 * ARGUMENTS: 00926 * DriverObject = Pointer to a driver object for this driver 00927 * RegistryPath = Registry node for configuration parameters 00928 * RETURNS: 00929 * Status of driver initialization 00930 */ 00931 { 00932 NDIS_STATUS Status; 00933 NDIS_HANDLE NdisWrapperHandle; 00934 NDIS_MINIPORT_CHARACTERISTICS Miniport; 00935 00936 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00937 00938 NdisZeroMemory(&Miniport, sizeof(Miniport)); 00939 Miniport.MajorNdisVersion = DRIVER_NDIS_MAJOR_VERSION; 00940 Miniport.MinorNdisVersion = DRIVER_NDIS_MINOR_VERSION; 00941 Miniport.CheckForHangHandler = MiniportCheckForHang; 00942 Miniport.DisableInterruptHandler = MiniportDisableInterrupt; 00943 Miniport.EnableInterruptHandler = MiniportEnableInterrupt; 00944 Miniport.HaltHandler = MiniportHalt; 00945 Miniport.HandleInterruptHandler = MiniportHandleInterrupt; 00946 Miniport.InitializeHandler = MiniportInitialize; 00947 Miniport.ISRHandler = MiniportISR; 00948 Miniport.QueryInformationHandler = MiniportQueryInformation; 00949 Miniport.ReconfigureHandler = MiniportReconfigure; 00950 Miniport.ResetHandler = MiniportReset; 00951 Miniport.SendHandler = MiniportSend; 00952 Miniport.SetInformationHandler = MiniportSetInformation; 00953 Miniport.TransferDataHandler = MiniportTransferData; 00954 00955 NdisMInitializeWrapper(&NdisWrapperHandle, 00956 DriverObject, 00957 RegistryPath, 00958 NULL); 00959 00960 if (!NdisWrapperHandle) { 00961 NDIS_DbgPrint(MIN_TRACE, ("NdisMInitializeWrapper() failed\n")); 00962 return STATUS_UNSUCCESSFUL; 00963 } 00964 00965 DriverInfo.NdisWrapperHandle = NdisWrapperHandle; 00966 DriverInfo.NdisMacHandle = NULL; 00967 InitializeListHead(&DriverInfo.AdapterListHead); 00968 00969 Status = NdisMRegisterMiniport(NdisWrapperHandle, 00970 &Miniport, 00971 sizeof(NDIS_MINIPORT_CHARACTERISTICS)); 00972 if (Status != NDIS_STATUS_SUCCESS) { 00973 NDIS_DbgPrint(MIN_TRACE, ("NdisMRegisterMiniport() failed with status code (0x%X).\n", Status)); 00974 NdisTerminateWrapper(NdisWrapperHandle, NULL); 00975 return STATUS_UNSUCCESSFUL; 00976 } 00977 00978 return STATUS_SUCCESS; 00979 } 00980 00981 #if 0 00982 /* while i'm here - some basic registry sanity checks */ 00983 { 00984 /* write tests */ 00985 NDIS_CONFIGURATION_PARAMETER ParameterValue; 00986 00987 ParameterValue.ParameterType = NdisParameterInteger; 00988 ParameterValue.ParameterData.IntegerData = 0x12345678; 00989 NdisInitUnicodeString(&Keyword, L"DwordTest"); 00990 NdisWriteConfiguration(&Status, ConfigurationHandle, &Keyword, &ParameterValue); 00991 00992 if(Status != NDIS_STATUS_SUCCESS) 00993 { 00994 DbgPrint("ne2000!MiniportInitialize: failed to set DwordTest: 0x%x\n", Status); 00995 DbgBreakPoint(); 00996 } 00997 00998 DbgPrint("ne2000!MiniportInitialize: DwordTest successfully set\n"); 00999 01000 NdisInitUnicodeString(&Keyword, L"StringTest"); 01001 ParameterValue.ParameterType = NdisParameterString; 01002 NdisInitUnicodeString(&ParameterValue.ParameterData.StringData, L"Testing123"); 01003 01004 NdisWriteConfiguration(&Status, ConfigurationHandle, &Keyword, &ParameterValue); 01005 01006 if(Status != NDIS_STATUS_SUCCESS) 01007 { 01008 DbgPrint("ne2000!MiniportInitialize: failed to set StringTest: 0x%x\n", Status); 01009 DbgBreakPoint(); 01010 } 01011 01012 DbgPrint("ne2000!MiniportInitialize: StringTest successfully set\n"); 01013 } 01014 01015 { 01016 /* read back the test values */ 01017 NDIS_CONFIGURATION_PARAMETER *ParameterValue = 0; 01018 01019 NdisInitUnicodeString(&Keyword, L"DwordTest"); 01020 NdisReadConfiguration(&Status, &ParameterValue, ConfigurationHandle, &Keyword, NdisParameterInteger); 01021 01022 if(Status != NDIS_STATUS_SUCCESS) 01023 { 01024 DbgPrint("ne2000!MiniportInitialize: failed to read DwordTest: 0x%x\n", Status); 01025 DbgBreakPoint(); 01026 } 01027 01028 if(ParameterValue->ParameterData.IntegerData != 0x12345678) 01029 { 01030 DbgPrint("ne2000!MiniportInitialize: DwordTest value is wrong: 0x%x\n", 01031 ParameterValue->ParameterData.IntegerData); 01032 DbgBreakPoint(); 01033 } 01034 01035 DbgPrint("ne2000!MiniportInitialize: DwordTest value was correctly read\n"); 01036 01037 NdisInitUnicodeString(&Keyword, L"StringTest"); 01038 NdisReadConfiguration(&Status, &ParameterValue, ConfigurationHandle, &Keyword, NdisParameterString); 01039 01040 if(Status != NDIS_STATUS_SUCCESS) 01041 { 01042 DbgPrint("ne2000!MiniportInitialize: failed to read StringTest: 0x%x\n", Status); 01043 DbgBreakPoint(); 01044 } 01045 01046 if(wcsncmp(ParameterValue->ParameterData.StringData.Buffer, L"Testing123", 01047 wcslen(L"Testing123"))) 01048 { 01049 DbgPrint("ne2000!MiniportInitialize: StringTest value is wrong: %wZ\n", 01050 &ParameterValue->ParameterData.StringData); 01051 DbgBreakPoint(); 01052 } 01053 01054 DbgPrint("ne2000!MiniportInitialize: StringTest value was correctly read\n"); 01055 } 01056 01057 #endif 01058 /* EOF */ Generated on Fri May 25 2012 04:15:06 for ReactOS by
1.7.6.1
|