Leaked source code of windows server 2003
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.

2635 lines
74 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. ixhwsup.c
  5. Abstract:
  6. This module contains the IoXxx routines for the NT I/O system that
  7. are hardware dependent. Were these routines not hardware dependent,
  8. they would reside in the iosubs.c module.
  9. Author:
  10. Darryl E. Havens (darrylh) 11-Apr-1990
  11. Environment:
  12. Kernel mode
  13. Revision History:
  14. --*/
  15. #include "halp.h"
  16. #include "eisa.h"
  17. #include "pci.h"
  18. #include "pcip.h"
  19. //
  20. //Only take the prototype, don't instantiate
  21. //
  22. #include <wdmguid.h>
  23. #include "halpnpp.h"
  24. #ifdef ALLOC_PRAGMA
  25. #pragma alloc_text(PAGE,HalGetAdapter)
  26. #pragma alloc_text(PAGE,HalpGetIsaIrqState)
  27. #endif
  28. //
  29. // The HalpNewAdapter event is used to serialize allocations
  30. // of new adapter objects, additions to the HalpEisaAdapter
  31. // array, and some global values (MasterAdapterObject) and some
  32. // adapter fields modified by HalpGrowMapBuffers.
  33. // (AdapterObject->NumberOfMapRegisters is assumed not to be
  34. // growable while this even is held)
  35. //
  36. // Note: We don't really need our own an event object for this.
  37. //
  38. #ifndef ACPI_HAL
  39. #define HalpNewAdapter HalpBusDatabaseEvent
  40. extern KEVENT HalpNewAdapter;
  41. #else
  42. KEVENT HalpNewAdapter;
  43. //
  44. //F-Type DMA interface globals
  45. //
  46. ISA_FTYPE_DMA_INTERFACE HalpFDMAInterface;
  47. ULONG HalpFDMAAvail=FALSE;
  48. ULONG HalpFDMAChecked=FALSE;
  49. #endif
  50. #define ACQUIRE_NEW_ADAPTER_LOCK() \
  51. { \
  52. KeWaitForSingleObject ( \
  53. &HalpNewAdapter, \
  54. WrExecutive, \
  55. KernelMode, \
  56. FALSE, \
  57. NULL \
  58. ); \
  59. }
  60. #define RELEASE_NEW_ADAPTER_LOCK() \
  61. KeSetEvent (&HalpNewAdapter, 0, FALSE)
  62. PVOID HalpEisaControlBase = 0;
  63. extern KSPIN_LOCK HalpSystemHardwareLock;
  64. //
  65. // Define save area for EISA adapter objects.
  66. //
  67. PADAPTER_OBJECT HalpEisaAdapter[8];
  68. //
  69. // DMA channel control values
  70. // Global, so zero initialized by the compiler.
  71. //
  72. DMA_CHANNEL_CONTEXT HalpDmaChannelState [EISA_DMA_CHANNELS] ;
  73. extern USHORT HalpEisaIrqMask;
  74. //
  75. // Keep a list of all the dma adapters for debugging purposes
  76. //
  77. LIST_ENTRY HalpDmaAdapterList;
  78. KSPIN_LOCK HalpDmaAdapterListLock;
  79. VOID
  80. HalpCopyBufferMap(
  81. IN PMDL Mdl,
  82. IN PTRANSLATION_ENTRY TranslationEntry,
  83. IN PVOID CurrentVa,
  84. IN ULONG Length,
  85. IN BOOLEAN WriteToDevice
  86. );
  87. PHYSICAL_ADDRESS
  88. HalpMapTransfer(
  89. IN PADAPTER_OBJECT AdapterObject,
  90. IN PMDL Mdl,
  91. IN PVOID MapRegisterBase,
  92. IN PVOID CurrentVa,
  93. IN OUT PULONG Length,
  94. IN BOOLEAN WriteToDevice
  95. );
  96. VOID
  97. HalpMapTransferHelper(
  98. IN PMDL Mdl,
  99. IN PVOID CurrentVa,
  100. IN ULONG TransferLength,
  101. IN PPFN_NUMBER PageFrame,
  102. IN OUT PULONG Length
  103. );
  104. NTSTATUS
  105. HalAllocateAdapterChannel(
  106. IN PADAPTER_OBJECT AdapterObject,
  107. IN PWAIT_CONTEXT_BLOCK Wcb,
  108. IN ULONG NumberOfMapRegisters,
  109. IN PDRIVER_CONTROL ExecutionRoutine
  110. )
  111. /*++
  112. Routine Description:
  113. This routine allocates the adapter channel specified by the adapter object.
  114. This is accomplished by placing the device object of the driver that wants
  115. to allocate the adapter on the adapter's queue. If the queue is already
  116. "busy", then the adapter has already been allocated, so the device object
  117. is simply placed onto the queue and waits until the adapter becomes free.
  118. Once the adapter becomes free (or if it already is), then the driver's
  119. execution routine is invoked.
  120. Also, a number of map registers may be allocated to the driver by specifying
  121. a non-zero value for NumberOfMapRegisters. Then the map register must be
  122. allocated from the master adapter. Once there are a sufficient number of
  123. map registers available, then the execution routine is called and the
  124. base address of the allocated map registers in the adapter is also passed
  125. to the driver's execution routine.
  126. Arguments:
  127. AdapterObject - Pointer to the adapter control object to allocate to the
  128. driver.
  129. Wcb - Supplies a wait context block for saving the allocation parameters.
  130. The DeviceObject, CurrentIrp and DeviceContext should be initalized.
  131. NumberOfMapRegisters - The number of map registers that are to be allocated
  132. from the channel, if any.
  133. ExecutionRoutine - The address of the driver's execution routine that is
  134. invoked once the adapter channel (and possibly map registers) have been
  135. allocated.
  136. Return Value:
  137. Returns STATUS_SUCESS unless too many map registers are requested.
  138. Notes:
  139. Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
  140. --*/
  141. {
  142. PADAPTER_OBJECT MasterAdapter;
  143. BOOLEAN Busy = FALSE;
  144. IO_ALLOCATION_ACTION Action;
  145. KIRQL Irql;
  146. ULONG MapRegisterNumber;
  147. //
  148. // Begin by obtaining a pointer to the master adapter associated with this
  149. // request.
  150. //
  151. MasterAdapter = AdapterObject->MasterAdapter;
  152. //
  153. // Initialize the device object's wait context block in case this device
  154. // must wait before being able to allocate the adapter.
  155. //
  156. Wcb->DeviceRoutine = ExecutionRoutine;
  157. Wcb->NumberOfMapRegisters = NumberOfMapRegisters;
  158. //
  159. // Allocate the adapter object for this particular device. If the
  160. // adapter cannot be allocated because it has already been allocated
  161. // to another device, then return to the caller now; otherwise,
  162. // continue.
  163. //
  164. if (!KeInsertDeviceQueue( &AdapterObject->ChannelWaitQueue,
  165. &Wcb->WaitQueueEntry )) {
  166. //
  167. // Save the parameters in case there are not enough map registers.
  168. //
  169. AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
  170. AdapterObject->CurrentWcb = Wcb;
  171. //
  172. // The adapter was not busy so it has been allocated. Now check
  173. // to see whether this driver wishes to allocate any map registers.
  174. // Ensure that this adapter has enough total map registers
  175. // to satisfy the request.
  176. //
  177. if (NumberOfMapRegisters != 0 && AdapterObject->NeedsMapRegisters) {
  178. //
  179. // Lock the map register bit map and the adapter queue in the
  180. // master adapter object. The channel structure offset is used as
  181. // a hint for the register search.
  182. //
  183. if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) {
  184. AdapterObject->NumberOfMapRegisters = 0;
  185. IoFreeAdapterChannel(AdapterObject);
  186. return (STATUS_INSUFFICIENT_RESOURCES);
  187. }
  188. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  189. MapRegisterNumber = (ULONG)-1;
  190. if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
  191. MapRegisterNumber = RtlFindClearBitsAndSet(
  192. MasterAdapter->MapRegisters,
  193. NumberOfMapRegisters,
  194. 0
  195. );
  196. }
  197. if (MapRegisterNumber == -1) {
  198. PBUFFER_GROW_WORK_ITEM bufferWorkItem;
  199. //
  200. // There were not enough free map registers. Queue this request
  201. // on the master adapter where is will wait until some registers
  202. // are deallocated.
  203. //
  204. InsertTailList( &MasterAdapter->AdapterQueue,
  205. &AdapterObject->AdapterQueue
  206. );
  207. Busy = 1;
  208. //
  209. // Queue a work item to grow the map registers
  210. //
  211. bufferWorkItem =
  212. ExAllocatePoolWithTag( NonPagedPool,
  213. sizeof(BUFFER_GROW_WORK_ITEM),
  214. HAL_POOL_TAG);
  215. if (bufferWorkItem != NULL) {
  216. ExInitializeWorkItem( &bufferWorkItem->WorkItem,
  217. HalpGrowMapBufferWorker,
  218. bufferWorkItem );
  219. bufferWorkItem->AdapterObject = AdapterObject;
  220. bufferWorkItem->MapRegisterCount = NumberOfMapRegisters;
  221. ExQueueWorkItem( &bufferWorkItem->WorkItem,
  222. DelayedWorkQueue );
  223. }
  224. } else {
  225. //
  226. // Calculate the map register base from the allocated map
  227. // register and base of the master adapter object.
  228. //
  229. AdapterObject->MapRegisterBase = ((PTRANSLATION_ENTRY)
  230. MasterAdapter->MapRegisterBase + MapRegisterNumber);
  231. //
  232. // Set the no scatter/gather flag if scatter/gather not
  233. // supported.
  234. //
  235. if (!AdapterObject->ScatterGather) {
  236. AdapterObject->MapRegisterBase = (PVOID)
  237. ((ULONG_PTR) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);
  238. }
  239. }
  240. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  241. } else {
  242. AdapterObject->MapRegisterBase = NULL;
  243. AdapterObject->NumberOfMapRegisters = 0;
  244. }
  245. //
  246. // If there were either enough map registers available or no map
  247. // registers needed to be allocated, invoke the driver's execution
  248. // routine now.
  249. //
  250. if (!Busy) {
  251. AdapterObject->CurrentWcb = Wcb;
  252. Action = ExecutionRoutine( Wcb->DeviceObject,
  253. Wcb->CurrentIrp,
  254. AdapterObject->MapRegisterBase,
  255. Wcb->DeviceContext );
  256. //
  257. // If the driver would like to have the adapter deallocated,
  258. // then release the adapter object.
  259. //
  260. if (Action == DeallocateObject) {
  261. IoFreeAdapterChannel( AdapterObject );
  262. } else if (Action == DeallocateObjectKeepRegisters) {
  263. //
  264. // Set the NumberOfMapRegisters = 0 in the adapter object.
  265. // This will keep IoFreeAdapterChannel from freeing the
  266. // registers. After this it is the driver's responsiblity to
  267. // keep track of the number of map registers.
  268. //
  269. AdapterObject->NumberOfMapRegisters = 0;
  270. IoFreeAdapterChannel(AdapterObject);
  271. }
  272. }
  273. }
  274. return (STATUS_SUCCESS);
  275. }
  276. #if defined(_WIN64)
  277. NTSTATUS
  278. HalRealAllocateAdapterChannel(
  279. IN PADAPTER_OBJECT AdapterObject,
  280. IN PDEVICE_OBJECT DeviceObject,
  281. IN ULONG NumberOfMapRegisters,
  282. IN PDRIVER_CONTROL ExecutionRoutine,
  283. IN PVOID Context
  284. )
  285. /*++
  286. Routine Description:
  287. This routine allocates the adapter channel specified by the adapter object.
  288. This is accomplished by calling HalAllocateAdapterChannel which does all of
  289. the work.
  290. Arguments:
  291. AdapterObject - Pointer to the adapter control object to allocate to the
  292. driver.
  293. DeviceObject - Pointer to the driver's device object that represents the
  294. device allocating the adapter.
  295. NumberOfMapRegisters - The number of map registers that are to be allocated
  296. from the channel, if any.
  297. ExecutionRoutine - The address of the driver's execution routine that is
  298. invoked once the adapter channel (and possibly map registers) have been
  299. allocated.
  300. Context - An untyped longword context parameter passed to the driver's
  301. execution routine.
  302. Return Value:
  303. Returns STATUS_SUCESS unless too many map registers are requested.
  304. Notes:
  305. Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
  306. --*/
  307. {
  308. PWAIT_CONTEXT_BLOCK wcb;
  309. wcb = &DeviceObject->Queue.Wcb;
  310. wcb->DeviceObject = DeviceObject;
  311. wcb->CurrentIrp = DeviceObject->CurrentIrp;
  312. wcb->DeviceContext = Context;
  313. return( HalAllocateAdapterChannel( AdapterObject,
  314. wcb,
  315. NumberOfMapRegisters,
  316. ExecutionRoutine ) );
  317. }
  318. #endif
  319. VOID
  320. HalpGrowMapBufferWorker(
  321. IN PVOID Context
  322. )
  323. /*++
  324. Routine Description:
  325. This routine is called in the context of a work item from
  326. HalAllocateAdapterChannel() when it queues a map register allocation
  327. because map regiers are not available.
  328. Its purpose is to attempt to grow the map buffers for the adapter and,
  329. if successful, process queued adapter allocations.
  330. Arguments:
  331. Context - Actually a pointer to a BUFFER_GROW_WORK_ITEM structure.
  332. Return Value:
  333. None.
  334. --*/
  335. {
  336. PBUFFER_GROW_WORK_ITEM growWorkItem;
  337. PADAPTER_OBJECT masterAdapter;
  338. BOOLEAN allocated;
  339. ULONG bytesToGrow;
  340. KIRQL oldIrql;
  341. growWorkItem = (PBUFFER_GROW_WORK_ITEM)Context;
  342. masterAdapter = growWorkItem->AdapterObject->MasterAdapter;
  343. //
  344. // HalpGrowMapBuffers() takes a byte count
  345. //
  346. bytesToGrow = growWorkItem->MapRegisterCount * PAGE_SIZE +
  347. INCREMENT_MAP_BUFFER_SIZE;
  348. ACQUIRE_NEW_ADAPTER_LOCK();
  349. allocated = HalpGrowMapBuffers( masterAdapter,
  350. bytesToGrow );
  351. RELEASE_NEW_ADAPTER_LOCK();
  352. if (allocated != FALSE) {
  353. KeRaiseIrql( DISPATCH_LEVEL, &oldIrql );
  354. //
  355. // The map buffers were grown. It is likely that someone is waiting
  356. // in the adapter queue, so try to get things started.
  357. //
  358. // The code in IoFreeMapRegisters() does this, and it turns out
  359. // we can safely get it to do this work for us by freeing 0
  360. // map registers at a bogus (but non-NULL) register base.
  361. //
  362. IoFreeMapRegisters( growWorkItem->AdapterObject,
  363. (PVOID)2,
  364. 0 );
  365. KeLowerIrql( oldIrql );
  366. }
  367. ExFreePool( growWorkItem );
  368. }
  369. PVOID
  370. HalAllocateCrashDumpRegisters(
  371. IN PADAPTER_OBJECT AdapterObject,
  372. IN PULONG NumberOfMapRegisters
  373. )
  374. /*++
  375. Routine Description:
  376. This routine is called during the crash dump disk driver's initialization
  377. to allocate a number map registers permanently.
  378. Arguments:
  379. AdapterObject - Pointer to the adapter control object to allocate to the
  380. driver.
  381. NumberOfMapRegisters - Number of map registers requested. This field
  382. will be updated to reflect the actual number of registers allocated
  383. when the number is less than what was requested.
  384. Return Value:
  385. Returns STATUS_SUCESS if map registers allocated.
  386. --*/
  387. {
  388. PADAPTER_OBJECT MasterAdapter;
  389. ULONG MapRegisterNumber;
  390. //
  391. // Begin by obtaining a pointer to the master adapter associated with this
  392. // request.
  393. //
  394. MasterAdapter = AdapterObject->MasterAdapter;
  395. //
  396. // Check to see whether this driver needs to allocate any map registers.
  397. //
  398. if (AdapterObject->NeedsMapRegisters) {
  399. //
  400. // Ensure that this adapter has enough total map registers to satisfy
  401. // the request.
  402. //
  403. if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) {
  404. AdapterObject->NumberOfMapRegisters = 0;
  405. return NULL;
  406. }
  407. //
  408. // Attempt to allocate the required number of map registers w/o
  409. // affecting those registers that were allocated when the system
  410. // crashed.
  411. //
  412. MapRegisterNumber = (ULONG)-1;
  413. MapRegisterNumber = RtlFindClearBitsAndSet(
  414. MasterAdapter->MapRegisters,
  415. *NumberOfMapRegisters,
  416. 0
  417. );
  418. if (MapRegisterNumber == (ULONG)-1) {
  419. //
  420. // Not enough free map registers were found, so they were busy
  421. // being used by the system when it crashed. Force the appropriate
  422. // number to be "allocated" at the base by simply overjamming the
  423. // bits and return the base map register as the start.
  424. //
  425. RtlSetBits(
  426. MasterAdapter->MapRegisters,
  427. 0,
  428. *NumberOfMapRegisters
  429. );
  430. MapRegisterNumber = 0;
  431. }
  432. //
  433. // Calculate the map register base from the allocated map
  434. // register and base of the master adapter object.
  435. //
  436. AdapterObject->MapRegisterBase = ((PTRANSLATION_ENTRY)
  437. MasterAdapter->MapRegisterBase + MapRegisterNumber);
  438. //
  439. // Set the no scatter/gather flag if scatter/gather not
  440. // supported.
  441. //
  442. if (!AdapterObject->ScatterGather) {
  443. AdapterObject->MapRegisterBase = (PVOID)
  444. ((ULONG_PTR) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);
  445. }
  446. } else {
  447. AdapterObject->MapRegisterBase = NULL;
  448. AdapterObject->NumberOfMapRegisters = 0;
  449. }
  450. return AdapterObject->MapRegisterBase;
  451. }
  452. #ifdef ACPI_HAL
  453. NTSTATUS
  454. HalpFDMANotificationCallback(
  455. IN PVOID NotificationStructure,
  456. IN PVOID Context
  457. )
  458. {
  459. PAGED_CODE();
  460. //
  461. // Something is happening to the ISA bus that we've registered on.
  462. //
  463. if (IsEqualGUID (&((PTARGET_DEVICE_REMOVAL_NOTIFICATION)NotificationStructure)->Event,
  464. &GUID_TARGET_DEVICE_QUERY_REMOVE)) {
  465. //
  466. // It's a query remove, just get out.
  467. // dereference the interface, and clean up our internal data
  468. //
  469. ACQUIRE_NEW_ADAPTER_LOCK();
  470. HalpFDMAInterface.InterfaceDereference(HalpFDMAInterface.Context);
  471. HalpFDMAAvail=FALSE;
  472. //
  473. // Set checked to false, so that if a new bus arrives we can begin anew.
  474. //
  475. HalpFDMAChecked=FALSE;
  476. RELEASE_NEW_ADAPTER_LOCK();
  477. }
  478. return STATUS_SUCCESS;
  479. }
  480. #endif
  481. VOID
  482. HalpAddAdapterToList(
  483. IN PADAPTER_OBJECT AdapterObject
  484. )
  485. /*++
  486. Routine Description:
  487. Adds the adapter object to the HalpDmaAdapterList. This is a separate
  488. function because HalGetAdapter is paged code and cannot acquire a spinlock.
  489. Arguments:
  490. AdapterObject - Supplies the adapter object to be added to HalpDmaAdapterList
  491. Return Value:
  492. None
  493. --*/
  494. {
  495. KIRQL Irql;
  496. KeAcquireSpinLock(&HalpDmaAdapterListLock,&Irql);
  497. InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
  498. KeReleaseSpinLock(&HalpDmaAdapterListLock, Irql);
  499. }
  500. PADAPTER_OBJECT
  501. HalGetAdapter(
  502. IN PDEVICE_DESCRIPTION DeviceDescriptor,
  503. OUT PULONG NumberOfMapRegisters
  504. )
  505. /*++
  506. Routine Description:
  507. This function returns the appropriate adapter object for the device defined
  508. in the device description structure. This code works for Isa and Eisa
  509. systems.
  510. Arguments:
  511. DeviceDescriptor - Supplies a description of the deivce.
  512. NumberOfMapRegisters - Returns the maximum number of map registers which
  513. may be allocated by the device driver.
  514. Return Value:
  515. A pointer to the requested adapter object or NULL if an adapter could not
  516. be created.
  517. --*/
  518. {
  519. PADAPTER_OBJECT adapterObject;
  520. PVOID adapterBaseVa;
  521. ULONG channelNumber;
  522. ULONG controllerNumber;
  523. DMA_EXTENDED_MODE extendedMode;
  524. UCHAR adapterMode;
  525. ULONG numberOfMapRegisters;
  526. BOOLEAN useChannel;
  527. ULONG maximumLength;
  528. UCHAR DataByte;
  529. BOOLEAN dma32Bit;
  530. BOOLEAN ChannelEnabled;
  531. KIRQL Irql;
  532. #ifdef ACPI_HAL
  533. NTSTATUS Status;
  534. #endif
  535. PAGED_CODE();
  536. //
  537. // Make sure this is the correct version.
  538. //
  539. if (DeviceDescriptor->Version > DEVICE_DESCRIPTION_VERSION2) {
  540. return ( NULL );
  541. }
  542. #if DBG
  543. if (DeviceDescriptor->Version == DEVICE_DESCRIPTION_VERSION1) {
  544. ASSERT (DeviceDescriptor->Reserved1 == FALSE);
  545. }
  546. #endif
  547. *((PUCHAR) &extendedMode) = 0;
  548. //
  549. // Determine if the the channel number is important. Master cards on
  550. // Eisa and Mca do not use a channel number.
  551. //
  552. if (DeviceDescriptor->InterfaceType != Isa &&
  553. DeviceDescriptor->Master) {
  554. useChannel = FALSE;
  555. } else {
  556. useChannel = TRUE;
  557. }
  558. // Support for ISA local bus machines:
  559. // If the driver is a Master but really does not want a channel since it
  560. // is using the local bus DMA, just don't use an ISA channel.
  561. //
  562. if (DeviceDescriptor->InterfaceType == Isa &&
  563. DeviceDescriptor->DmaChannel > 7) {
  564. useChannel = FALSE;
  565. }
  566. //
  567. // Determine if Eisa DMA is supported.
  568. //
  569. if (HalpBusType == MACHINE_TYPE_EISA) {
  570. WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort.Channel2, 0x55);
  571. DataByte = READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort.Channel2);
  572. if (DataByte == 0x55) {
  573. HalpEisaDma = TRUE;
  574. }
  575. }
  576. //
  577. // Limit the maximum length to 2 GB this is done so that the BYTES_TO_PAGES
  578. // macro works correctly.
  579. //
  580. maximumLength = DeviceDescriptor->MaximumLength & 0x7fffffff;
  581. //
  582. // Channel 4 cannot be used since it is used for chaining. Return null if
  583. // it is requested.
  584. //
  585. if (DeviceDescriptor->DmaChannel == 4 && useChannel) {
  586. return (NULL);
  587. }
  588. if (DeviceDescriptor->InterfaceType == PCIBus &&
  589. DeviceDescriptor->Master != FALSE &&
  590. DeviceDescriptor->ScatterGather != FALSE) {
  591. //
  592. // This device can handle 32 bits, even if the caller forgot to
  593. // set Dma32BitAddresses.
  594. //
  595. DeviceDescriptor->Dma32BitAddresses = TRUE;
  596. }
  597. dma32Bit = DeviceDescriptor->Dma32BitAddresses;
  598. //
  599. // Determine the number of map registers for this device.
  600. //
  601. if (DeviceDescriptor->ScatterGather &&
  602. //
  603. // If we are not in PAE mode or the device can handle 64 bit addresses,
  604. // then the device can DMA to any physical location
  605. //
  606. (HalPaeEnabled() == FALSE ||
  607. DeviceDescriptor->Dma64BitAddresses != FALSE) &&
  608. (LessThan16Mb ||
  609. DeviceDescriptor->InterfaceType == Eisa ||
  610. DeviceDescriptor->InterfaceType == PCIBus) ) {
  611. //
  612. // Since the device support scatter/Gather then map registers are not
  613. // required.
  614. //
  615. numberOfMapRegisters = 0;
  616. } else {
  617. ULONG maximumMapRegisters;
  618. ULONG mapBufferSize;
  619. maximumMapRegisters = HalpMaximumMapRegisters( dma32Bit );
  620. //
  621. // Determine the number of map registers required based on the maximum
  622. // transfer length, up to a maximum number.
  623. //
  624. numberOfMapRegisters = BYTES_TO_PAGES(maximumLength) + 1;
  625. if (numberOfMapRegisters > maximumMapRegisters) {
  626. numberOfMapRegisters = maximumMapRegisters;
  627. }
  628. //
  629. // Make sure there where enough registers allocated initalize to support
  630. // this size relaibly. This implies there must be to chunks equal to
  631. // the allocatd size. This is only a problem on Isa systems where the
  632. // map buffers cannot cross 64KB boundtires.
  633. //
  634. mapBufferSize = HalpMapBufferSize( dma32Bit );
  635. if (!HalpEisaDma &&
  636. numberOfMapRegisters > mapBufferSize / (PAGE_SIZE * 2)) {
  637. numberOfMapRegisters = (mapBufferSize / (PAGE_SIZE * 2));
  638. }
  639. //
  640. // If the device is not a master then it only needs one map register
  641. // and does scatter/Gather.
  642. //
  643. if (DeviceDescriptor->ScatterGather && !DeviceDescriptor->Master) {
  644. numberOfMapRegisters = 1;
  645. }
  646. }
  647. //
  648. // Set the channel number number.
  649. //
  650. if (useChannel != FALSE) {
  651. channelNumber = DeviceDescriptor->DmaChannel & 0x03;
  652. //
  653. // Set the adapter base address to the Base address register and
  654. // controller number.
  655. //
  656. if (!(DeviceDescriptor->DmaChannel & 0x04)) {
  657. controllerNumber = 1;
  658. adapterBaseVa =
  659. (PVOID) &((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort;
  660. } else {
  661. controllerNumber = 2;
  662. adapterBaseVa =
  663. &((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort;
  664. }
  665. } else {
  666. adapterBaseVa = NULL;
  667. }
  668. //
  669. // Determine if a new adapter object is necessary. If so then allocate it.
  670. //
  671. if (useChannel && HalpEisaAdapter[DeviceDescriptor->DmaChannel] != NULL) {
  672. adapterObject = HalpEisaAdapter[DeviceDescriptor->DmaChannel];
  673. if (adapterObject->NeedsMapRegisters) {
  674. if (numberOfMapRegisters > adapterObject->MapRegistersPerChannel) {
  675. adapterObject->MapRegistersPerChannel = numberOfMapRegisters;
  676. }
  677. }
  678. } else {
  679. //
  680. // Serialize before allocating a new adapter
  681. //
  682. ACQUIRE_NEW_ADAPTER_LOCK();
  683. //
  684. // Determine if a new adapter object has already been allocated.
  685. // If so use it, otherwise allocate a new adapter object
  686. //
  687. if (useChannel && HalpEisaAdapter[DeviceDescriptor->DmaChannel] != NULL) {
  688. adapterObject = HalpEisaAdapter[DeviceDescriptor->DmaChannel];
  689. if (adapterObject->NeedsMapRegisters) {
  690. if (numberOfMapRegisters > adapterObject->MapRegistersPerChannel) {
  691. adapterObject->MapRegistersPerChannel = numberOfMapRegisters;
  692. }
  693. }
  694. } else {
  695. //
  696. // Allocate an adapter object.
  697. //
  698. adapterObject =
  699. (PADAPTER_OBJECT) HalpAllocateAdapterEx( numberOfMapRegisters,
  700. adapterBaseVa,
  701. NULL,
  702. dma32Bit );
  703. if (adapterObject == NULL) {
  704. RELEASE_NEW_ADAPTER_LOCK();
  705. return (NULL);
  706. }
  707. if (useChannel) {
  708. HalpEisaAdapter[DeviceDescriptor->DmaChannel] = adapterObject;
  709. }
  710. //
  711. // Set the maximum number of map registers for this channel bus on
  712. // the number requested and the type of device.
  713. //
  714. if (numberOfMapRegisters) {
  715. PADAPTER_OBJECT masterAdapterObject;
  716. masterAdapterObject =
  717. HalpMasterAdapter( dma32Bit );
  718. //
  719. // The speicified number of registers are actually allowed to be
  720. // allocated.
  721. //
  722. adapterObject->MapRegistersPerChannel = numberOfMapRegisters;
  723. //
  724. // Increase the commitment for the map registers.
  725. //
  726. if (DeviceDescriptor->Master) {
  727. //
  728. // Master I/O devices use several sets of map registers double
  729. // their commitment.
  730. //
  731. masterAdapterObject->CommittedMapRegisters +=
  732. numberOfMapRegisters * 2;
  733. } else {
  734. masterAdapterObject->CommittedMapRegisters +=
  735. numberOfMapRegisters;
  736. }
  737. //
  738. // If the committed map registers is signicantly greater than the
  739. // number allocated then grow the map buffer.
  740. //
  741. if (masterAdapterObject->CommittedMapRegisters >
  742. masterAdapterObject->NumberOfMapRegisters ) {
  743. HalpGrowMapBuffers(
  744. masterAdapterObject,
  745. INCREMENT_MAP_BUFFER_SIZE
  746. );
  747. }
  748. adapterObject->NeedsMapRegisters = TRUE;
  749. } else {
  750. //
  751. // No real map registers were allocated. If this is a master
  752. // device, then the device can have as may registers as it wants.
  753. //
  754. adapterObject->NeedsMapRegisters = FALSE;
  755. if (DeviceDescriptor->Master) {
  756. adapterObject->MapRegistersPerChannel =
  757. BYTES_TO_PAGES( maximumLength ) + 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. RELEASE_NEW_ADAPTER_LOCK();
  768. }
  769. adapterObject->IgnoreCount = FALSE;
  770. if (DeviceDescriptor->Version >= DEVICE_DESCRIPTION_VERSION1) {
  771. //
  772. // Move version 1 structure flags.
  773. // IgnoreCount is used on machines where the DMA Counter
  774. // is broken. (Namely PS/1 model 1000s). Setting this
  775. // bit informs the hal not to rely on the DmaCount to determine
  776. // how much data was DMAed.
  777. //
  778. adapterObject->IgnoreCount = DeviceDescriptor->IgnoreCount;
  779. }
  780. adapterObject->Dma32BitAddresses = DeviceDescriptor->Dma32BitAddresses;
  781. adapterObject->Dma64BitAddresses = DeviceDescriptor->Dma64BitAddresses;
  782. adapterObject->ScatterGather = DeviceDescriptor->ScatterGather;
  783. *NumberOfMapRegisters = adapterObject->MapRegistersPerChannel;
  784. adapterObject->LegacyAdapter = (DeviceDescriptor->InterfaceType != PCIBus);
  785. if (DeviceDescriptor->Master) {
  786. adapterObject->MasterDevice = TRUE;
  787. } else {
  788. adapterObject->MasterDevice = FALSE;
  789. }
  790. //
  791. // If the channel number is not used then we are finished. The rest of
  792. // the work deals with channels.
  793. //
  794. if (!useChannel) {
  795. //
  796. // Add this adapter to our list
  797. //
  798. HalpAddAdapterToList(adapterObject);
  799. return (adapterObject);
  800. }
  801. //
  802. // Setup the pointers to all the random registers.
  803. //
  804. adapterObject->ChannelNumber = (UCHAR) channelNumber;
  805. if (controllerNumber == 1) {
  806. switch ((UCHAR)channelNumber) {
  807. case 0:
  808. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel0;
  809. break;
  810. case 1:
  811. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel1;
  812. break;
  813. case 2:
  814. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel2;
  815. break;
  816. case 3:
  817. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel3;
  818. break;
  819. }
  820. //
  821. // Set the adapter number.
  822. //
  823. adapterObject->AdapterNumber = 1;
  824. //
  825. // Save the extended mode register address.
  826. //
  827. adapterBaseVa =
  828. &((PEISA_CONTROL) HalpEisaControlBase)->Dma1ExtendedModePort;
  829. } else {
  830. switch (channelNumber) {
  831. case 1:
  832. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel5;
  833. break;
  834. case 2:
  835. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel6;
  836. break;
  837. case 3:
  838. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel7;
  839. break;
  840. }
  841. //
  842. // Set the adapter number.
  843. //
  844. adapterObject->AdapterNumber = 2;
  845. //
  846. // Save the extended mode register address.
  847. //
  848. adapterBaseVa =
  849. &((PEISA_CONTROL) HalpEisaControlBase)->Dma2ExtendedModePort;
  850. }
  851. adapterObject->Width16Bits = FALSE;
  852. #ifdef ACPI_HAL
  853. //
  854. //Keep this code here, because if we ever support dynamic ISA buses (ok, ok, stop laughing)
  855. //We'll want to be able to re-instantiate the interface to the ISAPNP driver for the new bus
  856. //
  857. //
  858. //Get the interface to the ISA bridge iff it supports an
  859. //interface to F-type DMA support
  860. //
  861. if (DeviceDescriptor->DmaSpeed == TypeF) {
  862. if (!HalpFDMAChecked) {
  863. PWSTR HalpFDMAInterfaceList;
  864. Status=IoGetDeviceInterfaces (&GUID_FDMA_INTERFACE_PRIVATE,NULL,0,&HalpFDMAInterfaceList);
  865. if (!NT_SUCCESS (Status)) {
  866. HalpFDMAAvail=FALSE;
  867. } else {
  868. if (HalpFDMAInterfaceList) {
  869. HalpFDMAAvail=TRUE;
  870. }
  871. }
  872. HalpFDMAChecked=TRUE;
  873. //
  874. // Motherboard devices TypeF dma support
  875. //
  876. if (HalpFDMAAvail) {
  877. PDEVICE_OBJECT HalpFDMADevObj;
  878. PFILE_OBJECT HalpFDMAFileObject;
  879. PIRP irp;
  880. KEVENT irpCompleted;
  881. IO_STATUS_BLOCK statusBlock;
  882. PIO_STACK_LOCATION irpStack;
  883. UNICODE_STRING localInterfaceName;
  884. //
  885. // Convert the symbolic link to an object reference
  886. //
  887. RtlInitUnicodeString (&localInterfaceName,HalpFDMAInterfaceList);
  888. Status = IoGetDeviceObjectPointer (&localInterfaceName,
  889. FILE_ALL_ACCESS,
  890. &HalpFDMAFileObject,
  891. &HalpFDMADevObj);
  892. ExFreePool (HalpFDMAInterfaceList);
  893. if (NT_SUCCESS (Status)) {
  894. PVOID HalpFDMANotificationHandle;
  895. //
  896. // Setup the IRP to get the interface
  897. //
  898. KeInitializeEvent(&irpCompleted, SynchronizationEvent, FALSE);
  899. irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
  900. HalpFDMADevObj,
  901. NULL, // Buffer
  902. 0, // Length
  903. 0, // StartingOffset
  904. &irpCompleted,
  905. &statusBlock
  906. );
  907. if (!irp) {
  908. HalpFDMAAvail=FALSE;
  909. goto noFtype;
  910. }
  911. irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  912. irp->IoStatus.Information = 0;
  913. //
  914. // Initialize the stack location
  915. //
  916. irpStack = IoGetNextIrpStackLocation(irp);
  917. ASSERT(irpStack->MajorFunction == IRP_MJ_PNP);
  918. irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
  919. irpStack->Parameters.QueryInterface.InterfaceType =
  920. &GUID_ISA_FDMA_INTERFACE;
  921. irpStack->Parameters.QueryInterface.Size =
  922. sizeof(ISA_FTYPE_DMA_INTERFACE);
  923. irpStack->Parameters.QueryInterface.Version = 1;
  924. irpStack->Parameters.QueryInterface.Interface =
  925. (PINTERFACE) &HalpFDMAInterface;
  926. //
  927. // Call the driver and wait for completion
  928. //
  929. Status = IoCallDriver(HalpFDMADevObj, irp);
  930. if (Status == STATUS_PENDING) {
  931. KeWaitForSingleObject(&irpCompleted,
  932. Executive,
  933. KernelMode,
  934. FALSE,
  935. NULL);
  936. Status = statusBlock.Status;
  937. }
  938. if (!NT_SUCCESS(Status)) {
  939. HalpFDMAAvail=FALSE;
  940. goto noFtype;
  941. }
  942. //
  943. // Now, register a callback so that the ISA bus can go
  944. // away.
  945. //
  946. IoRegisterPlugPlayNotification (EventCategoryTargetDeviceChange,
  947. 0,
  948. HalpFDMAFileObject,
  949. HalpFDMADevObj->DriverObject,
  950. HalpFDMANotificationCallback,
  951. 0,
  952. &HalpFDMANotificationHandle);
  953. //
  954. // Release the handle to the interface from IoGetDevicePointer
  955. //
  956. ObDereferenceObject (HalpFDMAFileObject);
  957. } else {
  958. HalpFDMAAvail=FALSE;
  959. }
  960. }
  961. }
  962. if (HalpFDMAAvail) {
  963. ULONG chMask;
  964. //
  965. // Fence this, so that no two people can ask for F-Type at once.
  966. //
  967. ACQUIRE_NEW_ADAPTER_LOCK();
  968. Status = HalpFDMAInterface.IsaSetFTypeChannel (HalpFDMAInterface.Context,DeviceDescriptor->DmaChannel,&chMask);
  969. RELEASE_NEW_ADAPTER_LOCK();
  970. #if DBG
  971. if (!(NT_SUCCESS (Status))) {
  972. DbgPrint ("HAL: Tried to get F-Type DMA for channel %d, "
  973. "but channel Mask %X already has it!\n",
  974. channelNumber,
  975. chMask);
  976. }
  977. #endif
  978. }
  979. }
  980. noFtype:
  981. #endif
  982. if (HalpEisaDma) {
  983. //
  984. // Initialzie the extended mode port.
  985. //
  986. extendedMode.ChannelNumber = (UCHAR)channelNumber;
  987. switch (DeviceDescriptor->DmaSpeed) {
  988. case Compatible:
  989. extendedMode.TimingMode = COMPATIBLITY_TIMING;
  990. break;
  991. case TypeA:
  992. extendedMode.TimingMode = TYPE_A_TIMING;
  993. break;
  994. case TypeB:
  995. extendedMode.TimingMode = TYPE_B_TIMING;
  996. break;
  997. case TypeC:
  998. extendedMode.TimingMode = BURST_TIMING;
  999. break;
  1000. case TypeF:
  1001. //
  1002. // DMA chip should be set to compatibility mode
  1003. // and the bridge handles type-f
  1004. //
  1005. extendedMode.TimingMode = COMPATIBLITY_TIMING;
  1006. break;
  1007. default:
  1008. ObDereferenceObject( adapterObject );
  1009. return (NULL);
  1010. }
  1011. switch (DeviceDescriptor->DmaWidth) {
  1012. case Width8Bits:
  1013. extendedMode.TransferSize = BY_BYTE_8_BITS;
  1014. break;
  1015. case Width16Bits:
  1016. extendedMode.TransferSize = BY_BYTE_16_BITS;
  1017. //
  1018. // Note Width16bits should not be set here because there is no need
  1019. // to shift the address and the transfer count.
  1020. //
  1021. break;
  1022. case Width32Bits:
  1023. extendedMode.TransferSize = BY_BYTE_32_BITS;
  1024. break;
  1025. default:
  1026. ObDereferenceObject( adapterObject );
  1027. return (NULL);
  1028. }
  1029. WRITE_PORT_UCHAR( adapterBaseVa, *((PUCHAR) &extendedMode));
  1030. } else if (!DeviceDescriptor->Master) {
  1031. switch (DeviceDescriptor->DmaWidth) {
  1032. case Width8Bits:
  1033. //
  1034. // The channel must use controller 1.
  1035. //
  1036. if (controllerNumber != 1) {
  1037. ObDereferenceObject( adapterObject );
  1038. return (NULL);
  1039. }
  1040. break;
  1041. case Width16Bits:
  1042. //
  1043. // The channel must use controller 2.
  1044. //
  1045. if (controllerNumber != 2) {
  1046. ObDereferenceObject( adapterObject );
  1047. return (NULL);
  1048. }
  1049. adapterObject->Width16Bits = TRUE;
  1050. break;
  1051. default:
  1052. ObDereferenceObject( adapterObject );
  1053. return (NULL);
  1054. }
  1055. }
  1056. //
  1057. // Initialize the adapter mode register value to the correct parameters,
  1058. // and save them in the adapter object.
  1059. //
  1060. ChannelEnabled = FALSE;
  1061. adapterMode = 0;
  1062. ((PDMA_EISA_MODE) &adapterMode)->Channel = adapterObject->ChannelNumber;
  1063. if (DeviceDescriptor->Master) {
  1064. ChannelEnabled = TRUE;
  1065. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = CASCADE_REQUEST_MODE;
  1066. //
  1067. // Set the mode, and enable the request.
  1068. //
  1069. if (adapterObject->AdapterNumber == 1) {
  1070. //
  1071. // This request is for DMA controller 1
  1072. //
  1073. PDMA1_CONTROL dmaControl;
  1074. dmaControl = adapterObject->AdapterBaseVa;
  1075. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  1076. //
  1077. // Unmask the DMA channel.
  1078. //
  1079. WRITE_PORT_UCHAR(
  1080. &dmaControl->SingleMask,
  1081. (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
  1082. );
  1083. } else {
  1084. //
  1085. // This request is for DMA controller 2
  1086. //
  1087. PDMA2_CONTROL dmaControl;
  1088. dmaControl = adapterObject->AdapterBaseVa;
  1089. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  1090. //
  1091. // Unmask the DMA channel.
  1092. //
  1093. WRITE_PORT_UCHAR(
  1094. &dmaControl->SingleMask,
  1095. (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
  1096. );
  1097. }
  1098. } else if (DeviceDescriptor->DemandMode) {
  1099. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = DEMAND_REQUEST_MODE;
  1100. } else {
  1101. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = SINGLE_REQUEST_MODE;
  1102. }
  1103. if (DeviceDescriptor->AutoInitialize) {
  1104. ((PDMA_EISA_MODE) &adapterMode)->AutoInitialize = 1;
  1105. }
  1106. adapterObject->AdapterMode = adapterMode;
  1107. //
  1108. // Store the value we wrote to the Mode and Mask registers so that we
  1109. // can restore it after the machine sleeps.
  1110. //
  1111. HalpDmaChannelState [adapterObject->ChannelNumber + ((adapterObject->AdapterNumber - 1) * 4)].ChannelMode =
  1112. adapterMode;
  1113. HalpDmaChannelState [adapterObject->ChannelNumber + ((adapterObject->AdapterNumber - 1) * 4)].ChannelExtendedMode =
  1114. *((PUCHAR)&extendedMode);
  1115. HalpDmaChannelState [adapterObject->ChannelNumber + ((adapterObject->AdapterNumber - 1) * 4)].ChannelMask = (ChannelEnabled) ?
  1116. (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber):
  1117. (UCHAR) (DMA_SETMASK | adapterObject->ChannelNumber);
  1118. HalpDmaChannelState [adapterObject->ChannelNumber + ((adapterObject->AdapterNumber - 1) * 4)].ChannelProgrammed = TRUE;
  1119. return (adapterObject);
  1120. }
  1121. PHYSICAL_ADDRESS
  1122. IoMapTransfer(
  1123. IN PADAPTER_OBJECT AdapterObject,
  1124. IN PMDL Mdl,
  1125. IN PVOID MapRegisterBase,
  1126. IN PVOID CurrentVa,
  1127. IN OUT PULONG Length,
  1128. IN BOOLEAN WriteToDevice
  1129. )
  1130. /*++
  1131. Routine Description:
  1132. This routine is invoked to set up the map registers in the DMA controller
  1133. to allow a transfer to or from a device.
  1134. Arguments:
  1135. AdapterObject - Pointer to the adapter object representing the DMA
  1136. controller channel that has been allocated.
  1137. Mdl - Pointer to the MDL that describes the pages of memory that are
  1138. being read or written.
  1139. MapRegisterBase - The address of the base map register that has been
  1140. allocated to the device driver for use in mapping the transfer.
  1141. CurrentVa - Current virtual address in the buffer described by the MDL
  1142. that the transfer is being done to or from.
  1143. Length - Supplies the length of the transfer. This determines the
  1144. number of map registers that need to be written to map the transfer.
  1145. Returns the length of the transfer which was actually mapped.
  1146. WriteToDevice - Boolean value that indicates whether this is a write
  1147. to the device from memory (TRUE), or vice versa.
  1148. Return Value:
  1149. Returns the logical address that should be used bus master controllers.
  1150. --*/
  1151. {
  1152. ULONG transferLength;
  1153. PHYSICAL_ADDRESS returnAddress;
  1154. PPFN_NUMBER pageFrame;
  1155. ULONG pageOffset;
  1156. //
  1157. // If the adapter is a 32-bit bus master, take the fast path,
  1158. // otherwise call HalpMapTransfer for the slow path
  1159. //
  1160. if (MapRegisterBase == NULL) {
  1161. pageOffset = BYTE_OFFSET(CurrentVa);
  1162. //
  1163. // Calculate how much of the transfer is contiguous
  1164. //
  1165. transferLength = PAGE_SIZE - pageOffset;
  1166. pageFrame = MmGetMdlPfnArray(Mdl);
  1167. pageFrame += ((ULONG_PTR) CurrentVa - (ULONG_PTR) MmGetMdlBaseVa(Mdl)) >> PAGE_SHIFT;
  1168. //
  1169. // Compute the starting address of the transfer
  1170. //
  1171. returnAddress.QuadPart =
  1172. ((ULONG64)*pageFrame << PAGE_SHIFT) + pageOffset;
  1173. //
  1174. // If the transfer is not completely contained within
  1175. // a page, call the helper to compute the appropriate
  1176. // length.
  1177. //
  1178. if (transferLength < *Length) {
  1179. HalpMapTransferHelper(Mdl, CurrentVa, transferLength, pageFrame, Length);
  1180. }
  1181. return (returnAddress);
  1182. }
  1183. return (HalpMapTransfer(AdapterObject,
  1184. Mdl,
  1185. MapRegisterBase,
  1186. CurrentVa,
  1187. Length,
  1188. WriteToDevice));
  1189. }
  1190. VOID
  1191. HalpMapTransferHelper(
  1192. IN PMDL Mdl,
  1193. IN PVOID CurrentVa,
  1194. IN ULONG TransferLength,
  1195. IN PPFN_NUMBER PageFrame,
  1196. IN OUT PULONG Length
  1197. )
  1198. /*++
  1199. Routine Description:
  1200. Helper routine for bus master transfers that cross a page
  1201. boundary. This routine is separated out from the IoMapTransfer
  1202. fast path in order to minimize the total instruction path
  1203. length taken for the common network case where the entire
  1204. buffer being mapped is contained within one page.
  1205. Arguments:
  1206. Mdl - Pointer to the MDL that describes the pages of memory that are
  1207. being read or written.
  1208. CurrentVa - Current virtual address in the buffer described by the MDL
  1209. that the transfer is being done to or from.
  1210. TransferLength = Supplies the current transferLength
  1211. PageFrame - Supplies a pointer to the starting page frame of the transfer
  1212. Length - Supplies the length of the transfer. This determines the
  1213. number of map registers that need to be written to map the transfer.
  1214. Returns the length of the transfer which was actually mapped.
  1215. Return Value:
  1216. None. *Length will be updated
  1217. --*/
  1218. {
  1219. PFN_NUMBER thisPageFrame;
  1220. PFN_NUMBER nextPageFrame;
  1221. do {
  1222. thisPageFrame = *PageFrame;
  1223. PageFrame += 1;
  1224. nextPageFrame = *PageFrame;
  1225. if ((thisPageFrame + 1) != nextPageFrame) {
  1226. //
  1227. // The next page frame is not contiguous with this one,
  1228. // so break the transfer here.
  1229. //
  1230. break;
  1231. }
  1232. if (((thisPageFrame ^ nextPageFrame) & 0xFFFFFFFFFFF00000UI64) != 0) {
  1233. //
  1234. // The next page frame is contiguous with this one,
  1235. // but it crosses a 4GB boundary, another reason to
  1236. // break the transfer.
  1237. //
  1238. break;
  1239. }
  1240. TransferLength += PAGE_SIZE;
  1241. } while ( TransferLength < *Length );
  1242. //
  1243. // Limit the Length to the maximum TransferLength.
  1244. //
  1245. if (TransferLength < *Length) {
  1246. *Length = TransferLength;
  1247. }
  1248. }
  1249. PHYSICAL_ADDRESS
  1250. HalpMapTransfer(
  1251. IN PADAPTER_OBJECT AdapterObject,
  1252. IN PMDL Mdl,
  1253. IN PVOID MapRegisterBase,
  1254. IN PVOID CurrentVa,
  1255. IN OUT PULONG Length,
  1256. IN BOOLEAN WriteToDevice
  1257. )
  1258. /*++
  1259. Routine Description:
  1260. This routine is invoked to set up the map registers in the DMA controller
  1261. to allow a transfer to or from a device.
  1262. Arguments:
  1263. AdapterObject - Pointer to the adapter object representing the DMA
  1264. controller channel that has been allocated.
  1265. Mdl - Pointer to the MDL that describes the pages of memory that are
  1266. being read or written.
  1267. MapRegisterBase - The address of the base map register that has been
  1268. allocated to the device driver for use in mapping the transfer.
  1269. CurrentVa - Current virtual address in the buffer described by the MDL
  1270. that the transfer is being done to or from.
  1271. Length - Supplies the length of the transfer. This determines the
  1272. number of map registers that need to be written to map the transfer.
  1273. Returns the length of the transfer which was actually mapped.
  1274. WriteToDevice - Boolean value that indicates whether this is a write
  1275. to the device from memory (TRUE), or vice versa.
  1276. Return Value:
  1277. Returns the logical address that should be used bus master controllers.
  1278. --*/
  1279. {
  1280. BOOLEAN useBuffer;
  1281. ULONG transferLength;
  1282. PHYSICAL_ADDRESS logicalAddress;
  1283. PHYSICAL_ADDRESS returnAddress;
  1284. ULONG index;
  1285. PPFN_NUMBER pageFrame;
  1286. PUCHAR bytePointer;
  1287. UCHAR adapterMode;
  1288. UCHAR dataByte;
  1289. PTRANSLATION_ENTRY translationEntry;
  1290. ULONG pageOffset;
  1291. KIRQL Irql;
  1292. BOOLEAN masterDevice;
  1293. PHYSICAL_ADDRESS maximumPhysicalAddress;
  1294. masterDevice = AdapterObject == NULL || AdapterObject->MasterDevice ?
  1295. TRUE : FALSE;
  1296. pageOffset = BYTE_OFFSET(CurrentVa);
  1297. #if DBG
  1298. //
  1299. // Catch slave mode devices that seem to want to try and have more than one
  1300. // outstanding request. If they do then the bus locks.
  1301. //
  1302. if (!masterDevice) {
  1303. ASSERT (HalpDmaChannelState [AdapterObject->ChannelNumber + ((AdapterObject->AdapterNumber - 1) * 4)].ChannelBusy == FALSE);
  1304. HalpDmaChannelState [AdapterObject->ChannelNumber + ((AdapterObject->AdapterNumber - 1) * 4)].ChannelBusy =
  1305. TRUE;
  1306. }
  1307. #endif
  1308. //
  1309. // Calculate how much of the transfer is contiguous.
  1310. //
  1311. transferLength = PAGE_SIZE - pageOffset;
  1312. pageFrame = MmGetMdlPfnArray(Mdl);
  1313. pageFrame += ((ULONG_PTR) CurrentVa - (ULONG_PTR) MmGetMdlBaseVa(Mdl)) >> PAGE_SHIFT;
  1314. logicalAddress.QuadPart =
  1315. (((ULONGLONG)*pageFrame) << PAGE_SHIFT) + pageOffset;
  1316. //
  1317. // If the buffer is contigous and does not cross a 64 K bountry then
  1318. // just extend the buffer. The 64 K bountry restriction does not apply
  1319. // to Eisa systems.
  1320. //
  1321. if (HalpEisaDma) {
  1322. while ( transferLength < *Length ) {
  1323. if (*pageFrame + 1 != *(pageFrame + 1)) {
  1324. break;
  1325. }
  1326. transferLength += PAGE_SIZE;
  1327. pageFrame++;
  1328. }
  1329. } else {
  1330. while ( transferLength < *Length ) {
  1331. if (*pageFrame + 1 != *(pageFrame + 1) ||
  1332. (*pageFrame & ~0x0f) != (*(pageFrame + 1) & ~0x0f)) {
  1333. break;
  1334. }
  1335. transferLength += PAGE_SIZE;
  1336. pageFrame++;
  1337. }
  1338. }
  1339. //
  1340. // Limit the transferLength to the requested Length.
  1341. //
  1342. transferLength = transferLength > *Length ? *Length : transferLength;
  1343. ASSERT(MapRegisterBase != NULL);
  1344. //
  1345. // Strip no scatter/gather flag.
  1346. //
  1347. translationEntry = (PTRANSLATION_ENTRY) ((ULONG_PTR) MapRegisterBase & ~NO_SCATTER_GATHER);
  1348. if ((ULONG_PTR) MapRegisterBase & NO_SCATTER_GATHER
  1349. && transferLength < *Length) {
  1350. logicalAddress.QuadPart = translationEntry->PhysicalAddress + pageOffset;
  1351. translationEntry->Index = COPY_BUFFER;
  1352. index = 0;
  1353. transferLength = *Length;
  1354. useBuffer = TRUE;
  1355. } else {
  1356. //
  1357. // If there are map registers, then update the index to indicate
  1358. // how many have been used.
  1359. //
  1360. useBuffer = FALSE;
  1361. index = translationEntry->Index;
  1362. translationEntry->Index += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
  1363. CurrentVa,
  1364. transferLength
  1365. );
  1366. //
  1367. // PeterJ added the following to catch drivers which don't call
  1368. // IoFlushAdapterBuffers. Calling IoMapTransfer repeatedly
  1369. // without calling IoFlushAdapterBuffers will run you out of
  1370. // map registers,.... Some PCI device drivers think they can
  1371. // get away with this because they do 32 bit direct transfers.
  1372. // Try plugging one of these into a system with > 4GB and see
  1373. // what happens to you.
  1374. //
  1375. ASSERT(translationEntry->Index <=
  1376. AdapterObject->MapRegistersPerChannel);
  1377. }
  1378. //
  1379. // It must require memory to be within the adapter's address range. If the
  1380. // logical address is greater than that which the adapter can directly
  1381. // access then map registers must be used
  1382. //
  1383. maximumPhysicalAddress =
  1384. HalpGetAdapterMaximumPhysicalAddress( AdapterObject );
  1385. if ((ULONGLONG)(logicalAddress.QuadPart + transferLength - 1) >
  1386. (ULONGLONG)maximumPhysicalAddress.QuadPart) {
  1387. logicalAddress.QuadPart = (translationEntry + index)->PhysicalAddress +
  1388. pageOffset;
  1389. useBuffer = TRUE;
  1390. if ((ULONG_PTR) MapRegisterBase & NO_SCATTER_GATHER) {
  1391. translationEntry->Index = COPY_BUFFER;
  1392. index = 0;
  1393. }
  1394. }
  1395. //
  1396. // Copy the data if necessary.
  1397. //
  1398. if (useBuffer && WriteToDevice) {
  1399. HalpCopyBufferMap(
  1400. Mdl,
  1401. translationEntry + index,
  1402. CurrentVa,
  1403. transferLength,
  1404. WriteToDevice
  1405. );
  1406. }
  1407. //
  1408. // Return the length.
  1409. //
  1410. *Length = transferLength;
  1411. //
  1412. // Return the logical address to transfer to.
  1413. //
  1414. returnAddress = logicalAddress;
  1415. //
  1416. // If no adapter was specificed then there is no more work to do so
  1417. // return.
  1418. //
  1419. if (AdapterObject == NULL || AdapterObject->MasterDevice) {
  1420. return (returnAddress);
  1421. }
  1422. //
  1423. // Determine the mode based on the transfer direction.
  1424. //
  1425. adapterMode = AdapterObject->AdapterMode;
  1426. if (WriteToDevice) {
  1427. ((PDMA_EISA_MODE) &adapterMode)->TransferType = (UCHAR) WRITE_TRANSFER;
  1428. } else {
  1429. ((PDMA_EISA_MODE) &adapterMode)->TransferType = (UCHAR) READ_TRANSFER;
  1430. if (AdapterObject->IgnoreCount) {
  1431. //
  1432. // When the DMA is over there will be no way to tell how much
  1433. // data was transfered, so the entire transfer length will be
  1434. // copied. To ensure that no stale data is returned to the
  1435. // caller zero the buffer before hand.
  1436. //
  1437. RtlZeroMemory (
  1438. (PUCHAR) translationEntry[index].VirtualAddress + pageOffset,
  1439. transferLength
  1440. );
  1441. }
  1442. }
  1443. bytePointer = (PUCHAR) &logicalAddress;
  1444. if (AdapterObject->Width16Bits) {
  1445. //
  1446. // If this is a 16 bit transfer then adjust the length and the address
  1447. // for the 16 bit DMA mode.
  1448. //
  1449. transferLength >>= 1;
  1450. //
  1451. // In 16 bit DMA mode the low 16 bits are shifted right one and the
  1452. // page register value is unchanged. So save the page register value
  1453. // and shift the logical address then restore the page value.
  1454. //
  1455. dataByte = bytePointer[2];
  1456. logicalAddress.QuadPart >>= 1;
  1457. bytePointer[2] = dataByte;
  1458. }
  1459. //
  1460. // grab the spinlock for the system DMA controller
  1461. //
  1462. KeAcquireSpinLock( &AdapterObject->MasterAdapter->SpinLock, &Irql );
  1463. //
  1464. // Determine the controller number based on the Adapter number.
  1465. //
  1466. if (AdapterObject->AdapterNumber == 1) {
  1467. //
  1468. // This request is for DMA controller 1
  1469. //
  1470. PDMA1_CONTROL dmaControl;
  1471. dmaControl = AdapterObject->AdapterBaseVa;
  1472. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  1473. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  1474. WRITE_PORT_UCHAR(
  1475. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1476. .DmaBaseAddress,
  1477. bytePointer[0]
  1478. );
  1479. WRITE_PORT_UCHAR(
  1480. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1481. .DmaBaseAddress,
  1482. bytePointer[1]
  1483. );
  1484. WRITE_PORT_UCHAR(
  1485. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
  1486. (ULONG_PTR)AdapterObject->PagePort,
  1487. bytePointer[2]
  1488. );
  1489. if (HalpEisaDma) {
  1490. //
  1491. // Write the high page register with zero value. This enable a special mode
  1492. // which allows ties the page register and base count into a single 24 bit
  1493. // address register.
  1494. //
  1495. WRITE_PORT_UCHAR(
  1496. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
  1497. (ULONG_PTR)AdapterObject->PagePort,
  1498. 0
  1499. );
  1500. }
  1501. //
  1502. // Notify DMA chip of the length to transfer.
  1503. //
  1504. WRITE_PORT_UCHAR(
  1505. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1506. .DmaBaseCount,
  1507. (UCHAR) ((transferLength - 1) & 0xff)
  1508. );
  1509. WRITE_PORT_UCHAR(
  1510. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1511. .DmaBaseCount,
  1512. (UCHAR) ((transferLength - 1) >> 8)
  1513. );
  1514. //
  1515. // Set the DMA chip to read or write mode; and unmask it.
  1516. //
  1517. WRITE_PORT_UCHAR(
  1518. &dmaControl->SingleMask,
  1519. (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
  1520. );
  1521. } else {
  1522. //
  1523. // This request is for DMA controller 2
  1524. //
  1525. PDMA2_CONTROL dmaControl;
  1526. dmaControl = AdapterObject->AdapterBaseVa;
  1527. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  1528. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  1529. WRITE_PORT_UCHAR(
  1530. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1531. .DmaBaseAddress,
  1532. bytePointer[0]
  1533. );
  1534. WRITE_PORT_UCHAR(
  1535. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1536. .DmaBaseAddress,
  1537. bytePointer[1]
  1538. );
  1539. WRITE_PORT_UCHAR(
  1540. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
  1541. (ULONG_PTR)AdapterObject->PagePort,
  1542. bytePointer[2]
  1543. );
  1544. if (HalpEisaDma) {
  1545. //
  1546. // Write the high page register with zero value. This enable a
  1547. // special mode which allows ties the page register and base
  1548. // count into a single 24 bit address register.
  1549. //
  1550. WRITE_PORT_UCHAR(
  1551. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
  1552. (ULONG_PTR)AdapterObject->PagePort,
  1553. 0
  1554. );
  1555. }
  1556. //
  1557. // Notify DMA chip of the length to transfer.
  1558. //
  1559. WRITE_PORT_UCHAR(
  1560. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1561. .DmaBaseCount,
  1562. (UCHAR) ((transferLength - 1) & 0xff)
  1563. );
  1564. WRITE_PORT_UCHAR(
  1565. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1566. .DmaBaseCount,
  1567. (UCHAR) ((transferLength - 1) >> 8)
  1568. );
  1569. //
  1570. // Set the DMA chip to read or write mode; and unmask it.
  1571. //
  1572. WRITE_PORT_UCHAR(
  1573. &dmaControl->SingleMask,
  1574. (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
  1575. );
  1576. }
  1577. //
  1578. // Record what we wrote to the mask register.
  1579. //
  1580. HalpDmaChannelState [AdapterObject->ChannelNumber + ((AdapterObject->AdapterNumber - 1) * 4)].ChannelMask =
  1581. (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber);
  1582. KeReleaseSpinLock (&AdapterObject->MasterAdapter->SpinLock, Irql);
  1583. return (returnAddress);
  1584. }
  1585. BOOLEAN
  1586. IoFlushAdapterBuffers(
  1587. IN PADAPTER_OBJECT AdapterObject,
  1588. IN PMDL Mdl,
  1589. IN PVOID MapRegisterBase,
  1590. IN PVOID CurrentVa,
  1591. IN ULONG Length,
  1592. IN BOOLEAN WriteToDevice
  1593. )
  1594. /*++
  1595. Routine Description:
  1596. This routine flushes the DMA adapter object buffers. For the Jazz system
  1597. its clears the enable flag which aborts the dma.
  1598. Arguments:
  1599. AdapterObject - Pointer to the adapter object representing the DMA
  1600. controller channel.
  1601. Mdl - A pointer to a Memory Descriptor List (MDL) that maps the locked-down
  1602. buffer to/from which the I/O occured.
  1603. MapRegisterBase - A pointer to the base of the map registers in the adapter
  1604. or DMA controller.
  1605. CurrentVa - The current virtual address in the buffer described the the Mdl
  1606. where the I/O operation occurred.
  1607. Length - Supplies the length of the transfer.
  1608. WriteToDevice - Supplies a BOOLEAN value that indicates the direction of
  1609. the data transfer was to the device.
  1610. Return Value:
  1611. TRUE - No errors are detected so the transfer must succeed.
  1612. --*/
  1613. {
  1614. PTRANSLATION_ENTRY translationEntry;
  1615. PPFN_NUMBER pageFrame;
  1616. ULONG transferLength;
  1617. ULONG partialLength;
  1618. BOOLEAN masterDevice;
  1619. PHYSICAL_ADDRESS maximumPhysicalAddress;
  1620. ULONG maximumPhysicalPage;
  1621. masterDevice = AdapterObject == NULL || AdapterObject->MasterDevice ?
  1622. TRUE : FALSE;
  1623. //
  1624. // If this is a slave device, then stop the DMA controller.
  1625. //
  1626. if (!masterDevice) {
  1627. //
  1628. // Mask the DMA request line so that DMA requests cannot occur.
  1629. //
  1630. if (AdapterObject->AdapterNumber == 1) {
  1631. //
  1632. // This request is for DMA controller 1
  1633. //
  1634. PDMA1_CONTROL dmaControl;
  1635. dmaControl = AdapterObject->AdapterBaseVa;
  1636. WRITE_PORT_UCHAR(
  1637. &dmaControl->SingleMask,
  1638. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  1639. );
  1640. } else {
  1641. //
  1642. // This request is for DMA controller 2
  1643. //
  1644. PDMA2_CONTROL dmaControl;
  1645. dmaControl = AdapterObject->AdapterBaseVa;
  1646. WRITE_PORT_UCHAR(
  1647. &dmaControl->SingleMask,
  1648. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  1649. );
  1650. }
  1651. //
  1652. // Record what we wrote to the mask register.
  1653. //
  1654. HalpDmaChannelState [AdapterObject->ChannelNumber + ((AdapterObject->AdapterNumber - 1) * 4)].ChannelMask =
  1655. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber);
  1656. //
  1657. // Mark the channel as not in use
  1658. //
  1659. #if DBG
  1660. HalpDmaChannelState [AdapterObject->ChannelNumber + ((AdapterObject->AdapterNumber - 1) * 4)].ChannelBusy =
  1661. FALSE;
  1662. #endif
  1663. }
  1664. if (MapRegisterBase == NULL) {
  1665. return (TRUE);
  1666. }
  1667. //
  1668. // Determine if the data needs to be copied to the orginal buffer.
  1669. // This only occurs if the data tranfer is from the device, the
  1670. // MapReisterBase is not NULL and the transfer spans a page.
  1671. //
  1672. if (!WriteToDevice) {
  1673. //
  1674. // Strip no scatter/gather flag.
  1675. //
  1676. translationEntry = (PTRANSLATION_ENTRY) ((ULONG_PTR) MapRegisterBase & ~NO_SCATTER_GATHER);
  1677. //
  1678. // If this is not a master device, then just transfer the buffer.
  1679. //
  1680. if ((ULONG_PTR) MapRegisterBase & NO_SCATTER_GATHER) {
  1681. if (translationEntry->Index == COPY_BUFFER) {
  1682. if (!masterDevice && !AdapterObject->IgnoreCount) {
  1683. ULONG DmaCount;
  1684. //
  1685. // Copy only the bytes that have actually been transfered.
  1686. //
  1687. //
  1688. DmaCount = HalReadDmaCounter(AdapterObject);
  1689. ASSERT(DmaCount <= Length);
  1690. Length -= DmaCount;
  1691. }
  1692. //
  1693. // The adapter does not support scatter/gather copy the buffer.
  1694. //
  1695. HalpCopyBufferMap(
  1696. Mdl,
  1697. translationEntry,
  1698. CurrentVa,
  1699. Length,
  1700. WriteToDevice
  1701. );
  1702. }
  1703. } else {
  1704. //
  1705. // Cycle through the pages of the transfer to determine if there
  1706. // are any which need to be copied back.
  1707. //
  1708. maximumPhysicalAddress =
  1709. HalpGetAdapterMaximumPhysicalAddress( AdapterObject );
  1710. maximumPhysicalPage =
  1711. (ULONG)(maximumPhysicalAddress.QuadPart >> PAGE_SHIFT);
  1712. transferLength = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
  1713. partialLength = transferLength;
  1714. pageFrame = MmGetMdlPfnArray(Mdl);
  1715. pageFrame += ((ULONG_PTR) CurrentVa - (ULONG_PTR) MmGetMdlBaseVa(Mdl)) >> PAGE_SHIFT;
  1716. while ( transferLength <= Length ) {
  1717. if (*pageFrame > maximumPhysicalPage) {
  1718. HalpCopyBufferMap(
  1719. Mdl,
  1720. translationEntry,
  1721. CurrentVa,
  1722. partialLength,
  1723. WriteToDevice
  1724. );
  1725. }
  1726. (PCCHAR) CurrentVa += partialLength;
  1727. partialLength = PAGE_SIZE;
  1728. //
  1729. // Note that transferLength indicates the amount which will be
  1730. // transfered after the next loop; thus, it is updated with the
  1731. // new partial length.
  1732. //
  1733. transferLength += partialLength;
  1734. pageFrame++;
  1735. translationEntry++;
  1736. }
  1737. //
  1738. // Process the any remaining residue.
  1739. //
  1740. partialLength = Length - transferLength + partialLength;
  1741. if (partialLength && *pageFrame > maximumPhysicalPage) {
  1742. HalpCopyBufferMap(
  1743. Mdl,
  1744. translationEntry,
  1745. CurrentVa,
  1746. partialLength,
  1747. WriteToDevice
  1748. );
  1749. }
  1750. }
  1751. }
  1752. //
  1753. // Strip no scatter/gather flag.
  1754. //
  1755. translationEntry = (PTRANSLATION_ENTRY) ((ULONG_PTR) MapRegisterBase & ~NO_SCATTER_GATHER);
  1756. //
  1757. // Clear index in map register.
  1758. //
  1759. translationEntry->Index = 0;
  1760. return TRUE;
  1761. }
  1762. ULONG
  1763. HalReadDmaCounter(
  1764. IN PADAPTER_OBJECT AdapterObject
  1765. )
  1766. /*++
  1767. Routine Description:
  1768. This function reads the DMA counter and returns the number of bytes left
  1769. to be transfered.
  1770. Arguments:
  1771. AdapterObject - Supplies a pointer to the adapter object to be read.
  1772. Return Value:
  1773. Returns the number of bytes still be be transfered.
  1774. --*/
  1775. {
  1776. ULONG count;
  1777. ULONG high;
  1778. KIRQL Irql;
  1779. //
  1780. // Grab the spinlock for the system DMA controller.
  1781. //
  1782. KeAcquireSpinLock( &AdapterObject->MasterAdapter->SpinLock, &Irql );
  1783. //
  1784. // Determine the controller number based on the Adapter number.
  1785. //
  1786. if (AdapterObject->AdapterNumber == 1) {
  1787. //
  1788. // This request is for DMA controller 1
  1789. //
  1790. PDMA1_CONTROL dmaControl;
  1791. dmaControl = AdapterObject->AdapterBaseVa;
  1792. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  1793. //
  1794. // Initialize count to a value which will not match.
  1795. //
  1796. count = 0xFFFF00;
  1797. //
  1798. // Loop until the same high byte is read twice.
  1799. //
  1800. do {
  1801. high = count;
  1802. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  1803. //
  1804. // Read the current DMA count.
  1805. //
  1806. count = READ_PORT_UCHAR(
  1807. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1808. .DmaBaseCount
  1809. );
  1810. count |= READ_PORT_UCHAR(
  1811. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1812. .DmaBaseCount
  1813. ) << 8;
  1814. } while ((count & 0xFFFF00) != (high & 0xFFFF00));
  1815. } else {
  1816. //
  1817. // This request is for DMA controller 2
  1818. //
  1819. PDMA2_CONTROL dmaControl;
  1820. dmaControl = AdapterObject->AdapterBaseVa;
  1821. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  1822. //
  1823. // Initialize count to a value which will not match.
  1824. //
  1825. count = 0xFFFF00;
  1826. //
  1827. // Loop until the same high byte is read twice.
  1828. //
  1829. do {
  1830. high = count;
  1831. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  1832. //
  1833. // Read the current DMA count.
  1834. //
  1835. count = READ_PORT_UCHAR(
  1836. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1837. .DmaBaseCount
  1838. );
  1839. count |= READ_PORT_UCHAR(
  1840. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  1841. .DmaBaseCount
  1842. ) << 8;
  1843. } while ((count & 0xFFFF00) != (high & 0xFFFF00));
  1844. }
  1845. //
  1846. // Release the spinlock for the system DMA controller.
  1847. //
  1848. KeReleaseSpinLock( &AdapterObject->MasterAdapter->SpinLock, Irql );
  1849. //
  1850. // The DMA counter has a bias of one and can only be 16 bit long.
  1851. //
  1852. count = (count + 1) & 0xFFFF;
  1853. //
  1854. // If this is a 16 bit dma the multiply the count by 2.
  1855. //
  1856. if (AdapterObject->Width16Bits) {
  1857. count *= 2;
  1858. }
  1859. return (count);
  1860. }
  1861. ULONG
  1862. HalpGetIsaIrqState(
  1863. ULONG Vector
  1864. )
  1865. {
  1866. ULONG vectorState = CM_RESOURCE_INTERRUPT_LATCHED;
  1867. if (HalpBusType == MACHINE_TYPE_EISA) {
  1868. if (HalpEisaIrqMask & (1 << Vector)) {
  1869. vectorState = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
  1870. }
  1871. }
  1872. return vectorState;
  1873. }