Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

681 lines
25 KiB

  1. /*
  2. (C) Copyright 1999
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the same terms
  7. outlined in the Microsoft Windows Device Driver Development Kit.
  8. (C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
  9. License to use this software is granted under the terms outlined in
  10. the Microsoft Windows Device Driver Development Kit.
  11. @doc INTERNAL Miniport Miniport_c
  12. @module Miniport.c |
  13. This module implements the <f DriverEntry> routine, which is the first
  14. routine called when the driver is loaded into memory. The Miniport
  15. initialization and termination routines are also implemented here.
  16. @comm
  17. This module should not require any changes.
  18. @head3 Contents |
  19. @index class,mfunc,func,msg,mdata,struct,enum | Miniport_c
  20. @end
  21. */
  22. #define __FILEID__ MINIPORT_DRIVER_OBJECT_TYPE
  23. // Unique file ID for error logging
  24. #include "Miniport.h" // Defines all the miniport objects
  25. #include "TpiParam.h"
  26. #if defined(NDIS_LCODE)
  27. # pragma NDIS_LCODE // Windows 9x wants this code locked down!
  28. # pragma NDIS_LDATA
  29. #endif
  30. DBG_STATIC NDIS_HANDLE g_NdisWrapperHandle = NULL; // @globalv
  31. // Receives the context value representing the Miniport wrapper
  32. // as returned from NdisMInitializeWrapper.
  33. NDIS_PHYSICAL_ADDRESS g_HighestAcceptableAddress = // @globalv
  34. // This constant is used for places where NdisAllocateMemory needs to be
  35. // called and the g_HighestAcceptableAddress does not matter.
  36. NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
  37. /* @doc EXTERNAL INTERNAL Miniport Miniport_c DriverEntry
  38. @func
  39. <f DriverEntry> is called by the operating system when a driver is loaded.
  40. This function creates an association between the miniport NIC driver and
  41. the NDIS library and registers the miniport's characteristics with NDIS.
  42. DriverEntry calls NdisMInitializeWrapper and then NdisMRegisterMiniport.
  43. DriverEntry passes both pointers it received to NdisMInitializeWrapper,
  44. which returns a wrapper handle. DriverEntry passes the wrapper handle to
  45. NdisMRegisterMiniport.
  46. The registry contains data that is persistent across system boots, as well
  47. as configuration information generated anew at each system boot. During
  48. driver installation, data describing the driver and the NIC is stored in
  49. the registry. The registry contains adapter characteristics that are read
  50. by the NIC driver to initialize itself and the NIC. See the Kernel-Mode
  51. Driver Design Guide for more about the registry and the Programmer's Guide
  52. for more information about the .inf files that install the driver and
  53. write to the registry.
  54. @comm
  55. Every miniport driver must provide a function called DriverEntry. By
  56. convention, DriverEntry is the entry point address for a driver. If a
  57. driver does not use the name DriverEntry, the driver developer must define
  58. the name of its entry function to the linker so that the entry point
  59. address can be known into the OS loader.
  60. It is interesting to note, that at the time DriverEntry is called, the OS
  61. doesn't know that the driver is an NDIS driver. The OS thinks it is just
  62. another driver being loaded. So it is possible to do anything any driver
  63. might do at this point. Since NDIS is the one who requested this driver
  64. to be loaded, it would be polite to register with the NDIS wrapper. But
  65. you can also hook into other OS functions to use and provide interfaces
  66. outside the NDIS wrapper. (Not recommended for the faint of heart).
  67. @comm
  68. The parameters passed to DriverEntry are OS specific! NT passes in valid
  69. values, but Windows 3.1 and Windows 95 just pass in zeros. We don't
  70. care, because we just pass them to the NDIS wrapper anyway.
  71. @rdesc
  72. <f DriverEntry> returns zero if it is successful.<nl>
  73. Otherwise, a non-zero return value indicates an error condition.
  74. */
  75. NTSTATUS DriverEntry(
  76. IN PDRIVER_OBJECT DriverObject, // @parm
  77. // A pointer to the driver object, which was created by the I/O system.
  78. IN PUNICODE_STRING RegistryPath // @parm
  79. // A pointer to the registry path, which specifies where driver-specific
  80. // parameters are stored.
  81. )
  82. {
  83. DBG_FUNC("DriverEntry")
  84. NDIS_STATUS Status;
  85. // Status result returned from an NDIS function call.
  86. NTSTATUS Result;
  87. // Result code returned by this function.
  88. NDIS_MINIPORT_CHARACTERISTICS NdisCharacteristics;
  89. // Characteristics table passed to NdisMWanRegisterMiniport.
  90. /*
  91. // Setup default debug flags then breakpoint so we can tweak them
  92. // when this module is first loaded. It is also useful to see the
  93. // build date and time to be sure it's the one you think it is.
  94. */
  95. #if DBG
  96. DbgInfo->DbgFlags = DBG_DEFAULTS;
  97. DbgInfo->DbgID[0] = '0';
  98. DbgInfo->DbgID[1] = ':';
  99. if (sizeof(VER_TARGET_STR) < sizeof(DbgInfo->DbgID)-3)
  100. {
  101. memcpy(&DbgInfo->DbgID[2], VER_TARGET_STR, sizeof(VER_TARGET_STR));
  102. }
  103. else
  104. {
  105. memcpy(&DbgInfo->DbgID[2], VER_TARGET_STR, sizeof(DbgInfo->DbgID)-3);
  106. DbgInfo->DbgID[sizeof(DbgInfo->DbgID)-1] = 0;
  107. }
  108. #endif // DBG
  109. DBG_PRINT((VER_TARGET_STR": Build Date:"__DATE__" Time:"__TIME__"\n"));
  110. DBG_PRINT((VER_TARGET_STR": DbgInfo=0x%X DbgFlags=0x%X\n",
  111. DbgInfo, DbgInfo->DbgFlags));
  112. DBG_BREAK(DbgInfo);
  113. DBG_ENTER(DbgInfo);
  114. DBG_PARAMS(DbgInfo,
  115. ("\n"
  116. "\t|DriverObject=0x%X\n"
  117. "\t|RegistryPath=0x%X\n",
  118. DriverObject,
  119. RegistryPath
  120. ));
  121. /*
  122. // Initialize the Miniport wrapper - THIS MUST BE THE FIRST NDIS CALL.
  123. */
  124. NdisMInitializeWrapper(
  125. &g_NdisWrapperHandle,
  126. DriverObject,
  127. RegistryPath,
  128. NULL
  129. );
  130. ASSERT(g_NdisWrapperHandle);
  131. /*
  132. // Initialize the characteristics table, exporting the Miniport's entry
  133. // points to the Miniport wrapper.
  134. */
  135. NdisZeroMemory((PVOID)&NdisCharacteristics, sizeof(NdisCharacteristics));
  136. NdisCharacteristics.MajorNdisVersion = NDIS_MAJOR_VERSION;
  137. NdisCharacteristics.MinorNdisVersion = NDIS_MINOR_VERSION;
  138. NdisCharacteristics.Reserved = NDIS_USE_WAN_WRAPPER;
  139. NdisCharacteristics.InitializeHandler = MiniportInitialize;
  140. NdisCharacteristics.CheckForHangHandler = MiniportCheckForHang;
  141. NdisCharacteristics.HaltHandler = MiniportHalt;
  142. NdisCharacteristics.ResetHandler = MiniportReset;
  143. NdisCharacteristics.ReturnPacketHandler = MiniportReturnPacket;
  144. NdisCharacteristics.CoActivateVcHandler = MiniportCoActivateVc;
  145. NdisCharacteristics.CoDeactivateVcHandler = MiniportCoDeactivateVc;
  146. NdisCharacteristics.CoRequestHandler = MiniportCoRequest;
  147. NdisCharacteristics.CoSendPacketsHandler = MiniportCoSendPackets;
  148. // These two routines are not needed because we are an MCM.
  149. // NdisCharacteristics.CoCreateVcHandler = MiniportCoCreateVc;
  150. // NdisCharacteristics.CoDeleteVcHandler = MiniportCoDeleteVc;
  151. /*
  152. // If the adapter does not generate an interrupt, these entry points
  153. // are not required. Otherwise, you can use the have the ISR routine
  154. // called each time an interupt is generated, or you can use the
  155. // enable/disable routines.
  156. */
  157. #if defined(CARD_REQUEST_ISR)
  158. # if (CARD_REQUEST_ISR == FALSE)
  159. NdisCharacteristics.DisableInterruptHandler = MiniportDisableInterrupt;
  160. NdisCharacteristics.EnableInterruptHandler = MiniportEnableInterrupt;
  161. # endif // CARD_REQUEST_ISR == FALSE
  162. NdisCharacteristics.HandleInterruptHandler = MiniportHandleInterrupt;
  163. NdisCharacteristics.ISRHandler = MiniportISR;
  164. #endif // defined(CARD_REQUEST_ISR)
  165. /*
  166. // Register the driver with the Miniport wrapper.
  167. */
  168. Status = NdisMRegisterMiniport(
  169. g_NdisWrapperHandle,
  170. (PNDIS_MINIPORT_CHARACTERISTICS) &NdisCharacteristics,
  171. sizeof(NdisCharacteristics)
  172. );
  173. /*
  174. // The driver will not load if this call fails.
  175. // The system will log the error for us.
  176. */
  177. if (Status != NDIS_STATUS_SUCCESS)
  178. {
  179. DBG_ERROR(DbgInfo,("Status=0x%X\n",Status));
  180. Result = STATUS_UNSUCCESSFUL;
  181. }
  182. else
  183. {
  184. DBG_NOTICE(DbgInfo,("Status=0x%X\n",Status));
  185. Result = STATUS_SUCCESS;
  186. }
  187. DBG_RETURN(DbgInfo, Result);
  188. return (Result);
  189. }
  190. /* @doc EXTERNAL INTERNAL Miniport Miniport_c MiniportInitialize
  191. @func
  192. <f MiniportInitialize> is a required function that sets up a NIC (or
  193. virtual NIC) for network I/O operations, claims all hardware resources
  194. necessary to the NIC in the registry, and allocates resources the driver
  195. needs to carry out network I/O operations.
  196. @comm
  197. No other outstanding requests to the miniport driver are possible when
  198. MiniportInitialize is called. No other request is submitted to the
  199. miniport driver until initialization is completed.
  200. The NDIS library supplies an array of supported media types. The miniport
  201. driver reads this array and provides the index of the media type that the
  202. NDIS library should use with this miniport driver. If the miniport driver
  203. is emulating a media type, its emulation must be transparent to the NDIS
  204. library.
  205. MiniportInitialize must call NdisMSetAttributes in order to return
  206. MiniportAdapterContext.
  207. If the miniport driver cannot find a common media type supported by both
  208. itself and the NDIS library, it should return
  209. NDIS_STATUS_UNSUPPORTED_MEDIA.
  210. If NDIS_STATUS_OPEN_ERROR is returned, the NDIS wrapper can examine the
  211. output parameter OpenErrorStatus to obtain more information about the
  212. error.
  213. MiniportInitialize is called with interrupts enabled. MiniportISR is
  214. called if the NIC generates any interrupts. The NDIS library will not call
  215. MiniportDisableInterrupt and MiniportEnableInterrupt during the
  216. MiniportInitialize function, so it is the responsibility of the miniport
  217. driver to acknowledge and clear any interrupts generated.
  218. @rdesc
  219. <f MiniportInitialize> returns zero if it is successful.<nl>
  220. Otherwise, a non-zero return value indicates an error condition.
  221. */
  222. NDIS_STATUS MiniportInitialize(
  223. OUT PNDIS_STATUS OpenErrorStatus, // @parm
  224. // Points to a variable that MiniportInitialize sets to an
  225. // NDIS_STATUS_XXX code specifying additional information about the
  226. // error if MiniportInitialize will return NDIS_STATUS_OPEN_ERROR.
  227. OUT PUINT SelectedMediumIndex, // @parm
  228. // Points to a variable in which MiniportInitialize sets the index of
  229. // the MediumArray element that specifies the medium type the driver
  230. // or its NIC uses.
  231. IN PNDIS_MEDIUM MediumArray, // @parm
  232. // Specifies an array of NdisMediumXxx values from which
  233. // MiniportInitialize selects one that its NIC supports or that the
  234. // driver supports as an interface to higher-level drivers.
  235. IN UINT MediumArraySize, // @parm
  236. // Specifies the number of elements at MediumArray.
  237. IN NDIS_HANDLE MiniportAdapterHandle, // @parm
  238. // Specifies a handle identifying the miniport's NIC, which is assigned
  239. // by the NDIS library. MiniportInitialize should save this handle; it
  240. // is a required parameter in subsequent calls to NdisXxx functions.
  241. IN NDIS_HANDLE WrapperConfigurationContext // @parm
  242. // Specifies a handle used only during initialization for calls to
  243. // NdisXxx configuration and initialization functions. For example,
  244. // this handle is a required parameter to NdisOpenConfiguration and
  245. // the NdisImmediateReadXxx and NdisImmediateWriteXxx functions.
  246. )
  247. {
  248. DBG_FUNC("MiniportInitialize")
  249. NDIS_STATUS Status;
  250. // Status result returned from an NDIS function call.
  251. PMINIPORT_ADAPTER_OBJECT pAdapter;
  252. // Pointer to our newly allocated object.
  253. UINT Index;
  254. // Loop counter.
  255. NDIS_CALL_MANAGER_CHARACTERISTICS McmCharacteristics;
  256. // Characteristics table passed to NdisMCmRegisterAddressFamily.
  257. CO_ADDRESS_FAMILY McmAddressFamily;
  258. // Address family passed to NdisMCmRegisterAddressFamily.
  259. DBG_ENTER(DbgInfo);
  260. DBG_PARAMS(DbgInfo,
  261. ("\n"
  262. "\t|OpenErrorStatus=0x%X\n"
  263. "\t|SelectedMediumIndex=0x%X\n"
  264. "\t|MediumArray=0x%X\n"
  265. "\t|MediumArraySize=0x%X\n"
  266. "\t|MiniportAdapterHandle=0x%X\n"
  267. "\t|WrapperConfigurationContext=0x%X\n",
  268. OpenErrorStatus,
  269. SelectedMediumIndex,
  270. MediumArray,
  271. MediumArraySize,
  272. MiniportAdapterHandle,
  273. WrapperConfigurationContext
  274. ));
  275. /*
  276. // Search the MediumArray for the NdisMediumCoWan media type.
  277. */
  278. for (Index = 0; Index < MediumArraySize; Index++)
  279. {
  280. if (MediumArray[Index] == NdisMediumCoWan)
  281. {
  282. break;
  283. }
  284. }
  285. /*
  286. // Make sure the protocol has requested the proper media type.
  287. */
  288. if (Index < MediumArraySize)
  289. {
  290. /*
  291. // Allocate memory for the adapter information structure.
  292. */
  293. Status = AdapterCreate(
  294. &pAdapter,
  295. MiniportAdapterHandle,
  296. WrapperConfigurationContext
  297. );
  298. if (Status == NDIS_STATUS_SUCCESS)
  299. {
  300. /*
  301. // Now it's time to initialize the hardware resources.
  302. */
  303. Status = AdapterInitialize(pAdapter);
  304. if (Status == NDIS_STATUS_SUCCESS)
  305. {
  306. /*
  307. // Initialize the address family so NDIS know's what we support.
  308. */
  309. NdisZeroMemory(&McmAddressFamily, sizeof(McmAddressFamily));
  310. McmAddressFamily.MajorVersion = NDIS_MAJOR_VERSION;
  311. McmAddressFamily.MinorVersion = NDIS_MINOR_VERSION;
  312. McmAddressFamily.AddressFamily = CO_ADDRESS_FAMILY_TAPI_PROXY;
  313. /*
  314. // Initialize the characteristics table, exporting the Miniport's entry
  315. // points to the Miniport wrapper.
  316. */
  317. NdisZeroMemory((PVOID)&McmCharacteristics, sizeof(McmCharacteristics));
  318. McmCharacteristics.MajorVersion = NDIS_MAJOR_VERSION;
  319. McmCharacteristics.MinorVersion = NDIS_MINOR_VERSION;
  320. McmCharacteristics.CmCreateVcHandler = ProtocolCoCreateVc;
  321. McmCharacteristics.CmDeleteVcHandler = ProtocolCoDeleteVc;
  322. McmCharacteristics.CmOpenAfHandler = ProtocolCmOpenAf;
  323. McmCharacteristics.CmCloseAfHandler = ProtocolCmCloseAf;
  324. McmCharacteristics.CmRegisterSapHandler = ProtocolCmRegisterSap;
  325. McmCharacteristics.CmDeregisterSapHandler = ProtocolCmDeregisterSap;
  326. McmCharacteristics.CmMakeCallHandler = ProtocolCmMakeCall;
  327. McmCharacteristics.CmCloseCallHandler = ProtocolCmCloseCall;
  328. McmCharacteristics.CmIncomingCallCompleteHandler = ProtocolCmIncomingCallComplete;
  329. McmCharacteristics.CmActivateVcCompleteHandler = ProtocolCmActivateVcComplete;
  330. McmCharacteristics.CmDeactivateVcCompleteHandler = ProtocolCmDeactivateVcComplete;
  331. McmCharacteristics.CmModifyCallQoSHandler = ProtocolCmModifyCallQoS;
  332. McmCharacteristics.CmRequestHandler = ProtocolCoRequest;
  333. McmCharacteristics.CmRequestCompleteHandler = ProtocolCoRequestComplete;
  334. DBG_NOTICE(pAdapter,("Calling NdisMCmRegisterAddressFamily\n"));
  335. Status = NdisMCmRegisterAddressFamily(
  336. MiniportAdapterHandle,
  337. &McmAddressFamily,
  338. &McmCharacteristics,
  339. sizeof(McmCharacteristics)
  340. );
  341. if (Status != NDIS_STATUS_SUCCESS)
  342. {
  343. DBG_ERROR(DbgInfo,("NdisMCmRegisterAddressFamily Status=0x%X\n",
  344. Status));
  345. /*
  346. // Log error message and return.
  347. */
  348. NdisWriteErrorLogEntry(
  349. MiniportAdapterHandle,
  350. NDIS_ERROR_CODE_OUT_OF_RESOURCES,
  351. 3,
  352. Status,
  353. __FILEID__,
  354. __LINE__
  355. );
  356. }
  357. }
  358. if (Status == NDIS_STATUS_SUCCESS)
  359. {
  360. /*
  361. // Save the selected media type.
  362. */
  363. *SelectedMediumIndex = Index;
  364. }
  365. else
  366. {
  367. /*
  368. // Something went wrong, so let's make sure everything is
  369. // cleaned up.
  370. */
  371. MiniportHalt(pAdapter);
  372. }
  373. }
  374. }
  375. else
  376. {
  377. DBG_ERROR(DbgInfo,("No NdisMediumCoWan found (Array=0x%X, ArraySize=%d)\n",
  378. MediumArray, MediumArraySize));
  379. /*
  380. // Log error message and return.
  381. */
  382. NdisWriteErrorLogEntry(
  383. MiniportAdapterHandle,
  384. NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
  385. 3,
  386. Index,
  387. __FILEID__,
  388. __LINE__
  389. );
  390. Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
  391. }
  392. /*
  393. // If all goes well, register a shutdown handler for this adapter.
  394. */
  395. if (Status == NDIS_STATUS_SUCCESS)
  396. {
  397. NdisMRegisterAdapterShutdownHandler(MiniportAdapterHandle,
  398. pAdapter, MiniportShutdown);
  399. }
  400. DBG_NOTICE(DbgInfo,("Status=0x%X\n",Status));
  401. DBG_RETURN(DbgInfo, Status);
  402. return (Status);
  403. }
  404. /* @doc EXTERNAL INTERNAL Miniport Miniport_c MiniportHalt
  405. @func
  406. <f MiniportHalt> request is used to halt the adapter such that it is
  407. no longer functioning.
  408. @comm
  409. The Miniport should stop the adapter and deregister all of its resources
  410. before returning from this routine.
  411. It is not necessary for the Miniport to complete all outstanding
  412. requests and no other requests will be submitted to the Miniport
  413. until the operation is completed.
  414. Interrupts are enabled during the call to this routine.
  415. */
  416. VOID MiniportHalt(
  417. IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
  418. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  419. )
  420. {
  421. DBG_FUNC("MiniportHalt")
  422. DBG_ENTER(DbgInfo);
  423. /*
  424. // Remove our shutdown handler from the system.
  425. */
  426. NdisMDeregisterAdapterShutdownHandler(pAdapter->MiniportAdapterHandle);
  427. /*
  428. // Free adapter instance.
  429. */
  430. AdapterDestroy(pAdapter);
  431. DBG_LEAVE(DbgInfo);
  432. }
  433. /* @doc EXTERNAL INTERNAL Miniport Miniport_c MiniportShutdown
  434. @func
  435. <f MiniportShutdown> is an optional function that restores a NIC to its
  436. initial state when the system is shut down, whether by the user or because
  437. an unrecoverable system error occurred.
  438. @comm
  439. Every NIC driver should have a <f MiniportShutdown> function.
  440. <f MiniportShutdown> does nothing more than restore the NIC to its initial
  441. state (before the miniport's DriverEntry function runs). However, this
  442. ensures that the NIC is in a known state and ready to be reinitialized
  443. when the machine is rebooted after a system shutdown occurs for any
  444. reason, including a crash dump.
  445. A NIC driver's MiniportInitialize function must call
  446. NdisMRegisterAdapterShutdownHandler to set up a <f MiniportShutdown>
  447. function. The driver's MiniportHalt function must make a reciprocal call
  448. to NdisMDeregisterAdapterShutdownHandler.
  449. If <f MiniportShutdown> is called due to a user-initiated system shutdown,
  450. it runs at IRQL PASSIVE_LEVEL in a system-thread context. If it is called
  451. due to an unrecoverable error, <f MiniportShutdown> runs at an arbitrary
  452. IRQL and in the context of whatever component raised the error. For
  453. example, <f MiniportShutdown> might be run at high DIRQL in the context of
  454. an ISR for a device essential to continued execution of the system.
  455. <f MiniportShutdown> should call no NdisXxx functions.
  456. */
  457. VOID MiniportShutdown(
  458. IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
  459. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  460. )
  461. {
  462. DBG_FUNC("MiniportShutdown")
  463. DBG_ENTER(pAdapter);
  464. /*
  465. // Reset the hardware and bial out - don't release any resources!
  466. */
  467. CardReset(pAdapter->pCard);
  468. DBG_LEAVE(pAdapter);
  469. }
  470. /* @doc EXTERNAL INTERNAL Miniport Miniport_c MiniportReset
  471. @func
  472. <f MiniportReset> request instructs the Miniport to issue a hardware
  473. reset to the network adapter. The Miniport also resets its software
  474. state.
  475. The <F MiniportReset> request may also reset the parameters of the adapter.
  476. If a hardware reset of the adapter resets the current station address
  477. to a value other than what it is currently configured to, the Miniport
  478. driver automatically restores the current station address following the
  479. reset. Any multicast or functional addressing masks reset by the
  480. hardware do not have to be reprogrammed by the Miniport.
  481. <f Note>: This is change from the NDIS 3.0 driver specification. If the
  482. multicast or functional addressing information, the packet filter, the
  483. lookahead size, and so on, needs to be restored, the Miniport indicates
  484. this with setting the flag AddressingReset to TRUE.
  485. It is not necessary for the Miniport to complete all outstanding requests
  486. and no other requests will be submitted to the Miniport until the
  487. operation is completed. Also, the Miniport does not have to signal
  488. the beginning and ending of the reset with NdisMIndicateStatus.
  489. <f Note>: These are different than the NDIS 3.0 driver specification.
  490. The Miniport must complete the original request, if the orginal
  491. call to <F MiniportReset> return NDIS_STATUS_PENDING, by calling
  492. NdisMResetComplete.
  493. If the underlying hardware does not provide a reset function under
  494. software control, then this request completes abnormally with
  495. NDIS_STATUS_NOT_RESETTABLE. If the underlying hardware attempts a
  496. reset and finds recoverable errors, the request completes successfully
  497. with NDIS_STATUS_SOFT_ERRORS. If the underlying hardware resets and,
  498. in the process, finds nonrecoverable errors, the request completes
  499. successfully with the status NDIS_STATUS_HARD_ERRORS. If the
  500. underlying hardware reset is accomplished without any errors,
  501. the request completes successfully with the status NDIS_STATUS_SUCCESS.
  502. Interrupts are in any state during this call.
  503. @comm
  504. I have only seen MiniportReset called when the driver is not working
  505. properly. If this gets called, your code is probably broken, so fix
  506. it. Don't try to recover here unless there is some hardware/firmware
  507. problem you must work around.
  508. @rdesc
  509. <f MiniportReset> returns zero if it is successful.<nl>
  510. Otherwise, a non-zero return value indicates an error condition.
  511. */
  512. NDIS_STATUS MiniportReset(
  513. OUT PBOOLEAN AddressingReset, // @parm
  514. // The Miniport indicates if the wrapper needs to call
  515. // <f MiniportCoRequest> to restore the addressing information
  516. // to the current values by setting this value to TRUE.
  517. IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
  518. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  519. )
  520. {
  521. DBG_FUNC("MiniportReset")
  522. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  523. // Result code returned by this function.
  524. DBG_ENTER(pAdapter);
  525. DBG_ERROR(pAdapter,("##### !!! THIS SHOULD NEVER BE CALLED !!! #####\n"));
  526. /*
  527. // If anything goes wrong here, it's very likely an unrecoverable
  528. // hardware failure. So we'll just shut this thing down for good.
  529. */
  530. Result = NDIS_STATUS_HARD_ERRORS;
  531. *AddressingReset = TRUE;
  532. return (Result);
  533. }