Windows NT 4.0 source code leak
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.

2788 lines
68 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. config.c
  5. Abstract:
  6. NDIS wrapper functions for full mac drivers configuration/initialization
  7. Author:
  8. Sean Selitrennikoff (SeanSe) 05-Oct-93
  9. Jameel Hyder (JameelH) 01-Jun-95 Re-organization/optimization
  10. Environment:
  11. Kernel mode, FSD
  12. Revision History:
  13. --*/
  14. #include <precomp.h>
  15. #pragma hdrstop
  16. #include <stdarg.h>
  17. //
  18. // Define the module number for debug code.
  19. //
  20. #define MODULE_NUMBER MODULE_CONFIG
  21. //
  22. // Requests Used by MAC Drivers
  23. //
  24. //
  25. VOID
  26. NdisInitializeWrapper(
  27. OUT PNDIS_HANDLE NdisWrapperHandle,
  28. IN PVOID SystemSpecific1,
  29. IN PVOID SystemSpecific2,
  30. IN PVOID SystemSpecific3
  31. )
  32. /*++
  33. Routine Description:
  34. Called at the beginning of every MAC's initialization routine.
  35. Arguments:
  36. NdisWrapperHandle - A MAC specific handle for the wrapper.
  37. SystemSpecific1, a pointer to the driver object for the MAC.
  38. SystemSpecific2, a PUNICODE_STRING containing the location of
  39. the registry subtree for this driver.
  40. SystemSpecific3, unused on NT.
  41. Return Value:
  42. None.
  43. --*/
  44. {
  45. NDIS_STATUS Status;
  46. PUNICODE_STRING RegPath;
  47. PNDIS_WRAPPER_HANDLE WrapperHandle;
  48. UNREFERENCED_PARAMETER (SystemSpecific3);
  49. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  50. ("==>NdisInitializeWrapper\n"));
  51. *NdisWrapperHandle = NULL;
  52. Status = NdisAllocateMemory((PVOID*)NdisWrapperHandle,
  53. sizeof(NDIS_WRAPPER_HANDLE) +
  54. sizeof(UNICODE_STRING) +
  55. ((PUNICODE_STRING)SystemSpecific2)->Length +
  56. sizeof(WCHAR),
  57. 0,
  58. HighestAcceptableMax);
  59. if (Status == NDIS_STATUS_SUCCESS)
  60. {
  61. WrapperHandle = (PNDIS_WRAPPER_HANDLE)(*NdisWrapperHandle);
  62. WrapperHandle->NdisWrapperDriver = (PDRIVER_OBJECT)SystemSpecific1;
  63. RegPath = (PUNICODE_STRING)((PUCHAR)WrapperHandle + sizeof(NDIS_WRAPPER_HANDLE));
  64. RegPath->Buffer = (PWSTR)((PUCHAR)RegPath + sizeof(UNICODE_STRING));
  65. RegPath->MaximumLength =
  66. RegPath->Length = ((PUNICODE_STRING)SystemSpecific2)->Length;
  67. NdisMoveMemory(RegPath->Buffer,
  68. ((PUNICODE_STRING)SystemSpecific2)->Buffer,
  69. RegPath->Length);
  70. WrapperHandle->NdisWrapperConfigurationHandle = RegPath;
  71. }
  72. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  73. ("<==NdisInitializeWrapper\n"));
  74. }
  75. VOID
  76. NdisTerminateWrapper(
  77. IN NDIS_HANDLE NdisWrapperHandle,
  78. IN PVOID SystemSpecific
  79. )
  80. /*++
  81. Routine Description:
  82. Called at the end of every MAC's termination routine.
  83. Arguments:
  84. NdisWrapperHandle - The handle returned from NdisInitializeWrapper.
  85. SystemSpecific - No defined value.
  86. Return Value:
  87. None.
  88. --*/
  89. {
  90. PNDIS_WRAPPER_HANDLE NdisMacInfo = (PNDIS_WRAPPER_HANDLE)NdisWrapperHandle;
  91. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  92. ("==>NdisTerminateWrapper\n"));
  93. UNREFERENCED_PARAMETER(SystemSpecific);
  94. if (NdisMacInfo != NULL)
  95. {
  96. NdisFreeMemory(NdisMacInfo, sizeof(NDIS_WRAPPER_HANDLE), 0);
  97. }
  98. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  99. ("<==NdisTerminateWrapper\n"));
  100. }
  101. //
  102. // Operating System Requests
  103. //
  104. //
  105. VOID
  106. NdisMapIoSpace(
  107. OUT PNDIS_STATUS Status,
  108. OUT PVOID * VirtualAddress,
  109. IN NDIS_HANDLE NdisAdapterHandle,
  110. IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
  111. IN UINT Length
  112. )
  113. /*++
  114. Routine Description:
  115. Map virtual memory address space onto a physical address.
  116. Arguments:
  117. Status - resulting status
  118. VirtualAddress - resulting address in virtual space.
  119. NdisAdapterHandle - value returned by NdisRegisterAdapter.
  120. PhysicalAddress - Physical address.
  121. Length - Size of requested memory mapping
  122. Return Value:
  123. none.
  124. --*/
  125. {
  126. ULONG addressSpace = 0;
  127. ULONG NumberOfElements;
  128. ULONG BusNumber;
  129. NDIS_INTERFACE_TYPE BusType;
  130. PHYSICAL_ADDRESS PhysicalTemp;
  131. PCM_RESOURCE_LIST Resources, Resc;
  132. BOOLEAN Conflict;
  133. NTSTATUS NtStatus;
  134. PNDIS_ADAPTER_BLOCK AdptrP = (PNDIS_ADAPTER_BLOCK)(NdisAdapterHandle);
  135. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)(NdisAdapterHandle);
  136. //
  137. // First check if any bus access is allowed
  138. //
  139. BusType = (AdptrP->DeviceObject != NULL) ? AdptrP->BusType : Miniport->BusType;
  140. BusNumber = (AdptrP->DeviceObject != NULL) ? AdptrP->BusNumber : Miniport->BusNumber;
  141. do
  142. {
  143. if ((BusType == (NDIS_INTERFACE_TYPE)-1) || (BusNumber == (ULONG)-1))
  144. {
  145. *Status = NDIS_STATUS_FAILURE;
  146. break;
  147. }
  148. //
  149. // First check for resource conflict by expanding current resource list,
  150. // adding in the mapped space, and then re-submitting the resource list.
  151. //
  152. Resc = (AdptrP->DeviceObject != NULL) ? AdptrP->Resources : Miniport->Resources;
  153. if (Resc != NULL)
  154. {
  155. NumberOfElements = Resc->List[0].PartialResourceList.Count + 1;
  156. }
  157. else
  158. {
  159. NumberOfElements = 1;
  160. }
  161. //
  162. // First check for resource conflict by expanding current resource list,
  163. // adding in the mapped space, and then re-submitting the resource list.
  164. //
  165. Resources = (PCM_RESOURCE_LIST)ALLOC_FROM_POOL(sizeof(CM_RESOURCE_LIST) +
  166. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) *
  167. NumberOfElements,
  168. NDIS_TAG_RSRC_LIST);
  169. if (Resources == NULL)
  170. {
  171. *Status = NDIS_STATUS_RESOURCES;
  172. break;
  173. }
  174. if (Resc != NULL)
  175. {
  176. CopyMemory(Resources,
  177. Resc,
  178. sizeof(CM_RESOURCE_LIST) +
  179. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) *
  180. (NumberOfElements-1));
  181. }
  182. else
  183. {
  184. //
  185. // Setup initial resource info -- NOTE: This is definitely a mini-port
  186. //
  187. ASSERT(AdptrP->DeviceObject == NULL);
  188. Resources->Count = 1;
  189. Resources->List[0].InterfaceType = Miniport->AdapterType;
  190. Resources->List[0].BusNumber = BusNumber;
  191. Resources->List[0].PartialResourceList.Version = 0;
  192. Resources->List[0].PartialResourceList.Revision = 0;
  193. Resources->List[0].PartialResourceList.Count = 0;
  194. }
  195. //
  196. // Setup memory
  197. //
  198. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].Type =
  199. CmResourceTypeMemory;
  200. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].ShareDisposition =
  201. CmResourceShareDeviceExclusive;
  202. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].Flags =
  203. CM_RESOURCE_MEMORY_READ_WRITE;
  204. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].u.Memory.Start =
  205. PhysicalAddress;
  206. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].u.Memory.Length =
  207. Length;
  208. Resources->List[0].PartialResourceList.Count++;
  209. //
  210. // Make the call
  211. //
  212. NtStatus = IoReportResourceUsage(NULL,
  213. ((AdptrP->DeviceObject != NULL) ?
  214. AdptrP->MacHandle->NdisMacInfo->NdisWrapperDriver :
  215. Miniport->DriverHandle->NdisDriverInfo->NdisWrapperDriver),
  216. NULL,
  217. 0,
  218. (AdptrP->DeviceObject != NULL) ?
  219. AdptrP->DeviceObject:
  220. Miniport->DeviceObject,
  221. Resources,
  222. sizeof(CM_RESOURCE_LIST) +
  223. (sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)*Resources->List[0].PartialResourceList.Count),
  224. TRUE,
  225. &Conflict);
  226. //
  227. // Check for conflict.
  228. //
  229. if (Resc != NULL)
  230. {
  231. FREE_POOL(Resc);
  232. }
  233. if (AdptrP->DeviceObject != NULL)
  234. {
  235. AdptrP->Resources = Resources;
  236. }
  237. else
  238. {
  239. Miniport->Resources = Resources;
  240. }
  241. if (Conflict || (NtStatus != STATUS_SUCCESS))
  242. {
  243. if (Conflict)
  244. {
  245. //
  246. // Log an error
  247. //
  248. PIO_ERROR_LOG_PACKET errorLogEntry;
  249. volatile ULONG i;
  250. ULONG StringSize;
  251. PUCHAR Place;
  252. PWCH baseFileName;
  253. WCHAR Character;
  254. ULONG Value;
  255. baseFileName = ((AdptrP->DeviceObject != NULL) ?
  256. AdptrP->AdapterName.Buffer :
  257. Miniport->MiniportName.Buffer);
  258. //
  259. // Parse out the path name, leaving only the device name.
  260. //
  261. for (i = 0;
  262. i < ((AdptrP->DeviceObject != NULL) ?
  263. AdptrP->AdapterName.Length :
  264. Miniport->MiniportName.Length) / sizeof(WCHAR);
  265. i++)
  266. {
  267. //
  268. // If s points to a directory separator, set baseFileName to
  269. // the character after the separator.
  270. //
  271. if (((AdptrP->DeviceObject != NULL) ?
  272. AdptrP->AdapterName.Buffer[i] :
  273. Miniport->MiniportName.Buffer[i]) == OBJ_NAME_PATH_SEPARATOR)
  274. {
  275. baseFileName = ((AdptrP->DeviceObject != NULL) ?
  276. &(AdptrP->AdapterName.Buffer[++i]):
  277. &(Miniport->MiniportName.Buffer[++i]));
  278. }
  279. }
  280. StringSize = ((AdptrP->DeviceObject != NULL) ?
  281. AdptrP->AdapterName.MaximumLength :
  282. Miniport->MiniportName.MaximumLength) -
  283. (((ULONG)baseFileName) -
  284. ((AdptrP->DeviceObject != NULL) ?
  285. ((ULONG)AdptrP->AdapterName.Buffer) :
  286. ((ULONG)Miniport->MiniportName.Buffer)));
  287. errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(((AdptrP->DeviceObject != NULL) ?
  288. AdptrP->DeviceObject : Miniport->DeviceObject),
  289. (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) + StringSize + 34));
  290. // wstrlen("FFFFFFFFFFFFFFFF") * sizeof(WHCAR) + sizeof(UNICODE_NULL)
  291. if (errorLogEntry != NULL)
  292. {
  293. errorLogEntry->ErrorCode = EVENT_NDIS_MEMORY_CONFLICT;
  294. //
  295. // store the time
  296. //
  297. errorLogEntry->MajorFunctionCode = 0;
  298. errorLogEntry->RetryCount = 0;
  299. errorLogEntry->UniqueErrorValue = 0;
  300. errorLogEntry->FinalStatus = 0;
  301. errorLogEntry->SequenceNumber = 0;
  302. errorLogEntry->IoControlCode = 0;
  303. //
  304. // Set string information
  305. //
  306. if (StringSize != 0)
  307. {
  308. errorLogEntry->NumberOfStrings = 1;
  309. errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
  310. CopyMemory (((PUCHAR)errorLogEntry) + sizeof(IO_ERROR_LOG_PACKET),
  311. (PVOID)baseFileName,
  312. StringSize);
  313. Place = ((PUCHAR)errorLogEntry) +
  314. sizeof(IO_ERROR_LOG_PACKET) +
  315. StringSize;
  316. }
  317. else
  318. {
  319. Place = ((PUCHAR)errorLogEntry) +
  320. sizeof(IO_ERROR_LOG_PACKET);
  321. errorLogEntry->NumberOfStrings = 0;
  322. }
  323. errorLogEntry->NumberOfStrings++;
  324. //
  325. // Put in memory address
  326. //
  327. for (StringSize = 0; StringSize < 2; StringSize++)
  328. {
  329. if (StringSize == 0)
  330. {
  331. //
  332. // Do high part
  333. //
  334. Value = NdisGetPhysicalAddressHigh(PhysicalAddress);
  335. }
  336. else
  337. {
  338. //
  339. // Do Low part
  340. //
  341. Value = NdisGetPhysicalAddressLow(PhysicalAddress);
  342. }
  343. //
  344. // Convert value
  345. //
  346. for (i = 1; i <= (sizeof(ULONG) * 2); i++)
  347. {
  348. WCHAR c;
  349. c = (WCHAR)((Value >> (((sizeof(ULONG) * 2) - i) * 4)) & 0x0F);
  350. if (c <= 9)
  351. {
  352. Character = L'0' + c;
  353. }
  354. else
  355. {
  356. Character = L'A' + c - 10;
  357. }
  358. memcpy((PVOID)Place, (PVOID)&Character, sizeof(WCHAR));
  359. Place += sizeof(WCHAR);
  360. }
  361. }
  362. Character = UNICODE_NULL;
  363. memcpy((PVOID)Place, (PVOID)&Character, sizeof(WCHAR));
  364. //
  365. // write it out
  366. //
  367. IoWriteErrorLogEntry(errorLogEntry);
  368. }
  369. *Status = NDIS_STATUS_RESOURCE_CONFLICT;
  370. break;
  371. }
  372. *Status = NDIS_STATUS_FAILURE;
  373. break;
  374. }
  375. if (!HalTranslateBusAddress(BusType,
  376. BusNumber,
  377. PhysicalAddress,
  378. &addressSpace,
  379. &PhysicalTemp))
  380. {
  381. //
  382. // It would be nice to return a better status here, but we only get
  383. // TRUE/FALSE back from HalTranslateBusAddress.
  384. //
  385. *Status = NDIS_STATUS_FAILURE;
  386. break;
  387. }
  388. if (addressSpace == 0)
  389. {
  390. //
  391. // memory space
  392. //
  393. *VirtualAddress = MmMapIoSpace(PhysicalTemp, (Length), FALSE);
  394. }
  395. else
  396. {
  397. //
  398. // I/O space
  399. //
  400. *VirtualAddress = (PVOID)(PhysicalTemp.LowPart);
  401. }
  402. *Status = NDIS_STATUS_SUCCESS;
  403. if (*VirtualAddress == NULL)
  404. {
  405. *Status = NDIS_STATUS_RESOURCES;
  406. }
  407. } while (FALSE);
  408. }
  409. VOID
  410. NdisAllocateDmaChannel(
  411. OUT PNDIS_STATUS Status,
  412. OUT PNDIS_HANDLE NdisDmaHandle,
  413. IN NDIS_HANDLE NdisAdapterHandle,
  414. IN PNDIS_DMA_DESCRIPTION DmaDescription,
  415. IN ULONG MaximumLength
  416. )
  417. /*++
  418. Routine Description:
  419. Sets up a DMA channel for future DMA operations.
  420. Arguments:
  421. Status - Returns the status of the request.
  422. NdisDmaHandle - Returns a handle used to specify this channel to
  423. future operations.
  424. NdisAdapterHandle - handle returned by NdisRegisterAdapter.
  425. DmaDescription - Details of the DMA channel.
  426. MaximumLength - The maximum length DMA transfer that will be done
  427. using this channel.
  428. Return Value:
  429. None.
  430. --*/
  431. {
  432. //
  433. // For registering this set of resources
  434. //
  435. PCM_RESOURCE_LIST Resources;
  436. BOOLEAN Conflict;
  437. //
  438. // Needed to call HalGetAdapter.
  439. //
  440. DEVICE_DESCRIPTION DeviceDescription;
  441. //
  442. // Returned by HalGetAdapter.
  443. //
  444. PADAPTER_OBJECT AdapterObject;
  445. //
  446. // Map registers needed per channel.
  447. //
  448. ULONG MapRegistersNeeded;
  449. //
  450. // Map registers allowed per channel.
  451. //
  452. ULONG MapRegistersAllowed;
  453. //
  454. // Saves the structure we allocate for this channel.
  455. //
  456. PNDIS_DMA_BLOCK DmaBlock;
  457. //
  458. // Convert the handle to our internal structure.
  459. PNDIS_ADAPTER_BLOCK AdapterBlock =
  460. (PNDIS_ADAPTER_BLOCK) NdisAdapterHandle;
  461. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK) NdisAdapterHandle;
  462. BOOLEAN IsAMiniport;
  463. //
  464. // Save our IRQL when we raise it to call IoAllocateAdapterChannel.
  465. //
  466. KIRQL OldIrql;
  467. ULONG NumberOfElements;
  468. NTSTATUS NtStatus;
  469. LARGE_INTEGER TimeoutValue;
  470. IsAMiniport = (AdapterBlock->DeviceObject == NULL);
  471. //
  472. // First check if any bus access is allowed
  473. //
  474. if (((IsAMiniport ?
  475. Miniport->BusType :
  476. AdapterBlock->BusType) == (NDIS_INTERFACE_TYPE)-1) ||
  477. ((IsAMiniport ?
  478. Miniport->BusNumber :
  479. AdapterBlock->BusNumber) == (ULONG)-1))
  480. {
  481. *Status = NDIS_STATUS_FAILURE;
  482. return;
  483. }
  484. //
  485. // First check for resource conflict by expanding current resource list,
  486. // adding in the mapped space, and then re-submitting the resource list.
  487. //
  488. if ((IsAMiniport ? Miniport->Resources : AdapterBlock->Resources) != NULL)
  489. {
  490. NumberOfElements =
  491. (IsAMiniport ?
  492. Miniport->Resources->List[0].PartialResourceList.Count :
  493. AdapterBlock->Resources->List[0].PartialResourceList.Count) + 1;
  494. }
  495. else
  496. {
  497. NumberOfElements = 1;
  498. }
  499. //
  500. // First check for resource conflict by expanding current resource list,
  501. // adding in the mapped space, and then re-submitting the resource list.
  502. //
  503. Resources = (PCM_RESOURCE_LIST)ALLOC_FROM_POOL(sizeof(CM_RESOURCE_LIST) +
  504. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) *
  505. NumberOfElements,
  506. NDIS_TAG_RSRC_LIST);
  507. if (Resources == NULL)
  508. {
  509. *Status = NDIS_STATUS_RESOURCES;
  510. return;
  511. }
  512. if ((IsAMiniport ? Miniport->Resources : AdapterBlock->Resources) != NULL)
  513. {
  514. CopyMemory(Resources,
  515. (IsAMiniport ? Miniport->Resources : AdapterBlock->Resources),
  516. sizeof(CM_RESOURCE_LIST) +
  517. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) *
  518. (NumberOfElements - 1));
  519. }
  520. else
  521. {
  522. //
  523. // Setup initial resource info
  524. //
  525. ASSERT(IsAMiniport);
  526. Resources->Count = 1;
  527. Resources->List[0].InterfaceType = Miniport->AdapterType;
  528. Resources->List[0].BusNumber = Miniport->BusNumber;
  529. Resources->List[0].PartialResourceList.Version = 0;
  530. Resources->List[0].PartialResourceList.Revision = 0;
  531. Resources->List[0].PartialResourceList.Count = 0;
  532. }
  533. //
  534. // Setup DMA Channel
  535. //
  536. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].Type =
  537. CmResourceTypeDma;
  538. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].ShareDisposition =
  539. CmResourceShareDeviceExclusive;
  540. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].Flags =
  541. 0;
  542. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].u.Dma.Channel =
  543. (IsAMiniport ? Miniport->ChannelNumber :
  544. (DmaDescription->DmaChannelSpecified ?
  545. DmaDescription->DmaChannel : AdapterBlock->ChannelNumber));
  546. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].u.Dma.Port =
  547. DmaDescription->DmaPort;
  548. Resources->List[0].PartialResourceList.Count++;
  549. //
  550. // Make the call
  551. //
  552. *Status = IoReportResourceUsage(NULL,
  553. (IsAMiniport ?
  554. Miniport->DriverHandle->NdisDriverInfo->NdisWrapperDriver :
  555. AdapterBlock->MacHandle->NdisMacInfo->NdisWrapperDriver),
  556. NULL,
  557. 0,
  558. (IsAMiniport ? Miniport->DeviceObject : AdapterBlock->DeviceObject),
  559. Resources,
  560. sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * Resources->List[0].PartialResourceList.Count,
  561. TRUE,
  562. &Conflict);
  563. if ((IsAMiniport ? Miniport->Resources : AdapterBlock->Resources) != NULL)
  564. {
  565. FREE_POOL((IsAMiniport ? Miniport->Resources : AdapterBlock->Resources));
  566. }
  567. if (IsAMiniport)
  568. {
  569. Miniport->Resources = Resources;
  570. }
  571. else
  572. {
  573. AdapterBlock->Resources = Resources;
  574. }
  575. //
  576. // Check for conflict.
  577. //
  578. if (Conflict || (*Status != STATUS_SUCCESS))
  579. {
  580. if (Conflict)
  581. {
  582. //
  583. // Log an error
  584. //
  585. PIO_ERROR_LOG_PACKET errorLogEntry;
  586. ULONG i;
  587. ULONG StringSize;
  588. PUCHAR Place;
  589. PWCH baseFileName;
  590. WCHAR Character;
  591. ULONG Value;
  592. baseFileName = (IsAMiniport ?
  593. Miniport->MiniportName.Buffer :
  594. AdapterBlock->AdapterName.Buffer);
  595. //
  596. // Parse out the path name, leaving only the device name.
  597. //
  598. for (i = 0;
  599. i < (IsAMiniport ? Miniport->MiniportName.Length :
  600. AdapterBlock->AdapterName.Length)
  601. / sizeof(WCHAR);
  602. i++)
  603. {
  604. //
  605. // If s points to a directory separator, set baseFileName to
  606. // the character after the separator.
  607. //
  608. if ((IsAMiniport ?
  609. Miniport->MiniportName.Buffer[i] :
  610. AdapterBlock->AdapterName.Buffer[i]) == OBJ_NAME_PATH_SEPARATOR)
  611. {
  612. baseFileName = (IsAMiniport ?
  613. &(Miniport->MiniportName.Buffer[++i]) :
  614. &(AdapterBlock->AdapterName.Buffer[++i]));
  615. }
  616. }
  617. StringSize = (IsAMiniport ?
  618. Miniport->MiniportName.MaximumLength :
  619. AdapterBlock->AdapterName.MaximumLength) -
  620. (((ULONG)baseFileName) -
  621. (IsAMiniport ?
  622. ((ULONG)Miniport->MiniportName.Buffer) :
  623. ((ULONG)AdapterBlock->AdapterName.Buffer)));
  624. errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
  625. (IsAMiniport ?
  626. Miniport->DeviceObject :
  627. AdapterBlock->DeviceObject),
  628. (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) +
  629. StringSize +
  630. 6)); // wstrlen("99") * sizeof(WHCAR) + sizeof(UNICODE_NULL)
  631. if (errorLogEntry != NULL)
  632. {
  633. errorLogEntry->ErrorCode = EVENT_NDIS_DMA_CONFLICT;
  634. //
  635. // store the time
  636. //
  637. errorLogEntry->MajorFunctionCode = 0;
  638. errorLogEntry->RetryCount = 0;
  639. errorLogEntry->UniqueErrorValue = 0;
  640. errorLogEntry->FinalStatus = 0;
  641. errorLogEntry->SequenceNumber = 0;
  642. errorLogEntry->IoControlCode = 0;
  643. //
  644. // Set string information
  645. //
  646. if (StringSize != 0)
  647. {
  648. errorLogEntry->NumberOfStrings = 1;
  649. errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
  650. CopyMemory(((PUCHAR)errorLogEntry) + sizeof(IO_ERROR_LOG_PACKET),
  651. (PVOID)baseFileName,
  652. StringSize);
  653. Place = ((PUCHAR)errorLogEntry) +
  654. sizeof(IO_ERROR_LOG_PACKET) +
  655. StringSize;
  656. }
  657. else
  658. {
  659. Place = ((PUCHAR)errorLogEntry) +
  660. sizeof(IO_ERROR_LOG_PACKET);
  661. errorLogEntry->NumberOfStrings = 0;
  662. }
  663. errorLogEntry->NumberOfStrings++;
  664. //
  665. // Put in dma channel
  666. //
  667. Value = (IsAMiniport ? Miniport->ChannelNumber :
  668. AdapterBlock->ChannelNumber);
  669. //
  670. // Convert value
  671. //
  672. // I couldn't think of a better way to do this (with some
  673. // loop). If you find one, plz put it in.
  674. //
  675. if (Value > 9)
  676. {
  677. Character = L'0' + (WCHAR)(Value / 10);
  678. memcpy((PVOID)Place, (PVOID)&Character, sizeof(WCHAR));
  679. Place += sizeof(WCHAR);
  680. Value -= 10;
  681. }
  682. Character = L'0' + (WCHAR)Value;
  683. memcpy((PVOID)Place, (PVOID)&Character, sizeof(WCHAR));
  684. Place += sizeof(WCHAR);
  685. Character = UNICODE_NULL;
  686. memcpy((PVOID)Place, (PVOID)&Character, sizeof(WCHAR));
  687. //
  688. // write it out
  689. //
  690. IoWriteErrorLogEntry(errorLogEntry);
  691. }
  692. *Status = NDIS_STATUS_RESOURCE_CONFLICT;
  693. return;
  694. }
  695. *Status = NDIS_STATUS_FAILURE;
  696. return;
  697. }
  698. //
  699. // Set up the device description; zero it out in case its
  700. // size changes.
  701. //
  702. ZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));
  703. DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
  704. DeviceDescription.Master =
  705. (BOOLEAN)(IsAMiniport ?
  706. MINIPORT_TEST_FLAG(Miniport, fMINIPORT_BUS_MASTER) : FALSE);
  707. DeviceDescription.ScatterGather =
  708. (BOOLEAN)(IsAMiniport ?
  709. MINIPORT_TEST_FLAG(Miniport, fMINIPORT_BUS_MASTER) : FALSE);
  710. DeviceDescription.DemandMode = DmaDescription->DemandMode;
  711. DeviceDescription.AutoInitialize = DmaDescription->AutoInitialize;
  712. DeviceDescription.Dma32BitAddresses =
  713. (BOOLEAN)(IsAMiniport ?
  714. MINIPORT_TEST_FLAG(Miniport, fMINIPORT_DMA_32_BIT_ADDRESSES) : FALSE);
  715. DeviceDescription.BusNumber = (IsAMiniport ? Miniport->BusNumber : AdapterBlock->BusNumber);
  716. DeviceDescription.DmaChannel = (IsAMiniport ? Miniport->ChannelNumber :
  717. (DmaDescription->DmaChannelSpecified ?
  718. DmaDescription->DmaChannel : AdapterBlock->ChannelNumber));
  719. DeviceDescription.InterfaceType = (IsAMiniport ? Miniport->BusType : AdapterBlock->BusType);
  720. DeviceDescription.DmaWidth = DmaDescription->DmaWidth;
  721. DeviceDescription.DmaSpeed = DmaDescription->DmaSpeed;
  722. DeviceDescription.MaximumLength = MaximumLength;
  723. DeviceDescription.DmaPort = DmaDescription->DmaPort;
  724. MapRegistersNeeded = ((MaximumLength - 2) / PAGE_SIZE) + 2;
  725. //
  726. // Get the adapter object.
  727. //
  728. AdapterObject = HalGetAdapter (&DeviceDescription, &MapRegistersAllowed);
  729. if ((AdapterObject == NULL) || (MapRegistersAllowed < MapRegistersNeeded))
  730. {
  731. *Status = NDIS_STATUS_RESOURCES;
  732. return;
  733. }
  734. //
  735. // Allocate storage for our DMA block.
  736. //
  737. DmaBlock = (PNDIS_DMA_BLOCK)ALLOC_FROM_POOL(sizeof(NDIS_DMA_BLOCK), NDIS_TAG_DMA);
  738. if (DmaBlock == (PNDIS_DMA_BLOCK)NULL)
  739. {
  740. *Status = NDIS_STATUS_RESOURCES;
  741. return;
  742. }
  743. //
  744. // Use this event to tell us when ndisAllocationExecutionRoutine
  745. // has been called.
  746. //
  747. INITIALIZE_EVENT(&DmaBlock->AllocationEvent);
  748. //
  749. // We save this to call IoFreeAdapterChannel later.
  750. //
  751. DmaBlock->SystemAdapterObject = AdapterObject;
  752. //
  753. // Now allocate the adapter channel.
  754. //
  755. RAISE_IRQL_TO_DISPATCH(&OldIrql);
  756. NtStatus = IoAllocateAdapterChannel(
  757. AdapterObject,
  758. (IsAMiniport ? Miniport->DeviceObject : AdapterBlock->DeviceObject),
  759. MapRegistersNeeded,
  760. ndisDmaExecutionRoutine,
  761. (PVOID)DmaBlock);
  762. LOWER_IRQL(OldIrql);
  763. if (!NT_SUCCESS(NtStatus))
  764. {
  765. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  766. ("NDIS DMA AllocateAdapterChannel: %lx\n", NtStatus));
  767. FREE_POOL(DmaBlock);
  768. *Status = NDIS_STATUS_RESOURCES;
  769. return;
  770. }
  771. TimeoutValue.QuadPart = Int32x32To64(100 * 1000, -10000);
  772. //
  773. // ndisDmaExecutionRoutine will set this event
  774. // when it has been called.
  775. //
  776. NtStatus = WAIT_FOR_OBJECT(&DmaBlock->AllocationEvent, &TimeoutValue);
  777. if (NtStatus != STATUS_SUCCESS)
  778. {
  779. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  780. ("NDIS DMA AllocateAdapterChannel: %lx\n", NtStatus));
  781. FREE_POOL(DmaBlock);
  782. *Status = NDIS_STATUS_RESOURCES;
  783. return;
  784. }
  785. RESET_EVENT(&DmaBlock->AllocationEvent);
  786. //
  787. // We now have the DMA channel allocated, we are done.
  788. //
  789. DmaBlock->InProgress = FALSE;
  790. *NdisDmaHandle = (NDIS_HANDLE)DmaBlock;
  791. *Status = NDIS_STATUS_SUCCESS;
  792. }
  793. VOID
  794. NdisFreeDmaChannel(
  795. IN NDIS_HANDLE NdisDmaHandle
  796. )
  797. /*++
  798. Routine Description:
  799. Frees a DMA channel allocated with NdisAllocateDmaChannel.
  800. Arguments:
  801. NdisDmaHandle - Handle returned by NdisAllocateDmaChannel, indicating the
  802. DMA channel that is to be freed.
  803. Return Value:
  804. None.
  805. --*/
  806. {
  807. KIRQL OldIrql;
  808. PNDIS_DMA_BLOCK DmaBlock = (PNDIS_DMA_BLOCK)NdisDmaHandle;
  809. RAISE_IRQL_TO_DISPATCH(&OldIrql);
  810. IoFreeAdapterChannel (DmaBlock->SystemAdapterObject);
  811. LOWER_IRQL(OldIrql);
  812. FREE_POOL(DmaBlock);
  813. }
  814. VOID
  815. NdisSetupDmaTransfer(
  816. OUT PNDIS_STATUS Status,
  817. IN PNDIS_HANDLE NdisDmaHandle,
  818. IN PNDIS_BUFFER Buffer,
  819. IN ULONG Offset,
  820. IN ULONG Length,
  821. IN BOOLEAN WriteToDevice
  822. )
  823. /*++
  824. Routine Description:
  825. Sets up the host DMA controller for a DMA transfer. The
  826. DMA controller is set up to transfer the specified MDL.
  827. Since we register all DMA channels as non-scatter/gather,
  828. IoMapTransfer will ensure that the entire MDL is
  829. in a single logical piece for transfer.
  830. Arguments:
  831. Status - Returns the status of the request.
  832. NdisDmaHandle - Handle returned by NdisAllocateDmaChannel.
  833. Buffer - An NDIS_BUFFER which describes the host memory involved in the
  834. transfer.
  835. Offset - An offset within buffer where the transfer should
  836. start.
  837. Length - The length of the transfer. VirtualAddress plus Length must not
  838. extend beyond the end of the buffer.
  839. WriteToDevice - TRUE for a download operation (host to adapter); FALSE
  840. for an upload operation (adapter to host).
  841. Return Value:
  842. None.
  843. --*/
  844. {
  845. PNDIS_DMA_BLOCK DmaBlock = (PNDIS_DMA_BLOCK)NdisDmaHandle;
  846. PHYSICAL_ADDRESS LogicalAddress;
  847. ULONG LengthMapped;
  848. //
  849. // Make sure another request is not in progress.
  850. //
  851. if (DmaBlock->InProgress)
  852. {
  853. *Status = NDIS_STATUS_RESOURCES;
  854. return;
  855. }
  856. DmaBlock->InProgress = TRUE;
  857. //
  858. // Use IoMapTransfer to set up the transfer.
  859. //
  860. LengthMapped = Length;
  861. LogicalAddress = IoMapTransfer(DmaBlock->SystemAdapterObject,
  862. (PMDL)Buffer,
  863. DmaBlock->MapRegisterBase,
  864. (PUCHAR)(MDL_VA(Buffer)) + Offset,
  865. &LengthMapped,
  866. WriteToDevice);
  867. if (LengthMapped != Length)
  868. {
  869. //
  870. // Somehow the request could not be mapped competely,
  871. // this should not happen for a non-scatter/gather adapter.
  872. //
  873. (VOID)IoFlushAdapterBuffers(DmaBlock->SystemAdapterObject,
  874. (PMDL)Buffer,
  875. DmaBlock->MapRegisterBase,
  876. (PUCHAR)(MDL_VA(Buffer)) + Offset,
  877. LengthMapped,
  878. WriteToDevice);
  879. DmaBlock->InProgress = FALSE;
  880. *Status = NDIS_STATUS_RESOURCES;
  881. }
  882. else *Status = NDIS_STATUS_SUCCESS;
  883. }
  884. VOID
  885. NdisCompleteDmaTransfer(
  886. OUT PNDIS_STATUS Status,
  887. IN PNDIS_HANDLE NdisDmaHandle,
  888. IN PNDIS_BUFFER Buffer,
  889. IN ULONG Offset,
  890. IN ULONG Length,
  891. IN BOOLEAN WriteToDevice
  892. )
  893. /*++
  894. Routine Description:
  895. Completes a previously started DMA transfer.
  896. Arguments:
  897. Status - Returns the status of the transfer.
  898. NdisDmaHandle - Handle returned by NdisAllocateDmaChannel.
  899. Buffer - An NDIS_BUFFER which was passed to NdisSetupDmaTransfer.
  900. Offset - the offset passed to NdisSetupDmaTransfer.
  901. Length - The length passed to NdisSetupDmaTransfer.
  902. WriteToDevice - TRUE for a download operation (host to adapter); FALSE
  903. for an upload operation (adapter to host).
  904. Return Value:
  905. None.
  906. --*/
  907. {
  908. PNDIS_DMA_BLOCK DmaBlock = (PNDIS_DMA_BLOCK)NdisDmaHandle;
  909. BOOLEAN Successful;
  910. Successful = IoFlushAdapterBuffers(DmaBlock->SystemAdapterObject,
  911. (PMDL)Buffer,
  912. DmaBlock->MapRegisterBase,
  913. (PUCHAR)(MDL_VA(Buffer)) + Offset,
  914. Length,
  915. WriteToDevice);
  916. *Status = (Successful ? NDIS_STATUS_SUCCESS : NDIS_STATUS_RESOURCES);
  917. DmaBlock->InProgress = FALSE;
  918. }
  919. VOID
  920. NdisRegisterMac(
  921. OUT PNDIS_STATUS Status,
  922. OUT PNDIS_HANDLE NdisMacHandle,
  923. IN NDIS_HANDLE NdisWrapperHandle,
  924. IN NDIS_HANDLE MacMacContext,
  925. IN PNDIS_MAC_CHARACTERISTICS MacCharacteristics,
  926. IN UINT CharacteristicsLength
  927. )
  928. /*++
  929. Routine Description:
  930. Register an NDIS MAC.
  931. Arguments:
  932. Status - Returns the final status.
  933. NdisMacHandle - Returns a handle referring to this MAC.
  934. NdisWrapperHandle - Handle returned by NdisInitializeWrapper.
  935. MacMacContext - Context for calling MACUnloadMac and MACAddAdapter.
  936. MacCharacteritics - The NDIS_MAC_CHARACTERISTICS table.
  937. CharacteristicsLength - The length of MacCharacteristics.
  938. Return Value:
  939. None.
  940. --*/
  941. {
  942. PNDIS_WRAPPER_HANDLE NdisMacInfo = (PNDIS_WRAPPER_HANDLE)(NdisWrapperHandle);
  943. PNDIS_MAC_BLOCK MacBlock;
  944. UNICODE_STRING Us;
  945. PWSTR pWch;
  946. USHORT i;
  947. UINT MemNeeded;
  948. KIRQL OldIrql;
  949. //
  950. // check that this is an NDIS 3.0 MAC.
  951. //
  952. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  953. ("==>NdisRegisterMac\n"));
  954. do
  955. {
  956. *NdisMacHandle = (NDIS_HANDLE)NULL;
  957. if (NdisMacInfo == NULL)
  958. {
  959. *Status = NDIS_STATUS_FAILURE;
  960. break;
  961. }
  962. IF_DBG(DBG_COMP_CONFIG, DBG_LEVEL_ERR)
  963. {
  964. BOOLEAN f = FALSE;
  965. if (DbgIsNull(MacCharacteristics->OpenAdapterHandler))
  966. {
  967. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  968. ("RegisterMac: Null OpenAdapterHandler \n"));
  969. f = TRUE;
  970. }
  971. if (DbgIsNull(MacCharacteristics->CloseAdapterHandler))
  972. {
  973. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  974. ("RegisterMac: Null CloseAdapterHandler \n"));
  975. f = TRUE;
  976. }
  977. if (DbgIsNull(MacCharacteristics->SendHandler))
  978. {
  979. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  980. ("RegisterMac: Null SendHandler \n"));
  981. f = TRUE;
  982. }
  983. if (DbgIsNull(MacCharacteristics->TransferDataHandler))
  984. {
  985. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  986. ("RegisterMac: Null TransferDataHandler \n"));
  987. f = TRUE;
  988. }
  989. if (DbgIsNull(MacCharacteristics->ResetHandler))
  990. {
  991. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  992. ("RegisterMac: Null ResetHandler \n"));
  993. f = TRUE;
  994. }
  995. if (DbgIsNull(MacCharacteristics->RequestHandler))
  996. {
  997. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  998. ("RegisterMac: Null RequestHandler \n"));
  999. f = TRUE;
  1000. }
  1001. if (DbgIsNull(MacCharacteristics->QueryGlobalStatisticsHandler))
  1002. {
  1003. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1004. ("RegisterMac: Null QueryGlobalStatisticsHandler \n"));
  1005. f = TRUE;
  1006. }
  1007. if (DbgIsNull(MacCharacteristics->UnloadMacHandler))
  1008. {
  1009. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1010. ("RegisterMac: Null UnloadMacHandler \n"));
  1011. f = TRUE;
  1012. }
  1013. if (DbgIsNull(MacCharacteristics->AddAdapterHandler))
  1014. {
  1015. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1016. ("RegisterMac: Null AddAdapterHandler \n"));
  1017. f = TRUE;
  1018. }
  1019. if (DbgIsNull(MacCharacteristics->RemoveAdapterHandler))
  1020. {
  1021. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1022. ("RegisterMac: Null RemoveAdapterHandler \n"));
  1023. f = TRUE;
  1024. }
  1025. if (f)
  1026. DBGBREAK(DBG_COMP_CONFIG, DBG_LEVEL_ERR);
  1027. }
  1028. if ((MacCharacteristics->MajorNdisVersion != 3) ||
  1029. (MacCharacteristics->MinorNdisVersion != 0))
  1030. {
  1031. *Status = NDIS_STATUS_BAD_VERSION;
  1032. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1033. ("<==NdisRegisterMac\n"));
  1034. break;
  1035. }
  1036. //
  1037. // Check that CharacteristicsLength is enough.
  1038. //
  1039. if (CharacteristicsLength < sizeof(NDIS_MAC_CHARACTERISTICS))
  1040. {
  1041. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1042. ("char len = %d < %d\n",
  1043. CharacteristicsLength,
  1044. sizeof(NDIS_MAC_CHARACTERISTICS)));
  1045. *Status = NDIS_STATUS_BAD_CHARACTERISTICS;
  1046. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1047. ("<==NdisRegisterMac\n"));
  1048. break;
  1049. }
  1050. //
  1051. // Allocate memory for the NDIS MAC block.
  1052. //
  1053. MemNeeded = sizeof(NDIS_MAC_BLOCK) + MacCharacteristics->Name.Length;
  1054. //
  1055. // Extract the base-name, determine its length and allocate that much more
  1056. //
  1057. Us = *(PUNICODE_STRING)(NdisMacInfo->NdisWrapperConfigurationHandle);
  1058. for (i = Us.Length/sizeof(WCHAR), pWch = Us.Buffer + i - 1;
  1059. i > 0;
  1060. pWch --, i--)
  1061. {
  1062. if (*pWch == L'\\')
  1063. {
  1064. Us.Buffer = pWch + 1;
  1065. Us.Length -= i*sizeof(WCHAR);
  1066. Us.MaximumLength = Us.Length + sizeof(WCHAR);
  1067. break;
  1068. }
  1069. }
  1070. MemNeeded += Us.MaximumLength;
  1071. MacBlock = (PNDIS_MAC_BLOCK)ALLOC_FROM_POOL(MemNeeded, NDIS_TAG_MAC_BLOCK);
  1072. if (MacBlock == (PNDIS_MAC_BLOCK)NULL)
  1073. {
  1074. *Status = NDIS_STATUS_RESOURCES;
  1075. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1076. ("<==NdisRegisterMac\n"));
  1077. break;
  1078. }
  1079. ZeroMemory(MacBlock, MemNeeded);
  1080. MacBlock->Length = MemNeeded;
  1081. //
  1082. // Copy over the characteristics table.
  1083. //
  1084. CopyMemory((PVOID)&MacBlock->MacCharacteristics,
  1085. (PVOID)MacCharacteristics,
  1086. sizeof(NDIS_MAC_CHARACTERISTICS));
  1087. //
  1088. // Move buffer pointer to correct location (extra space at the end of
  1089. // the characteristics table)
  1090. //
  1091. MacBlock->MacCharacteristics.Name.Buffer = (PWSTR)((PUCHAR)MacBlock + sizeof(NDIS_MAC_BLOCK));
  1092. //
  1093. // Copy String over.
  1094. //
  1095. MacBlock->MacCharacteristics.Name.Length =
  1096. MacBlock->MacCharacteristics.Name.MaximumLength = MacCharacteristics->Name.Length;
  1097. CopyMemory(MacBlock->MacCharacteristics.Name.Buffer,
  1098. MacCharacteristics->Name.Buffer,
  1099. MacCharacteristics->Name.Length);
  1100. //
  1101. // Upcase the base-name and save it in the MiniBlock
  1102. //
  1103. MacBlock->BaseName.Buffer = (PWSTR)((PUCHAR)MacBlock->MacCharacteristics.Name.Buffer +
  1104. MacCharacteristics->Name.Length);
  1105. MacBlock->BaseName.Length = Us.Length;
  1106. MacBlock->BaseName.MaximumLength = Us.MaximumLength;
  1107. RtlUpcaseUnicodeString(&MacBlock->BaseName,
  1108. &Us,
  1109. FALSE);
  1110. //
  1111. // No adapters yet registered for this MAC.
  1112. //
  1113. MacBlock->AdapterQueue = (PNDIS_ADAPTER_BLOCK)NULL;
  1114. MacBlock->MacMacContext = MacMacContext;
  1115. //
  1116. // Set up unload handler
  1117. //
  1118. NdisMacInfo->NdisWrapperDriver->DriverUnload = ndisUnload;
  1119. //
  1120. // Set up shutdown handler
  1121. //
  1122. NdisMacInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_SHUTDOWN] = ndisShutdown;
  1123. //
  1124. // Set up the handlers for this driver (they all do nothing).
  1125. //
  1126. NdisMacInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_CREATE] = ndisCreateIrpHandler;
  1127. NdisMacInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ndisDeviceControlIrpHandler;
  1128. NdisMacInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_CLEANUP] = ndisSuccessIrpHandler;
  1129. NdisMacInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_CLOSE] = ndisCloseIrpHandler;
  1130. MacBlock->NdisMacInfo = NdisMacInfo;
  1131. //
  1132. // Use this event to tell us when all adapters are removed from the mac
  1133. // during an unload
  1134. //
  1135. INITIALIZE_EVENT(&MacBlock->AdaptersRemovedEvent);
  1136. MacBlock->Unloading = FALSE;
  1137. NdisInitializeRef(&MacBlock->Ref);
  1138. // Lock the init code down now - before we take the lock below
  1139. InitReferencePackage();
  1140. //
  1141. // Put MAC on global list.
  1142. //
  1143. ACQUIRE_SPIN_LOCK(&ndisDriverListLock, &OldIrql);
  1144. MacBlock->NextMac = ndisMacDriverList;
  1145. ndisMacDriverList = MacBlock;
  1146. RELEASE_SPIN_LOCK(&ndisDriverListLock, OldIrql);
  1147. *NdisMacHandle = (NDIS_HANDLE)MacBlock;
  1148. if (NdisMacInfo->NdisWrapperConfigurationHandle)
  1149. {
  1150. *Status = ndisInitializeAllAdapterInstances(MacBlock, NULL);
  1151. if (*Status != NDIS_STATUS_SUCCESS)
  1152. {
  1153. *Status = NDIS_STATUS_FAILURE;
  1154. ndisDereferenceMac(MacBlock);
  1155. }
  1156. }
  1157. else
  1158. {
  1159. *Status = NDIS_STATUS_FAILURE;
  1160. }
  1161. InitDereferencePackage();
  1162. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1163. ("<==NdisRegisterMac\n"));
  1164. } while (FALSE);
  1165. ASSERT(CURRENT_IRQL < DISPATCH_LEVEL);
  1166. }
  1167. VOID
  1168. NdisDeregisterMac(
  1169. OUT PNDIS_STATUS Status,
  1170. IN NDIS_HANDLE NdisMacHandle
  1171. )
  1172. /*++
  1173. Routine Description:
  1174. Deregisters an NDIS MAC.
  1175. Arguments:
  1176. Status - Returns the status of the request.
  1177. NdisMacHandle - The handle returned by NdisRegisterMac.
  1178. Return Value:
  1179. None.
  1180. --*/
  1181. {
  1182. PNDIS_MAC_BLOCK OldMacP = (PNDIS_MAC_BLOCK)NdisMacHandle;
  1183. //
  1184. // If the MAC is already closing, return.
  1185. //
  1186. *Status = NDIS_STATUS_SUCCESS;
  1187. if (OldMacP == NULL)
  1188. {
  1189. return;
  1190. }
  1191. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1192. ("==>NdisDeregisterMac\n"));
  1193. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1194. (" Mac %wZ being deregistered\n",&OldMacP->MacCharacteristics.Name));
  1195. IF_DBG(DBG_COMP_CONFIG, DBG_LEVEL_ERR)
  1196. {
  1197. if (DbgIsNull(NdisMacHandle))
  1198. {
  1199. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1200. ("DeregisterMac: Null Handle\n"));
  1201. DBGBREAK(DBG_COMP_CONFIG, DBG_LEVEL_ERR);
  1202. }
  1203. if (!DbgIsNonPaged(NdisMacHandle))
  1204. {
  1205. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1206. ("DeregisterMac: Handle not in NonPaged Memory\n"));
  1207. DBGBREAK(DBG_COMP_CONFIG, DBG_LEVEL_ERR);
  1208. }
  1209. }
  1210. if (!NdisCloseRef(&OldMacP->Ref))
  1211. {
  1212. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1213. ("<==NdisDeregisterMac\n"));
  1214. return;
  1215. }
  1216. ASSERT(OldMacP->AdapterQueue == (PNDIS_ADAPTER_BLOCK)NULL);
  1217. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1218. ("<==NdisDeregisterMac\n"));
  1219. }
  1220. NDIS_STATUS
  1221. NdisRegisterAdapter(
  1222. OUT PNDIS_HANDLE NdisAdapterHandle,
  1223. IN NDIS_HANDLE NdisMacHandle,
  1224. IN NDIS_HANDLE MacAdapterContext,
  1225. IN NDIS_HANDLE WrapperConfigurationContext,
  1226. IN PNDIS_STRING AdapterName,
  1227. IN PVOID AdapterInformation
  1228. )
  1229. /*++
  1230. Routine Description:
  1231. Register an NDIS adapter.
  1232. Arguments:
  1233. NdisAdapterHandle - Returns a handle referring to this adapter.
  1234. NdisMacHandle - A handle for a previously registered MAC.
  1235. MacAdapterContext - A context for calls into this MAC.
  1236. WrapperConfigurationContext - Context passed to MacAddAdapter.
  1237. AdapterName - The name the adapter should be registered under.
  1238. AdapterInformation - Contains adapter information. For future
  1239. use. NULL for the meantime. Storage for it
  1240. must be allocated by the caller.
  1241. Return Value:
  1242. The final status.
  1243. --*/
  1244. {
  1245. PNDIS_ADAPTER_BLOCK NewAdaptP = NULL;
  1246. PDEVICE_OBJECT TmpDeviceP = NULL;
  1247. PNDIS_WRAPPER_CONFIGURATION_HANDLE ConfigurationHandle;
  1248. PNDIS_MAC_BLOCK TmpMacP;
  1249. NTSTATUS NtStatus;
  1250. NDIS_STRING NdisAdapterName = { 0 };
  1251. PHYSICAL_ADDRESS PortAddress;
  1252. PHYSICAL_ADDRESS InitialPortAddress;
  1253. ULONG addressSpace;
  1254. PNDIS_ADAPTER_INFORMATION AdapterInfo = (PNDIS_ADAPTER_INFORMATION)AdapterInformation;
  1255. BOOLEAN Conflict, ValidBus;
  1256. PCM_RESOURCE_LIST Resources = NULL;
  1257. LARGE_INTEGER TimeoutValue;
  1258. BOOLEAN AllocateIndividualPorts = TRUE, DerefMacOnError = FALSE;
  1259. ULONG i, Size;
  1260. ULONG BusNumber;
  1261. NDIS_INTERFACE_TYPE BusType;
  1262. NDIS_STATUS Status;
  1263. UNICODE_STRING DeviceName, UpcaseDeviceName;
  1264. UNICODE_STRING SymbolicLink;
  1265. WCHAR SymLnkBuf[40];
  1266. KIRQL OldIrql;
  1267. ConfigurationHandle = (PNDIS_WRAPPER_CONFIGURATION_HANDLE)WrapperConfigurationContext;
  1268. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  1269. ("==>NdisRegisterAdapter\n"));
  1270. IF_DBG(DBG_COMP_CONFIG, DBG_LEVEL_ERR)
  1271. {
  1272. BOOLEAN f = FALSE;
  1273. if (DbgIsNull(NdisMacHandle))
  1274. {
  1275. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1276. ("RegisterAdapter: Null Handle\n"));
  1277. f = TRUE;
  1278. }
  1279. if (!DbgIsNonPaged(NdisMacHandle))
  1280. {
  1281. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1282. ("RegisterAdapter: Handle not in NonPaged Memory\n"));
  1283. f = TRUE;
  1284. }
  1285. if (DbgIsNull(MacAdapterContext))
  1286. {
  1287. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1288. ("RegisterAdapter: Null Context\n"));
  1289. f = TRUE;
  1290. }
  1291. if (!DbgIsNonPaged(MacAdapterContext))
  1292. {
  1293. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1294. ("RegisterAdapter: Context not in NonPaged Memory\n"));
  1295. f = TRUE;
  1296. }
  1297. if (f)
  1298. DBGBREAK(DBG_COMP_CONFIG, DBG_LEVEL_ERR);
  1299. }
  1300. do
  1301. {
  1302. //
  1303. // Increment the MAC's refernce count.
  1304. //
  1305. if (!ndisReferenceMac((PNDIS_MAC_BLOCK)NdisMacHandle))
  1306. {
  1307. //
  1308. // The MAC is closing.
  1309. //
  1310. Status = NDIS_STATUS_CLOSING;
  1311. break;
  1312. }
  1313. DerefMacOnError = TRUE;
  1314. //
  1315. // Allocate the string structure and space for the string. This
  1316. // must be allocated from nonpaged pool, because it is touched by
  1317. // NdisWriteErrorLogEntry, which may be called from DPC level.
  1318. //
  1319. NdisAdapterName.Buffer = (PWSTR)ALLOC_FROM_POOL(AdapterName->MaximumLength,
  1320. NDIS_TAG_NAME_BUF);
  1321. if (NdisAdapterName.Buffer == NULL)
  1322. {
  1323. Status = NDIS_STATUS_RESOURCES;
  1324. break;
  1325. }
  1326. NdisAdapterName.MaximumLength = AdapterName->MaximumLength;
  1327. NdisAdapterName.Length = AdapterName->Length;
  1328. CopyMemory(NdisAdapterName.Buffer,
  1329. AdapterName->Buffer,
  1330. AdapterName->MaximumLength);
  1331. //
  1332. // Create a device object for this adapter.
  1333. //
  1334. NtStatus = IoCreateDevice(((PNDIS_MAC_BLOCK)NdisMacHandle)->NdisMacInfo->NdisWrapperDriver,
  1335. sizeof(NDIS_ADAPTER_BLOCK) +
  1336. ConfigurationHandle->DriverBaseName->Length +
  1337. sizeof(NDIS_WRAPPER_CONTEXT),
  1338. AdapterName,
  1339. FILE_DEVICE_PHYSICAL_NETCARD,
  1340. 0,
  1341. FALSE, // exclusive flag
  1342. &TmpDeviceP);
  1343. if (NtStatus != STATUS_SUCCESS)
  1344. {
  1345. Status = NDIS_STATUS_DEVICE_FAILED;
  1346. break;
  1347. }
  1348. //
  1349. // Create symbolic link for the device
  1350. //
  1351. SymbolicLink.Buffer = SymLnkBuf;
  1352. SymbolicLink.Length = sizeof(L"\\DosDevices\\") - sizeof(WCHAR);
  1353. SymbolicLink.MaximumLength = sizeof(SymLnkBuf);
  1354. RtlCopyMemory(SymLnkBuf, L"\\DosDevices\\", sizeof(L"\\DosDevices\\"));
  1355. RtlAppendUnicodeStringToString(&SymbolicLink, ConfigurationHandle->DriverBaseName);
  1356. IoCreateSymbolicLink(&SymbolicLink, AdapterName);
  1357. //
  1358. // Initialize the NDIS adapter block in the device object extension
  1359. //
  1360. // *** NDIS_WRAPPER_CONTEXT has a higher alignment requirement than
  1361. // NDIS_ADAPTER_BLOCK, so we put it first in the extension.
  1362. //
  1363. ASSERT((sizeof(NDIS_WRAPPER_CONTEXT) & 3) <= (sizeof(NDIS_ADAPTER_BLOCK) & 3));
  1364. NewAdaptP = (PNDIS_ADAPTER_BLOCK)((PNDIS_WRAPPER_CONTEXT)TmpDeviceP->DeviceExtension + 1);
  1365. ZeroMemory(NewAdaptP, sizeof(NDIS_ADAPTER_BLOCK));
  1366. NewAdaptP->BaseName.Buffer = (PWSTR)((PUCHAR)NewAdaptP + sizeof(NDIS_ADAPTER_BLOCK));
  1367. NewAdaptP->BaseName.MaximumLength =
  1368. NewAdaptP->BaseName.Length = ConfigurationHandle->DriverBaseName->Length;
  1369. RtlUpcaseUnicodeString(&NewAdaptP->BaseName,
  1370. ConfigurationHandle->DriverBaseName,
  1371. FALSE);
  1372. NewAdaptP->DeviceObject = TmpDeviceP;
  1373. NewAdaptP->MacHandle = TmpMacP = (PNDIS_MAC_BLOCK)NdisMacHandle;
  1374. NewAdaptP->MacAdapterContext = MacAdapterContext;
  1375. NewAdaptP->AdapterName = NdisAdapterName;
  1376. NewAdaptP->OpenQueue = (PNDIS_OPEN_BLOCK)NULL;
  1377. NewAdaptP->WrapperContext = TmpDeviceP->DeviceExtension;
  1378. //
  1379. // Save the bus information in the adapter block
  1380. //
  1381. NewAdaptP->BusType = ConfigurationHandle->Db.BusType;
  1382. NewAdaptP->BusId = ConfigurationHandle->Db.BusId;
  1383. NewAdaptP->BusNumber = ConfigurationHandle->Db.BusNumber;
  1384. NewAdaptP->SlotNumber = ConfigurationHandle->Db.SlotNumber;
  1385. //
  1386. // Get the BusNumber and BusType from the context
  1387. //
  1388. BusNumber = ConfigurationHandle->ParametersQueryTable[3].DefaultLength;
  1389. if (ConfigurationHandle->ParametersQueryTable[3].DefaultType == (NDIS_INTERFACE_TYPE)-1)
  1390. {
  1391. BusType = (NDIS_INTERFACE_TYPE)-1;
  1392. }
  1393. else
  1394. {
  1395. BusType = AdapterInfo->AdapterType;
  1396. }
  1397. //
  1398. // Check that if there is no bus number or no bus type that the driver is not
  1399. // going to try to acquire any hardware resources
  1400. //
  1401. ValidBus = ((BusType != (NDIS_INTERFACE_TYPE)-1) && (BusNumber != (ULONG)-1));
  1402. if ((BusType == (NDIS_INTERFACE_TYPE)-1) || (BusNumber == (ULONG)-1))
  1403. {
  1404. if ((AdapterInfo != NULL) && ((AdapterInfo->NumberOfPortDescriptors != 0) || (AdapterInfo->Master)))
  1405. {
  1406. //
  1407. // Error out
  1408. //
  1409. Status = NDIS_STATUS_BAD_CHARACTERISTICS;
  1410. break;
  1411. }
  1412. }
  1413. //
  1414. // Free up previously assigned Resource memory
  1415. //
  1416. if ((BusType == NdisInterfacePci) &&
  1417. (BusNumber != -1) &&
  1418. (AdapterInfo != NULL) &&
  1419. (TmpMacP->PciAssignedResources != NULL))
  1420. {
  1421. TmpMacP->PciAssignedResources->Count = 0;
  1422. NtStatus = IoReportResourceUsage(NULL,
  1423. ((PNDIS_MAC_BLOCK)NdisMacHandle)->NdisMacInfo->NdisWrapperDriver,
  1424. TmpMacP->PciAssignedResources,
  1425. sizeof(CM_RESOURCE_LIST),
  1426. NULL,
  1427. NULL,
  1428. 0,
  1429. TRUE,
  1430. &Conflict);
  1431. FREE_POOL(TmpMacP->PciAssignedResources);
  1432. TmpMacP->PciAssignedResources = NULL;
  1433. }
  1434. //
  1435. // Calculate size of new buffer
  1436. //
  1437. Size = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) *
  1438. (AdapterInfo->NumberOfPortDescriptors +
  1439. (((AdapterInfo->Master == TRUE) && (AdapterInfo->AdapterType == NdisInterfaceIsa)) ? 1 : 0));
  1440. Resources = (PCM_RESOURCE_LIST)ALLOC_FROM_POOL(Size, NDIS_TAG_RSRC_LIST);
  1441. if (Resources == NULL)
  1442. {
  1443. //
  1444. // Error out
  1445. //
  1446. Status = NDIS_STATUS_RESOURCES;
  1447. break;
  1448. }
  1449. //
  1450. // Fix up counts
  1451. //
  1452. Resources->List[0].PartialResourceList.Count = 0;
  1453. //
  1454. // Setup resources for the ports
  1455. //
  1456. if (ValidBus)
  1457. {
  1458. if (AdapterInfo != NULL)
  1459. {
  1460. ULONG HighestPort;
  1461. ULONG LowestPort;
  1462. Resources->Count = 1;
  1463. Resources->List[0].InterfaceType = AdapterInfo->AdapterType;
  1464. Resources->List[0].BusNumber = BusNumber;
  1465. Resources->List[0].PartialResourceList.Version = 0;
  1466. Resources->List[0].PartialResourceList.Revision = 0;
  1467. NewAdaptP->Resources = Resources;
  1468. NewAdaptP->BusNumber = BusNumber;
  1469. NewAdaptP->BusType = BusType;
  1470. NewAdaptP->AdapterType = AdapterInfo->AdapterType;
  1471. NewAdaptP->Master = AdapterInfo->Master;
  1472. //
  1473. // NewAdaptP->InitialPort and NumberOfPorts refer to the
  1474. // union of all port mappings specified; the area must
  1475. // cover all possible ports. We scan the list, keeping track
  1476. // of the highest and lowest ports used.
  1477. //
  1478. if (AdapterInfo->NumberOfPortDescriptors > 0)
  1479. {
  1480. //
  1481. // Setup port
  1482. //
  1483. LowestPort = AdapterInfo->PortDescriptors[0].InitialPort;
  1484. HighestPort = LowestPort + AdapterInfo->PortDescriptors[0].NumberOfPorts;
  1485. if (AdapterInfo->PortDescriptors[0].PortOffset == NULL)
  1486. {
  1487. AllocateIndividualPorts = FALSE;
  1488. }
  1489. for (i = 0; i < AdapterInfo->NumberOfPortDescriptors; i++)
  1490. {
  1491. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count + i].Type =
  1492. CmResourceTypePort;
  1493. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count + i].ShareDisposition =
  1494. CmResourceShareDeviceExclusive;
  1495. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count + i].Flags =
  1496. (AdapterInfo->AdapterType == NdisInterfaceInternal)?
  1497. CM_RESOURCE_PORT_MEMORY : CM_RESOURCE_PORT_IO;
  1498. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count + i].u.Port.Start.QuadPart =
  1499. (ULONG)AdapterInfo->PortDescriptors[i].InitialPort;
  1500. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count + i].u.Port.Length =
  1501. AdapterInfo->PortDescriptors[i].NumberOfPorts;
  1502. if (AdapterInfo->PortDescriptors[i].PortOffset == NULL)
  1503. {
  1504. AllocateIndividualPorts = FALSE;
  1505. }
  1506. if (AdapterInfo->PortDescriptors[i].InitialPort < LowestPort)
  1507. {
  1508. LowestPort = AdapterInfo->PortDescriptors[i].InitialPort;
  1509. }
  1510. if ((AdapterInfo->PortDescriptors[i].InitialPort +
  1511. AdapterInfo->PortDescriptors[i].NumberOfPorts) > HighestPort)
  1512. {
  1513. HighestPort = AdapterInfo->PortDescriptors[i].InitialPort +
  1514. AdapterInfo->PortDescriptors[i].NumberOfPorts;
  1515. }
  1516. }
  1517. NewAdaptP->InitialPort = LowestPort;
  1518. NewAdaptP->NumberOfPorts = HighestPort - LowestPort;
  1519. }
  1520. else
  1521. {
  1522. NewAdaptP->NumberOfPorts = 0;
  1523. }
  1524. Resources->List[0].PartialResourceList.Count += AdapterInfo->NumberOfPortDescriptors;
  1525. }
  1526. else
  1527. {
  1528. //
  1529. // Error out
  1530. //
  1531. Status = NDIS_STATUS_FAILURE;
  1532. break;
  1533. }
  1534. }
  1535. NewAdaptP->BeingRemoved = FALSE;
  1536. if (ValidBus)
  1537. {
  1538. //
  1539. // Submit Resources
  1540. //
  1541. NtStatus = IoReportResourceUsage(NULL,
  1542. ((PNDIS_MAC_BLOCK)NdisMacHandle)->NdisMacInfo->NdisWrapperDriver,
  1543. NULL,
  1544. 0,
  1545. NewAdaptP->DeviceObject,
  1546. Resources,
  1547. sizeof(CM_RESOURCE_LIST) +
  1548. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) *
  1549. Resources->List[0].PartialResourceList.Count,
  1550. TRUE,
  1551. &Conflict);
  1552. //
  1553. // Check for conflict.
  1554. //
  1555. if (Conflict || (NtStatus != STATUS_SUCCESS))
  1556. {
  1557. if (Conflict)
  1558. {
  1559. //
  1560. // Log an error
  1561. //
  1562. PIO_ERROR_LOG_PACKET errorLogEntry;
  1563. ULONG StringSize;
  1564. PWCH baseFileName;
  1565. baseFileName = NewAdaptP->AdapterName.Buffer;
  1566. //
  1567. // Parse out the path name, leaving only the device name.
  1568. //
  1569. for (i = 0; i < NewAdaptP->AdapterName.Length / sizeof(WCHAR); i++)
  1570. {
  1571. //
  1572. // If s points to a directory separator, set baseFileName to
  1573. // the character after the separator.
  1574. //
  1575. if (NewAdaptP->AdapterName.Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
  1576. {
  1577. baseFileName = &(NewAdaptP->AdapterName.Buffer[++i]);
  1578. }
  1579. }
  1580. StringSize = NewAdaptP->AdapterName.MaximumLength -
  1581. (((ULONG)baseFileName) - ((ULONG)NewAdaptP->AdapterName.Buffer)) ;
  1582. errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(TmpDeviceP,
  1583. (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) + StringSize));
  1584. if (errorLogEntry != NULL)
  1585. {
  1586. errorLogEntry->ErrorCode = EVENT_NDIS_IO_PORT_CONFLICT;
  1587. //
  1588. // store the time
  1589. //
  1590. errorLogEntry->MajorFunctionCode = 0;
  1591. errorLogEntry->RetryCount = 0;
  1592. errorLogEntry->UniqueErrorValue = 0;
  1593. errorLogEntry->FinalStatus = 0;
  1594. errorLogEntry->SequenceNumber = 0;
  1595. errorLogEntry->IoControlCode = 0;
  1596. //
  1597. // Set string information
  1598. //
  1599. if (StringSize != 0)
  1600. {
  1601. errorLogEntry->NumberOfStrings = 1;
  1602. errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
  1603. CopyMemory (((PUCHAR)errorLogEntry) + sizeof(IO_ERROR_LOG_PACKET),
  1604. (PVOID)baseFileName,
  1605. StringSize);
  1606. }
  1607. else
  1608. {
  1609. errorLogEntry->NumberOfStrings = 0;
  1610. }
  1611. //
  1612. // write it out
  1613. //
  1614. IoWriteErrorLogEntry(errorLogEntry);
  1615. }
  1616. Status = NDIS_STATUS_RESOURCE_CONFLICT;
  1617. break;
  1618. }
  1619. Status = NDIS_STATUS_FAILURE;
  1620. break;
  1621. }
  1622. //
  1623. // If port mapping is needed, we do that. If the result
  1624. // is in memory, we have to map it. We map only the
  1625. // ports specified in AdapterInformation; the default
  1626. // is to map the first 4K.
  1627. //
  1628. // Note that NumberOfPorts can only be 0 if AdapterInfo
  1629. // is provided and explicitly sets it to 0, so in that
  1630. // case it is OK to leave the adapter in a state where
  1631. // a call to NdisXXXPort will probably crash (because
  1632. // PortOffset will be undefined).
  1633. //
  1634. if (NewAdaptP->NumberOfPorts > 0)
  1635. {
  1636. if (AllocateIndividualPorts)
  1637. {
  1638. Status = NDIS_STATUS_SUCCESS;
  1639. //
  1640. // We get here if we are supposed to allocate ports on an
  1641. // individual bases -- which implies that the driver will
  1642. // be using the Raw functions.
  1643. //
  1644. // Get the system physical address for this card. The card uses
  1645. // I/O space, except for "internal" Jazz devices which use
  1646. // memory space.
  1647. //
  1648. for (i = 0; i < AdapterInfo->NumberOfPortDescriptors; i++)
  1649. {
  1650. addressSpace = (NewAdaptP->AdapterType == NdisInterfaceInternal) ? 0 : 1;
  1651. InitialPortAddress.LowPart = AdapterInfo->PortDescriptors[i].InitialPort;
  1652. InitialPortAddress.HighPart = 0;
  1653. if (!HalTranslateBusAddress(NewAdaptP->BusType, // InterfaceType
  1654. NewAdaptP->BusNumber, // BusNumber
  1655. InitialPortAddress, // Bus Address
  1656. &addressSpace, // AddressSpace
  1657. &PortAddress)) // Translated address
  1658. {
  1659. Status = NDIS_STATUS_FAILURE;
  1660. break;
  1661. }
  1662. if (addressSpace == 0)
  1663. {
  1664. //
  1665. // memory space
  1666. //
  1667. *(AdapterInfo->PortDescriptors[i].PortOffset) =
  1668. MmMapIoSpace(PortAddress,
  1669. AdapterInfo->PortDescriptors[i].NumberOfPorts,
  1670. FALSE);
  1671. if (*(AdapterInfo->PortDescriptors[i].PortOffset) == NULL)
  1672. {
  1673. Status = NDIS_STATUS_RESOURCES;
  1674. break;
  1675. }
  1676. }
  1677. else
  1678. {
  1679. //
  1680. // I/O space
  1681. //
  1682. *(AdapterInfo->PortDescriptors[i].PortOffset) = (PUCHAR)PortAddress.LowPart;
  1683. }
  1684. }
  1685. if (!NT_SUCCESS(Status))
  1686. break;
  1687. }
  1688. else
  1689. {
  1690. //
  1691. // The driver will not use the Raw functions, only the
  1692. // old NdisRead and NdisWrite port functions.
  1693. //
  1694. // Get the system physical address for this card. The card uses
  1695. // I/O space, except for "internal" Jazz devices which use
  1696. // memory space.
  1697. //
  1698. addressSpace = (NewAdaptP->AdapterType == NdisInterfaceInternal) ? 0 : 1;
  1699. InitialPortAddress.LowPart = NewAdaptP->InitialPort;
  1700. InitialPortAddress.HighPart = 0;
  1701. if (!HalTranslateBusAddress(NewAdaptP->BusType, // InterfaceType
  1702. NewAdaptP->BusNumber, // BusNumber
  1703. InitialPortAddress, // Bus Address
  1704. &addressSpace, // AddressSpace
  1705. &PortAddress)) // Translated address
  1706. {
  1707. Status = NDIS_STATUS_FAILURE;
  1708. break;
  1709. }
  1710. if (addressSpace == 0)
  1711. {
  1712. //
  1713. // memory space
  1714. //
  1715. NewAdaptP->InitialPortMapping = MmMapIoSpace(PortAddress,
  1716. NewAdaptP->NumberOfPorts,
  1717. FALSE);
  1718. if (NewAdaptP->InitialPortMapping == NULL)
  1719. {
  1720. Status = NDIS_STATUS_RESOURCES;
  1721. break;
  1722. }
  1723. NewAdaptP->InitialPortMapped = TRUE;
  1724. }
  1725. else
  1726. {
  1727. //
  1728. // I/O space
  1729. //
  1730. NewAdaptP->InitialPortMapping = (PUCHAR)PortAddress.LowPart;
  1731. NewAdaptP->InitialPortMapped = FALSE;
  1732. }
  1733. //
  1734. // PortOffset holds the mapped address of port 0.
  1735. //
  1736. NewAdaptP->PortOffset = NewAdaptP->InitialPortMapping - NewAdaptP->InitialPort;
  1737. }
  1738. }
  1739. else
  1740. {
  1741. //
  1742. // Technically should not allow this, but do it until
  1743. // all drivers register their info correctly.
  1744. //
  1745. NewAdaptP->PortOffset = 0;
  1746. }
  1747. }
  1748. //
  1749. // If the driver want to be called back now, use
  1750. // supplied callback routine.
  1751. //
  1752. if ((AdapterInfo != NULL) && (AdapterInfo->ActivateCallback != NULL))
  1753. {
  1754. Status = (*(AdapterInfo->ActivateCallback))((NDIS_HANDLE)NewAdaptP,
  1755. MacAdapterContext,
  1756. AdapterInfo->DmaChannel);
  1757. if (Status != NDIS_STATUS_SUCCESS)
  1758. {
  1759. break;
  1760. }
  1761. }
  1762. //
  1763. // Set information from AdapterInformation. The call back
  1764. // routine can set these values.
  1765. //
  1766. NewAdaptP->ChannelNumber = AdapterInfo->DmaChannel;
  1767. NewAdaptP->PhysicalMapRegistersNeeded = AdapterInfo->PhysicalMapRegistersNeeded;
  1768. NewAdaptP->MaximumPhysicalMapping = AdapterInfo->MaximumPhysicalMapping;
  1769. //
  1770. // Check for resource conflic on DmaChannel.
  1771. //
  1772. if (NewAdaptP->Master && ValidBus && (NewAdaptP->AdapterType == NdisInterfaceIsa))
  1773. {
  1774. //
  1775. // Put the DMA channel in the resource list.
  1776. //
  1777. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].Type =
  1778. CmResourceTypeDma;
  1779. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].ShareDisposition =
  1780. CmResourceShareDeviceExclusive;
  1781. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].Flags =
  1782. 0;
  1783. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].u.Dma.Channel =
  1784. NewAdaptP->ChannelNumber;
  1785. Resources->List[0].PartialResourceList.PartialDescriptors[Resources->List[0].PartialResourceList.Count].u.Dma.Port =
  1786. 0;
  1787. Resources->List[0].PartialResourceList.Count++;
  1788. //
  1789. // Submit Resources
  1790. //
  1791. NtStatus = IoReportResourceUsage(NULL,
  1792. ((PNDIS_MAC_BLOCK)NdisMacHandle)->NdisMacInfo->NdisWrapperDriver,
  1793. NULL,
  1794. 0,
  1795. NewAdaptP->DeviceObject,
  1796. Resources,
  1797. sizeof(CM_RESOURCE_LIST) +
  1798. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) *
  1799. Resources->List[0].PartialResourceList.Count,
  1800. TRUE,
  1801. &Conflict);
  1802. //
  1803. // Check for conflict.
  1804. //
  1805. if (Conflict || (NtStatus != STATUS_SUCCESS))
  1806. {
  1807. if (Conflict)
  1808. {
  1809. //
  1810. // Log an error
  1811. //
  1812. PIO_ERROR_LOG_PACKET errorLogEntry;
  1813. ULONG StringSize;
  1814. PWCH baseFileName;
  1815. baseFileName = NewAdaptP->AdapterName.Buffer;
  1816. //
  1817. // Parse out the path name, leaving only the device name.
  1818. //
  1819. for (i = 0; i < NewAdaptP->AdapterName.Length / sizeof(WCHAR); i++)
  1820. {
  1821. //
  1822. // If s points to a directory separator, set baseFileName to
  1823. // the character after the separator.
  1824. //
  1825. if (NewAdaptP->AdapterName.Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
  1826. {
  1827. baseFileName = &(NewAdaptP->AdapterName.Buffer[++i]);
  1828. }
  1829. }
  1830. StringSize = NewAdaptP->AdapterName.MaximumLength -
  1831. (((ULONG)baseFileName) - ((ULONG)NewAdaptP->AdapterName.Buffer)) ;
  1832. errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(TmpDeviceP,
  1833. (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) + StringSize));
  1834. if (errorLogEntry != NULL)
  1835. {
  1836. if ((NewAdaptP->Master) &&
  1837. (NewAdaptP->AdapterType == Isa))
  1838. {
  1839. errorLogEntry->ErrorCode = EVENT_NDIS_PORT_OR_DMA_CONFLICT;
  1840. }
  1841. else
  1842. {
  1843. errorLogEntry->ErrorCode = EVENT_NDIS_IO_PORT_CONFLICT;
  1844. }
  1845. //
  1846. // store the time
  1847. //
  1848. errorLogEntry->MajorFunctionCode = 0;
  1849. errorLogEntry->RetryCount = 0;
  1850. errorLogEntry->UniqueErrorValue = 0;
  1851. errorLogEntry->FinalStatus = 0;
  1852. errorLogEntry->SequenceNumber = 0;
  1853. errorLogEntry->IoControlCode = 0;
  1854. //
  1855. // Set string information
  1856. //
  1857. if (StringSize != 0)
  1858. {
  1859. errorLogEntry->NumberOfStrings = 1;
  1860. errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
  1861. CopyMemory (((PUCHAR)errorLogEntry) + sizeof(IO_ERROR_LOG_PACKET),
  1862. (PVOID)baseFileName,
  1863. StringSize);
  1864. }
  1865. else
  1866. {
  1867. errorLogEntry->NumberOfStrings = 0;
  1868. }
  1869. //
  1870. // write it out
  1871. //
  1872. IoWriteErrorLogEntry(errorLogEntry);
  1873. }
  1874. Status = NDIS_STATUS_RESOURCE_CONFLICT;
  1875. break;
  1876. }
  1877. Status = NDIS_STATUS_FAILURE;
  1878. break;
  1879. }
  1880. }
  1881. //
  1882. // If the device is a busmaster, we get an adapter
  1883. // object for it.
  1884. // If map registers are needed, we loop, allocating an
  1885. // adapter channel for each map register needed.
  1886. //
  1887. if ((NewAdaptP->Master) && ValidBus)
  1888. {
  1889. //
  1890. // This is needed by HalGetAdapter.
  1891. //
  1892. DEVICE_DESCRIPTION DeviceDescription;
  1893. //
  1894. // Returned by HalGetAdapter.
  1895. //
  1896. ULONG MapRegistersAllowed;
  1897. //
  1898. // Returned by HalGetAdapter.
  1899. //
  1900. PADAPTER_OBJECT AdapterObject;
  1901. //
  1902. // Map registers needed per channel.
  1903. //
  1904. ULONG MapRegistersPerChannel;
  1905. NTSTATUS Status;
  1906. //
  1907. // Allocate storage for holding the appropriate
  1908. // information for each map register.
  1909. //
  1910. NewAdaptP->MapRegisters = (PMAP_REGISTER_ENTRY)ALLOC_FROM_POOL(sizeof(MAP_REGISTER_ENTRY) *
  1911. NewAdaptP->PhysicalMapRegistersNeeded,
  1912. NDIS_TAG_MAP_REG);
  1913. if (NewAdaptP->MapRegisters == (PMAP_REGISTER_ENTRY)NULL)
  1914. {
  1915. Status = NDIS_STATUS_RESOURCES;
  1916. break;
  1917. }
  1918. //
  1919. // Use this event to tell us when ndisAllocationExecutionRoutine
  1920. // has been called.
  1921. //
  1922. INITIALIZE_EVENT(&NewAdaptP->AllocationEvent);
  1923. //
  1924. // Set up the device description; zero it out in case its
  1925. // size changes.
  1926. //
  1927. ZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));
  1928. DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
  1929. DeviceDescription.Master = TRUE;
  1930. DeviceDescription.ScatterGather = TRUE;
  1931. DeviceDescription.BusNumber = NewAdaptP->BusNumber;
  1932. DeviceDescription.DmaChannel = NewAdaptP->ChannelNumber;
  1933. DeviceDescription.InterfaceType = NewAdaptP->AdapterType;
  1934. if (DeviceDescription.InterfaceType == NdisInterfaceIsa)
  1935. {
  1936. //
  1937. // For ISA devices, the width is based on the DMA channel:
  1938. // 0-3 == 8 bits, 5-7 == 16 bits. Timing is compatibility
  1939. // mode.
  1940. //
  1941. if (NewAdaptP->ChannelNumber > 4)
  1942. {
  1943. DeviceDescription.DmaWidth = Width16Bits;
  1944. }
  1945. else
  1946. {
  1947. DeviceDescription.DmaWidth = Width8Bits;
  1948. }
  1949. DeviceDescription.DmaSpeed = Compatible;
  1950. }
  1951. else if ((DeviceDescription.InterfaceType == NdisInterfaceMca) ||
  1952. (DeviceDescription.InterfaceType == NdisInterfaceEisa) ||
  1953. (DeviceDescription.InterfaceType == NdisInterfacePci))
  1954. {
  1955. DeviceDescription.Dma32BitAddresses = AdapterInfo->Dma32BitAddresses;
  1956. DeviceDescription.DmaPort = 0;
  1957. }
  1958. DeviceDescription.MaximumLength = NewAdaptP->MaximumPhysicalMapping;
  1959. //
  1960. // Determine how many map registers we need per channel.
  1961. //
  1962. MapRegistersPerChannel =
  1963. ((NewAdaptP->MaximumPhysicalMapping - 2) / PAGE_SIZE) + 2;
  1964. //
  1965. // Get the adapter object.
  1966. //
  1967. AdapterObject = HalGetAdapter (&DeviceDescription, &MapRegistersAllowed);
  1968. if (AdapterObject == NULL)
  1969. {
  1970. Status = NDIS_STATUS_RESOURCES;
  1971. break;
  1972. }
  1973. ASSERT (MapRegistersAllowed >= MapRegistersPerChannel);
  1974. //
  1975. // We save this to call IoFreeMapRegisters later.
  1976. //
  1977. NewAdaptP->SystemAdapterObject = AdapterObject;
  1978. //
  1979. // Now loop, allocating an adapter channel each time, then
  1980. // freeing everything but the map registers.
  1981. //
  1982. for (i=0; i<NewAdaptP->PhysicalMapRegistersNeeded; i++)
  1983. {
  1984. NewAdaptP->CurrentMapRegister = i;
  1985. RAISE_IRQL_TO_DISPATCH(&OldIrql);
  1986. Status = IoAllocateAdapterChannel(AdapterObject,
  1987. NewAdaptP->DeviceObject,
  1988. MapRegistersPerChannel,
  1989. ndisAllocationExecutionRoutine,
  1990. (PVOID)NewAdaptP);
  1991. if (!NT_SUCCESS(Status))
  1992. {
  1993. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1994. ("Failed to load driver because of\n"));
  1995. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1996. ("insufficient map registers.\n"));
  1997. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  1998. ("AllocateAdapterChannel: %lx\n", Status));
  1999. FREE_POOL(Resources);
  2000. for (; i != 0; i--)
  2001. {
  2002. IoFreeMapRegisters(NewAdaptP->SystemAdapterObject,
  2003. NewAdaptP->MapRegisters[i-1].MapRegister,
  2004. MapRegistersPerChannel);
  2005. }
  2006. LOWER_IRQL(OldIrql);
  2007. Status = NDIS_STATUS_RESOURCES;
  2008. break;
  2009. }
  2010. LOWER_IRQL(OldIrql);
  2011. TimeoutValue.QuadPart = Int32x32To64(10 * 1000, -10000);
  2012. //
  2013. // ndisAllocationExecutionRoutine will set this event
  2014. // when it has gotten FirstTranslationEntry.
  2015. //
  2016. NtStatus = WAIT_FOR_OBJECT(&NewAdaptP->AllocationEvent, &TimeoutValue);
  2017. if (NtStatus != STATUS_SUCCESS)
  2018. {
  2019. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  2020. ("NDIS DMA AllocateAdapterChannel: %lx\n", NtStatus));
  2021. FREE_POOL(Resources);
  2022. RAISE_IRQL_TO_DISPATCH(&OldIrql);
  2023. for (; i != 0; i--)
  2024. {
  2025. IoFreeMapRegisters(NewAdaptP->SystemAdapterObject,
  2026. NewAdaptP->MapRegisters[i-1].MapRegister,
  2027. MapRegistersPerChannel);
  2028. }
  2029. LOWER_IRQL(OldIrql);
  2030. Status = NDIS_STATUS_RESOURCES;
  2031. break;
  2032. }
  2033. RESET_EVENT(&NewAdaptP->AllocationEvent);
  2034. }
  2035. if (!NT_SUCCESS(Status))
  2036. break;
  2037. }
  2038. NdisInitializeRef(&NewAdaptP->Ref);
  2039. if (!ndisQueueAdapterOnMac(NewAdaptP, TmpMacP))
  2040. {
  2041. //
  2042. // The MAC is closing, undo what we have done.
  2043. //
  2044. if (NewAdaptP->Master)
  2045. {
  2046. ULONG MapRegistersPerChannel =
  2047. ((NewAdaptP->MaximumPhysicalMapping - 2) / PAGE_SIZE) + 2;
  2048. for (i=0; i<NewAdaptP->PhysicalMapRegistersNeeded; i++)
  2049. {
  2050. RAISE_IRQL_TO_DISPATCH(&OldIrql);
  2051. IoFreeMapRegisters(NewAdaptP->SystemAdapterObject,
  2052. NewAdaptP->MapRegisters[i].MapRegister,
  2053. MapRegistersPerChannel);
  2054. LOWER_IRQL(OldIrql);
  2055. }
  2056. }
  2057. Status = NDIS_STATUS_CLOSING;
  2058. break;
  2059. }
  2060. //
  2061. // Add an extra reference because the wrapper is using the MAC
  2062. //
  2063. ndisReferenceAdapter(NewAdaptP);
  2064. MacReferencePackage();
  2065. *NdisAdapterHandle = (NDIS_HANDLE)NewAdaptP;
  2066. Status = NDIS_STATUS_SUCCESS;
  2067. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  2068. ("<==NdisRegisterAdapter\n"));
  2069. } while (FALSE);
  2070. if (Status != NDIS_STATUS_SUCCESS)
  2071. {
  2072. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  2073. ("<==NdisRegisterAdapter\n"));
  2074. if (NewAdaptP != NULL)
  2075. {
  2076. NdisWriteErrorLogEntry(NewAdaptP,
  2077. Status,
  2078. 0);
  2079. }
  2080. if (DerefMacOnError)
  2081. {
  2082. ndisDereferenceMac(TmpMacP);
  2083. }
  2084. if (NdisAdapterName.Buffer != NULL)
  2085. {
  2086. FREE_POOL(NdisAdapterName.Buffer);
  2087. }
  2088. if (TmpDeviceP != NULL)
  2089. {
  2090. IoDeleteDevice(TmpDeviceP);
  2091. if (NewAdaptP->MapRegisters != NULL)
  2092. {
  2093. FREE_POOL(NewAdaptP->MapRegisters);
  2094. }
  2095. if (Resources != NULL)
  2096. {
  2097. FREE_POOL(Resources);
  2098. }
  2099. }
  2100. }
  2101. return Status;
  2102. }
  2103. NDIS_STATUS
  2104. NdisDeregisterAdapter(
  2105. IN NDIS_HANDLE NdisAdapterHandle
  2106. )
  2107. /*++
  2108. Routine Description:
  2109. Deregisters an NDIS adapter.
  2110. Arguments:
  2111. NdisAdapterHandle - The handle returned by NdisRegisterAdapter.
  2112. Return Value:
  2113. NDIS_STATUS_SUCCESS.
  2114. --*/
  2115. {
  2116. //
  2117. // KillAdapter does all the work.
  2118. //
  2119. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  2120. ("==>NdisDeregisterAdapter\n"));
  2121. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  2122. (" Deregistering Adapter %s\n",
  2123. ((PNDIS_ADAPTER_BLOCK)NdisAdapterHandle)->AdapterName.Buffer));
  2124. IF_DBG(DBG_COMP_CONFIG, DBG_LEVEL_ERR)
  2125. {
  2126. if (DbgIsNull(NdisAdapterHandle))
  2127. {
  2128. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  2129. ("DeregisterAdapter: Null Handle\n"));
  2130. DBGBREAK(DBG_COMP_CONFIG, DBG_LEVEL_ERR);
  2131. }
  2132. if (!DbgIsNonPaged(NdisAdapterHandle))
  2133. {
  2134. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR,
  2135. ("DeregisterAdapter: Handle not in NonPaged Memory\n"));
  2136. DBGBREAK(DBG_COMP_CONFIG, DBG_LEVEL_ERR);
  2137. }
  2138. }
  2139. ndisKillAdapter((PNDIS_ADAPTER_BLOCK)NdisAdapterHandle);
  2140. //
  2141. // Remove reference from wrapper
  2142. //
  2143. ndisDereferenceAdapter((PNDIS_ADAPTER_BLOCK)NdisAdapterHandle);
  2144. MacDereferencePackage();
  2145. DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO,
  2146. ("<==NdisDeregisterAdapter\n"));
  2147. return NDIS_STATUS_SUCCESS;
  2148. }
  2149. VOID
  2150. NdisRegisterAdapterShutdownHandler(
  2151. IN NDIS_HANDLE NdisAdapterHandle,
  2152. IN PVOID ShutdownContext,
  2153. IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
  2154. )
  2155. /*++
  2156. Routine Description:
  2157. Registers an NDIS adapter.
  2158. Arguments:
  2159. NdisAdapterHandle - The handle returned by NdisRegisterAdapter.
  2160. ShutdownContext - Context to pass the the handler, when called.
  2161. ShutdownHandler - The Handler for the Adapter, to be called on shutdown.
  2162. Return Value:
  2163. NDIS_STATUS_SUCCESS.
  2164. --*/
  2165. {
  2166. PNDIS_ADAPTER_BLOCK Adapter = (PNDIS_ADAPTER_BLOCK) NdisAdapterHandle;
  2167. PNDIS_WRAPPER_CONTEXT WrapperContext = Adapter->WrapperContext;
  2168. if (WrapperContext->ShutdownHandler == NULL)
  2169. {
  2170. //
  2171. // Store information
  2172. //
  2173. WrapperContext->ShutdownHandler = ShutdownHandler;
  2174. WrapperContext->ShutdownContext = ShutdownContext;
  2175. //
  2176. // Register our shutdown handler for either a system shutdown
  2177. // notification or a bugcheck.
  2178. //
  2179. IoRegisterShutdownNotification(Adapter->DeviceObject);
  2180. KeInitializeCallbackRecord(&WrapperContext->BugcheckCallbackRecord);
  2181. KeRegisterBugCheckCallback(
  2182. &WrapperContext->BugcheckCallbackRecord,// callback record.
  2183. (PVOID) ndisBugcheckHandler, // callback routine.
  2184. (PVOID) WrapperContext, // free form buffer.
  2185. sizeof(NDIS_WRAPPER_CONTEXT), // buffer size.
  2186. "Ndis mac"); // component id.
  2187. }
  2188. }
  2189. VOID
  2190. NdisDeregisterAdapterShutdownHandler(
  2191. IN NDIS_HANDLE NdisAdapterHandle
  2192. )
  2193. /*++
  2194. Routine Description:
  2195. Deregisters an NDIS adapter.
  2196. Arguments:
  2197. NdisAdapterHandle - The handle returned by NdisRegisterAdapter.
  2198. Return Value:
  2199. NDIS_STATUS_SUCCESS.
  2200. --*/
  2201. {
  2202. PNDIS_ADAPTER_BLOCK Adapter = (PNDIS_ADAPTER_BLOCK) NdisAdapterHandle;
  2203. PNDIS_WRAPPER_CONTEXT WrapperContext = Adapter->WrapperContext;
  2204. if (WrapperContext->ShutdownHandler != NULL)
  2205. {
  2206. //
  2207. // Clear information
  2208. //
  2209. WrapperContext->ShutdownHandler = NULL;
  2210. IoUnregisterShutdownNotification(Adapter->DeviceObject);
  2211. KeDeregisterBugCheckCallback(&WrapperContext->BugcheckCallbackRecord);
  2212. }
  2213. }
  2214. NDIS_STATUS
  2215. NdisPciAssignResources(
  2216. IN NDIS_HANDLE NdisMacHandle,
  2217. IN NDIS_HANDLE NdisWrapperHandle,
  2218. IN NDIS_HANDLE WrapperConfigurationContext,
  2219. IN ULONG SlotNumber,
  2220. OUT PNDIS_RESOURCE_LIST * AssignedResources
  2221. )
  2222. /*++
  2223. Routine Description:
  2224. This routine uses the Hal to assign a set of resources to a PCI
  2225. device.
  2226. Arguments:
  2227. NdisMacHandle - Handle returned from NdisRegisterMac.
  2228. NdisWrapperHandle - Handle returned from NdisInitializeWrapper.
  2229. WrapperConfigurationContext - Handle passed to MacAddAdapter.
  2230. SlotNumber - Slot number of the device.
  2231. AssignedResources - The returned resources.
  2232. Return Value:
  2233. Status of the operation
  2234. --*/
  2235. {
  2236. NTSTATUS NdisStatus = NDIS_STATUS_FAILURE;
  2237. NTSTATUS NtStatus;
  2238. ULONG BusNumber;
  2239. NDIS_INTERFACE_TYPE BusType;
  2240. PRTL_QUERY_REGISTRY_TABLE KeyQueryTable;
  2241. PCM_RESOURCE_LIST AllocatedResources = NULL;
  2242. PNDIS_WRAPPER_HANDLE NdisMacInfo = (PNDIS_WRAPPER_HANDLE)NdisWrapperHandle;
  2243. //
  2244. // Get the BusNumber and the BusType from the Context here!!
  2245. //
  2246. KeyQueryTable = ((PNDIS_WRAPPER_CONFIGURATION_HANDLE)WrapperConfigurationContext)->ParametersQueryTable;
  2247. BusType = (NDIS_INTERFACE_TYPE)KeyQueryTable[3].DefaultType;
  2248. BusNumber = KeyQueryTable[3].DefaultLength;
  2249. NtStatus = HalAssignSlotResources((PUNICODE_STRING)(NdisMacInfo->NdisWrapperConfigurationHandle),
  2250. NULL,
  2251. NdisMacInfo->NdisWrapperDriver,
  2252. NULL,
  2253. BusType,
  2254. BusNumber,
  2255. SlotNumber,
  2256. &AllocatedResources);
  2257. *AssignedResources = NULL; // Assume failure
  2258. if (NtStatus == STATUS_SUCCESS)
  2259. {
  2260. //
  2261. // Store resources into the driver wide block
  2262. //
  2263. ((PNDIS_MAC_BLOCK)NdisMacHandle)->PciAssignedResources = AllocatedResources;
  2264. *AssignedResources = &(AllocatedResources->List[0].PartialResourceList);
  2265. //
  2266. // Update slot number since the driver can also scan and so the one
  2267. // in the registry is probably invalid
  2268. //
  2269. KeyQueryTable[4].DefaultLength = SlotNumber;
  2270. NdisStatus = NDIS_STATUS_SUCCESS;
  2271. }
  2272. return NdisStatus;
  2273. }