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.

4290 lines
108 KiB

4 years ago
  1. #if defined(JENSEN)
  2. /*++
  3. Copyright (c) 1990 Microsoft Corporation
  4. Copyright (c) 1992 Digital Equipment Corporation
  5. Module Name:
  6. jxhwsup.c
  7. Abstract:
  8. This module contains the HalpXxx routines for the NT I/O system that
  9. are hardware dependent. Were these routines not hardware dependent,
  10. they would normally reside in the internal.c module.
  11. Author:
  12. Jeff Havens (jhavens) 14-Feb-1990
  13. Miche Baker-Harvey (miche) 22-May-1992
  14. Jeff McLeman (mcleman) 27-May-1992
  15. Environment:
  16. Kernel mode, local to I/O system
  17. Revision History:
  18. --*/
  19. #include "halp.h"
  20. #include "jnsndef.h"
  21. #include "jnsnint.h"
  22. #include "jnsndma.h"
  23. #include "eisa.h"
  24. #include "jxisa.h"
  25. #include "string.h"
  26. #define HAL_32MB 0x2000000
  27. #define HALF_MEGABYTE 0x80000
  28. #define NUMBER_OF_SPECIAL_REGIONS 6
  29. #define SPECIAL_BUFFER_SIZE NUMBER_OF_SPECIAL_REGIONS*sizeof(MEMORY_REGION)
  30. PVOID HalpEisaControlBase;
  31. //
  32. // We have one fixed special memory region at half a megabyte.
  33. //
  34. MEMORY_REGION HalpHalfMeg;
  35. //
  36. // Pointer to special memory regions that must be checked on every I/O.
  37. // Use to check if PFN is contained in a special memory region.
  38. //
  39. PMEMORY_REGION HalpSpecialRegions = NULL;
  40. //
  41. // Buffers used for MEMORY_REGION descriptors. We cannot allocate non-paged
  42. // pool when we are building the MEMORY_REGION descriptors. So we will have
  43. // our own little pool.
  44. //
  45. UCHAR HalpMemoryRegionFree[SPECIAL_BUFFER_SIZE];
  46. //
  47. // We have one fixed pool to allocate MEMORY_REGIONS from.
  48. //
  49. PVOID HalpMemoryRegionBuffers = HalpMemoryRegionFree;
  50. ULONG HalpMemoryRegionSize = SPECIAL_BUFFER_SIZE;
  51. //
  52. // The following is the interrupt object used by the DMA controller dispatch
  53. // routine to provide synchronization to the DMA controller. It is initialized
  54. // by the I/O system during system initialization.
  55. //
  56. KINTERRUPT HalpDmaInterrupt;
  57. //
  58. // The HaeIndex, used in creating QVAs for EISA memory space.
  59. //
  60. ULONG HaeIndex;
  61. //
  62. // This is the HAE table. The first table entry is used to map the lowest
  63. // 32MB in a Jensen system. The second entry is used to map the next 32MB
  64. // entry so that graphics cards, etc., will work.
  65. //
  66. CHAR HalpHaeTable[4] = { 0, 1, 0, 0 };
  67. //
  68. // The following is an array of adapter object structures for the Eisa DMA
  69. // channels.
  70. //
  71. //
  72. // Define the area for the Eisa objects
  73. //
  74. PADAPTER_OBJECT HalpEisaAdapter[8];
  75. //
  76. // Some devices require a phyicially contiguous data buffers for DMA transfers.
  77. // Map registers are used give the appearance that all data buffers are
  78. // contiguous. In order to pool all of the map registers a master
  79. // adapter object is used. This object is allocated and saved internal to this
  80. // file. It contains a bit map for allocation of the registers and a queue
  81. // for requests which are waiting for more map registers. This object is
  82. // allocated during the first request to allocate an adapter which requires
  83. // map registers.
  84. //
  85. PADAPTER_OBJECT MasterAdapterObject;
  86. BOOLEAN LessThan16Mb;
  87. BOOLEAN HalpEisaDma;
  88. IO_ALLOCATION_ACTION
  89. HalpAllocationRoutine (
  90. IN PDEVICE_OBJECT DeviceObject,
  91. IN PIRP Irp,
  92. IN PVOID MapRegisterBase,
  93. IN PVOID Context
  94. );
  95. BOOLEAN
  96. HalpGrowMapBuffers(
  97. PADAPTER_OBJECT AdapterObject,
  98. ULONG Amount
  99. );
  100. PADAPTER_OBJECT
  101. HalpAllocateAdapter(
  102. IN ULONG MapRegistersPerChannel,
  103. IN PVOID AdapterBaseVa,
  104. IN PVOID ChannelNumber
  105. );
  106. VOID
  107. HalpCopyBufferMap(
  108. IN PMDL Mdl,
  109. IN PTRANSLATION_ENTRY translationEntry,
  110. IN PVOID CurrentVa,
  111. IN ULONG Length,
  112. IN BOOLEAN WriteToDevice
  113. );
  114. PVOID
  115. HalCreateQva(
  116. IN PHYSICAL_ADDRESS PA,
  117. IN PVOID VA
  118. );
  119. ULONG
  120. HalpGetEisaData(
  121. IN PBUS_HANDLER BusHandler,
  122. IN PBUS_HANDLER RootHandler,
  123. IN ULONG SlotNumber,
  124. IN PVOID Buffer,
  125. IN ULONG Offset,
  126. IN ULONG Length
  127. );
  128. ULONG
  129. HalpNoBusData (
  130. IN PVOID BusHandler,
  131. IN PVOID RootHandler,
  132. IN ULONG SlotNumber,
  133. IN PVOID Buffer,
  134. IN ULONG Offset,
  135. IN ULONG Length
  136. );
  137. BOOLEAN
  138. HalpSpecialMemory(
  139. IN ULONG PFN
  140. );
  141. BOOLEAN
  142. HalpAnySpecialMemory(
  143. IN PMDL Mdl,
  144. IN ULONG Length,
  145. IN ULONG Offset
  146. );
  147. VOID
  148. HalpCopyBufferMap(
  149. IN PMDL Mdl,
  150. IN PTRANSLATION_ENTRY translationEntry,
  151. IN PVOID CurrentVa,
  152. IN ULONG Length,
  153. IN BOOLEAN WriteToDevice
  154. )
  155. /*++
  156. Routine Description:
  157. This routine copies the specified data between the user buffer and the
  158. map register buffer. First, the user buffer is mapped, if need be then
  159. the data is copied. Finally, the user buffer will be unmapped, if need be.
  160. Arguments:
  161. Mdl - Pointer to the Mdl that describes the pages of memory that are
  162. being read or written.
  163. translationEntry - The address of the base map register that has been
  164. allocated to the device driver for use in mapping the xfer.
  165. CurrentVa - Current Virtual Address in the buffer described by the Mdl
  166. that the transfer is being done to or from.
  167. Length - The length of the transfer. This determines the number of map
  168. registers that need to be written to map the transfer.
  169. WriteToDevice - A Boolean value that indicates whether this is a write
  170. to the device from memory of vise-versa.
  171. Return Value:
  172. None
  173. --*/
  174. {
  175. PCCHAR bufferAddress;
  176. PCCHAR mapAddress;
  177. //
  178. // Get the system address of the MDL.
  179. //
  180. bufferAddress = MmGetSystemAddressForMdl(Mdl);
  181. //
  182. // Calculate the actual start of the buffer based on the system VA and
  183. // the current VA.
  184. //
  185. bufferAddress += (PCCHAR) CurrentVa - (PCCHAR) MmGetMdlVirtualAddress(Mdl);
  186. mapAddress = (PCCHAR) translationEntry->VirtualAddress +
  187. BYTE_OFFSET(CurrentVa);
  188. //
  189. // Copy the data between the user buffer and the map buffer.
  190. //
  191. if (WriteToDevice) {
  192. RtlMoveMemory( mapAddress, bufferAddress, Length);
  193. } else {
  194. RtlMoveMemory ( bufferAddress, mapAddress, Length);
  195. }
  196. }
  197. NTSTATUS
  198. HalAllocateAdapterChannel(
  199. IN PADAPTER_OBJECT AdapterObject,
  200. IN PWAIT_CONTEXT_BLOCK Wcb,
  201. IN ULONG NumberOfMapRegisters,
  202. IN PDRIVER_CONTROL ExecutionRoutine
  203. )
  204. /*++
  205. Routine Description:
  206. This routine allocates the adapter channel specified by the adapter object.
  207. This is accomplished by placing the device object of the driver that wants
  208. to allocate the adapter on the adapter's queue. If the queue is already
  209. "busy", then the adapter has already been allocated, so the device object
  210. is simply placed onto the queue and waits until the adapter becomes free.
  211. Once the adapter becomes free (or if it already is), then the driver's
  212. execution routine is invoked.
  213. Also, a number of map registers may be allocated to the driver by specifying
  214. a non-zero value for NumberOfMapRegisters. Then the map register must be
  215. allocated from the master adapter. Once there are a sufficient number of
  216. map registers available, then the execution routine is called and the
  217. base address of the allocated map registers in the adapter is also passed
  218. to the driver's execution routine.
  219. Arguments:
  220. AdapterObject - Pointer to the adapter control object to allocate to the
  221. driver.
  222. Wcb - Supplies a wait context block for saving the allocation parameters.
  223. The DeviceObject, CurrentIrp and DeviceContext should be initalized.
  224. NumberOfMapRegisters - The number of map registers that are to be allocated
  225. from the channel, if any.
  226. ExecutionRoutine - The address of the driver's execution routine that is
  227. invoked once the adapter channel (and possibly map registers) have been
  228. allocated.
  229. Return Value:
  230. Returns STATUS_SUCESS unless too many map registers are requested.
  231. Notes:
  232. Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
  233. --*/
  234. {
  235. PADAPTER_OBJECT MasterAdapter;
  236. BOOLEAN Busy = FALSE;
  237. IO_ALLOCATION_ACTION Action;
  238. KIRQL Irql;
  239. ULONG MapRegisterNumber;
  240. //
  241. // Begin by obtaining a pointer to the master adapter associated with this
  242. // request.
  243. //
  244. MasterAdapter = AdapterObject->MasterAdapter;
  245. //
  246. // Initialize the device object's wait context block in case this device
  247. // must wait before being able to allocate the adapter.
  248. //
  249. Wcb->DeviceRoutine = ExecutionRoutine;
  250. Wcb->NumberOfMapRegisters = NumberOfMapRegisters;
  251. //
  252. // Allocate the adapter object for this particular device. If the
  253. // adapter cannot be allocated because it has already been allocated
  254. // to another device, then return to the caller now; otherwise,
  255. // continue.
  256. //
  257. if (!KeInsertDeviceQueue( &AdapterObject->ChannelWaitQueue,
  258. &Wcb->WaitQueueEntry )) {
  259. //
  260. // Save the parameters in case there are not enough map registers.
  261. //
  262. AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
  263. AdapterObject->CurrentWcb = Wcb;
  264. //
  265. // The adapter was not busy so it has been allocated. Now check
  266. // to see whether this driver wishes to allocate any map registers.
  267. // Ensure that this adapter has enough total map registers
  268. // to satisfy the request.
  269. //
  270. if (NumberOfMapRegisters != 0 && AdapterObject->NeedsMapRegisters) {
  271. //
  272. // Lock the map register bit map and the adapter queue in the
  273. // master adapter object. The channel structure offset is used as
  274. // a hint for the register search.
  275. //
  276. if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) {
  277. AdapterObject->NumberOfMapRegisters = 0;
  278. IoFreeAdapterChannel(AdapterObject);
  279. return(STATUS_INSUFFICIENT_RESOURCES);
  280. }
  281. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  282. MapRegisterNumber = -1;
  283. if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
  284. MapRegisterNumber = RtlFindClearBitsAndSet(
  285. MasterAdapter->MapRegisters,
  286. NumberOfMapRegisters,
  287. 0
  288. );
  289. }
  290. if (MapRegisterNumber == -1) {
  291. //
  292. // There were not enough free map registers. Queue this request
  293. // on the master adapter where is will wait until some registers
  294. // are deallocated.
  295. //
  296. InsertTailList( &MasterAdapter->AdapterQueue,
  297. &AdapterObject->AdapterQueue
  298. );
  299. Busy = TRUE;
  300. } else {
  301. //
  302. // Calculate the map register base from the allocated map
  303. // register and base of the master adapter object.
  304. //
  305. AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY)
  306. MasterAdapter->MapRegisterBase + MapRegisterNumber);
  307. //
  308. // Set the no scatter/gather flag if scatter/gather not
  309. // supported.
  310. //
  311. if (!AdapterObject->ScatterGather) {
  312. AdapterObject->MapRegisterBase = (PVOID)
  313. ((ULONG) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);
  314. }
  315. if (AdapterObject->EisaAdapter) {
  316. AdapterObject->MapRegisterBase = (PVOID)
  317. ((ULONG) AdapterObject->MapRegisterBase | EISA_ADAPTER);
  318. }
  319. }
  320. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  321. } else {
  322. AdapterObject->MapRegisterBase = NULL;
  323. AdapterObject->NumberOfMapRegisters = 0;
  324. }
  325. //
  326. // If there were either enough map registers available or no map
  327. // registers needed to be allocated, invoke the driver's execution
  328. // routine now.
  329. //
  330. if (!Busy) {
  331. AdapterObject->CurrentWcb = Wcb;
  332. Action = ExecutionRoutine( Wcb->DeviceObject,
  333. Wcb->CurrentIrp,
  334. AdapterObject->MapRegisterBase,
  335. Wcb->DeviceContext );
  336. //
  337. // If the driver would like to have the adapter deallocated,
  338. // then release the adapter object.
  339. //
  340. if (Action == DeallocateObject) {
  341. IoFreeAdapterChannel( AdapterObject );
  342. } else if (Action == DeallocateObjectKeepRegisters) {
  343. //
  344. // Set the NumberOfMapRegisters = 0 in the adapter object.
  345. // This will keep IoFreeAdapterChannel from freeing the
  346. // registers. After this it is the driver's responsiblity to
  347. // keep track of the number of map registers.
  348. //
  349. AdapterObject->NumberOfMapRegisters = 0;
  350. IoFreeAdapterChannel(AdapterObject);
  351. }
  352. }
  353. }
  354. return(STATUS_SUCCESS);
  355. }
  356. PVOID
  357. HalAllocateCrashDumpRegisters(
  358. IN PADAPTER_OBJECT AdapterObject,
  359. IN PULONG NumberOfMapRegisters
  360. )
  361. /*++
  362. Routine Description:
  363. This routine is called during the crash dump disk driver's initialization
  364. to allocate a number map registers permanently.
  365. Arguments:
  366. AdapterObject - Pointer to the adapter control object to allocate to the
  367. driver.
  368. NumerOfMapRegisters - Number of map registers required. Updated to show
  369. actual number of registers allocated.
  370. Return Value:
  371. Returns STATUS_SUCESS if map registers allocated.
  372. --*/
  373. {
  374. PADAPTER_OBJECT MasterAdapter;
  375. ULONG MapRegisterNumber;
  376. //
  377. // Begin by obtaining a pointer to the master adapter associated with this
  378. // request.
  379. //
  380. MasterAdapter = AdapterObject->MasterAdapter;
  381. if ( MasterAdapter == NULL ) {
  382. if ( MasterAdapterObject == NULL ) {
  383. AdapterObject->NumberOfMapRegisters = 0;
  384. return NULL;
  385. } else {
  386. MasterAdapter = MasterAdapterObject;
  387. AdapterObject->MapRegistersPerChannel = 16;
  388. }
  389. }
  390. //
  391. // Check to see whether this driver needs to allocate any map registers.
  392. //
  393. //
  394. // Ensure that this adapter has enough total map registers to satisfy
  395. // the request.
  396. //
  397. if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) {
  398. AdapterObject->NumberOfMapRegisters = 0;
  399. return NULL;
  400. }
  401. //
  402. // Attempt to allocate the required number of map registers w/o
  403. // affecting those registers that were allocated when the system
  404. // crashed.
  405. //
  406. MapRegisterNumber = (ULONG)-1;
  407. MapRegisterNumber = RtlFindClearBitsAndSet(
  408. MasterAdapter->MapRegisters,
  409. *NumberOfMapRegisters,
  410. 0
  411. );
  412. if (MapRegisterNumber == (ULONG)-1) {
  413. //
  414. // Not enough free map registers were found, so they were busy
  415. // being used by the system when it crashed. Force the appropriate
  416. // number to be "allocated" at the base by simply overjamming the
  417. // bits and return the base map register as the start.
  418. //
  419. RtlSetBits(
  420. MasterAdapter->MapRegisters,
  421. 0,
  422. *NumberOfMapRegisters
  423. );
  424. MapRegisterNumber = 0;
  425. }
  426. //
  427. // Calculate the map register base from the allocated map
  428. // register and base of the master adapter object.
  429. //
  430. AdapterObject->MapRegisterBase = (PVOID)((PTRANSLATION_ENTRY)
  431. MasterAdapter->MapRegisterBase + MapRegisterNumber);
  432. //
  433. // Set the no scatter/gather flag if scatter/gather not
  434. // supported.
  435. //
  436. if (!AdapterObject->ScatterGather) {
  437. AdapterObject->MapRegisterBase = (PVOID)
  438. ((ULONG) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);
  439. }
  440. if (AdapterObject->EisaAdapter) {
  441. AdapterObject->MapRegisterBase = (PVOID)
  442. ((ULONG) AdapterObject->MapRegisterBase | EISA_ADAPTER);
  443. }
  444. return AdapterObject->MapRegisterBase;
  445. }
  446. PVOID
  447. HalAllocateCommonBuffer(
  448. IN PADAPTER_OBJECT AdapterObject,
  449. IN ULONG Length,
  450. OUT PPHYSICAL_ADDRESS LogicalAddress,
  451. IN BOOLEAN CacheEnabled
  452. )
  453. /*++
  454. Routine Description:
  455. This function allocates the memory for a common buffer and maps so that it
  456. can be accessed by a master device and the CPU.
  457. Arguments:
  458. AdapterObject - Supplies a pointer to the adapter object used by this
  459. device.
  460. Length - Supplies the length of the common buffer to be allocated.
  461. LogicalAddress - Returns the logical address of the common buffer.
  462. CacheEnable - Indicates whether the memory is cached or not.
  463. Return Value:
  464. Returns the virtual address of the common buffer. If the buffer cannot be
  465. allocated then NULL is returned.
  466. --*/
  467. {
  468. PVOID virtualAddress;
  469. PHYSICAL_ADDRESS physicalAddress;
  470. UNREFERENCED_PARAMETER(AdapterObject);
  471. UNREFERENCED_PARAMETER(CacheEnabled);
  472. //
  473. // Assume below 16M to support ISA devices
  474. //
  475. physicalAddress.LowPart = MAXIMUM_ISA_PHYSICAL_ADDRESS-1;
  476. physicalAddress.HighPart = 0;
  477. //
  478. // If the caller supports 32bit addresses, and it's a master, let
  479. // it have any memory below 1G
  480. //
  481. if (AdapterObject->Dma32BitAddresses && AdapterObject->MasterDevice) {
  482. physicalAddress.LowPart = 0xFFFFFFFF;
  483. }
  484. //
  485. // Allocate the actual buffer.
  486. //
  487. virtualAddress = MmAllocateContiguousMemory(
  488. Length,
  489. physicalAddress
  490. );
  491. if (!HALP_IS_PHYSICAL_ADDRESS(virtualAddress)) {
  492. *LogicalAddress = MmGetPhysicalAddress(virtualAddress);
  493. } else {
  494. LogicalAddress->QuadPart = (ULONG)virtualAddress & (~KSEG0_BASE);
  495. }
  496. return(virtualAddress);
  497. }
  498. BOOLEAN
  499. HalFlushCommonBuffer(
  500. IN PADAPTER_OBJECT AdapterObject,
  501. IN ULONG Length,
  502. IN PHYSICAL_ADDRESS LogicalAddress,
  503. IN PVOID VirtualAddress
  504. )
  505. /*++
  506. Routine Description:
  507. This function is called to flush any hardware adapter buffers when the
  508. driver needs to read data written by an I/O master device to a common
  509. buffer.
  510. Arguments:
  511. AdapterObject - Supplies a pointer to the adapter object used by this
  512. device.
  513. Length - Supplies the length of the common buffer. This should be the same
  514. value used for the allocation of the buffer.
  515. LogicalAddress - Supplies the logical address of the common buffer. This
  516. must be the same value return by HalAllocateCommonBuffer.
  517. VirtualAddress - Supplies the virtual address of the common buffer. This
  518. must be the same value return by HalAllocateCommonBuffer.
  519. Return Value:
  520. Returns TRUE if no errors were detected; otherwise, FALSE is return.
  521. --*/
  522. {
  523. UNREFERENCED_PARAMETER(AdapterObject);
  524. UNREFERENCED_PARAMETER(Length);
  525. UNREFERENCED_PARAMETER(LogicalAddress);
  526. UNREFERENCED_PARAMETER(VirtualAddress);
  527. return(TRUE);
  528. }
  529. VOID
  530. HalFreeCommonBuffer(
  531. IN PADAPTER_OBJECT AdapterObject,
  532. IN ULONG Length,
  533. IN PHYSICAL_ADDRESS LogicalAddress,
  534. IN PVOID VirtualAddress,
  535. IN BOOLEAN CacheEnabled
  536. )
  537. /*++
  538. Routine Description:
  539. This function frees a common buffer and all of the resouces it uses.
  540. Arguments:
  541. AdapterObject - Supplies a pointer to the adapter object used by this
  542. device.
  543. Length - Supplies the length of the common buffer. This should be the same
  544. value used for the allocation of the buffer.
  545. LogicalAddress - Supplies the logical address of the common buffer. This
  546. must be the same value return by HalAllocateCommonBuffer.
  547. VirtualAddress - Supplies the virtual address of the common buffer. This
  548. must be the same value return by HalAllocateCommonBuffer.
  549. CacheEnable - Indicates whether the memeory is cached or not.
  550. Return Value:
  551. None
  552. --*/
  553. {
  554. UNREFERENCED_PARAMETER(AdapterObject);
  555. UNREFERENCED_PARAMETER(Length);
  556. UNREFERENCED_PARAMETER(LogicalAddress);
  557. UNREFERENCED_PARAMETER(CacheEnabled);
  558. MmFreeContiguousMemory(VirtualAddress);
  559. }
  560. PADAPTER_OBJECT
  561. HalGetAdapter(
  562. IN PDEVICE_DESCRIPTION DeviceDescriptor,
  563. OUT PULONG NumberOfMapRegisters
  564. )
  565. /*++
  566. Routine Description:
  567. This function returns the appropriate adapter object for the device defined
  568. in the device description structure. This code works for Isa and Eisa
  569. systems.
  570. Arguments:
  571. DeviceDescriptor - Supplies a description of the deivce.
  572. NumberOfMapRegisters - Returns the maximum number of map registers which
  573. may be allocated by the device driver.
  574. Return Value:
  575. A pointer to the requested adapter object or NULL if an adapter could not
  576. be created.
  577. --*/
  578. {
  579. PADAPTER_OBJECT adapterObject;
  580. PVOID adapterBaseVa;
  581. ULONG channelNumber;
  582. ULONG controllerNumber;
  583. DMA_EXTENDED_MODE extendedMode;
  584. UCHAR adapterMode;
  585. ULONG numberOfMapRegisters;
  586. BOOLEAN useChannel;
  587. ULONG maximumLength;
  588. UCHAR DataByte;
  589. //
  590. // Determine if the the channel number is important. Master cards on
  591. // Eisa and Mca do not use a channel number.
  592. //
  593. if (DeviceDescriptor->InterfaceType != Isa &&
  594. DeviceDescriptor->Master) {
  595. useChannel = FALSE;
  596. } else {
  597. useChannel = TRUE;
  598. }
  599. //
  600. // Support for ISA local bus machines:
  601. // If the driver is a Master but really does not want a channel since it
  602. // is using the local bus DMA, just don't use an ISA channel.
  603. //
  604. if (DeviceDescriptor->InterfaceType == Isa &&
  605. DeviceDescriptor->DmaChannel > 7) {
  606. useChannel = FALSE;
  607. }
  608. //
  609. // Determine if Eisa DMA is supported.
  610. //
  611. if (HalpBusType == MACHINE_TYPE_EISA) {
  612. HalpEisaDma = FALSE;
  613. WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort.Channel2, 0x55);
  614. DataByte = READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort.Channel2);
  615. if (DataByte == 0x55) {
  616. HalpEisaDma = TRUE;
  617. }
  618. }
  619. //
  620. // Limit the maximum length to 2 GB this is done so that the BYTES_TO_PAGES
  621. // macro works correctly.
  622. //
  623. maximumLength = DeviceDescriptor->MaximumLength & 0x7fffffff;
  624. //
  625. // Channel 4 cannot be used since it is used for chaining. Return null if
  626. // it is requested.
  627. //
  628. if (DeviceDescriptor->DmaChannel == 4 && useChannel) {
  629. return(NULL);
  630. }
  631. //
  632. // Determine the number of map registers for this device.
  633. //
  634. if (DeviceDescriptor->ScatterGather && (LessThan16Mb ||
  635. DeviceDescriptor->InterfaceType == Eisa)) {
  636. //
  637. // Since the device support scatter/Gather then map registers are not
  638. // required.
  639. //
  640. numberOfMapRegisters = 0;
  641. } else {
  642. //
  643. // Determine the number of map registers required based on the maximum
  644. // transfer length, up to a maximum number.
  645. //
  646. numberOfMapRegisters = BYTES_TO_PAGES(maximumLength)
  647. + 1;
  648. numberOfMapRegisters = numberOfMapRegisters > MAXIMUM_ISA_MAP_REGISTER ?
  649. MAXIMUM_ISA_MAP_REGISTER : numberOfMapRegisters;
  650. //
  651. // Make sure there where enough registers allocated initalize to support
  652. // this size relaibly. This implies there must be to chunks equal to
  653. // the allocatd size. This is only a problem on Isa systems where the
  654. // map buffers cannot cross 64KB boundtires.
  655. //
  656. if (!HalpEisaDma &&
  657. numberOfMapRegisters > HalpMapBufferSize / (PAGE_SIZE * 2)) {
  658. numberOfMapRegisters = (HalpMapBufferSize / (PAGE_SIZE * 2));
  659. }
  660. //
  661. // If the device is not a master and does scatter/gather then
  662. // it only needs one map register.
  663. //
  664. if (DeviceDescriptor->ScatterGather && !DeviceDescriptor->Master) {
  665. numberOfMapRegisters = 1;
  666. }
  667. }
  668. //
  669. // Set the channel number.
  670. //
  671. channelNumber = DeviceDescriptor->DmaChannel & 0x03;
  672. //
  673. // Set the adapter base address to the Base address register and controller
  674. // number.
  675. //
  676. if (!(DeviceDescriptor->DmaChannel & 0x04)) {
  677. controllerNumber = 1;
  678. adapterBaseVa = (PVOID) &((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort;
  679. } else {
  680. controllerNumber = 2;
  681. adapterBaseVa = &((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort;
  682. }
  683. //
  684. // Determine if a new adapter object is necessary. If so then allocate it.
  685. //
  686. if (useChannel && HalpEisaAdapter[DeviceDescriptor->DmaChannel] != NULL) {
  687. adapterObject = HalpEisaAdapter[DeviceDescriptor->DmaChannel];
  688. if (adapterObject->NeedsMapRegisters) {
  689. if (numberOfMapRegisters > adapterObject->MapRegistersPerChannel) {
  690. adapterObject->MapRegistersPerChannel = numberOfMapRegisters;
  691. }
  692. }
  693. } else {
  694. //
  695. // Allocate an adapter object.
  696. //
  697. adapterObject = (PADAPTER_OBJECT) HalpAllocateAdapter(
  698. numberOfMapRegisters,
  699. adapterBaseVa,
  700. NULL
  701. );
  702. if (adapterObject == NULL) {
  703. return(NULL);
  704. }
  705. if (useChannel) {
  706. HalpEisaAdapter[DeviceDescriptor->DmaChannel] = adapterObject;
  707. }
  708. //
  709. // Set the maximum number of map registers for this channel bus to
  710. // the number requested and the type of device.
  711. //
  712. if (numberOfMapRegisters) {
  713. //
  714. // The speicified number of registers are actually allowed to be
  715. // allocated.
  716. //
  717. adapterObject->MapRegistersPerChannel = numberOfMapRegisters;
  718. //
  719. // Increase the commitment for the map registers.
  720. //
  721. if (DeviceDescriptor->Master) {
  722. //
  723. // Master I/O devices use several sets of map registers double
  724. // their commitment.
  725. //
  726. MasterAdapterObject->CommittedMapRegisters +=
  727. numberOfMapRegisters * 2;
  728. } else {
  729. MasterAdapterObject->CommittedMapRegisters +=
  730. numberOfMapRegisters;
  731. }
  732. //
  733. // If the committed map registers is signicantly greater than the
  734. // number allocated then grow the map buffer.
  735. //
  736. if (MasterAdapterObject->CommittedMapRegisters >
  737. MasterAdapterObject->NumberOfMapRegisters &&
  738. MasterAdapterObject->CommittedMapRegisters -
  739. MasterAdapterObject->NumberOfMapRegisters >
  740. MAXIMUM_ISA_MAP_REGISTER ) {
  741. HalpGrowMapBuffers(
  742. MasterAdapterObject,
  743. INCREMENT_MAP_BUFFER_SIZE
  744. );
  745. }
  746. adapterObject->NeedsMapRegisters = TRUE;
  747. } else {
  748. //
  749. // No real map registers were allocated. If this is a master
  750. // device, then the device can have as may registers as it wants.
  751. //
  752. adapterObject->NeedsMapRegisters = FALSE;
  753. if (DeviceDescriptor->Master) {
  754. adapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(
  755. maximumLength
  756. )
  757. + 1;
  758. } else {
  759. //
  760. // The device only gets one register. It must call
  761. // IoMapTransfer repeatedly to do a large transfer.
  762. //
  763. adapterObject->MapRegistersPerChannel = 1;
  764. }
  765. }
  766. }
  767. adapterObject->Dma32BitAddresses = DeviceDescriptor->Dma32BitAddresses;
  768. adapterObject->ScatterGather = DeviceDescriptor->ScatterGather;
  769. *NumberOfMapRegisters = adapterObject->MapRegistersPerChannel;
  770. if (DeviceDescriptor->Master) {
  771. adapterObject->MasterDevice = TRUE;
  772. } else {
  773. adapterObject->MasterDevice = FALSE;
  774. }
  775. //
  776. // Indicate whether the device is an Eisa adapter.
  777. //
  778. if ( DeviceDescriptor->InterfaceType == Eisa ) {
  779. adapterObject->EisaAdapter = TRUE;
  780. } else {
  781. adapterObject->EisaAdapter = FALSE;
  782. }
  783. //
  784. // If the channel number is not used then we are finished. The rest of
  785. // the work deals with channels.
  786. //
  787. if (!useChannel) {
  788. return(adapterObject);
  789. }
  790. //
  791. // Setup the pointers to all the random registers.
  792. //
  793. adapterObject->ChannelNumber = (UCHAR) channelNumber;
  794. if (controllerNumber == 1) {
  795. switch ((UCHAR)channelNumber) {
  796. case 0:
  797. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel0;
  798. break;
  799. case 1:
  800. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel1;
  801. break;
  802. case 2:
  803. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel2;
  804. break;
  805. case 3:
  806. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel3;
  807. break;
  808. }
  809. //
  810. // Set the adapter number.
  811. //
  812. adapterObject->AdapterNumber = 1;
  813. //
  814. // Save the extended mode register address.
  815. //
  816. adapterBaseVa =
  817. &((PEISA_CONTROL) HalpEisaControlBase)->Dma1ExtendedModePort;
  818. } else {
  819. switch (channelNumber) {
  820. case 1:
  821. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel5;
  822. break;
  823. case 2:
  824. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel6;
  825. break;
  826. case 3:
  827. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel7;
  828. break;
  829. }
  830. //
  831. // Set the adapter number.
  832. //
  833. adapterObject->AdapterNumber = 2;
  834. //
  835. // Save the extended mode register address.
  836. //
  837. adapterBaseVa =
  838. &((PEISA_CONTROL) HalpEisaControlBase)->Dma2ExtendedModePort;
  839. }
  840. adapterObject->Width16Bits = FALSE;
  841. if (HalpEisaDma) {
  842. //
  843. // Initialzie the extended mode port.
  844. //
  845. *((PUCHAR) &extendedMode) = 0;
  846. extendedMode.ChannelNumber = channelNumber;
  847. switch (DeviceDescriptor->DmaSpeed) {
  848. case Compatible:
  849. extendedMode.TimingMode = COMPATIBLITY_TIMING;
  850. break;
  851. case TypeA:
  852. extendedMode.TimingMode = TYPE_A_TIMING;
  853. break;
  854. case TypeB:
  855. extendedMode.TimingMode = TYPE_B_TIMING;
  856. break;
  857. case TypeC:
  858. extendedMode.TimingMode = BURST_TIMING;
  859. break;
  860. default:
  861. ObDereferenceObject( adapterObject );
  862. return(NULL);
  863. }
  864. switch (DeviceDescriptor->DmaWidth) {
  865. case Width8Bits:
  866. extendedMode.TransferSize = BY_BYTE_8_BITS;
  867. break;
  868. case Width16Bits:
  869. extendedMode.TransferSize = BY_BYTE_16_BITS;
  870. //
  871. // Note Width16bits should not be set here because there is no need
  872. // to shift the address and the transfer count.
  873. //
  874. break;
  875. case Width32Bits:
  876. extendedMode.TransferSize = BY_BYTE_32_BITS;
  877. break;
  878. default:
  879. ObDereferenceObject( adapterObject );
  880. return(NULL);
  881. }
  882. WRITE_PORT_UCHAR( adapterBaseVa, *((PUCHAR) &extendedMode));
  883. } else if (!DeviceDescriptor->Master) {
  884. switch (DeviceDescriptor->DmaWidth) {
  885. case Width8Bits:
  886. //
  887. // The channel must use controller 1.
  888. //
  889. if (controllerNumber != 1) {
  890. ObDereferenceObject( adapterObject );
  891. return(NULL);
  892. }
  893. break;
  894. case Width16Bits:
  895. //
  896. // The channel must use controller 2.
  897. //
  898. if (controllerNumber != 2) {
  899. ObDereferenceObject( adapterObject );
  900. return(NULL);
  901. }
  902. adapterObject->Width16Bits = TRUE;
  903. break;
  904. default:
  905. ObDereferenceObject( adapterObject );
  906. return(NULL);
  907. }
  908. }
  909. //
  910. // Initialize the adapter mode register value to the correct parameters,
  911. // and save them in the adapter object.
  912. //
  913. adapterMode = 0;
  914. ((PDMA_EISA_MODE) &adapterMode)->Channel = adapterObject->ChannelNumber;
  915. if (DeviceDescriptor->Master) {
  916. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = CASCADE_REQUEST_MODE;
  917. //
  918. // Set the mode, and enable the request.
  919. //
  920. if (adapterObject->AdapterNumber == 1) {
  921. //
  922. // This request is for DMA controller 1
  923. //
  924. PDMA1_CONTROL dmaControl;
  925. dmaControl = adapterObject->AdapterBaseVa;
  926. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  927. //
  928. // Unmask the DMA channel.
  929. //
  930. WRITE_PORT_UCHAR(
  931. &dmaControl->SingleMask,
  932. (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
  933. );
  934. } else {
  935. //
  936. // This request is for DMA controller 1
  937. //
  938. PDMA2_CONTROL dmaControl;
  939. dmaControl = adapterObject->AdapterBaseVa;
  940. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  941. //
  942. // Unmask the DMA channel.
  943. //
  944. WRITE_PORT_UCHAR(
  945. &dmaControl->SingleMask,
  946. (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
  947. );
  948. }
  949. } else if (DeviceDescriptor->DemandMode) {
  950. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = DEMAND_REQUEST_MODE;
  951. } else {
  952. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = SINGLE_REQUEST_MODE;
  953. }
  954. if (DeviceDescriptor->AutoInitialize) {
  955. ((PDMA_EISA_MODE) &adapterMode)->AutoInitialize = 1;
  956. }
  957. adapterObject->AdapterMode = adapterMode;
  958. return(adapterObject);
  959. }
  960. BOOLEAN
  961. HalpTranslateSystemBusAddress(
  962. IN PBUS_HANDLER BusHandler,
  963. IN PBUS_HANDLER RootHandler,
  964. IN PHYSICAL_ADDRESS BusAddress,
  965. IN OUT PULONG AddressSpace,
  966. OUT PPHYSICAL_ADDRESS TranslatedAddress
  967. )
  968. /*++
  969. Routine Description:
  970. This function returns the system physical address for a specified I/O bus
  971. address. The return value is suitable for use in a subsequent call to
  972. MmMapIoSpace.
  973. Arguments:
  974. BusHandler - Registered BUSHANDLER for the target configuration space
  975. Supplies the bus handler (bus no, interface type).
  976. RootHandler - Registered BUSHANDLER for the orginating
  977. HalTranslateBusAddress request.
  978. BusAddress - Supplies the bus relative address.
  979. AddressSpace - Supplies the address space number for the device: 0 for
  980. memory and 1 for I/O space. If the desired access mode is user mode,
  981. then bit 1 must be TRUE.
  982. TranslatedAddress - Supplies a pointer to return the translated address
  983. Notes:
  984. This is a variation of what began in the MIPS code. The intel code often
  985. assumes that if an address is in I/O space, the bottom 32 bits of the
  986. physical address can be used "like" a virtual address, and are returned
  987. to the user. This doesn't work on MIPs machines where physical
  988. addresses can be larger than 32 bits.
  989. Since we are using superpage addresses for I/O on Alpha, we can do
  990. almost what is done on intel. If AddressSpace is equal to 0 or 1, then
  991. we assume the user is doing kernel I/O and we call
  992. HalCreateQva to build a Quasi Virtual Address and return
  993. that to the caller. We then set AddressSpace to a 1, so that the caller
  994. will not call MmMapIoSpace. The Caller will use the low 32 bits of the
  995. physical address we return as the VA. (Which we built a QVA in).
  996. If the caller wants to access EISA I/O or Memory through user mode, then
  997. the caller must set bit 1 in AddressSpace to a 1 (AddressSpace=2 or 3,
  998. depending on whether EISA I/O or Memory), then the caller is returned the
  999. 34 bit Physical address. The caller will then call MmMapIoSpace, or
  1000. ZwMapViewOfSection which in turn calls HalCreateQva to build a QVA out
  1001. of a VA mapped through the page tables.
  1002. **** Note ****
  1003. The QVA in user mode can only be accessed with the routines WRITE/READ_
  1004. REGISTER_UCHAR/USHORT/ULONG, and they must be the ones in module
  1005. JXIOUSER.C. The user CANNOT call the above routines in the HAL from
  1006. usermode. (Which is pointless, since the HAL is superpage access
  1007. only).
  1008. Return Value:
  1009. A return value of TRUE indicates that a system physical address
  1010. corresponding to the supplied bus relative address and bus address
  1011. number has been returned in TranslatedAddress.
  1012. A return value of FALSE occurs if the translation for the address was
  1013. not possible
  1014. --*/
  1015. {
  1016. INTERFACE_TYPE InterfaceType = BusHandler->InterfaceType;
  1017. ULONG BusNumber = BusHandler->BusNumber;
  1018. PVOID va = 0; // note, this is used for a placeholder
  1019. HaeIndex = 0;
  1020. //
  1021. // If this is for the internal bus then the device is on the combo chip.
  1022. // BusAddress.LowPart should contains the port of the device.
  1023. //
  1024. if (InterfaceType == Internal) {
  1025. //
  1026. // Return the passed parameters.
  1027. //
  1028. TranslatedAddress->HighPart = 1;
  1029. TranslatedAddress->LowPart = 0xC0000000 + (BusAddress.LowPart << COMBO_BIT_SHIFT);
  1030. //
  1031. // Now call HalCreateQva. This will create a QVA
  1032. // that we'll return to the caller. Then we will implicitly set
  1033. // AddressSpace to a 1. The caller then will not call MmMapIoSpace
  1034. // and will use the address we return as a VA.
  1035. TranslatedAddress->LowPart = (ULONG) HalCreateQva(
  1036. *TranslatedAddress, va);
  1037. TranslatedAddress->HighPart = 0; // clear high longword for QVA
  1038. *AddressSpace = 1; // Make sure user doesn't call
  1039. // MmMapIoSpace.
  1040. return(TRUE);
  1041. }
  1042. if (InterfaceType != Isa && InterfaceType != Eisa) {
  1043. //
  1044. // Not on this system return nothing.
  1045. //
  1046. *AddressSpace = 0;
  1047. TranslatedAddress->LowPart = 0;
  1048. return(FALSE);
  1049. }
  1050. //
  1051. // Jensen only has one I/O bus which is an EISA, so the bus number is unused.
  1052. //
  1053. // Determine the address based on whether the bus address is in I/O space
  1054. // or bus memory space.
  1055. //
  1056. switch (*AddressSpace) {
  1057. case 0 : {
  1058. //
  1059. // The address is in EISA memory space, kernel mode.
  1060. //
  1061. //
  1062. // If the address cannot be mapped into the predefined low 32MB
  1063. // 'default' region, then find a free or matching region in the HAE
  1064. // Table. NB: slot zero is predefined to the lowest 32MB and cannot
  1065. // be overwritten.
  1066. //
  1067. if ( BusAddress.LowPart >= HAL_32MB ) {
  1068. ULONG HaeValue;
  1069. HaeValue = (BusAddress.LowPart >> 25);
  1070. for ( HaeIndex = 1; HaeIndex < 4; HaeIndex++ ) {
  1071. if ( HalpHaeTable[HaeIndex] == 0 ||
  1072. HalpHaeTable[HaeIndex] == HaeValue ) {
  1073. break;
  1074. }
  1075. }
  1076. // Check if no HAE slots were available, if so return error.
  1077. if ( HaeIndex == 4 ) {
  1078. *AddressSpace = 0;
  1079. TranslatedAddress->LowPart = 0;
  1080. return(FALSE);
  1081. } else {
  1082. HalpHaeTable[HaeIndex] = HaeValue;
  1083. }
  1084. }
  1085. TranslatedAddress->HighPart = 0x2;
  1086. //
  1087. // There is no component of the bus address in the low part
  1088. //
  1089. TranslatedAddress->LowPart = (BusAddress.LowPart << EISA_BIT_SHIFT);
  1090. //
  1091. // Now call HalCreateQva. This will create a QVA
  1092. // that we'll return to the caller. Then we will implicitly set
  1093. // AddressSpace to a 1. The caller then will not call MmMapIoSpace
  1094. // and will use the address we return as a VA.
  1095. TranslatedAddress->LowPart = (ULONG) HalCreateQva(
  1096. *TranslatedAddress, va);
  1097. TranslatedAddress->HighPart = 0; // clear high longword for QVA
  1098. *AddressSpace = 1; // don't let the user call MmMapIoSpace
  1099. return(TRUE);
  1100. }
  1101. case 1 : {
  1102. //
  1103. // The address is in EISA I/O space, kernel mode.
  1104. //
  1105. TranslatedAddress->HighPart = 0x3;
  1106. //
  1107. // There is no component of the bus address in the low part
  1108. //
  1109. TranslatedAddress->LowPart = (BusAddress.LowPart << EISA_BIT_SHIFT);
  1110. //
  1111. // Now call HalCreateQva. This will create a QVA
  1112. // that we'll return to the caller. Then we will implicitly set
  1113. // AddressSpace to a 1. The caller then will not call MmMapIoSpace
  1114. // and will use the address we return as a VA.
  1115. TranslatedAddress->LowPart = (ULONG) HalCreateQva(
  1116. *TranslatedAddress, va);
  1117. TranslatedAddress->HighPart = 0; // clear high longword for QVA
  1118. *AddressSpace = 1; // Make sure user doesn't call
  1119. // MmMapIoSpace.
  1120. return(TRUE);
  1121. }
  1122. case 2 : {
  1123. //
  1124. // The address is in EISA memory space, user mode.
  1125. //
  1126. TranslatedAddress->HighPart = 0x2;
  1127. //
  1128. // There is no component of the bus address in the low part
  1129. //
  1130. TranslatedAddress->LowPart = (BusAddress.LowPart << EISA_BIT_SHIFT);
  1131. *AddressSpace = 0; // Let the user call MmMapIoSpace
  1132. return(TRUE);
  1133. }
  1134. case 3 : {
  1135. //
  1136. // The address is in EISA I/O space, user mode.
  1137. //
  1138. TranslatedAddress->HighPart = 0x3;
  1139. //
  1140. // There is no component of the bus address in the low part
  1141. //
  1142. TranslatedAddress->LowPart = (BusAddress.LowPart << EISA_BIT_SHIFT);
  1143. *AddressSpace = 0; // Make sure user can call
  1144. // MmMapIoSpace.
  1145. return(TRUE);
  1146. }
  1147. }
  1148. }
  1149. PVOID
  1150. HalCreateQva(
  1151. IN PHYSICAL_ADDRESS PA,
  1152. IN PVOID VA
  1153. )
  1154. /*++
  1155. Routine Description:
  1156. This function is called two ways. First, from HalTranslateBusAddress,
  1157. if the caller is going to run in kernel mode and use superpages.
  1158. The second way is if the user is going to access in user mode.
  1159. MmMapIoSpace or ZwViewMapOfSection will call this.
  1160. If the input parameter VA is zero, then we assume super page and build
  1161. a QUASI virtual address that is only usable by calling the hal I/O
  1162. access routines.
  1163. if the input parameter VA is non-zero, we assume the user has either
  1164. called MmMapIoSpace or ZwMapViewOfSection and will use the access
  1165. routines in JXIOUSER.C
  1166. If the PA is not an I/O space address (Combo chip, Eisa I/O, Eisa
  1167. memory), then return the VA as the QVA.
  1168. Arguments:
  1169. PA - the physical address generated by HalTranslateBusAddress
  1170. VA - the virtual address returned by MmMapIoSpace
  1171. Return Value:
  1172. The returned value is a quasi virtual address in that it can be
  1173. added to and subtracted from, but it cannot be used to access the
  1174. bus directly. The top bits are set so that we can trap invalid
  1175. accesses in the memory management subsystem. All access should be
  1176. done through the Hal Access Routines in *ioacc.s if it was a superpage
  1177. kernel mode access. If it is usermode, then JXIOUSER.C should be built
  1178. into the users code.
  1179. --*/
  1180. {
  1181. PVOID qva;
  1182. if (PA.HighPart == 2) {
  1183. //
  1184. // in EISA MEMORY space
  1185. //
  1186. if (VA == 0) {
  1187. //
  1188. // Remember, the PA.LowPart has already been shifted up 7 bits. We
  1189. // must first make room at bits <31:30> to insert the HaeIndex.
  1190. //
  1191. PA.LowPart = PA.LowPart >> 2;
  1192. PA.LowPart |= (HaeIndex << 30);
  1193. qva = (PVOID)(PA.QuadPart >> EISA_BIT_SHIFT-2);
  1194. } else {
  1195. qva = (PVOID)((ULONG)VA >> EISA_BIT_SHIFT);
  1196. }
  1197. qva = (PVOID)((ULONG)qva | EISA_QVA);
  1198. return(qva);
  1199. }
  1200. if (PA.HighPart == 3) {
  1201. //
  1202. // in EISA IO space
  1203. //
  1204. if (VA == 0) {
  1205. PA.LowPart = PA.LowPart >> 2;
  1206. qva = (PVOID)(PA.QuadPart >> EISA_BIT_SHIFT-2);
  1207. } else {
  1208. qva = (PVOID)((ULONG)VA >> EISA_BIT_SHIFT);
  1209. }
  1210. qva = (PVOID)((ULONG)qva | EISA_QVA);
  1211. return(qva);
  1212. }
  1213. if (PA.HighPart == 1) {
  1214. //
  1215. // on the combo chip (82C106)
  1216. //
  1217. if (VA == 0) {
  1218. qva = (PVOID)(PA.QuadPart >> COMBO_BIT_SHIFT);
  1219. } else {
  1220. qva = (PVOID)((ULONG)VA >> COMBO_BIT_SHIFT);
  1221. }
  1222. qva = (PVOID)((ULONG)qva | COMBO_QVA);
  1223. return(qva);
  1224. }
  1225. //
  1226. // It is not an I/O space address, return the VA as the QVA
  1227. //
  1228. return(VA);
  1229. }
  1230. PVOID
  1231. HalDereferenceQva(
  1232. PVOID Qva,
  1233. INTERFACE_TYPE InterfaceType,
  1234. ULONG BusNumber
  1235. )
  1236. /*++
  1237. Routine Description:
  1238. This function performs the inverse of the HalCreateQva for I/O addresses
  1239. that are memory-mapped (i.e. the quasi-virtual address was created from
  1240. a virtual address rather than a physical address).
  1241. Arguments:
  1242. Qva - Supplies the quasi-virtual address to be converted back to a
  1243. virtual address.
  1244. InterfaceType - Supplies the interface type of the bus to which the
  1245. Qva pertains.
  1246. BusNumber - Supplies the bus number of the bus to which the Qva pertains.
  1247. Return Value:
  1248. The Virtual Address from which the quasi-address was originally created
  1249. is returned.
  1250. --*/
  1251. {
  1252. //
  1253. // For Jensen we have only 2 buses:
  1254. //
  1255. // Internal(0)
  1256. // Eisa(0)
  1257. //
  1258. // We will allow Isa as an alias for Eisa. All other values not named
  1259. // above will be considered bogus. Bus Number must be zero.
  1260. //
  1261. if( BusNumber != 0 ){
  1262. return NULL;
  1263. }
  1264. switch (InterfaceType ){
  1265. case Internal:
  1266. return( (PVOID)( (ULONG)Qva << COMBO_BIT_SHIFT ) );
  1267. case Isa:
  1268. case Eisa:
  1269. return( (PVOID)( (ULONG)Qva << EISA_BIT_SHIFT ) );
  1270. default:
  1271. return NULL;
  1272. }
  1273. }
  1274. BOOLEAN
  1275. HalpGrowMapBuffers(
  1276. PADAPTER_OBJECT AdapterObject,
  1277. ULONG Amount
  1278. )
  1279. /*++
  1280. Routine Description:
  1281. This function attempts to allocate additional map buffers for use by I/O
  1282. devices. The map register table is updated to indicate the additional
  1283. buffers.
  1284. Arguments:
  1285. AdapterObject - Supplies the adapter object for which the buffers are to be
  1286. allocated.
  1287. Amount - Indicates the size of the map buffers which should be allocated.
  1288. Return Value:
  1289. TRUE is returned if the memory could be allocated.
  1290. FALSE is returned if the memory could not be allocated.
  1291. --*/
  1292. {
  1293. ULONG MapBufferPhysicalAddress;
  1294. PVOID MapBufferVirtualAddress;
  1295. PTRANSLATION_ENTRY TranslationEntry;
  1296. LONG NumberOfPages;
  1297. LONG i;
  1298. KIRQL Irql;
  1299. PHYSICAL_ADDRESS physicalAddress;
  1300. KeAcquireSpinLock( &AdapterObject->SpinLock, &Irql );
  1301. NumberOfPages = BYTES_TO_PAGES(Amount);
  1302. //
  1303. // Make sure there is room for the addition pages. The maximum number of
  1304. // slots needed is equal to NumberOfPages + Amount / 64K + 1.
  1305. //
  1306. i = BYTES_TO_PAGES(MAXIMUM_MAP_BUFFER_SIZE) - (NumberOfPages +
  1307. (NumberOfPages * PAGE_SIZE) / 0x10000 + 1 +
  1308. AdapterObject->NumberOfMapRegisters);
  1309. if (i < 0) {
  1310. //
  1311. // Reduce the allocatation amount to so it will fit.
  1312. //
  1313. NumberOfPages += i;
  1314. }
  1315. if (NumberOfPages <= 0) {
  1316. //
  1317. // No more memory can be allocated.
  1318. //
  1319. KeReleaseSpinLock( &AdapterObject->SpinLock, Irql );
  1320. return(FALSE);
  1321. }
  1322. if (AdapterObject->NumberOfMapRegisters == 0 && HalpMapBufferSize) {
  1323. NumberOfPages = BYTES_TO_PAGES(HalpMapBufferSize);
  1324. //
  1325. // Since this is the initial allocation, use the buffer allocated by
  1326. // HalInitSystem rather than allocating a new one.
  1327. //
  1328. MapBufferPhysicalAddress = HalpMapBufferPhysicalAddress.LowPart;
  1329. //
  1330. // Map the buffer for access thru KSEG0, since we don't want to
  1331. // use translation entries.
  1332. //
  1333. MapBufferVirtualAddress =
  1334. (PVOID)(HalpMapBufferPhysicalAddress.LowPart |
  1335. (ULONG)KSEG0_BASE);
  1336. } else {
  1337. //
  1338. // Allocate the map buffers.
  1339. //
  1340. physicalAddress.LowPart = MAXIMUM_ISA_PHYSICAL_ADDRESS - 1;
  1341. physicalAddress.HighPart = 0;
  1342. MapBufferVirtualAddress = MmAllocateContiguousMemory(
  1343. NumberOfPages * PAGE_SIZE,
  1344. physicalAddress
  1345. );
  1346. if (MapBufferVirtualAddress == NULL) {
  1347. KeReleaseSpinLock( &AdapterObject->SpinLock, Irql );
  1348. return(FALSE);
  1349. }
  1350. //
  1351. // Get the physical address of the map base.
  1352. //
  1353. if (!HALP_IS_PHYSICAL_ADDRESS(MapBufferVirtualAddress)) {
  1354. MapBufferPhysicalAddress = MmGetPhysicalAddress(
  1355. MapBufferVirtualAddress
  1356. ).LowPart;
  1357. } else {
  1358. MapBufferPhysicalAddress = (ULONG)MapBufferVirtualAddress &
  1359. (~KSEG0_BASE);
  1360. }
  1361. }
  1362. //
  1363. // Initailize the map registers where memory has been allocated.
  1364. //
  1365. TranslationEntry = ((PTRANSLATION_ENTRY) AdapterObject->MapRegisterBase) +
  1366. AdapterObject->NumberOfMapRegisters;
  1367. for (i = 0; (ULONG) i < NumberOfPages; i++) {
  1368. //
  1369. // Make sure the perivous entry is physically contiguous with the next
  1370. // entry and that a 64K physical bountry is not crossed unless this
  1371. // is an Eisa system.
  1372. //
  1373. if (TranslationEntry != AdapterObject->MapRegisterBase &&
  1374. (((TranslationEntry - 1)->PhysicalAddress + PAGE_SIZE) !=
  1375. MapBufferPhysicalAddress || (!HalpEisaDma &&
  1376. ((TranslationEntry - 1)->PhysicalAddress & ~0x0ffff) !=
  1377. (MapBufferPhysicalAddress & ~0x0ffff)))) {
  1378. //
  1379. // An entry needs to be skipped in the table. This entry will
  1380. // remain marked as allocated so that no allocation of map
  1381. // registers will cross this bountry.
  1382. //
  1383. TranslationEntry++;
  1384. AdapterObject->NumberOfMapRegisters++;
  1385. }
  1386. //
  1387. // Clear the bits where the memory has been allocated.
  1388. //
  1389. RtlClearBits(
  1390. AdapterObject->MapRegisters,
  1391. TranslationEntry - (PTRANSLATION_ENTRY)
  1392. AdapterObject->MapRegisterBase,
  1393. 1
  1394. );
  1395. TranslationEntry->VirtualAddress = MapBufferVirtualAddress;
  1396. TranslationEntry->PhysicalAddress = MapBufferPhysicalAddress;
  1397. TranslationEntry++;
  1398. (PCCHAR) MapBufferVirtualAddress += PAGE_SIZE;
  1399. MapBufferPhysicalAddress += PAGE_SIZE;
  1400. }
  1401. //
  1402. // Remember the number of pages that where allocated.
  1403. //
  1404. AdapterObject->NumberOfMapRegisters += NumberOfPages;
  1405. KeReleaseSpinLock( &AdapterObject->SpinLock, Irql );
  1406. return(TRUE);
  1407. }
  1408. PADAPTER_OBJECT
  1409. HalpAllocateAdapter(
  1410. IN ULONG MapRegistersPerChannel,
  1411. IN PVOID AdapterBaseVa,
  1412. IN PVOID ChannelNumber
  1413. )
  1414. /*++
  1415. Routine Description:
  1416. This routine allocates and initializes an adapter object to represent an
  1417. adapter or a DMA controller on the system. If no map registers are required
  1418. then a standalone adapter object is allocated with no master adapter.
  1419. If map registers are required, then a master adapter object is used to
  1420. allocate the map registers. For Isa systems these registers are really
  1421. phyically contiguous memory pages.
  1422. Arguments:
  1423. MapRegistersPerChannel - Specifies the number of map registers that each
  1424. channel provides for I/O memory mapping.
  1425. AdapterBaseVa - Address of the the DMA controller.
  1426. ChannelNumber - Unused.
  1427. Return Value:
  1428. The function value is a pointer to the allocate adapter object.
  1429. --*/
  1430. {
  1431. PADAPTER_OBJECT AdapterObject;
  1432. OBJECT_ATTRIBUTES ObjectAttributes;
  1433. ULONG Size;
  1434. ULONG BitmapSize;
  1435. HANDLE Handle;
  1436. NTSTATUS Status;
  1437. UNREFERENCED_PARAMETER(ChannelNumber);
  1438. //
  1439. // Initalize the master adapter if necessary.
  1440. //
  1441. if (MasterAdapterObject == NULL && AdapterBaseVa != (PVOID) -1 &&
  1442. MapRegistersPerChannel) {
  1443. MasterAdapterObject = HalpAllocateAdapter(
  1444. MapRegistersPerChannel,
  1445. (PVOID) -1,
  1446. NULL
  1447. );
  1448. //
  1449. // If we could not allocate the master adapter then give up.
  1450. //
  1451. if (MasterAdapterObject == NULL) {
  1452. return(NULL);
  1453. }
  1454. }
  1455. //
  1456. // Begin by initializing the object attributes structure to be used when
  1457. // creating the adapter object.
  1458. //
  1459. InitializeObjectAttributes( &ObjectAttributes,
  1460. NULL,
  1461. OBJ_PERMANENT,
  1462. (HANDLE) NULL,
  1463. (PSECURITY_DESCRIPTOR) NULL
  1464. );
  1465. //
  1466. // Determine the size of the adapter object. If this is the master object
  1467. // then allocate space for the register bit map; otherwise, just allocate
  1468. // an adapter object.
  1469. //
  1470. if (AdapterBaseVa == (PVOID) -1) {
  1471. //
  1472. // Allocate a bit map large enough MAXIMUM_MAP_BUFFER_SIZE / PAGE_SIZE
  1473. // of map register buffers.
  1474. //
  1475. BitmapSize = (((sizeof( RTL_BITMAP ) +
  1476. (( MAXIMUM_MAP_BUFFER_SIZE / PAGE_SIZE ) + 7 >> 3)) + 3) & ~3);
  1477. Size = sizeof( ADAPTER_OBJECT ) + BitmapSize;
  1478. } else {
  1479. Size = sizeof( ADAPTER_OBJECT );
  1480. }
  1481. //
  1482. // Now create the adapter object.
  1483. //
  1484. Status = ObCreateObject( KernelMode,
  1485. *IoAdapterObjectType,
  1486. &ObjectAttributes,
  1487. KernelMode,
  1488. (PVOID) NULL,
  1489. Size,
  1490. 0,
  1491. 0,
  1492. (PVOID *)&AdapterObject );
  1493. //
  1494. // Reference the object.
  1495. //
  1496. if (NT_SUCCESS(Status)) {
  1497. Status = ObReferenceObjectByPointer(
  1498. AdapterObject,
  1499. FILE_READ_DATA | FILE_WRITE_DATA,
  1500. *IoAdapterObjectType,
  1501. KernelMode
  1502. );
  1503. }
  1504. //
  1505. // If the adapter object was successfully created, then attempt to insert
  1506. // it into the the object table.
  1507. //
  1508. if (NT_SUCCESS( Status )) {
  1509. RtlZeroMemory (AdapterObject, sizeof (ADAPTER_OBJECT));
  1510. Status = ObInsertObject( AdapterObject,
  1511. NULL,
  1512. FILE_READ_DATA | FILE_WRITE_DATA,
  1513. 0,
  1514. (PVOID *) NULL,
  1515. &Handle );
  1516. if (NT_SUCCESS( Status )) {
  1517. ZwClose( Handle );
  1518. //
  1519. // Initialize the adapter object itself.
  1520. //
  1521. AdapterObject->Type = IO_TYPE_ADAPTER;
  1522. AdapterObject->Size = (USHORT) Size;
  1523. AdapterObject->MapRegistersPerChannel = 1;
  1524. AdapterObject->AdapterBaseVa = AdapterBaseVa;
  1525. if (MapRegistersPerChannel) {
  1526. AdapterObject->MasterAdapter = MasterAdapterObject;
  1527. } else {
  1528. AdapterObject->MasterAdapter = NULL;
  1529. }
  1530. //
  1531. // Initialize the channel wait queue for this
  1532. // adapter.
  1533. //
  1534. KeInitializeDeviceQueue( &AdapterObject->ChannelWaitQueue );
  1535. //
  1536. // If this is the MasterAdatper then initialize the register bit map,
  1537. // AdapterQueue and the spin lock.
  1538. //
  1539. if ( AdapterBaseVa == (PVOID) -1 ) {
  1540. KeInitializeSpinLock( &AdapterObject->SpinLock );
  1541. InitializeListHead( &AdapterObject->AdapterQueue );
  1542. AdapterObject->MapRegisters = (PVOID) ( AdapterObject + 1);
  1543. RtlInitializeBitMap( AdapterObject->MapRegisters,
  1544. (PULONG) (((PCHAR) (AdapterObject->MapRegisters)) + sizeof( RTL_BITMAP )),
  1545. ( MAXIMUM_MAP_BUFFER_SIZE / PAGE_SIZE )
  1546. );
  1547. //
  1548. // Set all the bits in the memory to indicate that memory
  1549. // has not been allocated for the map buffers
  1550. //
  1551. RtlSetAllBits( AdapterObject->MapRegisters );
  1552. AdapterObject->NumberOfMapRegisters = 0;
  1553. AdapterObject->CommittedMapRegisters = 0;
  1554. //
  1555. // ALlocate the memory map registers.
  1556. //
  1557. AdapterObject->MapRegisterBase = ExAllocatePool(
  1558. NonPagedPool,
  1559. (MAXIMUM_MAP_BUFFER_SIZE / PAGE_SIZE) *
  1560. sizeof(TRANSLATION_ENTRY)
  1561. );
  1562. if (AdapterObject->MapRegisterBase == NULL) {
  1563. ObDereferenceObject( AdapterObject );
  1564. AdapterObject = NULL;
  1565. return(NULL);
  1566. }
  1567. //
  1568. // Zero the map registers.
  1569. //
  1570. RtlZeroMemory(
  1571. AdapterObject->MapRegisterBase,
  1572. (MAXIMUM_MAP_BUFFER_SIZE / PAGE_SIZE) *
  1573. sizeof(TRANSLATION_ENTRY)
  1574. );
  1575. if (!HalpGrowMapBuffers(AdapterObject, INITIAL_MAP_BUFFER_SMALL_SIZE))
  1576. {
  1577. //
  1578. // If no map registers could be allocated then free the
  1579. // object.
  1580. //
  1581. ObDereferenceObject( AdapterObject );
  1582. AdapterObject = NULL;
  1583. return(NULL);
  1584. }
  1585. }
  1586. } else {
  1587. //
  1588. // An error was incurred for some reason. Set the return value
  1589. // to NULL.
  1590. //
  1591. AdapterObject = (PADAPTER_OBJECT) NULL;
  1592. }
  1593. } else {
  1594. AdapterObject = (PADAPTER_OBJECT) NULL;
  1595. }
  1596. return AdapterObject;
  1597. }
  1598. VOID
  1599. IoFreeAdapterChannel(
  1600. IN PADAPTER_OBJECT AdapterObject
  1601. )
  1602. /*++
  1603. Routine Description:
  1604. This routine is invoked to deallocate the specified adapter object.
  1605. Any map registers that were allocated are also automatically deallocated.
  1606. No checks are made to ensure that the adapter is really allocated to
  1607. a device object. However, if it is not, then kernel will bugcheck.
  1608. If another device is waiting in the queue to allocate the adapter object
  1609. it will be pulled from the queue and its execution routine will be
  1610. invoked.
  1611. Arguments:
  1612. AdapterObject - Pointer to the adapter object to be deallocated.
  1613. Return Value:
  1614. None.
  1615. --*/
  1616. {
  1617. PKDEVICE_QUEUE_ENTRY Packet;
  1618. PWAIT_CONTEXT_BLOCK Wcb;
  1619. PADAPTER_OBJECT MasterAdapter;
  1620. BOOLEAN Busy = FALSE;
  1621. IO_ALLOCATION_ACTION Action;
  1622. KIRQL Irql;
  1623. LONG MapRegisterNumber;
  1624. //
  1625. // Begin by getting the address of the master adapter.
  1626. //
  1627. MasterAdapter = AdapterObject->MasterAdapter;
  1628. //
  1629. // Pull requests of the adapter's device wait queue as long as the
  1630. // adapter is free and there are sufficient map registers available.
  1631. //
  1632. while( TRUE ) {
  1633. //
  1634. // Begin by checking to see whether there are any map registers that
  1635. // need to be deallocated. If so, then deallocate them now.
  1636. //
  1637. if (AdapterObject->NumberOfMapRegisters != 0) {
  1638. IoFreeMapRegisters( AdapterObject,
  1639. AdapterObject->MapRegisterBase,
  1640. AdapterObject->NumberOfMapRegisters
  1641. );
  1642. }
  1643. //
  1644. // Simply remove the next entry from the adapter's device wait queue.
  1645. // If one was successfully removed, allocate any map registers that it
  1646. // requires and invoke its execution routine.
  1647. //
  1648. Packet = KeRemoveDeviceQueue( &AdapterObject->ChannelWaitQueue );
  1649. if (Packet == NULL) {
  1650. //
  1651. // There are no more requests break out of the loop.
  1652. //
  1653. break;
  1654. }
  1655. Wcb = CONTAINING_RECORD( Packet,
  1656. WAIT_CONTEXT_BLOCK,
  1657. WaitQueueEntry );
  1658. AdapterObject->CurrentWcb = Wcb;
  1659. AdapterObject->NumberOfMapRegisters = Wcb->NumberOfMapRegisters;
  1660. //
  1661. // Check to see whether this driver wishes to allocate any map
  1662. // registers. If so, then queue the device object to the master
  1663. // adapter queue to wait for them to become available. If the driver
  1664. // wants map registers, ensure that this adapter has enough total
  1665. // map registers to satisfy the request.
  1666. //
  1667. if (Wcb->NumberOfMapRegisters != 0 &&
  1668. AdapterObject->MasterAdapter != NULL) {
  1669. //
  1670. // Lock the map register bit map and the adapter queue in the
  1671. // master adapter object. The channel structure offset is used as
  1672. // a hint for the register search.
  1673. //
  1674. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  1675. MapRegisterNumber = -1;
  1676. if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
  1677. MapRegisterNumber = RtlFindClearBitsAndSet( MasterAdapter->MapRegisters,
  1678. Wcb->NumberOfMapRegisters,
  1679. 0
  1680. );
  1681. }
  1682. if (MapRegisterNumber == -1) {
  1683. //
  1684. // There were not enough free map registers. Queue this request
  1685. // on the master adapter where is will wait until some registers
  1686. // are deallocated.
  1687. //
  1688. InsertTailList( &MasterAdapter->AdapterQueue,
  1689. &AdapterObject->AdapterQueue
  1690. );
  1691. Busy = TRUE;
  1692. } else {
  1693. AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY)
  1694. MasterAdapter->MapRegisterBase + MapRegisterNumber);
  1695. //
  1696. // Set the no scatter/gather flag if scatter/gather not
  1697. // supported.
  1698. //
  1699. if (!AdapterObject->ScatterGather) {
  1700. AdapterObject->MapRegisterBase = (PVOID)
  1701. ((ULONG) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);
  1702. }
  1703. if (AdapterObject->EisaAdapter) {
  1704. AdapterObject->MapRegisterBase = (PVOID)
  1705. ((ULONG) AdapterObject->MapRegisterBase | EISA_ADAPTER);
  1706. }
  1707. }
  1708. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1709. } else {
  1710. AdapterObject->MapRegisterBase = NULL;
  1711. AdapterObject->NumberOfMapRegisters = 0;
  1712. }
  1713. //
  1714. // If there were either enough map registers available or no map
  1715. // registers needed to be allocated, invoke the driver's execution
  1716. // routine now.
  1717. //
  1718. if (!Busy) {
  1719. AdapterObject->CurrentWcb = Wcb;
  1720. Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
  1721. Wcb->CurrentIrp,
  1722. AdapterObject->MapRegisterBase,
  1723. Wcb->DeviceContext );
  1724. //
  1725. // If the execution routine would like to have the adapter
  1726. // deallocated, then release the adapter object.
  1727. //
  1728. if (Action == KeepObject) {
  1729. //
  1730. // This request wants to keep the channel a while so break
  1731. // out of the loop.
  1732. //
  1733. break;
  1734. }
  1735. //
  1736. // If the driver wants to keep the map registers then set the
  1737. // number allocated to 0. This keeps the deallocation routine
  1738. // from deallocating them.
  1739. //
  1740. if (Action == DeallocateObjectKeepRegisters) {
  1741. AdapterObject->NumberOfMapRegisters = 0;
  1742. }
  1743. } else {
  1744. //
  1745. // This request did not get the requested number of map registers so
  1746. // out of the loop.
  1747. //
  1748. break;
  1749. }
  1750. }
  1751. }
  1752. VOID
  1753. IoFreeMapRegisters(
  1754. PADAPTER_OBJECT AdapterObject,
  1755. PVOID MapRegisterBase,
  1756. ULONG NumberOfMapRegisters
  1757. )
  1758. /*++
  1759. Routine Description:
  1760. This routine deallocates the map registers for the adapter. If there are
  1761. any queued adapter waiting for an attempt is made to allocate the next
  1762. entry.
  1763. Arguments:
  1764. AdapterObject - The adapter object to where the map register should be
  1765. returned.
  1766. MapRegisterBase - The map register base of the registers to be deallocated.
  1767. NumberOfMapRegisters - The number of registers to be deallocated.
  1768. Return Value:
  1769. None
  1770. --+*/
  1771. {
  1772. PADAPTER_OBJECT MasterAdapter;
  1773. LONG MapRegisterNumber;
  1774. PWAIT_CONTEXT_BLOCK Wcb;
  1775. PLIST_ENTRY Packet;
  1776. IO_ALLOCATION_ACTION Action;
  1777. KIRQL Irql;
  1778. //
  1779. // Begin by getting the address of the master adapter.
  1780. //
  1781. if (AdapterObject->MasterAdapter != NULL && MapRegisterBase != NULL) {
  1782. MasterAdapter = AdapterObject->MasterAdapter;
  1783. } else {
  1784. //
  1785. // There are no map registers to return.
  1786. //
  1787. return;
  1788. }
  1789. //
  1790. // Strip no scatter/gather flag.
  1791. //
  1792. MapRegisterBase = (PVOID) ((ULONG) MapRegisterBase &
  1793. ~(NO_SCATTER_GATHER | EISA_ADAPTER));
  1794. MapRegisterNumber = (PTRANSLATION_ENTRY) MapRegisterBase -
  1795. (PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase;
  1796. //
  1797. // Acquire the master adapter spinlock which locks the adapter queue and the
  1798. // bit map for the map registers.
  1799. //
  1800. KeAcquireSpinLock(&MasterAdapter->SpinLock, &Irql);
  1801. //
  1802. // Return the registers to the bit map.
  1803. //
  1804. RtlClearBits( MasterAdapter->MapRegisters,
  1805. MapRegisterNumber,
  1806. NumberOfMapRegisters
  1807. );
  1808. //
  1809. // Process any requests waiting for map registers in the adapter queue.
  1810. // Requests are processed until a request cannot be satisfied or until
  1811. // there are no more requests in the queue.
  1812. //
  1813. while(TRUE) {
  1814. if ( IsListEmpty(&MasterAdapter->AdapterQueue) ){
  1815. break;
  1816. }
  1817. Packet = RemoveHeadList( &MasterAdapter->AdapterQueue );
  1818. AdapterObject = CONTAINING_RECORD( Packet,
  1819. ADAPTER_OBJECT,
  1820. AdapterQueue
  1821. );
  1822. Wcb = AdapterObject->CurrentWcb;
  1823. //
  1824. // Attempt to allocate map registers for this request. Use the previous
  1825. // register base as a hint.
  1826. //
  1827. MapRegisterNumber = RtlFindClearBitsAndSet( MasterAdapter->MapRegisters,
  1828. AdapterObject->NumberOfMapRegisters,
  1829. MasterAdapter->NumberOfMapRegisters
  1830. );
  1831. if (MapRegisterNumber == -1) {
  1832. //
  1833. // There were not enough free map registers. Put this request back on
  1834. // the adapter queue where is came from.
  1835. //
  1836. InsertHeadList( &MasterAdapter->AdapterQueue,
  1837. &AdapterObject->AdapterQueue
  1838. );
  1839. break;
  1840. }
  1841. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1842. AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY)
  1843. MasterAdapter->MapRegisterBase + MapRegisterNumber);
  1844. //
  1845. // Set the no scatter/gather flag if scatter/gather not
  1846. // supported.
  1847. //
  1848. if (!AdapterObject->ScatterGather) {
  1849. AdapterObject->MapRegisterBase = (PVOID)
  1850. ((ULONG) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);
  1851. }
  1852. if (AdapterObject->EisaAdapter) {
  1853. AdapterObject->MapRegisterBase = (PVOID)
  1854. ((ULONG) AdapterObject->MapRegisterBase | EISA_ADAPTER);
  1855. }
  1856. //
  1857. // Invoke the driver's execution routine now.
  1858. //
  1859. Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
  1860. Wcb->CurrentIrp,
  1861. AdapterObject->MapRegisterBase,
  1862. Wcb->DeviceContext );
  1863. //
  1864. // If the driver wishes to keep the map registers then set the number
  1865. // allocated to zero and set the action to deallocate object.
  1866. //
  1867. if (Action == DeallocateObjectKeepRegisters) {
  1868. AdapterObject->NumberOfMapRegisters = 0;
  1869. Action = DeallocateObject;
  1870. }
  1871. //
  1872. // If the driver would like to have the adapter deallocated,
  1873. // then deallocate any map registers allocated and then release
  1874. // the adapter object.
  1875. //
  1876. if (Action == DeallocateObject) {
  1877. //
  1878. // The map registers registers are deallocated here rather than in
  1879. // IoFreeAdapterChannel. This limits the number of times
  1880. // this routine can be called recursively possibly overflowing
  1881. // the stack. The worst case occurs if there is a pending
  1882. // request for the adapter that uses map registers and whos
  1883. // excution routine decallocates the adapter. In that case if there
  1884. // are no requests in the master adapter queue, then IoFreeMapRegisters
  1885. // will get called again.
  1886. //
  1887. if (AdapterObject->NumberOfMapRegisters != 0) {
  1888. //
  1889. // Deallocate the map registers and clear the count so that
  1890. // IoFreeAdapterChannel will not deallocate them again.
  1891. //
  1892. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  1893. RtlClearBits( MasterAdapter->MapRegisters,
  1894. MapRegisterNumber,
  1895. AdapterObject->NumberOfMapRegisters
  1896. );
  1897. AdapterObject->NumberOfMapRegisters = 0;
  1898. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1899. }
  1900. IoFreeAdapterChannel( AdapterObject );
  1901. }
  1902. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  1903. }
  1904. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1905. }
  1906. BOOLEAN
  1907. HalpCreateDmaStructures (
  1908. VOID
  1909. )
  1910. /*++
  1911. Routine Description:
  1912. This routine initializes the structures necessary for DMA operations
  1913. and connects the intermediate interrupt dispatcher.
  1914. Arguments:
  1915. None.
  1916. Return Value:
  1917. If the second level interrupt dispatcher is connected, then a value of
  1918. TRUE is returned. Otherwise, a value of FALSE is returned.
  1919. --*/
  1920. {
  1921. //
  1922. // Init the Eisa interrupts
  1923. //
  1924. return HalpCreateEisaStructures ();
  1925. }
  1926. PHYSICAL_ADDRESS
  1927. IoMapTransfer(
  1928. IN PADAPTER_OBJECT AdapterObject,
  1929. IN PMDL Mdl,
  1930. IN PVOID MapRegisterBase,
  1931. IN PVOID CurrentVa,
  1932. IN OUT PULONG Length,
  1933. IN BOOLEAN WriteToDevice
  1934. )
  1935. /*++
  1936. Routine Description:
  1937. This routine is invoked to set up the map registers in the DMA controller
  1938. to allow a transfer to or from a device.
  1939. Arguments:
  1940. AdapterObject - Pointer to the adapter object representing the DMA
  1941. controller channel that has been allocated.
  1942. Mdl - Pointer to the MDL that describes the pages of memory that are
  1943. being read or written.
  1944. MapRegisterBase - The address of the base map register that has been
  1945. allocated to the device driver for use in mapping the transfer.
  1946. CurrentVa - Current virtual address in the buffer described by the MDL
  1947. that the transfer is being done to or from.
  1948. Length - Supplies the length of the transfer. This determines the
  1949. number of map registers that need to be written to map the transfer.
  1950. Returns the length of the transfer which was actually mapped.
  1951. WriteToDevice - Boolean value that indicates whether this is a write
  1952. to the device from memory (TRUE), or vice versa.
  1953. Return Value:
  1954. Returns the logical address to be used by bus masters.
  1955. --*/
  1956. {
  1957. BOOLEAN useBuffer;
  1958. ULONG transferLength;
  1959. ULONG logicalAddress;
  1960. PHYSICAL_ADDRESS returnAddress;
  1961. ULONG index;
  1962. PULONG pageFrame;
  1963. PUCHAR bytePointer;
  1964. UCHAR adapterMode;
  1965. UCHAR dataByte;
  1966. PTRANSLATION_ENTRY translationEntry;
  1967. ULONG pageOffset;
  1968. KIRQL Irql;
  1969. BOOLEAN specialMemory;
  1970. pageOffset = BYTE_OFFSET(CurrentVa);
  1971. if ( MapRegisterBase != NULL ) {
  1972. specialMemory = HalpAnySpecialMemory( Mdl, *Length, pageOffset);
  1973. } else {
  1974. specialMemory = FALSE;
  1975. }
  1976. //
  1977. // Calculate how much of the transfer is contiguous.
  1978. //
  1979. transferLength = PAGE_SIZE - pageOffset;
  1980. pageFrame = (PULONG)(Mdl+1);
  1981. pageFrame += ((ULONG) CurrentVa - (ULONG) Mdl->StartVa) >> PAGE_SHIFT;
  1982. logicalAddress = (*pageFrame << PAGE_SHIFT) + pageOffset;
  1983. //
  1984. // If the buffer is contigous and does not cross a 64 K bountry then
  1985. // just extend the buffer. The 64 K bountry restriction does not apply
  1986. // to Eisa systems.
  1987. //
  1988. //
  1989. if ( !specialMemory ) {
  1990. if (HalpEisaDma) {
  1991. while( transferLength < *Length ) {
  1992. if (*pageFrame + 1 != *(pageFrame + 1)) {
  1993. break;
  1994. }
  1995. transferLength += PAGE_SIZE;
  1996. pageFrame++;
  1997. }
  1998. } else {
  1999. while( transferLength < *Length ) {
  2000. if (*pageFrame + 1 != *(pageFrame + 1) ||
  2001. (*pageFrame & ~0x07) != (*(pageFrame + 1) & ~0x07)) {
  2002. break;
  2003. }
  2004. transferLength += PAGE_SIZE;
  2005. pageFrame++;
  2006. }
  2007. }
  2008. //
  2009. // Limit the transferLength to the requested Length.
  2010. //
  2011. transferLength = transferLength > *Length ? *Length : transferLength;
  2012. }
  2013. //
  2014. // Determine if the data transfer needs to use the map buffer.
  2015. //
  2016. if (MapRegisterBase != NULL) {
  2017. //
  2018. // Strip no scatter/gather flag.
  2019. //
  2020. translationEntry = (PTRANSLATION_ENTRY) ((ULONG) MapRegisterBase &
  2021. ~(NO_SCATTER_GATHER | EISA_ADAPTER));
  2022. if ( specialMemory ) {
  2023. logicalAddress = translationEntry->PhysicalAddress + pageOffset;
  2024. translationEntry->Index = HOLE_BUFFER;
  2025. transferLength = *Length;
  2026. //
  2027. // Copy the data.
  2028. //
  2029. if (WriteToDevice) {
  2030. HalpCopyBufferMap(
  2031. Mdl,
  2032. translationEntry,
  2033. CurrentVa,
  2034. *Length,
  2035. WriteToDevice
  2036. );
  2037. }
  2038. } else {
  2039. if (((ULONG) MapRegisterBase & NO_SCATTER_GATHER) ||
  2040. !((ULONG)MapRegisterBase & EISA_ADAPTER)) {
  2041. if ((ULONG) MapRegisterBase & NO_SCATTER_GATHER
  2042. && transferLength < *Length) {
  2043. logicalAddress = translationEntry->PhysicalAddress + pageOffset;
  2044. translationEntry->Index = COPY_BUFFER;
  2045. index = 0;
  2046. transferLength = *Length;
  2047. useBuffer = TRUE;
  2048. } else {
  2049. useBuffer = FALSE;
  2050. index = translationEntry->Index;
  2051. translationEntry->Index += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
  2052. CurrentVa,
  2053. transferLength
  2054. );
  2055. }
  2056. //
  2057. // For devices with no scatter/gather or non-Eisa devices:
  2058. // It must require memory to be at less than 16 MB. If the logical
  2059. // address is greater than 16MB then map registers must be used.
  2060. //
  2061. if (logicalAddress+transferLength > MAXIMUM_ISA_PHYSICAL_ADDRESS) {
  2062. logicalAddress = (translationEntry + index)->PhysicalAddress
  2063. + pageOffset;
  2064. useBuffer = TRUE;
  2065. if ((ULONG) MapRegisterBase & NO_SCATTER_GATHER) {
  2066. translationEntry->Index = COPY_BUFFER;
  2067. index = 0;
  2068. }
  2069. }
  2070. //
  2071. // Copy the data if necessary.
  2072. //
  2073. if (useBuffer && WriteToDevice) {
  2074. HalpCopyBufferMap(
  2075. Mdl,
  2076. translationEntry + index,
  2077. CurrentVa,
  2078. *Length,
  2079. WriteToDevice
  2080. );
  2081. }
  2082. } else {
  2083. translationEntry->Index = SKIP_BUFFER;
  2084. }
  2085. }
  2086. }
  2087. //
  2088. // Return the length.
  2089. //
  2090. *Length = transferLength;
  2091. //
  2092. // We only support 32 bits, but the return is 64. Just
  2093. // zero extend
  2094. //
  2095. returnAddress.LowPart = logicalAddress;
  2096. returnAddress.HighPart = 0;
  2097. //
  2098. // If no adapter was specificed then there is no more work to do so
  2099. // return.
  2100. //
  2101. if (AdapterObject == NULL || AdapterObject->MasterDevice) {
  2102. return(returnAddress);
  2103. }
  2104. //
  2105. // Determine the mode based on the transfer direction.
  2106. //
  2107. adapterMode = AdapterObject->AdapterMode;
  2108. ((PDMA_EISA_MODE) &adapterMode)->TransferType = (UCHAR) (WriteToDevice ?
  2109. WRITE_TRANSFER : READ_TRANSFER);
  2110. bytePointer = (PUCHAR) &logicalAddress;
  2111. if (AdapterObject->Width16Bits) {
  2112. //
  2113. // If this is a 16 bit transfer then adjust the length and the address
  2114. // for the 16 bit DMA mode.
  2115. //
  2116. transferLength >>= 1;
  2117. //
  2118. // In 16 bit DMA mode the low 16 bits are shifted right one and the
  2119. // page register value is unchanged. So save the page register value
  2120. // and shift the logical address then restore the page value.
  2121. //
  2122. dataByte = bytePointer[2];
  2123. logicalAddress >>= 1;
  2124. bytePointer[2] = dataByte;
  2125. }
  2126. //
  2127. // grab the spinlock for the system DMA controller
  2128. //
  2129. KeAcquireSpinLock( &AdapterObject->MasterAdapter->SpinLock, &Irql );
  2130. //
  2131. // Determine the controller number based on the Adapter number.
  2132. //
  2133. if (AdapterObject->AdapterNumber == 1) {
  2134. //
  2135. // This request is for DMA controller 1
  2136. //
  2137. PDMA1_CONTROL dmaControl;
  2138. dmaControl = AdapterObject->AdapterBaseVa;
  2139. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2140. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  2141. WRITE_PORT_UCHAR(
  2142. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2143. .DmaBaseAddress,
  2144. bytePointer[0]
  2145. );
  2146. WRITE_PORT_UCHAR(
  2147. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2148. .DmaBaseAddress,
  2149. bytePointer[1]
  2150. );
  2151. WRITE_PORT_UCHAR(
  2152. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
  2153. (ULONG)AdapterObject->PagePort,
  2154. bytePointer[2]
  2155. );
  2156. if (HalpEisaDma) {
  2157. //
  2158. // Write the high page register with zero value. This enable a special mode
  2159. // which allows ties the page register and base count into a single 24 bit
  2160. // address register.
  2161. //
  2162. WRITE_PORT_UCHAR(
  2163. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
  2164. (ULONG)AdapterObject->PagePort,
  2165. 0
  2166. );
  2167. }
  2168. //
  2169. // Notify DMA chip of the length to transfer.
  2170. //
  2171. WRITE_PORT_UCHAR(
  2172. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2173. .DmaBaseCount,
  2174. (UCHAR) ((transferLength - 1) & 0xff)
  2175. );
  2176. WRITE_PORT_UCHAR(
  2177. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2178. .DmaBaseCount,
  2179. (UCHAR) ((transferLength - 1) >> 8)
  2180. );
  2181. //
  2182. // Set the DMA chip to read or write mode; and unmask it.
  2183. //
  2184. WRITE_PORT_UCHAR(
  2185. &dmaControl->SingleMask,
  2186. (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
  2187. );
  2188. } else {
  2189. //
  2190. // This request is for DMA controller 2
  2191. //
  2192. PDMA2_CONTROL dmaControl;
  2193. dmaControl = AdapterObject->AdapterBaseVa;
  2194. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2195. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  2196. WRITE_PORT_UCHAR(
  2197. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2198. .DmaBaseAddress,
  2199. bytePointer[0]
  2200. );
  2201. WRITE_PORT_UCHAR(
  2202. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2203. .DmaBaseAddress,
  2204. bytePointer[1]
  2205. );
  2206. WRITE_PORT_UCHAR(
  2207. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
  2208. (ULONG)AdapterObject->PagePort,
  2209. bytePointer[2]
  2210. );
  2211. if (HalpEisaDma) {
  2212. //
  2213. // Write the high page register with zero value. This enable a special mode
  2214. // which allows ties the page register and base count into a single 24 bit
  2215. // address register.
  2216. //
  2217. WRITE_PORT_UCHAR(
  2218. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
  2219. (ULONG)AdapterObject->PagePort,
  2220. 0
  2221. );
  2222. }
  2223. //
  2224. // Notify DMA chip of the length to transfer.
  2225. //
  2226. WRITE_PORT_UCHAR(
  2227. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2228. .DmaBaseCount,
  2229. (UCHAR) ((transferLength - 1) & 0xff)
  2230. );
  2231. WRITE_PORT_UCHAR(
  2232. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2233. .DmaBaseCount,
  2234. (UCHAR) ((transferLength - 1) >> 8)
  2235. );
  2236. //
  2237. // Set the DMA chip to read or write mode; and unmask it.
  2238. //
  2239. WRITE_PORT_UCHAR(
  2240. &dmaControl->SingleMask,
  2241. (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
  2242. );
  2243. }
  2244. KeReleaseSpinLock (&AdapterObject->MasterAdapter->SpinLock, Irql);
  2245. return(returnAddress);
  2246. }
  2247. BOOLEAN
  2248. IoFlushAdapterBuffers(
  2249. IN PADAPTER_OBJECT AdapterObject,
  2250. IN PMDL Mdl,
  2251. IN PVOID MapRegisterBase,
  2252. IN PVOID CurrentVa,
  2253. IN ULONG Length,
  2254. IN BOOLEAN WriteToDevice
  2255. )
  2256. /*++
  2257. Routine Description:
  2258. This routine flushes the DMA adapter object buffers. For the Jensen system
  2259. its clears the enable flag which aborts the dma.
  2260. Arguments:
  2261. AdapterObject - Pointer to the adapter object representing the DMA
  2262. controller channel.
  2263. Mdl - A pointer to a Memory Descriptor List (MDL) that maps the locked-down
  2264. buffer to/from which the I/O occured.
  2265. MapRegisterBase - A pointer to the base of the map registers in the adapter
  2266. or DMA controller.
  2267. CurrentVa - The current virtual address in the buffer described the the Mdl
  2268. where the I/O operation occurred.
  2269. Length - Supplies the length of the transfer.
  2270. WriteToDevice - Supplies a BOOLEAN value that indicates the direction of
  2271. the data transfer was to the device.
  2272. Return Value:
  2273. TRUE - If the transfer was successful.
  2274. FALSE - If there was an error in the transfer.
  2275. --*/
  2276. {
  2277. PTRANSLATION_ENTRY translationEntry;
  2278. PULONG pageFrame;
  2279. ULONG transferLength;
  2280. ULONG partialLength;
  2281. BOOLEAN masterDevice;
  2282. ULONG index;
  2283. masterDevice = AdapterObject == NULL || AdapterObject->MasterDevice ?
  2284. TRUE : FALSE;
  2285. //
  2286. // If this is a slave device, then stop the DMA controller.
  2287. //
  2288. if (!masterDevice) {
  2289. //
  2290. // Mask the DMA request line so that DMA requests cannot occur.
  2291. //
  2292. if (AdapterObject->AdapterNumber == 1) {
  2293. //
  2294. // This request is for DMA controller 1
  2295. //
  2296. PDMA1_CONTROL dmaControl;
  2297. dmaControl = AdapterObject->AdapterBaseVa;
  2298. WRITE_PORT_UCHAR(
  2299. &dmaControl->SingleMask,
  2300. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  2301. );
  2302. } else {
  2303. //
  2304. // This request is for DMA controller 2
  2305. //
  2306. PDMA2_CONTROL dmaControl;
  2307. dmaControl = AdapterObject->AdapterBaseVa;
  2308. WRITE_PORT_UCHAR(
  2309. &dmaControl->SingleMask,
  2310. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  2311. );
  2312. }
  2313. }
  2314. if (MapRegisterBase == NULL) {
  2315. return(TRUE);
  2316. }
  2317. //
  2318. // Determine if the data needs to be copied to the orginal buffer.
  2319. // This only occurs if the data tranfer is from the device, the
  2320. // MapReisterBase is not NULL and the transfer spans a page.
  2321. //
  2322. //
  2323. // Strip no scatter/gather flag.
  2324. //
  2325. translationEntry = (PTRANSLATION_ENTRY) ((ULONG) MapRegisterBase &
  2326. ~(NO_SCATTER_GATHER | EISA_ADAPTER));
  2327. if ( translationEntry->Index == SKIP_BUFFER ) {
  2328. translationEntry->Index = 0;
  2329. return(TRUE);
  2330. }
  2331. if (!WriteToDevice) {
  2332. //
  2333. // If this is not a master device, then just transfer the buffer.
  2334. //
  2335. if (translationEntry->Index == HOLE_BUFFER) {
  2336. if (!masterDevice) {
  2337. //
  2338. // Copy only the bytes that have actually been transfered.
  2339. //
  2340. Length -= HalReadDmaCounter(AdapterObject);
  2341. }
  2342. //
  2343. // The adapter does not support scatter/gather copy the buffer.
  2344. //
  2345. HalpCopyBufferMap(
  2346. Mdl,
  2347. translationEntry,
  2348. CurrentVa,
  2349. Length,
  2350. WriteToDevice
  2351. );
  2352. } else if ((ULONG) MapRegisterBase & NO_SCATTER_GATHER) {
  2353. if (translationEntry->Index == COPY_BUFFER) {
  2354. if (!masterDevice) {
  2355. //
  2356. // Copy only the bytes that have actually been transfered.
  2357. //
  2358. Length -= HalReadDmaCounter(AdapterObject);
  2359. }
  2360. //
  2361. // The adapter does not support scatter/gather copy the buffer.
  2362. //
  2363. HalpCopyBufferMap(
  2364. Mdl,
  2365. translationEntry,
  2366. CurrentVa,
  2367. Length,
  2368. WriteToDevice
  2369. );
  2370. }
  2371. } else if (!((ULONG) MapRegisterBase & NO_SCATTER_GATHER) &&
  2372. !((ULONG) MapRegisterBase & EISA_ADAPTER)) {
  2373. //
  2374. // Cycle through the pages of the transfer to determine if there
  2375. // are any which need to be copied back.
  2376. //
  2377. transferLength = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
  2378. partialLength = transferLength;
  2379. pageFrame = (PULONG)(Mdl+1);
  2380. pageFrame += ((ULONG) CurrentVa - (ULONG) Mdl->StartVa) >> PAGE_SHIFT;
  2381. while( transferLength <= Length ){
  2382. if (*pageFrame >= BYTES_TO_PAGES(MAXIMUM_ISA_PHYSICAL_ADDRESS)) {
  2383. HalpCopyBufferMap(
  2384. Mdl,
  2385. translationEntry,
  2386. CurrentVa,
  2387. partialLength,
  2388. WriteToDevice
  2389. );
  2390. }
  2391. (PCCHAR) CurrentVa += partialLength;
  2392. partialLength = PAGE_SIZE;
  2393. //
  2394. // Note that transferLength indicates the amount which will
  2395. // be transfered after the next loop; thus, it is updated
  2396. // with the new partial length.
  2397. //
  2398. transferLength += partialLength;
  2399. pageFrame++;
  2400. translationEntry++;
  2401. }
  2402. //
  2403. // Process any remaining residue.
  2404. //
  2405. partialLength = Length - transferLength + partialLength;
  2406. if (partialLength && (*pageFrame >= BYTES_TO_PAGES(MAXIMUM_ISA_PHYSICAL_ADDRESS))) {
  2407. HalpCopyBufferMap(
  2408. Mdl,
  2409. translationEntry,
  2410. CurrentVa,
  2411. partialLength,
  2412. WriteToDevice
  2413. );
  2414. }
  2415. }
  2416. }
  2417. //
  2418. // Strip no scatter/gather flag.
  2419. //
  2420. translationEntry = (PTRANSLATION_ENTRY) ((ULONG) MapRegisterBase &
  2421. ~(NO_SCATTER_GATHER | EISA_ADAPTER));
  2422. //
  2423. // Clear index in map register.
  2424. //
  2425. translationEntry->Index = 0;
  2426. return TRUE;
  2427. }
  2428. IO_ALLOCATION_ACTION
  2429. HalpAllocationRoutine (
  2430. IN PDEVICE_OBJECT DeviceObject,
  2431. IN PIRP Irp,
  2432. IN PVOID MapRegisterBase,
  2433. IN PVOID Context
  2434. )
  2435. /*++
  2436. Routine Description:
  2437. This function is called by HalAllocateAdapterChannel when sufficent resources
  2438. are available to the driver. This routine saves the MapRegisterBase,
  2439. and set the event pointed to by the context parameter.
  2440. Arguments:
  2441. DeviceObject - Supplies a pointer where the map register base should be
  2442. stored.
  2443. Irp - Unused.
  2444. MapRegisterBase - Supplied by the Io subsystem for use in IoMapTransfer.
  2445. Context - Supplies a pointer to an event which is set to indicate the
  2446. AdapterObject has been allocated.
  2447. Return Value:
  2448. DeallocateObjectKeepRegisters - Indicates the adapter should be freed
  2449. and mapregisters should remain allocated after return.
  2450. --*/
  2451. {
  2452. UNREFERENCED_PARAMETER(Irp);
  2453. *((PVOID *) DeviceObject) = MapRegisterBase;
  2454. (VOID) KeSetEvent( (PKEVENT) Context, 0L, FALSE );
  2455. return(DeallocateObjectKeepRegisters);
  2456. }
  2457. ULONG
  2458. HalpGetEisaData (
  2459. IN PBUS_HANDLER BusHandler,
  2460. IN PBUS_HANDLER RootHandler,
  2461. IN ULONG SlotNumber,
  2462. IN PVOID Buffer,
  2463. IN ULONG Offset,
  2464. IN ULONG Length
  2465. )
  2466. /*++
  2467. Routine Description:
  2468. The function returns the Eisa bus data for a slot or address.
  2469. Arguments:
  2470. BusHandler - Registered BUSHANDLER for the target configuration space
  2471. RootHandler - Registered BUSHANDLER for the orginating HalGetBusData
  2472. request.
  2473. Buffer - Supplies the space to store the data.
  2474. Length - Supplies a count in bytes of the maximum amount to return.
  2475. Return Value:
  2476. Returns the amount of data stored into the buffer.
  2477. --*/
  2478. {
  2479. OBJECT_ATTRIBUTES ObjectAttributes;
  2480. OBJECT_ATTRIBUTES BusObjectAttributes;
  2481. PWSTR EisaPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\EisaAdapter";
  2482. PWSTR ConfigData = L"Configuration Data";
  2483. ANSI_STRING TmpString;
  2484. ULONG BusNumber;
  2485. UCHAR BusString[] = "00";
  2486. UNICODE_STRING RootName, BusName;
  2487. UNICODE_STRING ConfigDataName;
  2488. NTSTATUS NtStatus;
  2489. PKEY_VALUE_FULL_INFORMATION ValueInformation;
  2490. PCM_FULL_RESOURCE_DESCRIPTOR Descriptor;
  2491. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource;
  2492. PCM_EISA_SLOT_INFORMATION SlotInformation;
  2493. ULONG PartialCount;
  2494. ULONG TotalDataSize, SlotDataSize;
  2495. HANDLE EisaHandle, BusHandle;
  2496. ULONG BytesWritten, BytesNeeded;
  2497. PUCHAR KeyValueBuffer;
  2498. ULONG i;
  2499. ULONG DataLength = 0;
  2500. PUCHAR DataBuffer = Buffer;
  2501. BOOLEAN Found = FALSE;
  2502. UNREFERENCED_PARAMETER( RootHandler );
  2503. RtlInitUnicodeString(
  2504. &RootName,
  2505. EisaPath
  2506. );
  2507. InitializeObjectAttributes(
  2508. &ObjectAttributes,
  2509. &RootName,
  2510. OBJ_CASE_INSENSITIVE,
  2511. (HANDLE)NULL,
  2512. NULL
  2513. );
  2514. //
  2515. // Open the EISA root
  2516. //
  2517. NtStatus = ZwOpenKey(
  2518. &EisaHandle,
  2519. KEY_READ,
  2520. &ObjectAttributes
  2521. );
  2522. if (!NT_SUCCESS(NtStatus)) {
  2523. #if DBG
  2524. DbgPrint("HAL: Open Status = %x\n",NtStatus);
  2525. #endif
  2526. return(0);
  2527. }
  2528. //
  2529. // Init bus number path
  2530. //
  2531. BusNumber = BusHandler->BusNumber;
  2532. if (BusNumber > 99) {
  2533. return (0);
  2534. }
  2535. if (BusNumber > 9) {
  2536. BusString[0] += (UCHAR) (BusNumber/10);
  2537. BusString[1] += (UCHAR) (BusNumber % 10);
  2538. } else {
  2539. BusString[0] += (UCHAR) BusNumber;
  2540. BusString[1] = '\0';
  2541. }
  2542. RtlInitAnsiString(
  2543. &TmpString,
  2544. BusString
  2545. );
  2546. RtlAnsiStringToUnicodeString(
  2547. &BusName,
  2548. &TmpString,
  2549. TRUE
  2550. );
  2551. InitializeObjectAttributes(
  2552. &BusObjectAttributes,
  2553. &BusName,
  2554. OBJ_CASE_INSENSITIVE,
  2555. (HANDLE)EisaHandle,
  2556. NULL
  2557. );
  2558. //
  2559. // Open the EISA root + Bus Number
  2560. //
  2561. NtStatus = ZwOpenKey(
  2562. &BusHandle,
  2563. KEY_READ,
  2564. &BusObjectAttributes
  2565. );
  2566. if (!NT_SUCCESS(NtStatus)) {
  2567. #if DBG
  2568. DbgPrint("HAL: Opening Bus Number: Status = %x\n",NtStatus);
  2569. #endif
  2570. return(0);
  2571. }
  2572. //
  2573. // opening the configuration data. This first call tells us how
  2574. // much memory we need to allocate
  2575. //
  2576. RtlInitUnicodeString(
  2577. &ConfigDataName,
  2578. ConfigData
  2579. );
  2580. //
  2581. // This should fail. We need to make this call so we can
  2582. // get the actual size of the buffer to allocate.
  2583. //
  2584. ValueInformation = (PKEY_VALUE_FULL_INFORMATION) &i;
  2585. NtStatus = ZwQueryValueKey(
  2586. BusHandle,
  2587. &ConfigDataName,
  2588. KeyValueFullInformation,
  2589. ValueInformation,
  2590. 0,
  2591. &BytesNeeded
  2592. );
  2593. KeyValueBuffer = ExAllocatePool(
  2594. NonPagedPool,
  2595. BytesNeeded
  2596. );
  2597. if (KeyValueBuffer == NULL) {
  2598. #if DBG
  2599. DbgPrint("HAL: Cannot allocate Key Value Buffer\n");
  2600. #endif
  2601. ZwClose(BusHandle);
  2602. return(0);
  2603. }
  2604. ValueInformation = (PKEY_VALUE_FULL_INFORMATION)KeyValueBuffer;
  2605. NtStatus = ZwQueryValueKey(
  2606. BusHandle,
  2607. &ConfigDataName,
  2608. KeyValueFullInformation,
  2609. ValueInformation,
  2610. BytesNeeded,
  2611. &BytesWritten
  2612. );
  2613. ZwClose(BusHandle);
  2614. if (!NT_SUCCESS(NtStatus) || ValueInformation->DataLength == 0) {
  2615. #if DBG
  2616. DbgPrint("HAL: Query Config Data: Status = %x\n",NtStatus);
  2617. #endif
  2618. ExFreePool(KeyValueBuffer);
  2619. return(0);
  2620. }
  2621. //
  2622. // We get back a Full Resource Descriptor List
  2623. //
  2624. Descriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PUCHAR)ValueInformation +
  2625. ValueInformation->DataOffset);
  2626. PartialResource = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
  2627. &(Descriptor->PartialResourceList.PartialDescriptors);
  2628. PartialCount = Descriptor->PartialResourceList.Count;
  2629. for (i = 0; i < PartialCount; i++) {
  2630. //
  2631. // Do each partial Resource
  2632. //
  2633. switch (PartialResource->Type) {
  2634. case CmResourceTypeNull:
  2635. case CmResourceTypePort:
  2636. case CmResourceTypeInterrupt:
  2637. case CmResourceTypeMemory:
  2638. case CmResourceTypeDma:
  2639. //
  2640. // We dont care about these.
  2641. //
  2642. PartialResource++;
  2643. break;
  2644. case CmResourceTypeDeviceSpecific:
  2645. //
  2646. // Bingo!
  2647. //
  2648. TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize;
  2649. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  2650. ((PUCHAR)PartialResource +
  2651. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  2652. while (((LONG)TotalDataSize) > 0) {
  2653. if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
  2654. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
  2655. } else {
  2656. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
  2657. SlotInformation->NumberFunctions *
  2658. sizeof(CM_EISA_FUNCTION_INFORMATION);
  2659. }
  2660. if (SlotDataSize > TotalDataSize) {
  2661. //
  2662. // Something is wrong again
  2663. //
  2664. ExFreePool(KeyValueBuffer);
  2665. return(0);
  2666. }
  2667. if (SlotNumber != 0) {
  2668. SlotNumber--;
  2669. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  2670. ((PUCHAR)SlotInformation + SlotDataSize);
  2671. TotalDataSize -= SlotDataSize;
  2672. continue;
  2673. }
  2674. //
  2675. // This is our slot
  2676. //
  2677. Found = TRUE;
  2678. break;
  2679. }
  2680. //
  2681. // End loop
  2682. //
  2683. i = PartialCount;
  2684. break;
  2685. default:
  2686. #if DBG
  2687. DbgPrint("Bad Data in registry!\n");
  2688. #endif
  2689. ExFreePool(KeyValueBuffer);
  2690. return(0);
  2691. }
  2692. }
  2693. if (Found) {
  2694. i = Length + Offset;
  2695. if (i > SlotDataSize) {
  2696. i = SlotDataSize;
  2697. }
  2698. DataLength = i - Offset;
  2699. RtlMoveMemory (Buffer, ((PUCHAR)SlotInformation + Offset), DataLength);
  2700. }
  2701. ExFreePool(KeyValueBuffer);
  2702. return DataLength;
  2703. }
  2704. ULONG
  2705. HalReadDmaCounter(
  2706. IN PADAPTER_OBJECT AdapterObject
  2707. )
  2708. /*++
  2709. Routine Description:
  2710. This function reads the DMA counter and returns the number of bytes left
  2711. to be transfered.
  2712. Arguments:
  2713. AdapterObject - Supplies a pointer to the adapter object to be read.
  2714. Return Value:
  2715. Returns the number of bytes still be be transfered.
  2716. --*/
  2717. {
  2718. ULONG count;
  2719. ULONG high;
  2720. KIRQL Irql;
  2721. //
  2722. // Grab the spinlock for the system DMA controller.
  2723. //
  2724. KeAcquireSpinLock( &AdapterObject->MasterAdapter->SpinLock, &Irql );
  2725. //
  2726. // Determine the controller number based on the Adapter number.
  2727. //
  2728. if (AdapterObject->AdapterNumber == 1) {
  2729. //
  2730. // This request is for DMA controller 1
  2731. //
  2732. PDMA1_CONTROL dmaControl;
  2733. dmaControl = AdapterObject->AdapterBaseVa;
  2734. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2735. //
  2736. // Initialize count to a value which will not match.
  2737. //
  2738. count = 0xFFFF00;
  2739. //
  2740. // Loop until the same high byte is read twice.
  2741. //
  2742. do {
  2743. high = count;
  2744. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2745. //
  2746. // Read the current DMA count.
  2747. //
  2748. count = READ_PORT_UCHAR(
  2749. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2750. .DmaBaseCount
  2751. );
  2752. count |= READ_PORT_UCHAR(
  2753. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2754. .DmaBaseCount
  2755. ) << 8;
  2756. } while ((count & 0xFFFF00) != (high & 0xFFFF00));
  2757. } else {
  2758. //
  2759. // This request is for DMA controller 2
  2760. //
  2761. PDMA2_CONTROL dmaControl;
  2762. dmaControl = AdapterObject->AdapterBaseVa;
  2763. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2764. //
  2765. // Initialize count to a value which will not match.
  2766. //
  2767. count = 0xFFFF00;
  2768. //
  2769. // Loop until the same high byte is read twice.
  2770. //
  2771. do {
  2772. high = count;
  2773. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2774. //
  2775. // Read the current DMA count.
  2776. //
  2777. count = READ_PORT_UCHAR(
  2778. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2779. .DmaBaseCount
  2780. );
  2781. count |= READ_PORT_UCHAR(
  2782. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2783. .DmaBaseCount
  2784. ) << 8;
  2785. } while ((count & 0xFFFF00) != (high & 0xFFFF00));
  2786. }
  2787. //
  2788. // Release the spinlock for the system DMA controller.
  2789. //
  2790. KeReleaseSpinLock( &AdapterObject->MasterAdapter->SpinLock, Irql );
  2791. //
  2792. // The DMA counter has a bias of one and can only be 16 bit long.
  2793. //
  2794. count = (count + 1) & 0xFFFF;
  2795. //
  2796. // If this is a 16 bit dma the multiply the count by 2.
  2797. //
  2798. if (AdapterObject->Width16Bits) {
  2799. count *= 2;
  2800. }
  2801. return(count);
  2802. }
  2803. BOOLEAN
  2804. HalpSpecialMemory(
  2805. IN ULONG PFN
  2806. )
  2807. /*++
  2808. Routine Description:
  2809. This function checks if the supplied PFN is contained within a section
  2810. of special memory.
  2811. Arguments:
  2812. PFN - Page Frame Number of the page in question.
  2813. Return Value:
  2814. Returns TRUE if the specified page is part of special memory.
  2815. --*/
  2816. {
  2817. PMEMORY_REGION specialMemoryRegion = HalpSpecialRegions;
  2818. while ( specialMemoryRegion != NULL ) {
  2819. if ( PFN >= specialMemoryRegion->PfnBase &&
  2820. PFN < specialMemoryRegion->PfnBase + specialMemoryRegion->PfnCount ) {
  2821. return TRUE;
  2822. }
  2823. specialMemoryRegion = specialMemoryRegion->Next;
  2824. }
  2825. return FALSE;
  2826. }
  2827. VOID
  2828. HalpInitializeSpecialMemory(
  2829. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  2830. )
  2831. /*++
  2832. Routine Description:
  2833. This function initializes the special memory regions on Jensen.
  2834. Arguments:
  2835. LoaderBlock - pointer to the Loader Parameter Block.
  2836. Return Value:
  2837. None
  2838. --*/
  2839. {
  2840. PLIST_ENTRY NextMd;
  2841. PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
  2842. PMEMORY_REGION MemoryRegion;
  2843. //
  2844. // Initialize the fixed half-meg region, length is half-meg also.
  2845. //
  2846. HalpHalfMeg.PfnBase = HALF_MEGABYTE / PAGE_SIZE;
  2847. HalpHalfMeg.PfnCount = HALF_MEGABYTE / PAGE_SIZE;
  2848. //
  2849. // Link the half-meg region into the special regions list
  2850. //
  2851. HalpHalfMeg.Next = HalpSpecialRegions;
  2852. HalpSpecialRegions = &HalpHalfMeg;
  2853. return;
  2854. #if 0
  2855. //
  2856. // Scan through all memory descriptors looking for special memory regions
  2857. //
  2858. NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
  2859. while ( NextMd != &LoaderBlock->MemoryDescriptorListHead ) {
  2860. Descriptor = CONTAINING_RECORD(NextMd,
  2861. MEMORY_ALLOCATION_DESCRIPTOR,
  2862. ListEntry);
  2863. if ( Descriptor->MemoryType == LoaderSpecialMemory ) {
  2864. //
  2865. // Allocate pool and copy info into MemoryRegion and insert in list
  2866. //
  2867. if ( sizeof(MEMORY_REGION) > HalpMemoryRegionSize ) {
  2868. return;
  2869. }
  2870. HalpMemoryRegionSize -= sizeof(MEMORY_REGION);
  2871. MemoryRegion = (PMEMORY_REGION) HalpMemoryRegionBuffers;
  2872. HalpMemoryRegionBuffers = (PVOID) (MemoryRegion + 1);
  2873. MemoryRegion->PfnBase = Descriptor->BasePage;
  2874. MemoryRegion->PfnCount = Descriptor->PageCount;
  2875. MemoryRegion->Next = HalpSpecialRegions;
  2876. HalpSpecialRegions = MemoryRegion;
  2877. Descriptor->MemoryType = LoaderFree;
  2878. }
  2879. NextMd = NextMd->Flink;
  2880. }
  2881. return;
  2882. #endif // 0
  2883. }
  2884. BOOLEAN
  2885. HalpAnySpecialMemory(
  2886. IN PMDL Mdl,
  2887. IN ULONG Length,
  2888. IN ULONG Offset
  2889. )
  2890. /*++
  2891. Routine Description:
  2892. This function checks an MDL to see if any pages contained in the MDL
  2893. are from 'special memory'.
  2894. Arguments:
  2895. Mdl - pointer to an MDL.
  2896. Length - length of requested transfer.
  2897. Offset - offset of first byte within the first page for this transfer.
  2898. Return Value:
  2899. Reutrns TRUE if any of the pages in the MDL are in 'special memory',
  2900. otherwise returns FALSE.
  2901. --*/
  2902. {
  2903. ULONG i;
  2904. PULONG pageFrame;
  2905. ULONG numRegs;
  2906. pageFrame = (PULONG)(Mdl + 1);
  2907. // Calculate number of PFNs to scan
  2908. numRegs = (Length + Offset - 1) >> PAGE_SHIFT;
  2909. for ( i = 0; i <= numRegs; i++ ) {
  2910. if ( HalpSpecialMemory(*pageFrame) ) {
  2911. return TRUE;
  2912. }
  2913. pageFrame++;
  2914. }
  2915. return FALSE;
  2916. }
  2917. VOID
  2918. HalpRegisterInternalBusHandlers (
  2919. VOID
  2920. )
  2921. /*++
  2922. Routine Description:
  2923. This function registers the bushandlers for buses on the system
  2924. that will always be present on the system.
  2925. Arguments:
  2926. None.
  2927. Return Value:
  2928. None.
  2929. --*/
  2930. {
  2931. PBUS_HANDLER Bus;
  2932. //
  2933. // Initalize BusHandler data before registering any handlers
  2934. //
  2935. HalpInitBusHandler ();
  2936. //
  2937. // Build the processor internal bus 0
  2938. //
  2939. HaliRegisterBusHandler (ProcessorInternal, // Bus Type
  2940. -1, // No config space
  2941. 0, // Bus Number
  2942. -1, // No parent bus type
  2943. 0, // No parent bus number
  2944. 0, // No extension data
  2945. NULL, // No install handler
  2946. &Bus); // Bushandler return
  2947. Bus->GetInterruptVector = HalpGetSystemInterruptVector;
  2948. //
  2949. // Build internal-bus 0, or system level bus
  2950. //
  2951. HaliRegisterBusHandler (Internal, // Bus Type
  2952. -1, // No config space
  2953. 0, // Bus Number
  2954. -1, // No parent bus type
  2955. 0, // No parent bus number
  2956. 0, // No extension data
  2957. NULL, // No install handler
  2958. &Bus); // Bushandler return
  2959. Bus->GetInterruptVector = HalpGetSystemInterruptVector;
  2960. Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
  2961. //
  2962. // Build Isa/Eisa bus #0
  2963. //
  2964. HaliRegisterBusHandler (Eisa, // Bus Type
  2965. EisaConfiguration, // Config space type
  2966. 0, // Internal bus #0
  2967. Internal, // Parent bus type
  2968. 0, // Parent bus number
  2969. 0, // No extension data
  2970. NULL, // No install handler
  2971. &Bus); // Bushandler return
  2972. Bus->GetBusData = HalpGetEisaData;
  2973. Bus->AdjustResourceList = HalpAdjustEisaResourceList;
  2974. HaliRegisterBusHandler (Isa, // Bus Type
  2975. -1, // No config space
  2976. 0, // Internal bus #0
  2977. Eisa, // Parent bus type
  2978. 0, // Parent bus number
  2979. 0, // No extension data
  2980. NULL, // No install handler
  2981. &Bus); // Bushandler returne
  2982. Bus->GetBusData = HalpNoBusData;
  2983. Bus->AdjustResourceList = HalpAdjustIsaResourceList;
  2984. }
  2985. NTSTATUS
  2986. HalpAdjustIsaResourceList (
  2987. IN PBUS_HANDLER BusHandler,
  2988. IN PBUS_HANDLER RootHandler,
  2989. IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
  2990. )
  2991. /*++
  2992. Routine Description:
  2993. Takes the pResourceList and limits any requested resource to
  2994. it's corrisponding bus requirements.
  2995. Arguments:
  2996. BusHandler - Registered BUSHANDLER for the target configuration space
  2997. RootHandler - Register BUSHANDLER for the orginating HalAdjustResourceList request.
  2998. pResourceList - The resource list to adjust.
  2999. Return Value:
  3000. STATUS_SUCCESS or error
  3001. --*/
  3002. {
  3003. //
  3004. // BUGBUG: This function should verify that the resoruces fit
  3005. // the bus requirements - for now we will assume that the bus
  3006. // can support anything the device may ask for.
  3007. //
  3008. return STATUS_SUCCESS;
  3009. }
  3010. NTSTATUS
  3011. HalpAdjustEisaResourceList (
  3012. IN PBUS_HANDLER BusHandler,
  3013. IN PBUS_HANDLER RootHandler,
  3014. IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
  3015. )
  3016. /*++
  3017. Routine Description:
  3018. Takes the pResourceList and limits any requested resource to
  3019. it's corrisponding bus requirements.
  3020. Arguments:
  3021. BusHandler - Registered BUSHANDLER for the target configuration space
  3022. RootHandler - Register BUSHANDLER for the orginating HalAdjustResourceList request.
  3023. pResourceList - The resource list to adjust.
  3024. Return Value:
  3025. STATUS_SUCCESS or error
  3026. --*/
  3027. {
  3028. //
  3029. // BUGBUG: This function should verify that the resoruces fit
  3030. // the bus requirements - for now we will assume that the bus
  3031. // can support anything the device may ask for.
  3032. //
  3033. return STATUS_SUCCESS;
  3034. }
  3035. #endif