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.

882 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. miniport.c
  5. Abstract:
  6. NDIS wrapper functions
  7. Author:
  8. Sean Selitrennikoff (SeanSe) 05-Oct-93
  9. Jameel Hyder (JameelH) Re-organization 01-Jun-95
  10. Environment:
  11. Kernel mode, FSD
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. //
  17. // Define the module number for debug code.
  18. //
  19. #define MODULE_NUMBER MODULE_MINISUB
  20. VOID
  21. NdisAllocateSpinLock(
  22. IN PNDIS_SPIN_LOCK SpinLock
  23. )
  24. {
  25. INITIALIZE_SPIN_LOCK(&SpinLock->SpinLock);
  26. }
  27. VOID
  28. NdisFreeSpinLock(
  29. IN PNDIS_SPIN_LOCK SpinLock
  30. )
  31. {
  32. UNREFERENCED_PARAMETER(SpinLock);
  33. }
  34. VOID
  35. NdisAcquireSpinLock(
  36. IN PNDIS_SPIN_LOCK SpinLock
  37. )
  38. {
  39. NDIS_ACQUIRE_SPIN_LOCK(SpinLock, &SpinLock->OldIrql);
  40. }
  41. VOID
  42. NdisReleaseSpinLock(
  43. IN PNDIS_SPIN_LOCK SpinLock
  44. )
  45. {
  46. NDIS_RELEASE_SPIN_LOCK(SpinLock, SpinLock->OldIrql);
  47. }
  48. VOID
  49. NdisDprAcquireSpinLock(
  50. IN PNDIS_SPIN_LOCK SpinLock
  51. )
  52. {
  53. NDIS_ACQUIRE_SPIN_LOCK_DPC(SpinLock);
  54. SpinLock->OldIrql = DISPATCH_LEVEL;
  55. }
  56. VOID
  57. NdisDprReleaseSpinLock(
  58. IN PNDIS_SPIN_LOCK SpinLock
  59. )
  60. {
  61. NDIS_RELEASE_SPIN_LOCK_DPC(SpinLock);
  62. }
  63. #undef NdisFreeBuffer
  64. VOID
  65. NdisFreeBuffer(
  66. IN PNDIS_BUFFER Buffer
  67. )
  68. {
  69. IoFreeMdl(Buffer);
  70. }
  71. #undef NdisQueryBuffer
  72. VOID
  73. NdisQueryBuffer(
  74. IN PNDIS_BUFFER Buffer,
  75. OUT PVOID * VirtualAddress OPTIONAL,
  76. OUT PUINT Length
  77. )
  78. {
  79. if (ARGUMENT_PRESENT(VirtualAddress))
  80. {
  81. *VirtualAddress = MDL_ADDRESS(Buffer);
  82. }
  83. *Length = MDL_SIZE(Buffer);
  84. }
  85. VOID
  86. NdisQueryBufferSafe(
  87. IN PNDIS_BUFFER Buffer,
  88. OUT PVOID * VirtualAddress OPTIONAL,
  89. OUT PUINT Length,
  90. IN MM_PAGE_PRIORITY Priority
  91. )
  92. {
  93. if (ARGUMENT_PRESENT(VirtualAddress))
  94. {
  95. *VirtualAddress = MDL_ADDRESS_SAFE(Buffer, Priority);
  96. }
  97. *Length = MDL_SIZE(Buffer);
  98. }
  99. VOID
  100. NdisQueryBufferOffset(
  101. IN PNDIS_BUFFER Buffer,
  102. OUT PUINT Offset,
  103. OUT PUINT Length
  104. )
  105. {
  106. *Offset = MDL_OFFSET(Buffer);
  107. *Length = MDL_SIZE(Buffer);
  108. }
  109. VOID
  110. NdisGetFirstBufferFromPacket(
  111. IN PNDIS_PACKET Packet,
  112. OUT PNDIS_BUFFER * FirstBuffer,
  113. OUT PVOID * FirstBufferVA,
  114. OUT PUINT FirstBufferLength,
  115. OUT PUINT TotalBufferLength
  116. )
  117. {
  118. PNDIS_BUFFER pBuf;
  119. pBuf = Packet->Private.Head;
  120. *FirstBuffer = pBuf;
  121. if (pBuf)
  122. {
  123. *FirstBufferVA = MmGetSystemAddressForMdl(pBuf);
  124. *FirstBufferLength = *TotalBufferLength = MmGetMdlByteCount(pBuf);
  125. for (pBuf = pBuf->Next;
  126. pBuf != NULL;
  127. pBuf = pBuf->Next)
  128. {
  129. *TotalBufferLength += MmGetMdlByteCount(pBuf);
  130. }
  131. }
  132. else
  133. {
  134. *FirstBufferVA = 0;
  135. *FirstBufferLength = 0;
  136. *TotalBufferLength = 0;
  137. }
  138. }
  139. //
  140. // safe version of NdisGetFirstBufferFromPacket
  141. // if the memory described by the first buffer can not be mapped
  142. // this function will return NULL for FirstBuferVA
  143. //
  144. VOID
  145. NdisGetFirstBufferFromPacketSafe(
  146. IN PNDIS_PACKET Packet,
  147. OUT PNDIS_BUFFER * FirstBuffer,
  148. OUT PVOID * FirstBufferVA,
  149. OUT PUINT FirstBufferLength,
  150. OUT PUINT TotalBufferLength,
  151. IN MM_PAGE_PRIORITY Priority
  152. )
  153. {
  154. PNDIS_BUFFER pBuf;
  155. pBuf = Packet->Private.Head;
  156. *FirstBuffer = pBuf;
  157. if (pBuf)
  158. {
  159. *FirstBufferVA = MmGetSystemAddressForMdlSafe(pBuf, Priority);
  160. *FirstBufferLength = *TotalBufferLength = MmGetMdlByteCount(pBuf);
  161. for (pBuf = pBuf->Next;
  162. pBuf != NULL;
  163. pBuf = pBuf->Next)
  164. {
  165. *TotalBufferLength += MmGetMdlByteCount(pBuf);
  166. }
  167. }
  168. else
  169. {
  170. *FirstBufferVA = 0;
  171. *FirstBufferLength = 0;
  172. *TotalBufferLength = 0;
  173. }
  174. }
  175. ULONG
  176. NdisBufferLength(
  177. IN PNDIS_BUFFER Buffer
  178. )
  179. {
  180. return (MmGetMdlByteCount(Buffer));
  181. }
  182. PVOID
  183. NdisBufferVirtualAddress(
  184. IN PNDIS_BUFFER Buffer
  185. )
  186. {
  187. return (MDL_ADDRESS_SAFE(Buffer, HighPagePriority));
  188. }
  189. ULONG
  190. NDIS_BUFFER_TO_SPAN_PAGES(
  191. IN PNDIS_BUFFER Buffer
  192. )
  193. {
  194. if (MDL_SIZE(Buffer) == 0)
  195. {
  196. return 1;
  197. }
  198. return ADDRESS_AND_SIZE_TO_SPAN_PAGES(MDL_VA(Buffer), MDL_SIZE(Buffer));
  199. }
  200. VOID
  201. NdisGetBufferPhysicalArraySize(
  202. IN PNDIS_BUFFER Buffer,
  203. OUT PUINT ArraySize
  204. )
  205. {
  206. if (MDL_SIZE(Buffer) == 0)
  207. {
  208. *ArraySize = 1;
  209. }
  210. else
  211. {
  212. *ArraySize = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MDL_VA(Buffer), MDL_SIZE(Buffer));
  213. }
  214. }
  215. NDIS_STATUS
  216. NdisAnsiStringToUnicodeString(
  217. IN OUT PUNICODE_STRING DestinationString,
  218. IN PANSI_STRING SourceString
  219. )
  220. {
  221. NDIS_STATUS Status;
  222. Status = RtlAnsiStringToUnicodeString(DestinationString,
  223. SourceString,
  224. FALSE);
  225. return Status;
  226. }
  227. NDIS_STATUS
  228. NdisUnicodeStringToAnsiString(
  229. IN OUT PANSI_STRING DestinationString,
  230. IN PUNICODE_STRING SourceString
  231. )
  232. {
  233. NDIS_STATUS Status;
  234. Status = RtlUnicodeStringToAnsiString(DestinationString,
  235. SourceString,
  236. FALSE);
  237. return Status;
  238. }
  239. NDIS_STATUS
  240. NdisUpcaseUnicodeString(
  241. OUT PUNICODE_STRING DestinationString,
  242. IN PUNICODE_STRING SourceString
  243. )
  244. {
  245. return(RtlUpcaseUnicodeString(DestinationString, SourceString, FALSE));
  246. }
  247. VOID
  248. NdisMStartBufferPhysicalMapping(
  249. IN NDIS_HANDLE MiniportAdapterHandle,
  250. IN PNDIS_BUFFER Buffer,
  251. IN ULONG PhysicalMapRegister,
  252. IN BOOLEAN WriteToDevice,
  253. OUT PNDIS_PHYSICAL_ADDRESS_UNIT PhysicalAddressArray,
  254. OUT PUINT ArraySize
  255. )
  256. {
  257. NdisMStartBufferPhysicalMappingMacro(MiniportAdapterHandle,
  258. Buffer,
  259. PhysicalMapRegister,
  260. WriteToDevice,
  261. PhysicalAddressArray,
  262. ArraySize);
  263. }
  264. VOID
  265. NdisMCompleteBufferPhysicalMapping(
  266. IN NDIS_HANDLE MiniportAdapterHandle,
  267. IN PNDIS_BUFFER Buffer,
  268. IN ULONG PhysicalMapRegister
  269. )
  270. {
  271. NdisMCompleteBufferPhysicalMappingMacro(MiniportAdapterHandle,
  272. Buffer,
  273. PhysicalMapRegister);
  274. }
  275. #undef NdisInterlockedIncrement
  276. ULONG
  277. NdisInterlockedIncrement(
  278. IN PULONG Addend
  279. )
  280. /*++
  281. Return Value:
  282. (eax) < 0 (but not necessarily -1) if result of add < 0
  283. (eax) == 0 if result of add == 0
  284. (eax) > 0 (but not necessarily +1) if result of add > 0
  285. --*/
  286. {
  287. return(InterlockedIncrement(Addend));
  288. }
  289. #undef NdisInterlockedDecrement
  290. ULONG
  291. NdisInterlockedDecrement(
  292. IN PULONG Addend
  293. )
  294. /*++
  295. Return Value:
  296. (eax) < 0 (but not necessarily -1) if result of add < 0
  297. (eax) == 0 if result of add == 0
  298. (eax) > 0 (but not necessarily +1) if result of add > 0
  299. --*/
  300. {
  301. return(InterlockedDecrement(Addend));
  302. }
  303. #undef NdisInterlockedAddUlong
  304. ULONG
  305. NdisInterlockedAddUlong(
  306. IN PULONG Addend,
  307. IN ULONG Increment,
  308. IN PNDIS_SPIN_LOCK SpinLock
  309. )
  310. {
  311. return(ExInterlockedAddUlong(Addend,Increment, &SpinLock->SpinLock));
  312. }
  313. #undef NdisInterlockedInsertHeadList
  314. PLIST_ENTRY
  315. NdisInterlockedInsertHeadList(
  316. IN PLIST_ENTRY ListHead,
  317. IN PLIST_ENTRY ListEntry,
  318. IN PNDIS_SPIN_LOCK SpinLock
  319. )
  320. {
  321. return(ExInterlockedInsertHeadList(ListHead,ListEntry,&SpinLock->SpinLock));
  322. }
  323. #undef NdisInterlockedInsertTailList
  324. PLIST_ENTRY
  325. NdisInterlockedInsertTailList(
  326. IN PLIST_ENTRY ListHead,
  327. IN PLIST_ENTRY ListEntry,
  328. IN PNDIS_SPIN_LOCK SpinLock
  329. )
  330. {
  331. return(ExInterlockedInsertTailList(ListHead,ListEntry,&SpinLock->SpinLock));
  332. }
  333. #undef NdisInterlockedRemoveHeadList
  334. PLIST_ENTRY
  335. NdisInterlockedRemoveHeadList(
  336. IN PLIST_ENTRY ListHead,
  337. IN PNDIS_SPIN_LOCK SpinLock
  338. )
  339. {
  340. return(ExInterlockedRemoveHeadList(ListHead, &SpinLock->SpinLock));
  341. }
  342. #undef NdisInterlockedPushEntryList
  343. PSINGLE_LIST_ENTRY
  344. NdisInterlockedPushEntryList(
  345. IN PSINGLE_LIST_ENTRY ListHead,
  346. IN PSINGLE_LIST_ENTRY ListEntry,
  347. IN PNDIS_SPIN_LOCK Lock
  348. )
  349. {
  350. return(ExInterlockedPushEntryList(ListHead, ListEntry, &Lock->SpinLock));
  351. }
  352. #undef NdisInterlockedPopEntryList
  353. PSINGLE_LIST_ENTRY
  354. NdisInterlockedPopEntryList(
  355. IN PSINGLE_LIST_ENTRY ListHead,
  356. IN PNDIS_SPIN_LOCK Lock
  357. )
  358. {
  359. return(ExInterlockedPopEntryList(ListHead, &Lock->SpinLock));
  360. }
  361. //
  362. // Logging support for miniports
  363. //
  364. NDIS_STATUS
  365. NdisMCreateLog(
  366. IN NDIS_HANDLE MiniportAdapterHandle,
  367. IN UINT Size,
  368. OUT PNDIS_HANDLE LogHandle
  369. )
  370. {
  371. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)MiniportAdapterHandle;
  372. PNDIS_LOG Log = NULL;
  373. NDIS_STATUS Status;
  374. KIRQL OldIrql;
  375. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  376. if (Miniport->Log != NULL)
  377. {
  378. Status = NDIS_STATUS_FAILURE;
  379. }
  380. else
  381. {
  382. Log = ALLOC_FROM_POOL(sizeof(NDIS_LOG) + Size, NDIS_TAG_DBG_LOG);
  383. if (Log != NULL)
  384. {
  385. Status = NDIS_STATUS_SUCCESS;
  386. Miniport->Log = Log;
  387. INITIALIZE_SPIN_LOCK(&Log->LogLock);
  388. Log->Miniport = Miniport;
  389. Log->Irp = NULL;
  390. Log->TotalSize = Size;
  391. Log->CurrentSize = 0;
  392. Log->InPtr = 0;
  393. Log->OutPtr = 0;
  394. }
  395. else
  396. {
  397. Status = NDIS_STATUS_RESOURCES;
  398. }
  399. }
  400. *LogHandle = Log;
  401. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  402. return Status;
  403. }
  404. VOID
  405. NdisMCloseLog(
  406. IN NDIS_HANDLE LogHandle
  407. )
  408. {
  409. PNDIS_LOG Log = (PNDIS_LOG)LogHandle;
  410. PNDIS_MINIPORT_BLOCK Miniport;
  411. KIRQL OldIrql;
  412. Miniport = Log->Miniport;
  413. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  414. Miniport->Log = NULL;
  415. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  416. FREE_POOL(Log);
  417. }
  418. NDIS_STATUS
  419. NdisMWriteLogData(
  420. IN NDIS_HANDLE LogHandle,
  421. IN PVOID LogBuffer,
  422. IN UINT LogBufferSize
  423. )
  424. {
  425. PNDIS_LOG Log = (PNDIS_LOG)LogHandle;
  426. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  427. KIRQL OldIrql;
  428. UINT AmtToCopy;
  429. IoAcquireCancelSpinLock(&OldIrql);
  430. ACQUIRE_SPIN_LOCK_DPC(&Log->LogLock);
  431. if (LogBufferSize <= Log->TotalSize)
  432. {
  433. if (LogBufferSize <= (Log->TotalSize - Log->InPtr))
  434. {
  435. //
  436. // Can copy the entire buffer
  437. //
  438. CopyMemory(Log->LogBuf+Log->InPtr, LogBuffer, LogBufferSize);
  439. }
  440. else
  441. {
  442. //
  443. // We are going to wrap around. Copy it in two chunks.
  444. //
  445. AmtToCopy = Log->TotalSize - Log->InPtr;
  446. CopyMemory(Log->LogBuf+Log->InPtr,
  447. LogBuffer,
  448. AmtToCopy);
  449. CopyMemory(Log->LogBuf + 0,
  450. (PUCHAR)LogBuffer+AmtToCopy,
  451. LogBufferSize - AmtToCopy);
  452. }
  453. //
  454. // Update the current size
  455. //
  456. Log->CurrentSize += LogBufferSize;
  457. if (Log->CurrentSize > Log->TotalSize)
  458. Log->CurrentSize = Log->TotalSize;
  459. //
  460. // Update the InPtr and possibly the outptr
  461. //
  462. Log->InPtr += LogBufferSize;
  463. if (Log->InPtr >= Log->TotalSize)
  464. {
  465. Log->InPtr -= Log->TotalSize;
  466. }
  467. if (Log->CurrentSize == Log->TotalSize)
  468. {
  469. Log->OutPtr = Log->InPtr;
  470. }
  471. //
  472. // Check if there is a pending Irp to complete
  473. //
  474. if (Log->Irp != NULL)
  475. {
  476. PIRP Irp = Log->Irp;
  477. PUCHAR Buffer;
  478. Log->Irp = NULL;
  479. //
  480. // If the InPtr is lagging the OutPtr. then we can simply
  481. // copy the data over in one shot.
  482. //
  483. AmtToCopy = MDL_SIZE(Irp->MdlAddress);
  484. if (AmtToCopy > Log->CurrentSize)
  485. AmtToCopy = Log->CurrentSize;
  486. if ((Log->TotalSize - Log->OutPtr) >= AmtToCopy)
  487. {
  488. Buffer = MDL_ADDRESS_SAFE(Irp->MdlAddress, LowPagePriority);
  489. if (Buffer != NULL)
  490. {
  491. CopyMemory(Buffer,
  492. Log->LogBuf+Log->OutPtr,
  493. AmtToCopy);
  494. }
  495. else Status = NDIS_STATUS_RESOURCES;
  496. }
  497. else
  498. {
  499. Buffer = MDL_ADDRESS_SAFE(Irp->MdlAddress, LowPagePriority);
  500. if (Buffer != NULL)
  501. {
  502. CopyMemory(Buffer,
  503. Log->LogBuf+Log->OutPtr,
  504. Log->TotalSize-Log->OutPtr);
  505. CopyMemory(Buffer+Log->TotalSize-Log->OutPtr,
  506. Log->LogBuf,
  507. AmtToCopy - (Log->TotalSize-Log->OutPtr));
  508. }
  509. else Status = NDIS_STATUS_RESOURCES;
  510. }
  511. Log->CurrentSize -= AmtToCopy;
  512. Log->OutPtr += AmtToCopy;
  513. if (Log->OutPtr >= Log->TotalSize)
  514. Log->OutPtr -= Log->TotalSize;
  515. Irp->IoStatus.Information = AmtToCopy;
  516. IoSetCancelRoutine(Irp, NULL);
  517. Irp->IoStatus.Status = STATUS_SUCCESS;
  518. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  519. }
  520. }
  521. else
  522. {
  523. Status = NDIS_STATUS_BUFFER_OVERFLOW;
  524. }
  525. RELEASE_SPIN_LOCK_DPC(&Log->LogLock);
  526. IoReleaseCancelSpinLock(OldIrql);
  527. return Status;
  528. }
  529. NDIS_STATUS
  530. FASTCALL
  531. ndisMGetLogData(
  532. IN PNDIS_MINIPORT_BLOCK Miniport,
  533. IN PIRP Irp
  534. )
  535. {
  536. NTSTATUS Status = STATUS_SUCCESS;
  537. KIRQL OldIrql;
  538. PNDIS_LOG Log;
  539. UINT AmtToCopy;
  540. IoAcquireCancelSpinLock(&OldIrql);
  541. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  542. if ((Log = Miniport->Log) != NULL)
  543. {
  544. ACQUIRE_SPIN_LOCK_DPC(&Log->LogLock);
  545. if (Log->CurrentSize != 0)
  546. {
  547. PUCHAR Buffer;
  548. //
  549. // If the InPtr is lagging the OutPtr. then we can simply
  550. // copy the data over in one shot.
  551. //
  552. AmtToCopy = MDL_SIZE(Irp->MdlAddress);
  553. if (AmtToCopy > Log->CurrentSize)
  554. AmtToCopy = Log->CurrentSize;
  555. Buffer = MDL_ADDRESS_SAFE(Irp->MdlAddress, LowPagePriority);
  556. if (Buffer != NULL)
  557. {
  558. if ((Log->TotalSize - Log->OutPtr) >= AmtToCopy)
  559. {
  560. CopyMemory(Buffer,
  561. Log->LogBuf+Log->OutPtr,
  562. AmtToCopy);
  563. }
  564. else
  565. {
  566. CopyMemory(Buffer,
  567. Log->LogBuf+Log->OutPtr,
  568. Log->TotalSize-Log->OutPtr);
  569. CopyMemory(Buffer+Log->TotalSize-Log->OutPtr,
  570. Log->LogBuf,
  571. AmtToCopy - (Log->TotalSize-Log->OutPtr));
  572. }
  573. Log->CurrentSize -= AmtToCopy;
  574. Log->OutPtr += AmtToCopy;
  575. if (Log->OutPtr >= Log->TotalSize)
  576. Log->OutPtr -= Log->TotalSize;
  577. Irp->IoStatus.Information = AmtToCopy;
  578. Status = STATUS_SUCCESS;
  579. }
  580. else
  581. {
  582. Status = STATUS_INSUFFICIENT_RESOURCES;
  583. }
  584. }
  585. else if (Log->Irp != NULL)
  586. {
  587. Status = STATUS_UNSUCCESSFUL;
  588. }
  589. else
  590. {
  591. IoSetCancelRoutine(Irp, ndisCancelLogIrp);
  592. Log->Irp = Irp;
  593. Status = STATUS_PENDING;
  594. }
  595. RELEASE_SPIN_LOCK_DPC(&Log->LogLock);
  596. }
  597. else
  598. {
  599. Status = STATUS_UNSUCCESSFUL;
  600. }
  601. NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  602. IoReleaseCancelSpinLock(OldIrql);
  603. return Status;
  604. }
  605. VOID
  606. NdisMFlushLog(
  607. IN NDIS_HANDLE LogHandle
  608. )
  609. {
  610. PNDIS_LOG Log = (PNDIS_LOG)LogHandle;
  611. KIRQL OldIrql;
  612. ACQUIRE_SPIN_LOCK(&Log->LogLock, &OldIrql);
  613. Log->InPtr = 0;
  614. Log->OutPtr = 0;
  615. Log->CurrentSize = 0;
  616. RELEASE_SPIN_LOCK(&Log->LogLock, OldIrql);
  617. }
  618. NDIS_STATUS
  619. NdisMQueryAdapterInstanceName(
  620. OUT PNDIS_STRING pAdapterInstanceName,
  621. IN NDIS_HANDLE NdisAdapterHandle
  622. )
  623. {
  624. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)NdisAdapterHandle;
  625. USHORT cbSize;
  626. PVOID ptmp = NULL;
  627. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  628. NTSTATUS NtStatus;
  629. DBGPRINT(DBG_COMP_CONFIG, DBG_LEVEL_INFO,
  630. ("==>NdisMQueryAdapterInstanceName\n"));
  631. //
  632. // If we failed to create the adapter instance name then fail this call.
  633. //
  634. if (NULL != Miniport->pAdapterInstanceName)
  635. {
  636. //
  637. // Allocate storage for the copy of the adapter instance name.
  638. //
  639. cbSize = Miniport->pAdapterInstanceName->MaximumLength;
  640. //
  641. // Allocate storage for the new string.
  642. //
  643. ptmp = ALLOC_FROM_POOL(cbSize, NDIS_TAG_NAME_BUF);
  644. if (NULL != ptmp)
  645. {
  646. RtlZeroMemory(ptmp, cbSize);
  647. pAdapterInstanceName->Buffer = ptmp;
  648. pAdapterInstanceName->Length = 0;
  649. pAdapterInstanceName->MaximumLength = cbSize;
  650. NtStatus = RtlAppendUnicodeStringToString(
  651. pAdapterInstanceName,
  652. Miniport->pAdapterInstanceName);
  653. if (NT_SUCCESS(NtStatus))
  654. {
  655. Status = NDIS_STATUS_SUCCESS;
  656. }
  657. }
  658. else
  659. {
  660. Status = NDIS_STATUS_RESOURCES;
  661. }
  662. }
  663. if (NDIS_STATUS_SUCCESS != Status)
  664. {
  665. if (NULL != ptmp)
  666. {
  667. FREE_POOL(ptmp);
  668. }
  669. }
  670. DBGPRINT(DBG_COMP_CONFIG, DBG_LEVEL_INFO,
  671. ("<==NdisMQueryAdapterInstanceName: 0x%x\n", Status));
  672. return(Status);
  673. }
  674. EXPORT
  675. VOID
  676. NdisInitializeReadWriteLock(
  677. IN PNDIS_RW_LOCK Lock
  678. )
  679. {
  680. NdisZeroMemory(Lock, sizeof(NDIS_RW_LOCK));
  681. }
  682. VOID
  683. NdisAcquireReadWriteLock(
  684. IN PNDIS_RW_LOCK Lock,
  685. IN BOOLEAN fWrite,
  686. IN PLOCK_STATE LockState
  687. )
  688. {
  689. if (fWrite)
  690. {
  691. LockState->LockState = WRITE_LOCK_STATE_UNKNOWN;
  692. {
  693. UINT i, refcount;
  694. ULONG Prc;
  695. /*
  696. * This means we need to attempt to acquire the lock,
  697. * if we do not already own it.
  698. * Set the state accordingly.
  699. */
  700. if ((Lock)->Context == CURRENT_THREAD)
  701. {
  702. (LockState)->LockState = LOCK_STATE_ALREADY_ACQUIRED;
  703. }
  704. else
  705. {
  706. ACQUIRE_SPIN_LOCK(&(Lock)->SpinLock, &(LockState)->OldIrql);
  707. Prc = KeGetCurrentProcessorNumber();
  708. refcount = (Lock)->RefCount[Prc].RefCount;
  709. (Lock)->RefCount[Prc].RefCount = 0;
  710. /* wait for all readers to exit */
  711. for (i=0; i < ndisNumberOfProcessors; i++)
  712. {
  713. volatile UINT *_p = &(Lock)->RefCount[i].RefCount;
  714. while (*_p != 0)
  715. NDIS_INTERNAL_STALL(50);
  716. }
  717. (Lock)->RefCount[Prc].RefCount = refcount;
  718. (Lock)->Context = CURRENT_THREAD;
  719. (LockState)->LockState = WRITE_LOCK_STATE_FREE;
  720. }
  721. }
  722. }
  723. else
  724. {
  725. LockState->LockState = READ_LOCK;
  726. {
  727. UINT refcount;
  728. ULONG Prc;
  729. RAISE_IRQL_TO_DISPATCH(&(LockState)->OldIrql);
  730. /* go ahead and bump up the ref count IF no writes are underway */
  731. Prc = CURRENT_PROCESSOR;
  732. refcount = InterlockedIncrement(&Lock->RefCount[Prc].RefCount);
  733. /* Test if spin lock is held, i.e., write is underway */
  734. /* if (KeTestSpinLock(&(_L)->SpinLock) == TRUE) */
  735. /* This processor already is holding the lock, just */
  736. /* allow him to take it again or else we run into a */
  737. /* dead-lock situation with the writer */
  738. if (TEST_SPIN_LOCK((Lock)->SpinLock) &&
  739. (refcount == 1) &&
  740. ((Lock)->Context != CURRENT_THREAD))
  741. {
  742. (Lock)->RefCount[Prc].RefCount--;
  743. ACQUIRE_SPIN_LOCK_DPC(&(Lock)->SpinLock);
  744. (Lock)->RefCount[Prc].RefCount++;
  745. RELEASE_SPIN_LOCK_DPC(&(Lock)->SpinLock);
  746. }
  747. (LockState)->LockState = READ_LOCK_STATE_FREE;
  748. }
  749. }
  750. // LockState->LockState = fWrite ? WRITE_LOCK_STATE_UNKNOWN : READ_LOCK;
  751. // xLockHandler(Lock, LockState);
  752. }
  753. VOID
  754. NdisReleaseReadWriteLock(
  755. IN PNDIS_RW_LOCK Lock,
  756. IN PLOCK_STATE LockState
  757. )
  758. {
  759. xLockHandler(Lock, LockState);
  760. }