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.

4265 lines
109 KiB

4 years ago
  1. // #pragma comment(exestr, "@(#) jxhwsup.c 1.1 95/09/28 15:38:22 nec")
  2. /*++
  3. Copyright (c) 1990-1993 Microsoft Corporation
  4. Module Name:
  5. jxhwsup.c
  6. Abstract:
  7. This module contains the HalpXxx routines for the NT I/O system that
  8. are hardware dependent. Were these routines not hardware dependent,
  9. they would normally reside in the internal.c module.
  10. Author:
  11. Jeff Havens (jhavens) 14-Feb-1990
  12. Environment:
  13. Kernel mode, local to I/O system
  14. Revision History:
  15. M0001 1994.9.8 kuriyama@oa2
  16. - Modify for R94A MIPS R4400
  17. HalGetAdapter() - add routine for support PCIBus
  18. Modify Internal MAX Dma Channel (r94a 0-3)
  19. HalTranslateBusAddress() - add routine for support PCIBus
  20. HalGetBusDataBy
  21. M0002 1994.10.7 kuriyama@oa2
  22. - Modify HalDmaChannel() - terminal count logic bug fix.
  23. M0003 1994.10.14 kuriyama@oa2
  24. - compile error clear
  25. CHG001 ataka@oa2.kb.nec.co.jp Mon Oct 17 23:20:04 JST 1994
  26. - Merge BusHandlers
  27. M0004 Fri Oct 28 14:56:02 JST 1994 kuriyama@oa2
  28. - add BBM DMA routine (for edit buffer)(for BBM limited)
  29. - add I/O cache flush if physical tag is valid(for BBM limited)
  30. D001 ataka@oa2.kb.nec.co.jp (DMA CopyBuffer by kuriyama@oa2, other toghether)
  31. Sat Nov 05 16:28:04 JST 1994
  32. - Limit Check of Length (Only DbgPrint)
  33. - Delete checking ByteMask
  34. - TLB fill 0xff(by Kuriyama)
  35. M005 Tue Dec 13 16:28:25 1994 kbnes!kisimoto
  36. - changed the address that copies from, and source re-formated.
  37. M0006 Thu Dec 22 11:46:16 JST 1994 kbnes!A.kuriyama
  38. - add beta machine limit
  39. S0007 Thu Jan 05 17:13:18 JST 1995 kbnes!A.Kuriyama
  40. - warning clear
  41. M0008 Fri Jan 13 13:49:51 JST 1995 kbnes!A.Kuriyama
  42. - I/O cache flush routine was deleted in functions as follows
  43. IoMapTransfer()
  44. HalFlushCommonBuffer()
  45. M0009 Mon Jan 23 14:31:44 JST 1995 kbnes!A.Kuriyama
  46. - DMA Channel Interrupt routine change
  47. - add Internal DMAC bytecount mask
  48. M0010 Mon Jan 23 15:36:18 JST 1995 kbnes!A.Kuriyama
  49. - Dma channel interrupt enable
  50. HalpAllocateAdapter()
  51. HalpCreateDmaStructure()
  52. S0011 Tue Jan 24 18:28:55 JST 1995 kbnes!A.Kuriyama
  53. - Compile error clear
  54. M0012 Tue Jan 31 18:04:08 JST 1995 kbnes!A.Kuriyama
  55. - add Internal slave dma 1MB limit.
  56. M0013 Tue Jan 31 18:07:53 JST 1995 kbnes!A.Kuriyama
  57. M0014 Tue Jan 31 18:37:33 JST 1995 kbnes!A.Kuriyama
  58. - change I/O cache flush routine.
  59. if length equal 0 no need i/o cache flush.
  60. S0015 Wed Feb 01 12:03:06 JST 1995 kbnes!A.Kuriyama
  61. - sccs update miss error clear
  62. B0016 Thu Feb 2 22:09:32 1995 kbnes!kishimoto
  63. - return pointer to adapterObject if InterfaceType
  64. equals PCIBus
  65. S0017 Wed Feb 22 12:00:58 JST 1995 kbnes!kuriyama (A)
  66. - disable dma terminal interrupt
  67. M0018 Tue Mar 07 11:26:44 JST 1995 kbnes!kuriyama (A)
  68. - expand dma logical address space
  69. S0019 Tue Mar 07 15:22:00 JST 1995 kbnes!kuriyama (A)
  70. - compile error clear
  71. M0020 Fri Mar 10 11:44:25 JST 1995 kbnes!kuriyama (A)
  72. - logical address expand bug fix
  73. S0021 Fri Mar 10 16:23:12 JST 1995 kbnes!kuriyama (A)
  74. - internal slave bug fix
  75. S0022 Tue Jun 27 19:12:30 JST 1995 kbnes!kisimoto
  76. - del memmove prototype definition
  77. to merge build 1057
  78. change strings displaied with Tyhoon error
  79. S0023 Thu Jul 20 20:11:34 JST 1995 kbnes!kisimoto
  80. - add code for ESM from J94C
  81. M0024 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 19:36:13 JST 1995
  82. - add for x86bios support
  83. - (change internal dma address to 1M-4M)
  84. --*/
  85. #include "halp.h"
  86. #include "bugcodes.h"
  87. #include "eisa.h"
  88. //
  89. // Put all code for HAL initialization in the INIT section. It will be
  90. // deallocated by memory management when phase 1 initialization is
  91. // completed.
  92. //
  93. #if defined(ALLOC_PRAGMA)
  94. #pragma alloc_text(INIT, HalpCreateDmaStructures)
  95. #endif
  96. extern POBJECT_TYPE IoAdapterObjectType;
  97. #define HalDump(x,y) if(HalDebug > 0) DbgPrint( x,y )
  98. /* M0006 */
  99. /* start M0004 */
  100. ULONG HalDebug = 0;
  101. #if defined(_BBM_DMA_)
  102. //
  103. // define copybuffer allocate routine.
  104. //
  105. VOID
  106. HalpAllocateCopyBuffer(
  107. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  108. );
  109. //
  110. // Allocate Variable for DMA CopyBuffer
  111. //
  112. ULONG CopyBufferPhysicalBase;
  113. ULONG CopyBufferVirtualAddress;
  114. #endif // _BBM_DMA_
  115. #if defined(_BETA_LIMIT_)
  116. PVOID
  117. HalViewMemory (
  118. IN PVOID Destination,
  119. IN ULONG Length
  120. );
  121. #endif // _BETA_LIMIT_
  122. /* end M0004 */
  123. //
  124. // The DMA controller has a larger number of map registers which may be used
  125. // by any adapter channel. In order to pool all of the map registers a master
  126. // adapter object is used. This object is allocated and saved internal to this
  127. // file. It contains a bit map for allocation of the registers and a queue
  128. // for requests which are waiting for more map registers. This object is
  129. // allocated during the first request to allocate an adapter.
  130. //
  131. PADAPTER_OBJECT MasterAdapterObject;
  132. //
  133. // The following is the interrupt object used for DMA controller interrupts.
  134. // DMA controller interrupts occur when a memory parity error occurs or a
  135. // programming error occurs to the DMA controller.
  136. //
  137. KINTERRUPT HalpDmaChannelInterrupt;
  138. /* start M0001 */
  139. #if defined(_R94A_)
  140. //
  141. // The following is the interrupt object used for Typhoon Error interrupts.
  142. // Typhoon errorr interrupts occur when internal busmaster device error occurs.
  143. //
  144. KINTERRUPT HalpTyphoonErrorInterrupt;
  145. #endif // _R94A_
  146. /* end M0001 */
  147. UCHAR DmaChannelMsg[] = "\nHAL: DMA channel x interrupted. ";
  148. //
  149. // Pointer to phyiscal memory for map registers.
  150. //
  151. ULONG HalpMapRegisterPhysicalBase;
  152. //
  153. // The following function is called when a DMA channel interrupt occurs.
  154. //
  155. BOOLEAN
  156. HalpDmaChannel(
  157. IN PKINTERRUPT Interrupt,
  158. IN PVOID ServiceContext
  159. );
  160. //
  161. // The following is an array of adapter object structures for the internal DMA
  162. // channels.
  163. //
  164. PADAPTER_OBJECT HalpInternalAdapters[8];
  165. IO_ALLOCATION_ACTION
  166. HalpAllocationRoutine (
  167. IN PDEVICE_OBJECT DeviceObject,
  168. IN PIRP Irp,
  169. IN PVOID MapRegisterBase,
  170. IN PVOID Context
  171. );
  172. ULONG
  173. HalpReadEisaData (
  174. IN ULONG BusNumber,
  175. IN ULONG SlotNumber,
  176. IN PVOID Buffer,
  177. IN ULONG Offset,
  178. IN ULONG Length
  179. );
  180. /* start M0001 */
  181. #if defined(_R94A_)
  182. BOOLEAN
  183. HalpCreateTyphoonErrorStructures (
  184. VOID
  185. );
  186. BOOLEAN
  187. HalpTyphoonError(
  188. IN PKINTERRUPT Interrupt,
  189. IN PVOID ServiceContext
  190. );
  191. #endif // _R94A_
  192. /* end M0001 */
  193. NTSTATUS
  194. HalAllocateAdapterChannel(
  195. IN PADAPTER_OBJECT AdapterObject,
  196. IN PWAIT_CONTEXT_BLOCK Wcb,
  197. IN ULONG NumberOfMapRegisters,
  198. IN PDRIVER_CONTROL ExecutionRoutine
  199. )
  200. /*++
  201. Routine Description:
  202. This routine allocates the adapter channel specified by the adapter object.
  203. This is accomplished by placing the device object of the driver that wants
  204. to allocate the adapter on the adapter's queue. If the queue is already
  205. "busy", then the adapter has already been allocated, so the device object
  206. is simply placed onto the queue and waits until the adapter becomes free.
  207. Once the adapter becomes free (or if it already is), then the driver's
  208. execution routine is invoked.
  209. Also, a number of map registers may be allocated to the driver by specifying
  210. a non-zero value for NumberOfMapRegisters. Then the map register must be
  211. allocated from the master adapter. Once there are a sufficient number of
  212. map registers available, then the execution routine is called and the
  213. base address of the allocated map registers in the adapter is also passed
  214. to the driver's execution routine.
  215. Arguments:
  216. AdapterObject - Pointer to the adapter control object to allocate to the
  217. driver.
  218. Wcb - Supplies a wait context block for saving the allocation parameters.
  219. The DeviceObject, CurrentIrp and DeviceContext should be initalized.
  220. NumberOfMapRegisters - The number of map registers that are to be allocated
  221. from the channel, if any.
  222. ExecutionRoutine - The address of the driver's execution routine that is
  223. invoked once the adapter channel (and possibly map registers) have been
  224. allocated.
  225. Return Value:
  226. Returns STATUS_SUCESS unless too many map registers are requested.
  227. Notes:
  228. Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
  229. --*/
  230. {
  231. PADAPTER_OBJECT MasterAdapter;
  232. BOOLEAN Busy = FALSE;
  233. IO_ALLOCATION_ACTION Action;
  234. LONG MapRegisterNumber;
  235. KIRQL Irql;
  236. ULONG Hint;
  237. // M0018 +++
  238. #if defined(_DMA_EXPAND_)
  239. ULONG Limit;
  240. #endif //_DMA_EXPAND_
  241. // M0018 ---
  242. //
  243. // Begin by obtaining a pointer to the master adapter associated with this
  244. // request.
  245. //
  246. if (AdapterObject->MasterAdapter != NULL) {
  247. MasterAdapter = AdapterObject->MasterAdapter;
  248. } else {
  249. MasterAdapter = AdapterObject;
  250. }
  251. //
  252. // Initialize the device object's wait context block in case this device
  253. // must wait before being able to allocate the adapter.
  254. //
  255. Wcb->DeviceRoutine = ExecutionRoutine;
  256. Wcb->NumberOfMapRegisters = NumberOfMapRegisters;
  257. //
  258. // Allocate the adapter object for this particular device. If the
  259. // adapter cannot be allocated because it has already been allocated
  260. // to another device, then return to the caller now; otherwise,
  261. // continue.
  262. //
  263. if (!KeInsertDeviceQueue( &AdapterObject->ChannelWaitQueue,
  264. &Wcb->WaitQueueEntry )) {
  265. //
  266. // The adapter was not busy so it has been allocated. Now check
  267. // to see whether this driver wishes to allocate any map registers.
  268. // If so, then queue the device object to the master adapter queue
  269. // to wait for them to become available. If the driver wants map
  270. // registers, ensure that this adapter has enough total map registers
  271. // to satisfy the request.
  272. //
  273. AdapterObject->CurrentWcb = Wcb;
  274. AdapterObject->NumberOfMapRegisters = Wcb->NumberOfMapRegisters;
  275. if (NumberOfMapRegisters != 0) {
  276. if (NumberOfMapRegisters > MasterAdapter->MapRegistersPerChannel) {
  277. AdapterObject->NumberOfMapRegisters = 0;
  278. IoFreeAdapterChannel(AdapterObject);
  279. return(STATUS_INSUFFICIENT_RESOURCES);
  280. }
  281. //
  282. // Lock the map register bit map and the adapter queue in the
  283. // master adapter object. The channel structure offset is used as
  284. // a hint for the register search.
  285. //
  286. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  287. MapRegisterNumber = -1;
  288. if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
  289. // M0018 +++
  290. #if defined(_DMA_EXPAND_)
  291. if (AdapterObject->Dma32BitAddresses) {
  292. Hint = EISA_MIN_ADR / PAGE_SIZE;
  293. Limit = EISA_MAX_ADR / PAGE_SIZE;
  294. } else {
  295. Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  296. Limit = ISA_MAX_ADR / PAGE_SIZE - NumberOfMapRegisters;
  297. }
  298. #else // _DMA_EXPAND_
  299. // Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  300. Hint = (0x100000 / PAGE_SIZE); // M0024
  301. #endif // _DMA_EXPAND_
  302. // M0018 ---
  303. MapRegisterNumber = RtlFindClearBitsAndSet(
  304. MasterAdapter->MapRegisters,
  305. NumberOfMapRegisters,
  306. Hint
  307. );
  308. //
  309. // Make sure this map register is valid for this adapter.
  310. //
  311. if ((ULONG) MapRegisterNumber < Hint) {
  312. //
  313. // Make it look like there are no map registers.
  314. //
  315. RtlClearBits(
  316. MasterAdapter->MapRegisters,
  317. MapRegisterNumber,
  318. NumberOfMapRegisters
  319. );
  320. MapRegisterNumber = -1;
  321. }
  322. // M0018 +++
  323. #if defined(_DMA_EXPAND_)
  324. //
  325. // Make sure this map register is valid for this adapter.
  326. //
  327. if ((ULONG) MapRegisterNumber >= Limit ) {
  328. //
  329. // Make it look like there are no map registers.
  330. //
  331. RtlClearBits(
  332. MasterAdapter->MapRegisters,
  333. MapRegisterNumber,
  334. NumberOfMapRegisters
  335. );
  336. MapRegisterNumber = -1;
  337. }
  338. #endif // _DMA_EXPAND_
  339. // M0018 ---
  340. }
  341. if (MapRegisterNumber == -1) {
  342. //
  343. // There were not enough free map registers. Queue this request
  344. // on the master adapter where is will wait until some registers
  345. // are deallocated.
  346. //
  347. InsertTailList( &MasterAdapter->AdapterQueue,
  348. &AdapterObject->AdapterQueue
  349. );
  350. Busy = 1;
  351. } else {
  352. AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
  353. }
  354. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  355. }
  356. //
  357. // If there were either enough map registers available or no map
  358. // registers needed to be allocated, invoke the driver's execution
  359. // routine now.
  360. //
  361. if (!Busy) {
  362. Action = ExecutionRoutine( Wcb->DeviceObject,
  363. Wcb->CurrentIrp,
  364. AdapterObject->MapRegisterBase,
  365. Wcb->DeviceContext
  366. );
  367. //
  368. // If the driver wishes to keep the map registers then set the number
  369. // allocated to zero and set the action to deallocate object.
  370. //
  371. if (Action == DeallocateObjectKeepRegisters) {
  372. AdapterObject->NumberOfMapRegisters = 0;
  373. Action = DeallocateObject;
  374. }
  375. //
  376. // If the driver would like to have the adapter deallocated,
  377. // then deallocate any map registers allocated and then release
  378. // the adapter object.
  379. //
  380. if (Action == DeallocateObject) {
  381. IoFreeAdapterChannel( AdapterObject );
  382. }
  383. }
  384. }
  385. return(STATUS_SUCCESS);
  386. }
  387. PVOID
  388. HalAllocateCommonBuffer(
  389. IN PADAPTER_OBJECT AdapterObject,
  390. IN ULONG Length,
  391. OUT PPHYSICAL_ADDRESS LogicalAddress,
  392. IN BOOLEAN CacheEnabled
  393. )
  394. /*++
  395. Routine Description:
  396. This function allocates the memory for a common buffer and maps so that it
  397. can be accessed by a master device and the CPU.
  398. Arguments:
  399. AdapterObject - Supplies a pointer to the adapter object used by this
  400. device.
  401. Length - Supplies the length of the common buffer to be allocated.
  402. LogicalAddress - Returns the logical address of the common buffer.
  403. CacheEnable - Indicates whether the memeory is cached or not.
  404. Return Value:
  405. Returns the virtual address of the common buffer. If the buffer cannot be
  406. allocated then NULL is returned.
  407. --*/
  408. {
  409. PVOID virtualAddress;
  410. PVOID mapRegisterBase;
  411. ULONG numberOfMapRegisters;
  412. ULONG mappedLength;
  413. WAIT_CONTEXT_BLOCK wcb;
  414. KEVENT allocationEvent;
  415. NTSTATUS status;
  416. PMDL mdl;
  417. KIRQL irql;
  418. numberOfMapRegisters = BYTES_TO_PAGES(Length);
  419. //
  420. // Allocate the actual buffer.
  421. //
  422. if (CacheEnabled != FALSE) {
  423. virtualAddress = ExAllocatePool(NonPagedPoolCacheAligned, Length);
  424. } else {
  425. virtualAddress = MmAllocateNonCachedMemory(Length);
  426. }
  427. if (virtualAddress == NULL) {
  428. return(virtualAddress);
  429. }
  430. //
  431. // Initialize an event.
  432. //
  433. KeInitializeEvent( &allocationEvent, NotificationEvent, FALSE);
  434. //
  435. // Initialize the wait context block. Use the device object to indicate
  436. // where the map register base should be stored.
  437. //
  438. wcb.DeviceObject = &mapRegisterBase;
  439. wcb.CurrentIrp = NULL;
  440. wcb.DeviceContext = &allocationEvent;
  441. //
  442. // Allocate the adapter and the map registers.
  443. //
  444. KeRaiseIrql(DISPATCH_LEVEL, &irql);
  445. status = HalAllocateAdapterChannel(
  446. AdapterObject,
  447. &wcb,
  448. numberOfMapRegisters,
  449. HalpAllocationRoutine
  450. );
  451. KeLowerIrql(irql);
  452. if (!NT_SUCCESS(status)) {
  453. //
  454. // Cleanup and return NULL.
  455. //
  456. if (CacheEnabled != FALSE) {
  457. ExFreePool(virtualAddress);
  458. } else {
  459. MmFreeNonCachedMemory(virtualAddress, Length);
  460. }
  461. return(NULL);
  462. }
  463. //
  464. // Wait for the map registers to be allocated.
  465. //
  466. status = KeWaitForSingleObject(
  467. &allocationEvent,
  468. Executive,
  469. KernelMode,
  470. FALSE,
  471. NULL
  472. );
  473. if (!NT_SUCCESS(status)) {
  474. //
  475. // Cleanup and return NULL.
  476. //
  477. if (CacheEnabled != FALSE) {
  478. ExFreePool(virtualAddress);
  479. } else {
  480. MmFreeNonCachedMemory(virtualAddress, Length);
  481. }
  482. return(NULL);
  483. }
  484. //
  485. // Create an mdl to use with call to I/O map transfer.
  486. //
  487. mdl = IoAllocateMdl(
  488. virtualAddress,
  489. Length,
  490. FALSE,
  491. FALSE,
  492. NULL
  493. );
  494. MmBuildMdlForNonPagedPool(mdl);
  495. //
  496. // Map the transfer so that the controller can access the memory.
  497. //
  498. mappedLength = Length;
  499. *LogicalAddress = IoMapTransfer(
  500. NULL,
  501. mdl,
  502. mapRegisterBase,
  503. virtualAddress,
  504. &mappedLength,
  505. TRUE
  506. );
  507. IoFreeMdl(mdl);
  508. if (mappedLength < Length) {
  509. //
  510. // Cleanup and indicate that the allocation failed.
  511. //
  512. HalFreeCommonBuffer(
  513. AdapterObject,
  514. Length,
  515. *LogicalAddress,
  516. virtualAddress,
  517. CacheEnabled
  518. );
  519. return(NULL);
  520. }
  521. //
  522. // The allocation completed successfully.
  523. //
  524. return(virtualAddress);
  525. }
  526. PVOID
  527. HalAllocateCrashDumpRegisters(
  528. IN PADAPTER_OBJECT AdapterObject,
  529. IN PULONG NumberOfMapRegisters
  530. )
  531. /*++
  532. Routine Description:
  533. This routine is called during the crash dump disk driver's initialization
  534. to allocate a number map registers permanently.
  535. Arguments:
  536. AdapterObject - Pointer to the adapter control object to allocate to the
  537. driver.
  538. NumberOfMapRegisters - Number of map registers requested and update to show
  539. number actually allocated.
  540. Return Value:
  541. Returns STATUS_SUCESS if map registers allocated.
  542. --*/
  543. {
  544. PADAPTER_OBJECT MasterAdapter;
  545. ULONG MapRegisterNumber;
  546. ULONG Hint;
  547. // M0018 +++
  548. #if defined(_DMA_EXPAND_)
  549. ULONG Limit;
  550. #endif // _DMA_EXPAND_
  551. // M0018 ---
  552. //
  553. // Begin by obtaining a pointer to the master adapter associated with this
  554. // request.
  555. //
  556. if (AdapterObject->MasterAdapter) {
  557. MasterAdapter = AdapterObject->MasterAdapter;
  558. } else {
  559. MasterAdapter = AdapterObject;
  560. }
  561. //
  562. // Ensure that this adapter has enough total map registers to satisfy
  563. // the request.
  564. //
  565. if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) {
  566. AdapterObject->NumberOfMapRegisters = 0;
  567. return NULL;
  568. }
  569. //
  570. // Attempt to allocate the required number of map registers w/o
  571. // affecting those registers that were allocated when the system
  572. // crashed. Note that once again the map registers to be allocated
  573. // must be above the 1MB range if this is an EISA bus device.
  574. //
  575. MapRegisterNumber = (ULONG)-1;
  576. // M0018 +++
  577. #if defined(_DMA_EXPAND_)
  578. if (AdapterObject->Dma32BitAddresses) {
  579. Hint = EISA_MIN_ADR / PAGE_SIZE;
  580. Limit = EISA_MAX_ADR / PAGE_SIZE;
  581. } else {
  582. Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  583. Limit = ISA_MAX_ADR / PAGE_SIZE - *NumberOfMapRegisters;
  584. }
  585. #else // _DMA_EXPAND
  586. // Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  587. Hint = (0x100000 / PAGE_SIZE); // M0024
  588. #endif // _DMA_EXPAND_
  589. // M0018 ---
  590. MapRegisterNumber = RtlFindClearBitsAndSet(
  591. MasterAdapter->MapRegisters,
  592. *NumberOfMapRegisters,
  593. Hint
  594. );
  595. //
  596. // Ensure that any allocated map registers are valid for this adapter.
  597. //
  598. if ((ULONG) MapRegisterNumber < Hint) {
  599. //
  600. // Make it appear as if there are no map registers.
  601. //
  602. RtlClearBits(
  603. MasterAdapter->MapRegisters,
  604. MapRegisterNumber,
  605. *NumberOfMapRegisters
  606. );
  607. MapRegisterNumber = (ULONG) -1;
  608. }
  609. // M0018 +++
  610. #if defined(_DMA_EXPAND_)
  611. //
  612. // Make sure this map register is valid for this adapter.
  613. //
  614. if ((ULONG) MapRegisterNumber >= Limit ) {
  615. //
  616. // Make it look like there are no map registers.
  617. //
  618. RtlClearBits(
  619. MasterAdapter->MapRegisters,
  620. MapRegisterNumber,
  621. *NumberOfMapRegisters
  622. );
  623. MapRegisterNumber = (ULONG) -1;
  624. }
  625. #endif // _DMA_EXPAND_
  626. // M0018 ---
  627. if (MapRegisterNumber == (ULONG)-1) {
  628. //
  629. // Not enough free map registers were found, so they were busy
  630. // being used by the system when it crashed. Force the appropriate
  631. // number to be "allocated" at the base by simply overjamming the
  632. // bits and return the base map register as the start.
  633. //
  634. RtlSetBits(
  635. MasterAdapter->MapRegisters,
  636. Hint,
  637. *NumberOfMapRegisters
  638. );
  639. MapRegisterNumber = Hint;
  640. }
  641. //
  642. // Calculate the map register base from the allocated map
  643. // register and base of the master adapter object.
  644. //
  645. AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
  646. return AdapterObject->MapRegisterBase;
  647. }
  648. BOOLEAN
  649. HalFlushCommonBuffer(
  650. IN PADAPTER_OBJECT AdapterObject,
  651. IN ULONG Length,
  652. IN PHYSICAL_ADDRESS LogicalAddress,
  653. IN PVOID VirtualAddress
  654. )
  655. /*++
  656. Routine Description:
  657. This function is called to flush any hardware adapter buffers when the
  658. driver needs to read data written by an I/O master device to a common
  659. buffer.
  660. Arguments:
  661. AdapterObject - Supplies a pointer to the adapter object used by this
  662. device.
  663. Length - Supplies the length of the common buffer. This should be the same
  664. value used for the allocation of the buffer.
  665. LogicalAddress - Supplies the logical address of the common buffer. This
  666. must be the same value return by HalAllocateCommonBuffer.
  667. VirtualAddress - Supplies the virtual address of the common buffer. This
  668. must be the same value return by HalAllocateCommonBuffer.
  669. Return Value:
  670. Returns TRUE if no errors were detected; otherwise, FALSE is return.
  671. --*/
  672. {
  673. #if 0 // M0008
  674. /* M0006 +++ */
  675. #if defined(_BETA_LIMIT_)
  676. {
  677. ULONG PtagReg, Ptag, LtagReg, Ltag, DummyRead, i;
  678. KIRQL OldIrql;
  679. // D001
  680. // DbgPrint("DmaFlush start\n");
  681. KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
  682. for (i = 0; i < 8; i++ ) {
  683. PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
  684. LtagReg = (ULONG)&DMA_CONTROL->IoCacheLogicalTag[i];
  685. Ptag = READ_REGISTER_ULONG(PtagReg);
  686. Ltag = READ_REGISTER_ULONG(LtagReg);
  687. if (Ptag & 0x1) {
  688. if (Ltag & 0x1) {
  689. if ((LogicalAddress.LowPart & 0xffffffc0) <= (Ltag & 0xffffffc0) && ((Ltag & 0xffffffc0) < (LogicalAddress.LowPart + Length))) {
  690. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  691. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  692. if (HalDebug)
  693. DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
  694. PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
  695. }
  696. }
  697. }
  698. }
  699. KeLowerIrql(OldIrql);
  700. // DbgPrint("DmaFlush end\n");
  701. }
  702. #endif // _BETA_LIMIT_
  703. /* M0006 --- */
  704. #endif // 0 // M0008
  705. return(TRUE);
  706. }
  707. VOID
  708. HalFreeCommonBuffer(
  709. IN PADAPTER_OBJECT AdapterObject,
  710. IN ULONG Length,
  711. IN PHYSICAL_ADDRESS LogicalAddress,
  712. IN PVOID VirtualAddress,
  713. IN BOOLEAN CacheEnabled
  714. )
  715. /*++
  716. Routine Description:
  717. This function frees a common buffer and all of the resouces it uses.
  718. Arguments:
  719. AdapterObject - Supplies a pointer to the adapter object used by this
  720. device.
  721. Length - Supplies the length of the common buffer. This should be the same
  722. value used for the allocation of the buffer.
  723. LogicalAddress - Supplies the logical address of the common buffer. This
  724. must be the same value return by HalAllocateCommonBuffer.
  725. VirtualAddress - Supplies the virtual address of the common buffer. This
  726. must be the same value return by HalAllocateCommonBuffer.
  727. CacheEnable - Indicates whether the memeory is cached or not.
  728. Return Value:
  729. None
  730. --*/
  731. {
  732. PTRANSLATION_ENTRY mapRegisterBase;
  733. ULONG numberOfMapRegisters;
  734. ULONG mapRegisterNumber;
  735. //
  736. // Calculate the number of map registers, the map register number and
  737. // the map register base.
  738. //
  739. numberOfMapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);
  740. mapRegisterNumber = LogicalAddress.LowPart >> PAGE_SHIFT;
  741. mapRegisterBase = (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase
  742. + mapRegisterNumber;
  743. //
  744. // Free the map registers.
  745. //
  746. IoFreeMapRegisters(
  747. AdapterObject,
  748. (PVOID) mapRegisterBase,
  749. numberOfMapRegisters
  750. );
  751. //
  752. // Free the memory for the common buffer.
  753. //
  754. if (CacheEnabled != FALSE) {
  755. ExFreePool(VirtualAddress);
  756. } else {
  757. MmFreeNonCachedMemory(VirtualAddress, Length);
  758. }
  759. return;
  760. }
  761. PADAPTER_OBJECT
  762. HalGetAdapter(
  763. IN PDEVICE_DESCRIPTION DeviceDescription,
  764. IN OUT PULONG NumberOfMapRegisters
  765. )
  766. /*++
  767. Routine Description:
  768. This function returns the appropriate adapter object for the device defined
  769. in the device description structure. Three bus types are supported for the
  770. system: Internal, Isa, and Eisa.
  771. Arguments:
  772. DeviceDescription - Supplies a description of the deivce.
  773. NumberOfMapRegisters - Returns the maximum number of map registers which
  774. may be allocated by the device driver.
  775. Return Value:
  776. A pointer to the requested adapter object or NULL if an adapter could not
  777. be created.
  778. --*/
  779. {
  780. PADAPTER_OBJECT adapterObject;
  781. // M0020 +++
  782. #if DBG
  783. #if defined (_DMA_EXPAND_)
  784. DbgPrint("\nHalGetAdapter(): DeviceDescription->32BitAddresses = %d\n",DeviceDescription->Dma32BitAddresses);
  785. #endif // _DMA_EXPAND_
  786. #endif // DBG
  787. // M0020 ---
  788. //
  789. // Make sure this is the correct version.
  790. //
  791. if (DeviceDescription->Version > DEVICE_DESCRIPTION_VERSION1) {
  792. return(NULL);
  793. }
  794. //
  795. // Return number of map registers requested based on the maximum
  796. // transfer length.
  797. //
  798. *NumberOfMapRegisters = BYTES_TO_PAGES(DeviceDescription->MaximumLength) + 1;
  799. if (*NumberOfMapRegisters > DMA_REQUEST_LIMIT) {
  800. *NumberOfMapRegisters = DMA_REQUEST_LIMIT;
  801. }
  802. if (DeviceDescription->InterfaceType == Internal) {
  803. //
  804. // Return the adapter pointer for internal adapters.
  805. //
  806. // If this is a master controler such as the SONIC then return the
  807. // last channel.
  808. //
  809. if (DeviceDescription->Master) {
  810. // M0018 +++
  811. #if defined(_DMA_EXPAND_)
  812. //
  813. // Create an adapter.
  814. //
  815. adapterObject = HalpAllocateAdapter(
  816. 0,
  817. (PVOID) &(DMA_CONTROL)->Channel[7],
  818. NULL
  819. );
  820. adapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
  821. // M0020 +++
  822. #if DBG
  823. DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
  824. #endif DBG
  825. if (adapterObject->Dma32BitAddresses) {
  826. if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
  827. / PAGE_SIZE / 8L) {
  828. *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
  829. / PAGE_SIZE / 8L;
  830. }
  831. } else {
  832. if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
  833. *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
  834. }
  835. }
  836. #if DBG
  837. DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
  838. DbgPrint("internal master adapterObject->Dma32BitAddresses = %d\n",adapterObject->Dma32BitAddresses);
  839. #endif // DBG
  840. // M0020 ---
  841. return(adapterObject);
  842. #else // _DMA_EXPAND
  843. //
  844. // Create an adapter if necessary.
  845. //
  846. if (HalpInternalAdapters[7] == NULL) {
  847. HalpInternalAdapters[7] = HalpAllocateAdapter(
  848. 0,
  849. (PVOID) &(DMA_CONTROL)->Channel[7],
  850. NULL
  851. );
  852. }
  853. return(HalpInternalAdapters[7]);
  854. #endif // _DMA_EXPAND_
  855. // M0018 ---
  856. }
  857. //
  858. // Make sure the DMA channel range is valid. Only use channels 0-6.
  859. //
  860. /* start M0001 */
  861. #if defined(_R94A_)
  862. if (DeviceDescription->DmaChannel > 3) { // duo and r94a have only 0-3 channel
  863. return(NULL);
  864. }
  865. #else // _R94A_
  866. if (DeviceDescription->DmaChannel > 6) {
  867. return(NULL);
  868. }
  869. #endif // _R94A_
  870. /* end M0001 */
  871. //
  872. // If necessary allocate an adapter; otherwise,
  873. // just return the adapter for the requested channel.
  874. //
  875. if (HalpInternalAdapters[DeviceDescription->DmaChannel] == NULL) {
  876. HalpInternalAdapters[DeviceDescription->DmaChannel] =
  877. HalpAllocateAdapter(
  878. 0,
  879. (PVOID) &(DMA_CONTROL)->Channel[DeviceDescription->DmaChannel],
  880. NULL
  881. );
  882. }
  883. // M0012 +++
  884. #if defined(_R94A_)
  885. // M0020 +++
  886. #if DBG
  887. DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
  888. #endif DBG
  889. // M0020 ---
  890. //
  891. // Internal slave dma limit 1MB. (TYPHOON tip limit)
  892. //
  893. if (*NumberOfMapRegisters > ( 0x100000 >> PAGE_SHIFT )) {
  894. *NumberOfMapRegisters = ( 0x100000 >> PAGE_SHIFT );
  895. }
  896. #endif // _R94A_
  897. // M0012 ---
  898. if (*NumberOfMapRegisters > MasterAdapterObject->MapRegistersPerChannel / 4) {
  899. *NumberOfMapRegisters = MasterAdapterObject->MapRegistersPerChannel / 4;
  900. }
  901. // M0018 +++
  902. #if defined(_DMA_EXPAND_)
  903. // M0020 +++
  904. if (HalpInternalAdapters[DeviceDescription->DmaChannel]->Dma32BitAddresses) { // S0021
  905. if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
  906. / PAGE_SIZE / 8L) {
  907. *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
  908. / PAGE_SIZE / 8L;
  909. }
  910. } else {
  911. if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
  912. *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
  913. }
  914. }
  915. HalpInternalAdapters[DeviceDescription->DmaChannel]->Dma32BitAddresses
  916. = DeviceDescription->Dma32BitAddresses;
  917. #if DBG
  918. DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
  919. DbgPrint("internal slave HalpInternalAdapters[%d]->Dma32BitAddresses = %d\n",
  920. DeviceDescription->DmaChannel,
  921. HalpInternalAdapters[DeviceDescription->DmaChannel]->Dma32BitAddresses);
  922. #endif // DBG
  923. // M0020 ---
  924. #endif // _DMA_EXPAND_
  925. // M0018 ---
  926. return(HalpInternalAdapters[DeviceDescription->DmaChannel]);
  927. }
  928. /* start M0001 */
  929. #if defined(_R94A_)
  930. //
  931. // PCI Bus check.
  932. //
  933. if (DeviceDescription->InterfaceType == PCIBus) {
  934. adapterObject = HalpAllocatePCIAdapter( DeviceDescription );
  935. if (*NumberOfMapRegisters > MasterAdapterObject->MapRegistersPerChannel / 4) {
  936. *NumberOfMapRegisters = MasterAdapterObject->MapRegistersPerChannel / 4;
  937. }
  938. // M0018 +++
  939. #if defined(_DMA_EXPAND_)
  940. // M0020 +++
  941. if (adapterObject->Dma32BitAddresses) {
  942. if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
  943. / PAGE_SIZE / 8L) {
  944. *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
  945. / PAGE_SIZE / 8L;
  946. }
  947. } else {
  948. if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
  949. *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
  950. }
  951. }
  952. adapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
  953. #if DBG
  954. DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
  955. DbgPrint("PCI master adapterObject->Dma32BitAddresses = %d\n",adapterObject->Dma32BitAddresses);
  956. #endif // DBG
  957. // M0020 ---
  958. #endif // _DMA_EXPAND_
  959. // M0018 ---
  960. return(adapterObject); // B0016
  961. }
  962. #endif // _R94A_
  963. /* end M0001 */
  964. //
  965. // If the request is for a unsupported bus then return NULL.
  966. //
  967. if (DeviceDescription->InterfaceType != Isa &&
  968. DeviceDescription->InterfaceType != Eisa) {
  969. //
  970. // This bus type is unsupported return NULL.
  971. //
  972. return(NULL);
  973. }
  974. // M0020 +++
  975. #if DBG
  976. DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
  977. #endif DBG
  978. // M0020 ---
  979. //
  980. // Create an adapter object.
  981. //
  982. adapterObject = HalpAllocateEisaAdapter( DeviceDescription );
  983. if (*NumberOfMapRegisters > MasterAdapterObject->MapRegistersPerChannel / 4) {
  984. *NumberOfMapRegisters = MasterAdapterObject->MapRegistersPerChannel / 4;
  985. }
  986. // M0018 +++
  987. #if defined(_DMA_EXPAND_)
  988. // M0020 +++
  989. if (adapterObject->Dma32BitAddresses) {
  990. if (*NumberOfMapRegisters > (EISA_MAX_ADR - EISA_MIN_ADR)
  991. / PAGE_SIZE / 8L) {
  992. *NumberOfMapRegisters = (EISA_MAX_ADR - EISA_MIN_ADR)
  993. / PAGE_SIZE / 8L;
  994. }
  995. } else {
  996. if (*NumberOfMapRegisters > ISA_MAX_ADR / PAGE_SIZE / 8L) {
  997. *NumberOfMapRegisters = ISA_MAX_ADR / PAGE_SIZE / 8L;
  998. }
  999. }
  1000. #if DBG
  1001. DbgPrint("*NumberOfMapRegisters = %d\n",*NumberOfMapRegisters);
  1002. DbgPrint("eisa/isa adapterObject->Dma32BitAddresses = %d\n",adapterObject->Dma32BitAddresses);
  1003. #endif // DBG
  1004. // M0020 ---
  1005. #endif // _DMA_EXPAND_
  1006. // M0018 ---
  1007. return(adapterObject);
  1008. }
  1009. #if 0 // CHG0001
  1010. BOOLEAN
  1011. HalTranslateBusAddress(
  1012. IN INTERFACE_TYPE InterfaceType,
  1013. IN ULONG BusNumber,
  1014. IN PHYSICAL_ADDRESS BusAddress,
  1015. IN OUT PULONG AddressSpace,
  1016. OUT PPHYSICAL_ADDRESS TranslatedAddress
  1017. )
  1018. /*++
  1019. Routine Description:
  1020. This function returns the system physical address for a specified I/O bus
  1021. address. The return value is suitable for use in a subsequent call to
  1022. MmMapIoSpace.
  1023. Arguments:
  1024. InterfaceType - Supplies the type of bus which the address is for.
  1025. BusNumber - Supplies the bus number for the device.
  1026. BusAddress - Supplies the bus relative address.
  1027. AddressSpace - Supplies the address space number for the device: 0 for
  1028. memory and 1 for I/O space. Returns the address space on this system.
  1029. TranslatedAddress - Supplies a pointer to return the translated address
  1030. Return Value:
  1031. A return value of TRUE indicates that a system physical address
  1032. corresponding to the supplied bus relative address and bus address
  1033. number has been returned in TranslatedAddress.
  1034. A return value of FALSE occurs if the translation for the address was
  1035. not possible
  1036. --*/
  1037. {
  1038. TranslatedAddress->HighPart = 0;
  1039. //
  1040. // If this is for the internal bus then just return the passed parameter.
  1041. //
  1042. if (InterfaceType == Internal) {
  1043. //
  1044. // Return the passed parameters.
  1045. //
  1046. TranslatedAddress->LowPart = BusAddress.LowPart;
  1047. return(TRUE);
  1048. }
  1049. /* start M0001 */
  1050. #if defined(_R94A_)
  1051. if (InterfaceType != Isa && InterfaceType != Eisa && InterfaceType != PCIBus) {
  1052. #else // _R94A_
  1053. if (InterfaceType != Isa && InterfaceType != Eisa) {
  1054. #endif // _R94A_
  1055. /* end M0001 */
  1056. //
  1057. // Not on this system return nothing.
  1058. //
  1059. *AddressSpace = 0;
  1060. TranslatedAddress->LowPart = 0;
  1061. return(FALSE);
  1062. }
  1063. //
  1064. // There is only one I/O bus which is an EISA, so the bus number is unused.
  1065. //
  1066. // Determine the address based on whether the bus address is in I/O space
  1067. // or bus memory space.
  1068. //
  1069. if (*AddressSpace) {
  1070. //
  1071. // The address is in I/O space.
  1072. //
  1073. *AddressSpace = 0;
  1074. TranslatedAddress->LowPart = BusAddress.LowPart + EISA_CONTROL_PHYSICAL_BASE;
  1075. if (TranslatedAddress->LowPart < BusAddress.LowPart) {
  1076. //
  1077. // A carry occurred.
  1078. //
  1079. TranslatedAddress->HighPart = 1;
  1080. }
  1081. return(TRUE);
  1082. } else {
  1083. //
  1084. // The address is in memory space.
  1085. //
  1086. *AddressSpace = 0;
  1087. #if !defined(_DUO_)
  1088. if (DMA_CONTROL->RevisionLevel.Long < 2) {
  1089. TranslatedAddress->LowPart = BusAddress.LowPart + EISA_MEMORY_PHYSICAL_BASE;
  1090. } else {
  1091. TranslatedAddress->LowPart = BusAddress.LowPart + EISA_MEMORY_VERSION2_LOW;
  1092. TranslatedAddress->HighPart = EISA_MEMORY_VERSION2_HIGH;
  1093. }
  1094. #else
  1095. TranslatedAddress->LowPart = BusAddress.LowPart + EISA_MEMORY_VERSION2_LOW;
  1096. TranslatedAddress->HighPart = EISA_MEMORY_VERSION2_HIGH;
  1097. #endif
  1098. if (TranslatedAddress->LowPart < BusAddress.LowPart) {
  1099. //
  1100. // A carry occurred.
  1101. //
  1102. TranslatedAddress->HighPart = 1;
  1103. }
  1104. return(TRUE);
  1105. }
  1106. }
  1107. #endif
  1108. PADAPTER_OBJECT
  1109. HalpAllocateAdapter(
  1110. IN ULONG MapRegistersPerChannel,
  1111. IN PVOID AdapterBaseVa,
  1112. IN PVOID MapRegisterBase
  1113. )
  1114. /*++
  1115. Routine Description:
  1116. This routine allocates and initializes an adapter object to represent an
  1117. adapter or a DMA controller on the system.
  1118. Arguments:
  1119. MapRegistersPerChannel - Unused.
  1120. AdapterBaseVa - Base virtual address of the adapter itself. If AdapterBaseVa
  1121. is NULL then the MasterAdapterObject is allocated.
  1122. MapRegisterBase - Unused.
  1123. Return Value:
  1124. The function value is a pointer to the allocate adapter object.
  1125. --*/
  1126. {
  1127. PADAPTER_OBJECT AdapterObject;
  1128. OBJECT_ATTRIBUTES ObjectAttributes;
  1129. ULONG Size;
  1130. ULONG BitmapSize;
  1131. HANDLE Handle;
  1132. NTSTATUS Status;
  1133. ULONG Mode;
  1134. //
  1135. // Initalize the master adapter if necessary.
  1136. //
  1137. if (MasterAdapterObject == NULL && AdapterBaseVa != NULL ) {
  1138. MasterAdapterObject = HalpAllocateAdapter( 0,
  1139. NULL,
  1140. NULL
  1141. );
  1142. //
  1143. // If we could not allocate the master adapter then give up.
  1144. //
  1145. if (MasterAdapterObject == NULL) {
  1146. return(NULL);
  1147. }
  1148. }
  1149. //
  1150. // Begin by initializing the object attributes structure to be used when
  1151. // creating the adapter object.
  1152. //
  1153. InitializeObjectAttributes( &ObjectAttributes,
  1154. NULL,
  1155. OBJ_PERMANENT,
  1156. (HANDLE) NULL,
  1157. (PSECURITY_DESCRIPTOR) NULL
  1158. );
  1159. //
  1160. // Determine the size of the adapter object. If this is the master object
  1161. // then allocate space for the register bit map; otherwise, just allocate
  1162. // an adapter object.
  1163. //
  1164. if (AdapterBaseVa == NULL) {
  1165. BitmapSize = (((sizeof( RTL_BITMAP ) +
  1166. ((DMA_TRANSLATION_LIMIT / sizeof( TRANSLATION_ENTRY)) + 7 >> 3))
  1167. + 3) & ~3);
  1168. Size = sizeof( ADAPTER_OBJECT ) + BitmapSize;
  1169. } else {
  1170. Size = sizeof( ADAPTER_OBJECT );
  1171. }
  1172. //
  1173. // Now create the adapter object.
  1174. //
  1175. Status = ObCreateObject( KernelMode,
  1176. *((POBJECT_TYPE *)IoAdapterObjectType),
  1177. &ObjectAttributes,
  1178. KernelMode,
  1179. (PVOID) NULL,
  1180. Size,
  1181. 0,
  1182. 0,
  1183. (PVOID *)&AdapterObject );
  1184. //
  1185. // Reference the object.
  1186. //
  1187. if (NT_SUCCESS(Status)) {
  1188. Status = ObReferenceObjectByPointer(
  1189. AdapterObject,
  1190. FILE_READ_DATA | FILE_WRITE_DATA,
  1191. *((POBJECT_TYPE *)IoAdapterObjectType),
  1192. KernelMode
  1193. );
  1194. }
  1195. //
  1196. // If the adapter object was successfully created, then attempt to insert
  1197. // it into the the object table.
  1198. //
  1199. if (NT_SUCCESS( Status )) {
  1200. Status = ObInsertObject( AdapterObject,
  1201. NULL,
  1202. FILE_READ_DATA | FILE_WRITE_DATA,
  1203. 0,
  1204. (PVOID *) NULL,
  1205. &Handle );
  1206. if (NT_SUCCESS( Status )) {
  1207. ZwClose( Handle );
  1208. //
  1209. // Initialize the adapter object itself.
  1210. //
  1211. AdapterObject->Type = IO_TYPE_ADAPTER;
  1212. AdapterObject->Size = (USHORT) Size;
  1213. AdapterObject->MapRegistersPerChannel =
  1214. DMA_TRANSLATION_LIMIT / sizeof( TRANSLATION_ENTRY);
  1215. AdapterObject->AdapterBaseVa = AdapterBaseVa;
  1216. AdapterObject->MasterAdapter = MasterAdapterObject;
  1217. AdapterObject->PagePort = NULL;
  1218. //
  1219. // Initialize the channel wait queue for this
  1220. // adapter.
  1221. //
  1222. KeInitializeDeviceQueue( &AdapterObject->ChannelWaitQueue );
  1223. //
  1224. // If this is the MasterAdatper then initialize the register bit map,
  1225. // AdapterQueue and the spin lock.
  1226. //
  1227. if ( AdapterBaseVa == NULL ) {
  1228. ULONG MapRegisterSize;
  1229. KeInitializeSpinLock( &AdapterObject->SpinLock );
  1230. InitializeListHead( &AdapterObject->AdapterQueue );
  1231. AdapterObject->MapRegisters = (PVOID) ( AdapterObject + 1);
  1232. RtlInitializeBitMap( AdapterObject->MapRegisters,
  1233. (PULONG) (((PCHAR) (AdapterObject->MapRegisters)) + sizeof( RTL_BITMAP )),
  1234. DMA_TRANSLATION_LIMIT / sizeof( TRANSLATION_ENTRY)
  1235. );
  1236. RtlClearAllBits( AdapterObject->MapRegisters );
  1237. // M0018 +++
  1238. #if defined(_DMA_EXPAND_)
  1239. //
  1240. // set bit for unusable area
  1241. //
  1242. // M0020 +++
  1243. #if DBG
  1244. DbgPrint("translatiron start %x\n",HalpMapRegisterPhysicalBase);
  1245. DbgPrint("translatiron size %x\n",MapRegisterSize);
  1246. #endif // DBG
  1247. RtlFindClearBitsAndSet(
  1248. AdapterObject->MapRegisters,
  1249. ((EISA_MIN_ADR - ISA_MAX_ADR) / PAGE_SIZE),
  1250. (ISA_MAX_ADR / PAGE_SIZE)
  1251. );
  1252. DbgPrint("unused start %x\n",ISA_MAX_ADR / PAGE_SIZE);
  1253. DbgPrint("unused length %x\n",(EISA_MIN_ADR - ISA_MAX_ADR) / PAGE_SIZE);
  1254. // M0020 ---
  1255. #endif // _DMA_EXPAND_
  1256. // M0018 ---
  1257. //
  1258. // The memory for the map registers was allocated by
  1259. // HalpAllocateMapRegisters during phase 0 initialization.
  1260. //
  1261. MapRegisterSize = DMA_TRANSLATION_LIMIT;
  1262. MapRegisterSize = ROUND_TO_PAGES(MapRegisterSize);
  1263. //
  1264. // Convert the physical address to a non-cached virtual address.
  1265. //
  1266. AdapterObject->MapRegisterBase = (PVOID)
  1267. (HalpMapRegisterPhysicalBase | KSEG1_BASE);
  1268. WRITE_REGISTER_ULONG(
  1269. &DMA_CONTROL->TranslationBase.Long,
  1270. HalpMapRegisterPhysicalBase
  1271. );
  1272. WRITE_REGISTER_ULONG(
  1273. &DMA_CONTROL->TranslationLimit.Long,
  1274. MapRegisterSize
  1275. );
  1276. //
  1277. // Initialize the DMA mode registers for the Floppy, SCSI and Sound.
  1278. // The initialization values come fomr the System Specification.
  1279. //
  1280. #if defined(_JAZZ_)
  1281. Mode = 0;
  1282. ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_80NS;
  1283. ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_16BITS;
  1284. ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
  1285. ((PDMA_CHANNEL_MODE) &Mode)->BurstMode = 0;
  1286. ((PDMA_CHANNEL_MODE) &Mode)->FastDmaCycle = 1;
  1287. WRITE_REGISTER_ULONG(
  1288. &DMA_CONTROL->Channel[SCSI_CHANNEL].Mode.Long,
  1289. (ULONG) Mode
  1290. );
  1291. ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_120NS;
  1292. ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_8BITS;
  1293. ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
  1294. ((PDMA_CHANNEL_MODE) &Mode)->FastDmaCycle = 1;
  1295. WRITE_REGISTER_ULONG(
  1296. &DMA_CONTROL->Channel[FLOPPY_CHANNEL].Mode.Long,
  1297. (ULONG) Mode
  1298. );
  1299. ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_80NS;
  1300. ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_16BITS;
  1301. ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
  1302. ((PDMA_CHANNEL_MODE) &Mode)->BurstMode = 1;
  1303. WRITE_REGISTER_ULONG(
  1304. &DMA_CONTROL->Channel[SOUND_CHANNEL_A].Mode.Long,
  1305. (ULONG) Mode
  1306. );
  1307. ((PDMA_CHANNEL_MODE) &Mode)->AccessTime = ACCESS_80NS;
  1308. ((PDMA_CHANNEL_MODE) &Mode)->TransferWidth = WIDTH_16BITS;
  1309. ((PDMA_CHANNEL_MODE) &Mode)->InterruptEnable = 0;
  1310. ((PDMA_CHANNEL_MODE) &Mode)->BurstMode = 1;
  1311. WRITE_REGISTER_ULONG(
  1312. &DMA_CONTROL->Channel[SOUND_CHANNEL_B].Mode.Long,
  1313. (ULONG) Mode
  1314. );
  1315. #endif
  1316. }
  1317. } else {
  1318. //
  1319. // An error was incurred for some reason. Set the return value
  1320. // to NULL.
  1321. //
  1322. AdapterObject = (PADAPTER_OBJECT) NULL;
  1323. }
  1324. } else {
  1325. AdapterObject = (PADAPTER_OBJECT) NULL;
  1326. }
  1327. return AdapterObject;
  1328. return (PADAPTER_OBJECT) NULL;
  1329. }
  1330. VOID
  1331. IoFreeMapRegisters(
  1332. PADAPTER_OBJECT AdapterObject,
  1333. PVOID MapRegisterBase,
  1334. ULONG NumberOfMapRegisters
  1335. )
  1336. /*++
  1337. Routine Description:
  1338. This routine deallocates the map registers for the adapter. If there are
  1339. any queued adapter waiting for an attempt is made to allocate the next
  1340. entry.
  1341. Arguments:
  1342. AdapterObject - The adapter object to where the map register should be
  1343. returned.
  1344. MapRegisterBase - The map register base of the registers to be deallocated.
  1345. NumberOfMapRegisters - The number of registers to be deallocated.
  1346. Return Value:
  1347. None
  1348. --+*/
  1349. {
  1350. PADAPTER_OBJECT MasterAdapter;
  1351. LONG MapRegisterNumber;
  1352. PLIST_ENTRY Packet;
  1353. IO_ALLOCATION_ACTION Action;
  1354. PWAIT_CONTEXT_BLOCK Wcb;
  1355. KIRQL Irql;
  1356. ULONG Hint;
  1357. // M0018 +++
  1358. #if defined(_DMA_EXPAND_)
  1359. ULONG Limit;
  1360. #endif // _DMA_EXPAND_
  1361. // M0018 ---
  1362. //
  1363. // Begin by getting the address of the master adapter.
  1364. //
  1365. if (AdapterObject->MasterAdapter != NULL) {
  1366. MasterAdapter = AdapterObject->MasterAdapter;
  1367. } else {
  1368. MasterAdapter = AdapterObject;
  1369. }
  1370. MapRegisterNumber = (PTRANSLATION_ENTRY) MapRegisterBase -
  1371. (PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase;
  1372. //
  1373. // Acquire the master adapter spinlock which locks the adapter queue and the
  1374. // bit map for the map registers.
  1375. //
  1376. KeAcquireSpinLock(&MasterAdapter->SpinLock, &Irql);
  1377. //
  1378. // Return the registers to the bit map.
  1379. //
  1380. RtlClearBits( MasterAdapter->MapRegisters,
  1381. MapRegisterNumber,
  1382. NumberOfMapRegisters
  1383. );
  1384. //
  1385. // Process any requests waiting for map registers in the adapter queue.
  1386. // Requests are processed until a request cannot be satisfied or until
  1387. // there are no more requests in the queue.
  1388. //
  1389. while(TRUE) {
  1390. if ( IsListEmpty(&MasterAdapter->AdapterQueue) ){
  1391. break;
  1392. }
  1393. Packet = RemoveHeadList( &MasterAdapter->AdapterQueue );
  1394. AdapterObject = CONTAINING_RECORD( Packet,
  1395. ADAPTER_OBJECT,
  1396. AdapterQueue
  1397. );
  1398. Wcb = AdapterObject->CurrentWcb;
  1399. //
  1400. // Attempt to allocate map registers for this request. Use the previous
  1401. // register base as a hint.
  1402. //
  1403. // M0018 +++
  1404. #if defined(_DMA_EXPAND_)
  1405. if (AdapterObject->Dma32BitAddresses) {
  1406. Hint = EISA_MIN_ADR / PAGE_SIZE;
  1407. Limit = EISA_MAX_ADR / PAGE_SIZE;
  1408. } else {
  1409. Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  1410. Limit = ISA_MAX_ADR / PAGE_SIZE - NumberOfMapRegisters;
  1411. }
  1412. #else // _DMA_EXPAND_
  1413. // Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  1414. Hint = (0x100000 / PAGE_SIZE); // M0024
  1415. #endif // _DMA_EXPAND_
  1416. // M0018 ---
  1417. MapRegisterNumber = RtlFindClearBitsAndSet(
  1418. MasterAdapter->MapRegisters,
  1419. NumberOfMapRegisters,
  1420. Hint
  1421. );
  1422. //
  1423. // Make sure this map register is valid for this adapter.
  1424. //
  1425. if ((ULONG) MapRegisterNumber < Hint) {
  1426. //
  1427. // Make it look like there are no map registers.
  1428. //
  1429. RtlClearBits(
  1430. MasterAdapter->MapRegisters,
  1431. MapRegisterNumber,
  1432. NumberOfMapRegisters
  1433. );
  1434. MapRegisterNumber = -1;
  1435. }
  1436. // M0018 +++
  1437. #if defined(_DMA_EXPAND_)
  1438. //
  1439. // Make sure this map register is valid for this adapter.
  1440. //
  1441. if ((ULONG) MapRegisterNumber >= Limit ) {
  1442. //
  1443. // Make it look like there are no map registers.
  1444. //
  1445. RtlClearBits(
  1446. MasterAdapter->MapRegisters,
  1447. MapRegisterNumber,
  1448. NumberOfMapRegisters
  1449. );
  1450. MapRegisterNumber = -1;
  1451. }
  1452. #endif // _DMA_EXPAND_
  1453. // M0018 ---
  1454. if (MapRegisterNumber == -1) {
  1455. //
  1456. // There were not enough free map registers. Put this request back on
  1457. // the adapter queue where is came from.
  1458. //
  1459. InsertHeadList( &MasterAdapter->AdapterQueue,
  1460. &AdapterObject->AdapterQueue
  1461. );
  1462. break;
  1463. }
  1464. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1465. AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
  1466. //
  1467. // Invoke the driver's execution routine now.
  1468. //
  1469. Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
  1470. Wcb->CurrentIrp,
  1471. AdapterObject->MapRegisterBase,
  1472. Wcb->DeviceContext
  1473. );
  1474. //
  1475. // If the driver wishes to keep the map registers then set the number
  1476. // allocated to zero and set the action to deallocate object.
  1477. //
  1478. if (Action == DeallocateObjectKeepRegisters) {
  1479. AdapterObject->NumberOfMapRegisters = 0;
  1480. Action = DeallocateObject;
  1481. }
  1482. //
  1483. // If the driver would like to have the adapter deallocated,
  1484. // then deallocate any map registers allocated and then release
  1485. // the adapter object.
  1486. //
  1487. if (Action == DeallocateObject) {
  1488. //
  1489. // The map registers registers are deallocated here rather than in
  1490. // IoFreeAdapterChannel. This limits the number of times
  1491. // this routine can be called recursively possibly overflowing
  1492. // the stack. The worst case occurs if there is a pending
  1493. // request for the adapter that uses map registers and whos
  1494. // excution routine decallocates the adapter. In that case if there
  1495. // are no requests in the master adapter queue, then IoFreeMapRegisters
  1496. // will get called again.
  1497. //
  1498. if (AdapterObject->NumberOfMapRegisters != 0) {
  1499. //
  1500. // Deallocate the map registers and clear the count so that
  1501. // IoFreeAdapterChannel will not deallocate them again.
  1502. //
  1503. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  1504. RtlClearBits( MasterAdapter->MapRegisters,
  1505. MapRegisterNumber,
  1506. AdapterObject->NumberOfMapRegisters
  1507. );
  1508. AdapterObject->NumberOfMapRegisters = 0;
  1509. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1510. }
  1511. IoFreeAdapterChannel( AdapterObject );
  1512. }
  1513. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  1514. }
  1515. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1516. }
  1517. VOID
  1518. IoFreeAdapterChannel(
  1519. IN PADAPTER_OBJECT AdapterObject
  1520. )
  1521. /*++
  1522. Routine Description:
  1523. This routine is invoked to deallocate the specified adapter object.
  1524. Any map registers that were allocated are also automatically deallocated.
  1525. No checks are made to ensure that the adapter is really allocated to
  1526. a device object. However, if it is not, then kernel will bugcheck.
  1527. If another device is waiting in the queue to allocate the adapter object
  1528. it will be pulled from the queue and its execution routine will be
  1529. invoked.
  1530. Arguments:
  1531. AdapterObject - Pointer to the adapter object to be deallocated.
  1532. Return Value:
  1533. None.
  1534. --*/
  1535. {
  1536. PKDEVICE_QUEUE_ENTRY Packet;
  1537. PADAPTER_OBJECT MasterAdapter;
  1538. BOOLEAN Busy = FALSE;
  1539. IO_ALLOCATION_ACTION Action;
  1540. PWAIT_CONTEXT_BLOCK Wcb;
  1541. KIRQL Irql;
  1542. LONG MapRegisterNumber;
  1543. ULONG Hint;
  1544. // M0018 +++
  1545. #if defined(_DMA_EXPAND_)
  1546. ULONG Limit;
  1547. #endif // _DMA_EXPAND_
  1548. // M0018 ---
  1549. //
  1550. // Begin by getting the address of the master adapter.
  1551. //
  1552. if (AdapterObject->MasterAdapter != NULL) {
  1553. MasterAdapter = AdapterObject->MasterAdapter;
  1554. } else {
  1555. MasterAdapter = AdapterObject;
  1556. }
  1557. //
  1558. // Pull requests of the adapter's device wait queue as long as the
  1559. // adapter is free and there are sufficient map registers available.
  1560. //
  1561. while( TRUE ){
  1562. //
  1563. // Begin by checking to see whether there are any map registers that
  1564. // need to be deallocated. If so, then deallocate them now.
  1565. //
  1566. if (AdapterObject->NumberOfMapRegisters != 0) {
  1567. IoFreeMapRegisters( AdapterObject,
  1568. AdapterObject->MapRegisterBase,
  1569. AdapterObject->NumberOfMapRegisters
  1570. );
  1571. }
  1572. //
  1573. // Simply remove the next entry from the adapter's device wait queue.
  1574. // If one was successfully removed, allocate any map registers that it
  1575. // requires and invoke its execution routine.
  1576. //
  1577. Packet = KeRemoveDeviceQueue( &AdapterObject->ChannelWaitQueue );
  1578. if (Packet == NULL) {
  1579. //
  1580. // There are no more requests break out of the loop.
  1581. //
  1582. break;
  1583. }
  1584. Wcb = CONTAINING_RECORD( Packet,
  1585. WAIT_CONTEXT_BLOCK,
  1586. WaitQueueEntry );
  1587. AdapterObject->CurrentWcb = Wcb;
  1588. AdapterObject->NumberOfMapRegisters = Wcb->NumberOfMapRegisters;
  1589. //
  1590. // Check to see whether this driver wishes to allocate any map
  1591. // registers. If so, then queue the device object to the master
  1592. // adapter queue to wait for them to become available. If the driver
  1593. // wants map registers, ensure that this adapter has enough total
  1594. // map registers to satisfy the request.
  1595. //
  1596. if (Wcb->NumberOfMapRegisters != 0) {
  1597. if (Wcb->NumberOfMapRegisters > MasterAdapter->MapRegistersPerChannel) {
  1598. KeBugCheck( INSUFFICIENT_SYSTEM_MAP_REGS );
  1599. }
  1600. //
  1601. // Lock the map register bit map and the adapter queue in the
  1602. // master adapter object. The channel structure offset is used as
  1603. // a hint for the register search.
  1604. //
  1605. KeAcquireSpinLock( &MasterAdapter->SpinLock, &Irql );
  1606. MapRegisterNumber = -1;
  1607. if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
  1608. // M0018 +++
  1609. #if defined(_DMA_EXPAND_)
  1610. if (AdapterObject->Dma32BitAddresses) {
  1611. Hint = EISA_MIN_ADR / PAGE_SIZE;
  1612. Limit = EISA_MAX_ADR / PAGE_SIZE;
  1613. } else {
  1614. Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  1615. Limit = ISA_MAX_ADR / PAGE_SIZE - Wcb->NumberOfMapRegisters;
  1616. }
  1617. #else // _DMA_EXPAND_
  1618. // Hint = AdapterObject->PagePort ? (0x100000 / PAGE_SIZE) : 0;
  1619. Hint = (0x100000 / PAGE_SIZE); // M0024
  1620. #endif // _DMA_EXPAND_
  1621. // M0018 ---
  1622. MapRegisterNumber = RtlFindClearBitsAndSet(
  1623. MasterAdapter->MapRegisters,
  1624. Wcb->NumberOfMapRegisters,
  1625. Hint
  1626. );
  1627. //
  1628. // Make sure this map register is valid for this adapter.
  1629. //
  1630. if ((ULONG) MapRegisterNumber < Hint) {
  1631. //
  1632. // Make it look like there are no map registers.
  1633. //
  1634. RtlClearBits(
  1635. MasterAdapter->MapRegisters,
  1636. MapRegisterNumber,
  1637. Wcb->NumberOfMapRegisters
  1638. );
  1639. MapRegisterNumber = -1;
  1640. }
  1641. // M0018 +++
  1642. #if defined(_DMA_EXPAND_)
  1643. //
  1644. // Make sure this map register is valid for this adapter.
  1645. //
  1646. if ((ULONG) MapRegisterNumber >= Limit ) {
  1647. //
  1648. // Make it look like there are no map registers.
  1649. //
  1650. RtlClearBits(
  1651. MasterAdapter->MapRegisters,
  1652. MapRegisterNumber,
  1653. Wcb->NumberOfMapRegisters
  1654. );
  1655. MapRegisterNumber = -1;
  1656. }
  1657. #endif // _DMA_EXPAND_
  1658. // M0018 ---
  1659. }
  1660. if (MapRegisterNumber == -1) {
  1661. //
  1662. // There were not enough free map registers. Queue this request
  1663. // on the master adapter where is will wait until some registers
  1664. // are deallocated.
  1665. //
  1666. InsertTailList( &MasterAdapter->AdapterQueue,
  1667. &AdapterObject->AdapterQueue
  1668. );
  1669. Busy = 1;
  1670. } else {
  1671. AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase + MapRegisterNumber);
  1672. }
  1673. KeReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
  1674. }
  1675. //
  1676. // If there were either enough map registers available or no map
  1677. // registers needed to be allocated, invoke the driver's execution
  1678. // routine now.
  1679. //
  1680. if (!Busy) {
  1681. AdapterObject->CurrentWcb = Wcb;
  1682. Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
  1683. Wcb->CurrentIrp,
  1684. AdapterObject->MapRegisterBase,
  1685. Wcb->DeviceContext
  1686. );
  1687. //
  1688. // If the execution routine would like to have the adapter
  1689. // deallocated, then release the adapter object.
  1690. //
  1691. if (Action == KeepObject) {
  1692. //
  1693. // This request wants to keep the channel a while so break
  1694. // out of the loop.
  1695. //
  1696. break;
  1697. }
  1698. //
  1699. // If the driver wants to keep the map registers then set the
  1700. // number allocated to 0. This keeps the deallocation routine
  1701. // from deallocating them.
  1702. //
  1703. if (Action == DeallocateObjectKeepRegisters) {
  1704. AdapterObject->NumberOfMapRegisters = 0;
  1705. }
  1706. } else {
  1707. //
  1708. // This request did not get the requested number of map registers so
  1709. // out of the loop.
  1710. //
  1711. break;
  1712. }
  1713. }
  1714. }
  1715. BOOLEAN
  1716. HalpCreateDmaStructures (
  1717. VOID
  1718. )
  1719. /*++
  1720. Routine Description:
  1721. This routine initializes the structures necessary for DMA operations
  1722. and connects the intermediate interrupt dispatcher. It also connects
  1723. an interrupt handler to the DMA channel interrupt.
  1724. Arguments:
  1725. None.
  1726. Return Value:
  1727. If the second level interrupt dispatcher is connected, then a value of
  1728. TRUE is returned. Otherwise, a value of FALSE is returned.
  1729. --*/
  1730. {
  1731. //
  1732. // Initialize the DMA interrupt dispatcher for I/O interrupts.
  1733. //
  1734. KeInitializeInterrupt( &HalpDmaChannelInterrupt,
  1735. HalpDmaChannel,
  1736. (PVOID) NULL,
  1737. (PKSPIN_LOCK) NULL,
  1738. DMA_LEVEL,
  1739. DMA_LEVEL,
  1740. DMA_LEVEL,
  1741. LevelSensitive,
  1742. FALSE,
  1743. 0,
  1744. FALSE
  1745. );
  1746. //
  1747. // Don't fail if the interrupt cannot be connected.
  1748. //
  1749. KeConnectInterrupt( &HalpDmaChannelInterrupt );
  1750. //
  1751. // Directly connect the local device interrupt dispatcher to the local
  1752. // device interrupt vector.
  1753. //
  1754. // N.B. This vector is reserved for exclusive use by the HAL (see
  1755. // interrupt initialization).
  1756. //
  1757. PCR->InterruptRoutine[DEVICE_LEVEL] = (PKINTERRUPT_ROUTINE) HalpDmaDispatch;
  1758. /* start M0001 */
  1759. #if defined(_R94A_)
  1760. /* M0010 +++ */
  1761. //
  1762. // Enable DmaChannel Interrupt
  1763. //
  1764. {
  1765. ULONG Dword,Channel;
  1766. Dword = READ_REGISTER_ULONG(&DMA_CONTROL->InterruptEnable.Long);
  1767. Dword |= 1; // S0011
  1768. WRITE_REGISTER_ULONG(&DMA_CONTROL->InterruptEnable.Long, Dword); // S011
  1769. #if 0 // S0017
  1770. //
  1771. // Enable Interrupt when done every channel
  1772. //
  1773. for (Channel = 0; Channel < 4; Channel++) {
  1774. Dword = READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Mode);
  1775. Dword |= 0x20;
  1776. WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Mode, Dword);
  1777. }
  1778. #endif // 0 // S0017
  1779. }
  1780. /* M0010 --- */
  1781. //
  1782. // Initialize Typhoon error interrupts.
  1783. //
  1784. HalpCreateTyphoonErrorStructures();
  1785. #endif // _R94A_
  1786. /* end M0001 */
  1787. return TRUE;
  1788. }
  1789. PHYSICAL_ADDRESS
  1790. IoMapTransfer(
  1791. IN PADAPTER_OBJECT AdapterObject,
  1792. IN PMDL Mdl,
  1793. IN PVOID MapRegisterBase,
  1794. IN PVOID CurrentVa,
  1795. IN OUT PULONG Length,
  1796. IN BOOLEAN WriteToDevice
  1797. )
  1798. /*++
  1799. Routine Description:
  1800. This routine is invoked to set up the map registers in the DMA controller
  1801. to allow a transfer to or from a device.
  1802. Arguments:
  1803. AdapterObject - Pointer to the adapter object representing the DMA
  1804. controller channel that has been allocated.
  1805. Mdl - Pointer to the MDL that describes the pages of memory that are
  1806. being read or written.
  1807. MapRegisterBase - The address of the base map register that has been
  1808. allocated to the device driver for use in mapping the transfer.
  1809. CurrentVa - Current virtual address in the buffer described by the MDL
  1810. that the transfer is being done to or from.
  1811. Length - Supplies the length of the transfer. This determines the
  1812. number of map registers that need to be written to map the transfer.
  1813. Returns the length of the transfer which was actually mapped.
  1814. WriteToDevice - Boolean value that indicates whether this is a write
  1815. to the device from memory (TRUE), or vice versa.
  1816. Return Value:
  1817. Returns the logical address to be used by bus masters.
  1818. --*/
  1819. {
  1820. PTRANSLATION_ENTRY DmaMapRegister = MapRegisterBase;
  1821. PULONG PageFrameNumber;
  1822. ULONG NumberOfPages;
  1823. ULONG Offset;
  1824. ULONG i;
  1825. KIRQL OldIrql; // kuriyama
  1826. //
  1827. // Begin by determining where in the buffer this portion of the operation
  1828. // is taking place.
  1829. //
  1830. /* start M0004 */
  1831. #if defined(_BBM_DMA_)
  1832. //
  1833. // Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
  1834. //
  1835. ULONG bufferAddress;
  1836. ULONG bufferLogical;
  1837. #endif // _BBM_DMA_
  1838. /* end M0004 */
  1839. #if 0 //M0008
  1840. /* M0005 +++ */
  1841. #if defined(_BETA_LIMIT_)
  1842. {
  1843. ULONG PtagReg, Ptag, LtagReg, Ltag, DummyRead, logicalAddress;
  1844. KIRQL OldIrql;
  1845. if (!WriteToDevice) {
  1846. logicalAddress = (ULONG)((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
  1847. KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
  1848. for (i = 0; i < 8; i++ ) {
  1849. PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
  1850. LtagReg = (ULONG)&DMA_CONTROL->IoCacheLogicalTag[i];
  1851. Ptag = READ_REGISTER_ULONG(PtagReg);
  1852. Ltag = READ_REGISTER_ULONG(LtagReg);
  1853. if (Ptag & 0x1) {
  1854. if (Ltag & 0x1) {
  1855. if ((logicalAddress & 0xffffffc0) <= (Ltag & 0xffffffc0) && ((Ltag & 0xffffffc0) < (logicalAddress + *Length))) {
  1856. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  1857. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  1858. if (HalDebug)
  1859. DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
  1860. PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
  1861. }
  1862. }
  1863. }
  1864. }
  1865. KeLowerIrql(OldIrql);
  1866. }
  1867. }
  1868. #endif // _BETA_LIMIT_
  1869. /* M0005 --- */
  1870. #endif // 0 // M0008
  1871. #if defined(_BBM_DMA_)
  1872. {
  1873. ULONG PtagReg, Ptag, DummyRead;
  1874. // D001
  1875. if (*Length > (PAGE_SIZE * DMA_TRANSLATION_LIMIT / 8 / 8 )) { // kuriyama
  1876. DbgPrint("IoMapTransfer: *Length > %d pages\n", (DMA_TRANSLATION_LIMIT / 8 / 8));
  1877. }
  1878. KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
  1879. for (i = 0; i < 8; i++ ) {
  1880. PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
  1881. Ptag = READ_REGISTER_ULONG(PtagReg);
  1882. if (Ptag & 0x1) {
  1883. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  1884. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  1885. if (HalDebug)
  1886. DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
  1887. PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
  1888. }
  1889. }
  1890. }
  1891. #endif // _BBM_DMA_
  1892. #if 0 // kuriyama // D001 Delete checking ByteMask
  1893. // temp kuriyama start
  1894. for (i=0; i < 8; i++) {
  1895. if (READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheLowByteMask[i])){
  1896. DbgPrint("IoMapTransfer : LowByteMask[%d] is 0x%x\n",i,(ULONG)READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheLowByteMask[i]));
  1897. KeBugCheck(NMI_HARDWARE_FAILURE);
  1898. }
  1899. if (READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheHighByteMask[i])){
  1900. DbgPrint("IoMapTransfer : HighByteMask[%d] is 0x%x\n",i,(ULONG)READ_REGISTER_ULONG(&DMA_CONTROL->IoCacheHighByteMask[i]));
  1901. KeBugCheck(NMI_HARDWARE_FAILURE);
  1902. }
  1903. }
  1904. // temp kuriyaam end
  1905. #endif // if 0 // kuriyama
  1906. Offset = BYTE_OFFSET( (PCHAR) CurrentVa - (PCHAR) Mdl->StartVa );
  1907. PageFrameNumber = (PULONG) (Mdl + 1);
  1908. NumberOfPages = (Offset + *Length + PAGE_SIZE - 1) >> PAGE_SHIFT;
  1909. PageFrameNumber += (((PCHAR) CurrentVa - (PCHAR) Mdl->StartVa) >> PAGE_SHIFT);
  1910. /* start M0004 */
  1911. #if defined(_BBM_DMA_)
  1912. //
  1913. // Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
  1914. //
  1915. if (!WriteToDevice) {
  1916. // HalSweepDcache();
  1917. // HalSweepIcache();
  1918. HalDump("IoMapTransfer: AdapterObject = %x\n",(ULONG)AdapterObject);
  1919. for (i = 0; i < NumberOfPages; i++) {
  1920. bufferLogical = (((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT) + (i << PAGE_SHIFT);
  1921. HalDump("IoMapTransfer: bufferLogical = %x\n",bufferLogical);
  1922. bufferAddress = CopyBufferPhysicalBase + bufferLogical;
  1923. HalDump("IoMapTransfer: bufferAddress = %x\n",bufferAddress);
  1924. (DmaMapRegister++)->PageFrame = bufferAddress;
  1925. }
  1926. } else {
  1927. for (i = 0; i < NumberOfPages; i++) {
  1928. (DmaMapRegister++)->PageFrame = (ULONG) *PageFrameNumber++ << PAGE_SHIFT;
  1929. }
  1930. }
  1931. #else // _BBM_DMA_
  1932. for (i = 0; i < NumberOfPages; i++) {
  1933. (DmaMapRegister++)->PageFrame = (ULONG) *PageFrameNumber++ << PAGE_SHIFT;
  1934. }
  1935. #endif // _BBM_DMA_
  1936. /* end M0004 */
  1937. /* start M0004 */
  1938. #if defined(_BBM_DMA_)
  1939. //
  1940. // Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
  1941. //
  1942. if (!WriteToDevice) {
  1943. Offset = 0;
  1944. ;
  1945. }
  1946. #endif // _BBM_DMA_
  1947. /* end M0004 */
  1948. //
  1949. // Set the offset to point to the map register plus the offset.
  1950. //
  1951. Offset += ((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
  1952. /* start M0004 */
  1953. if (!WriteToDevice) {
  1954. HalDump("IoMapTransfer: Offset %x\n",Offset); /* M0004 */
  1955. HalDump("IoMapTransfer: Length %x\n",*Length); /* M0004 */
  1956. HalDump("IoMapTransfer: CurrentVa %x\n",CurrentVa); /* M0004 */
  1957. }
  1958. /* end M0004 */
  1959. //
  1960. // Invalidate the translation entry.
  1961. //
  1962. WRITE_REGISTER_ULONG(&DMA_CONTROL->TranslationInvalidate.Long, 1);
  1963. #if defined(_BBM_DMA_)
  1964. KeLowerIrql(OldIrql); // kuriyama
  1965. #endif //_BBM_DMA_
  1966. if ( AdapterObject == NULL) {
  1967. return(RtlConvertUlongToLargeInteger(Offset));
  1968. }
  1969. if (AdapterObject->PagePort == NULL) {
  1970. // M0013 +++
  1971. #if defined(_R94A_)
  1972. //
  1973. // if Master Device, nothing set to DMAC.
  1974. //
  1975. if ( AdapterObject->AdapterBaseVa == &(DMA_CONTROL)->Channel[7]) {
  1976. return(RtlConvertUlongToLargeInteger(Offset));
  1977. }
  1978. #endif // _R94A_
  1979. // M0013 ---
  1980. //
  1981. // Set the local DMA Registers.
  1982. //
  1983. WRITE_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Address.Long, Offset);
  1984. WRITE_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->ByteCount.Long, *Length);
  1985. i = 0;
  1986. ((PDMA_CHANNEL_ENABLE) &i)->ChannelEnable = 1;
  1987. ((PDMA_CHANNEL_ENABLE) &i)->TransferDirection =
  1988. WriteToDevice ? DMA_WRITE_OP : DMA_READ_OP;
  1989. WRITE_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long, i);
  1990. } else {
  1991. //
  1992. // Start the EISA DMA controller.
  1993. //
  1994. HalpEisaMapTransfer(
  1995. AdapterObject,
  1996. Offset,
  1997. *Length,
  1998. WriteToDevice
  1999. );
  2000. }
  2001. return(RtlConvertUlongToLargeInteger(Offset));
  2002. }
  2003. BOOLEAN
  2004. IoFlushAdapterBuffers(
  2005. IN PADAPTER_OBJECT AdapterObject,
  2006. IN PMDL Mdl,
  2007. IN PVOID MapRegisterBase,
  2008. IN PVOID CurrentVa,
  2009. IN ULONG Length,
  2010. IN BOOLEAN WriteToDevice
  2011. )
  2012. /*++
  2013. Routine Description:
  2014. This routine flushes the DMA adapter object buffers and clears the
  2015. enable flag which aborts the dma.
  2016. Arguments:
  2017. AdapterObject - Pointer to the adapter object representing the DMA
  2018. controller channel.
  2019. Mdl - A pointer to a Memory Descriptor List (MDL) that maps the locked-down
  2020. buffer to/from which the I/O occured.
  2021. MapRegisterBase - A pointer to the base of the map registers in the adapter
  2022. or DMA controller.
  2023. CurrentVa - The current virtual address in the buffer described the the Mdl
  2024. where the I/O operation occurred.
  2025. Length - Supplies the length of the transfer.
  2026. WriteToDevice - Supplies a BOOLEAN value that indicates the direction of
  2027. the data transfer was to the device.
  2028. Return Value:
  2029. TRUE - If the transfer was successful.
  2030. FALSE - If there was an error in the transfer.
  2031. --*/
  2032. {
  2033. ULONG i;
  2034. UCHAR DataByte;
  2035. /* start M0004 */
  2036. #if defined(_BBM_DMA_)
  2037. //
  2038. // Note. BBM Must use 4kbyte aligned CopyBuffer when ReadFromDevice
  2039. //
  2040. #if 0
  2041. PCCHAR bufferAddress;
  2042. #endif
  2043. PCCHAR mapAddress;
  2044. ULONG logicalAddress;
  2045. ULONG Offset;
  2046. PULONG PageFrameNumber;
  2047. ULONG NumberOfPages;
  2048. if (!WriteToDevice) {
  2049. HalDump("IoFlushAdapterBuffers: AdapterObject = %x\n",(ULONG)AdapterObject);
  2050. #if 0
  2051. bufferAddress = MmGetSystemAddressForMdl(Mdl);
  2052. bufferAddress += (PCCHAR) CurrentVa - (PCCHAR) MmGetMdlVirtualAddress(Mdl);
  2053. HalDump("IoFlushAdapterBuffers: bufferAddress = %x\n",bufferAddress);
  2054. HalDump("IoFlushAdapterBuffers: Length = %x\n",Length);
  2055. #endif
  2056. logicalAddress = (ULONG)((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
  2057. HalDump("IoFlushAdapterBuffers: logicalAddress = %x\n",logicalAddress);
  2058. Offset = BYTE_OFFSET( (PCHAR) CurrentVa - (PCHAR) Mdl->StartVa );
  2059. HalDump("IoFlushAdapterBuffers: Offset = %x\n",Offset);
  2060. mapAddress = (PCCHAR)(CopyBufferVirtualAddress + logicalAddress);
  2061. HalDump("IoFlushAdapterBuffers: mapAddress = %x\n",mapAddress);
  2062. HalDump("IoFlushAdapterBuffers: CurrentVa = %x\n",CurrentVa);
  2063. // DbgBreakPoint();
  2064. // RtlMoveMemory(CurrentVa, mapAddress, Length);
  2065. // DbgBreakPoint();
  2066. PageFrameNumber = (PULONG) (Mdl + 1);
  2067. NumberOfPages = (Offset + Length + PAGE_SIZE - 1) >> PAGE_SHIFT;
  2068. HalDump("IoFlushAdapterBuffers: NumberOfPages = %x\n",NumberOfPages);
  2069. PageFrameNumber += (((PCHAR) CurrentVa - (PCHAR) Mdl->StartVa) >> PAGE_SHIFT);
  2070. HalDump("IoFlushAdapterBuffers: PageFrameNumber = %x\n",PageFrameNumber);
  2071. if (NumberOfPages == 1) {
  2072. #if 0
  2073. HalDump(
  2074. "IoFlushAdapterBuffers: USERBUFFER = %x\n",
  2075. (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
  2076. );
  2077. HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress);
  2078. HalDump("IoFlushAdapterBuffers: Length = %x\n",Length);
  2079. #endif
  2080. // HalSweepIcache();
  2081. // HalSweepDcache();
  2082. RtlMoveMemory(
  2083. (PVOID)((((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE )+ Offset),
  2084. (PVOID)mapAddress, Length
  2085. );
  2086. } else if ( NumberOfPages == 2) {
  2087. #if 0
  2088. HalDump(
  2089. "IoFlushAdapterBuffers: USERBUFFER = %x\n",
  2090. (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
  2091. );
  2092. HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress);
  2093. HalDump("IoFlushAdapterBuffers: Length = %x\n",PAGE_SIZE - Offset);
  2094. #endif
  2095. // HalSweepIcache();
  2096. // HalSweepDcache();
  2097. RtlMoveMemory(
  2098. (PVOID)((((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE ) + Offset),
  2099. (PVOID)mapAddress, (ULONG)(PAGE_SIZE - Offset)
  2100. );
  2101. #if 0
  2102. HalDump("IoFlushAdapterBuffers: USERBUFFER = %x\n",
  2103. (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE)
  2104. );
  2105. HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress + PAGE_SIZE + Offset);
  2106. HalDump("IoFlushAdapterBuffers: Length = %x\n" , BYTE_OFFSET(Length + Offset - 1) + 1);
  2107. #endif
  2108. // HalSweepIcache();
  2109. // HalSweepDcache();
  2110. RtlMoveMemory(
  2111. ((PVOID)(((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE )),
  2112. // (PVOID)(mapAddress + PAGE_SIZE + Offset),
  2113. (PVOID)(mapAddress + PAGE_SIZE - Offset), // H001
  2114. (ULONG)(BYTE_OFFSET(Length + Offset - 1) + 1)
  2115. );
  2116. } else {
  2117. #if 0
  2118. HalDump(
  2119. "IoFlushAdapterBuffers: USERBUFFER = %x\n",
  2120. (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
  2121. );
  2122. HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress);
  2123. HalDump("IoFlushAdapterBuffers: Length = %x\n",PAGE_SIZE - Offset);
  2124. #endif
  2125. // HalSweepIcache();
  2126. // HalSweepDcache();
  2127. RtlMoveMemory(
  2128. (PVOID)((((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE ) + Offset),
  2129. (PVOID)mapAddress,
  2130. (ULONG)(PAGE_SIZE - Offset)
  2131. );
  2132. for (i = 1; i < (NumberOfPages - 1); i++) {
  2133. #if 0
  2134. HalDump("IoFlushAdapterBuffers: USERBUFFER = %x\n",
  2135. (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE)
  2136. );
  2137. HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress + (i * PAGE_SIZE) +Offset);
  2138. HalDump("IoFlushAdapterBuffers: Length = %x\n",PAGE_SIZE);
  2139. #endif
  2140. // HalSweepIcache();
  2141. // HalSweepDcache();
  2142. RtlMoveMemory(
  2143. (PVOID)(((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE),
  2144. // (PVOID)((mapAddress + (i * PAGE_SIZE)) + Offset),
  2145. (PVOID)(mapAddress + (i * PAGE_SIZE) - Offset), // H001
  2146. PAGE_SIZE
  2147. );
  2148. }
  2149. #if 0
  2150. HalDump(
  2151. "IoFlushAdapterBuffers: USERBUFFER = %x\n",
  2152. (((ULONG)*PageFrameNumber << PAGE_SHIFT) | KSEG1_BASE) + Offset
  2153. );
  2154. HalDump("IoFlushAdapterBuffers: COPYBUFFER = %x\n",mapAddress + (i * PAGE_SIZE) + Offset);
  2155. HalDump("IoFlushAdapterBuffers: Length = %x\n",BYTE_OFFSET(Length + Offset - 1) + 1);
  2156. #endif
  2157. // HalSweepIcache();
  2158. // HalSweepDcache();
  2159. RtlMoveMemory(
  2160. (PVOID)(((ULONG) *PageFrameNumber++ << PAGE_SHIFT) | KSEG1_BASE ),
  2161. // (PVOID)(mapAddress + (i * PAGE_SIZE) + Offset),
  2162. (PVOID)(mapAddress + (NumberOfPages - 1) * PAGE_SIZE - Offset), // H001
  2163. (ULONG)(BYTE_OFFSET(Length + Offset - 1) + 1)
  2164. );
  2165. }
  2166. }
  2167. #endif // _BBM_DMA_
  2168. /* end M0004 */
  2169. /* M0006 +++ */
  2170. #if defined(_BETA_LIMIT_)
  2171. #if 0 // M0008
  2172. {
  2173. ULONG PtagReg, Ptag, LtagReg, Ltag, DummyRead, logicalAddress;
  2174. KIRQL OldIrql;
  2175. if (!WriteToDevice) { // M0005
  2176. logicalAddress = (ULONG)((PTRANSLATION_ENTRY) MapRegisterBase - (PTRANSLATION_ENTRY) MasterAdapterObject->MapRegisterBase) << PAGE_SHIFT;
  2177. // D001
  2178. // DbgPrint("DmaFlush start\n");
  2179. KeRaiseIrql(DEVICE_LEVEL, &OldIrql); // kuriyama
  2180. for (i = 0; i < 8; i++ ) {
  2181. PtagReg = (ULONG)&DMA_CONTROL->IoCachePhysicalTag[i];
  2182. LtagReg = (ULONG)&DMA_CONTROL->IoCacheLogicalTag[i];
  2183. Ptag = READ_REGISTER_ULONG(PtagReg);
  2184. Ltag = READ_REGISTER_ULONG(LtagReg);
  2185. if (Ptag & 0x1) {
  2186. if (Ltag & 0x1) {
  2187. if ((logicalAddress & 0xffffffc0) <= (Ltag & 0xffffffc0) && ((Ltag & 0xffffffc0) < (logicalAddress + Length))) {
  2188. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  2189. DummyRead = READ_REGISTER_ULONG((KSEG1_BASE|(Ptag&0xFFFFFFC0)));
  2190. if (HalDebug)
  2191. DbgPrint("Found Valid Entry:0x%x Tag:0x%x. Read 0x%x=0x%x\n",
  2192. PtagReg, Ptag, (KSEG1_BASE|(Ptag&0xFFFFFFC0)), DummyRead);
  2193. }
  2194. }
  2195. }
  2196. }
  2197. KeLowerIrql(OldIrql);
  2198. // DbgPrint("DmaFlush end\n");
  2199. } // M0005
  2200. }
  2201. #endif // 0 //M0008
  2202. /* M0005,M0014 +++ */
  2203. {
  2204. ULONG Offset, NumberOfPages;
  2205. PULONG PageFrameNumber;
  2206. KIRQL OldIrql;
  2207. if (Length != 0) { //S0015
  2208. if (!WriteToDevice) {
  2209. KeRaiseIrql(HIGH_LEVEL, &OldIrql); // kuriyama
  2210. Offset = BYTE_OFFSET( (PCHAR) CurrentVa - (PCHAR) Mdl->StartVa );
  2211. PageFrameNumber = (PULONG) (Mdl + 1);
  2212. NumberOfPages = (Offset + Length + PAGE_SIZE - 1) >> PAGE_SHIFT;
  2213. PageFrameNumber += (((PCHAR) CurrentVa - (PCHAR) Mdl->StartVa) >> PAGE_SHIFT);
  2214. if (NumberOfPages == 1) {
  2215. HalViewMemory((PVOID)((KSEG1_BASE |(((ULONG) *PageFrameNumber++
  2216. << PAGE_SHIFT) + Offset))),
  2217. Length);
  2218. } else {
  2219. HalViewMemory( (PVOID)((KSEG1_BASE |(((ULONG) *PageFrameNumber++
  2220. << PAGE_SHIFT) + Offset))),
  2221. (PAGE_SIZE - Offset));
  2222. for (i = 1; i < NumberOfPages -1; i++) {
  2223. HalViewMemory( (PVOID)((KSEG1_BASE |((ULONG) *PageFrameNumber++
  2224. << PAGE_SHIFT))), PAGE_SIZE);
  2225. }
  2226. HalViewMemory( (PVOID)((KSEG1_BASE
  2227. |((ULONG) *PageFrameNumber++ << PAGE_SHIFT))),
  2228. BYTE_OFFSET(Offset + Length -1) +1);
  2229. }
  2230. KeLowerIrql(OldIrql);
  2231. }
  2232. }
  2233. }
  2234. /* M0005,M0014 --- */
  2235. #endif // _BETA_LIMIT_
  2236. /* M0006 --- */
  2237. if (AdapterObject == NULL) {
  2238. //
  2239. // This is a master adadapter so there is nothing to do.
  2240. //
  2241. return(TRUE);
  2242. }
  2243. if (AdapterObject->PagePort) {
  2244. //
  2245. // If this is a master channel, then just return since the DMA
  2246. // request does not need to be disabled.
  2247. //
  2248. DataByte = AdapterObject->AdapterMode;
  2249. if (((PDMA_EISA_MODE) &DataByte)->RequestMode == CASCADE_REQUEST_MODE) {
  2250. return(TRUE);
  2251. }
  2252. //
  2253. // Clear the EISA DMA adapter.
  2254. //
  2255. if (AdapterObject->AdapterNumber == 1) {
  2256. //
  2257. // This request is for DMA controller 1
  2258. //
  2259. PDMA1_CONTROL dmaControl;
  2260. dmaControl = AdapterObject->AdapterBaseVa;
  2261. WRITE_REGISTER_UCHAR(
  2262. &dmaControl->SingleMask,
  2263. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  2264. );
  2265. } else {
  2266. //
  2267. // This request is for DMA controller 2
  2268. //
  2269. PDMA2_CONTROL dmaControl;
  2270. dmaControl = AdapterObject->AdapterBaseVa;
  2271. WRITE_REGISTER_UCHAR(
  2272. &dmaControl->SingleMask,
  2273. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  2274. );
  2275. }
  2276. } else {
  2277. // M0013 +++
  2278. #if defined(_R94A_)
  2279. //
  2280. // if Master Device, nothing set to DMAC.
  2281. //
  2282. if ( AdapterObject->AdapterBaseVa == &(DMA_CONTROL)->Channel[7]) {
  2283. return(TRUE);
  2284. }
  2285. #endif // _R94A_
  2286. // M0013 ---
  2287. //
  2288. // Clear on board DMA
  2289. //
  2290. i = READ_REGISTER_ULONG(
  2291. &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long
  2292. );
  2293. ((PDMA_CHANNEL_ENABLE) &i)->ChannelEnable = 0;
  2294. WRITE_REGISTER_ULONG(
  2295. &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long,
  2296. i
  2297. );
  2298. i = READ_REGISTER_USHORT(
  2299. &((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable
  2300. );
  2301. }
  2302. return(TRUE);
  2303. }
  2304. IO_ALLOCATION_ACTION
  2305. HalpAllocationRoutine (
  2306. IN PDEVICE_OBJECT DeviceObject,
  2307. IN PIRP Irp,
  2308. IN PVOID MapRegisterBase,
  2309. IN PVOID Context
  2310. )
  2311. /*++
  2312. Routine Description:
  2313. This function is called by HalAllocateAdapterChannel when sufficent resources
  2314. are available to the driver. This routine saves the MapRegisterBase,
  2315. and set the event pointed to by the context parameter.
  2316. Arguments:
  2317. DeviceObject - Supplies a pointer where the map register base should be
  2318. stored.
  2319. Irp - Unused.
  2320. MapRegisterBase - Supplied by the Io subsystem for use in IoMapTransfer.
  2321. Context - Supplies a pointer to an event which is set to indicate the
  2322. AdapterObject has been allocated.
  2323. Return Value:
  2324. DeallocateObjectKeepRegisters - Indicates the adapter should be freed
  2325. and mapregisters should remain allocated after return.
  2326. --*/
  2327. {
  2328. UNREFERENCED_PARAMETER(Irp);
  2329. *((PVOID *) DeviceObject) = MapRegisterBase;
  2330. (VOID) KeSetEvent( (PKEVENT) Context, 0L, FALSE );
  2331. return(DeallocateObjectKeepRegisters);
  2332. }
  2333. #if 0 // CHG0001
  2334. ULONG
  2335. HalGetBusDataByOffset(
  2336. IN BUS_DATA_TYPE BusDataType,
  2337. IN ULONG BusNumber,
  2338. IN ULONG SlotNumber,
  2339. IN PVOID Buffer,
  2340. IN ULONG Offset,
  2341. IN ULONG Length
  2342. )
  2343. /*++
  2344. Routine Description:
  2345. The function returns the bus data for a slot or address.
  2346. Arguments:
  2347. BusDataType - Supplies the type of bus.
  2348. BusNumber - Indicates which bus.
  2349. Buffer - Supplies the space to store the data.
  2350. Offset - Offset in the BusData buffer
  2351. Length - Supplies a count in bytes of the maximum amount to return.
  2352. Return Value:
  2353. Returns the amount of data stored into the buffer.
  2354. --*/
  2355. {
  2356. ULONG DataLength = 0;
  2357. switch (BusDataType) {
  2358. case EisaConfiguration:
  2359. DataLength = HalpReadEisaData(BusNumber, SlotNumber, Buffer, Offset, Length);
  2360. break;
  2361. /* start M0001 */
  2362. #if 0
  2363. #if defined(_R94A_)
  2364. case PCIConfiguration:
  2365. DataLength = HalpReadPCIData(BusNumber, SlotNumber, Buffer, Offset, Length);
  2366. break;
  2367. #endif // _R94A_
  2368. #endif // 0
  2369. /* end M0001 */
  2370. }
  2371. return(DataLength);
  2372. }
  2373. ULONG
  2374. HalGetBusData(
  2375. IN BUS_DATA_TYPE BusDataType,
  2376. IN ULONG BusNumber,
  2377. IN ULONG SlotNumber,
  2378. IN PVOID Buffer,
  2379. IN ULONG Length
  2380. )
  2381. /*++
  2382. Routine Description:
  2383. Subset of HalGetBusDataByOffset, just pass the request along.
  2384. --*/
  2385. {
  2386. return HalGetBusDataByOffset (
  2387. BusDataType,
  2388. BusNumber,
  2389. SlotNumber,
  2390. Buffer,
  2391. 0,
  2392. Length
  2393. );
  2394. }
  2395. ULONG
  2396. HalSetBusDataByOffset(
  2397. IN BUS_DATA_TYPE BusDataType,
  2398. IN ULONG BusNumber,
  2399. IN ULONG SlotNumber,
  2400. IN PVOID Buffer,
  2401. IN ULONG Offset,
  2402. IN ULONG Length
  2403. )
  2404. /*++
  2405. Routine Description:
  2406. The function sets the bus data for a slot or address.
  2407. Arguments:
  2408. BusDataType - Supplies the type of bus.
  2409. BusNumber - Indicates which bus.
  2410. Buffer - Supplies the space to store the data.
  2411. Offset - Offset in the BusData buffer
  2412. Length - Supplies a count in bytes of the maximum amount to return.
  2413. Return Value:
  2414. Returns the amount of data stored into the buffer.
  2415. --*/
  2416. {
  2417. ULONG DataLength = 0;
  2418. /* start M0001 */
  2419. #if 0
  2420. #if defined(_R94A_)
  2421. switch (BusDataType) {
  2422. case PCIConfiguration:
  2423. DataLength = HalpWritePCIData(BusNumber, SlotNumber, Buffer, Offset, Length);
  2424. break;
  2425. }
  2426. #endif // _R94A_
  2427. #endif // 0
  2428. /* end M0001 */
  2429. return(DataLength);
  2430. }
  2431. ULONG
  2432. HalSetBusData(
  2433. IN BUS_DATA_TYPE BusDataType,
  2434. IN ULONG BusNumber,
  2435. IN ULONG SlotNumber,
  2436. IN PVOID Buffer,
  2437. IN ULONG Length
  2438. )
  2439. /*++
  2440. Routine Description:
  2441. Subset of HalGetBusDataByOffset, just pass the request along.
  2442. --*/
  2443. {
  2444. return HalSetBusDataByOffset(
  2445. BusDataType,
  2446. BusNumber,
  2447. SlotNumber,
  2448. Buffer,
  2449. 0,
  2450. Length
  2451. );
  2452. }
  2453. NTSTATUS
  2454. HalAssignSlotResources (
  2455. IN PUNICODE_STRING RegistryPath,
  2456. IN PUNICODE_STRING DriverClassName OPTIONAL,
  2457. IN PDRIVER_OBJECT DriverObject,
  2458. IN PDEVICE_OBJECT DeviceObject OPTIONAL,
  2459. IN INTERFACE_TYPE BusType,
  2460. IN ULONG BusNumber,
  2461. IN ULONG SlotNumber,
  2462. IN OUT PCM_RESOURCE_LIST *AllocatedResources
  2463. )
  2464. /*++
  2465. Routine Description:
  2466. Reads the targeted device to determine it's required resources.
  2467. Calls IoAssignResources to allocate them.
  2468. Sets the targeted device with it's assigned resoruces
  2469. and returns the assignments to the caller.
  2470. Arguments:
  2471. RegistryPath - Passed to IoAssignResources.
  2472. A device specific registry path in the current-control-set, used
  2473. to check for pre-assigned settings and to track various resource
  2474. assignment information for this device.
  2475. DriverClassName Used to report the assigned resources for the driver/device
  2476. DriverObject - Used to report the assigned resources for the driver/device
  2477. DeviceObject - Used to report the assigned resources for the driver/device
  2478. (ie, IoReportResoruceUsage)
  2479. BusType
  2480. BusNumber
  2481. SlotNumber - Together BusType,BusNumber,SlotNumber uniquely
  2482. indentify the device to be queried & set.
  2483. Return Value:
  2484. STATUS_SUCCESS or error
  2485. --*/
  2486. {
  2487. //
  2488. // This HAL doesn't support any buses which support
  2489. // HalAssignSlotResources
  2490. //
  2491. return STATUS_NOT_SUPPORTED;
  2492. }
  2493. NTSTATUS
  2494. HalAdjustResourceList (
  2495. IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList
  2496. )
  2497. /*++
  2498. Routine Description:
  2499. Takes the pResourceList and limits any requested resource to
  2500. it's corrisponding bus requirements.
  2501. Arguments:
  2502. pResourceList - The resource list to adjust.
  2503. Return Value:
  2504. STATUS_SUCCESS or error
  2505. --*/
  2506. {
  2507. //
  2508. // BUGBUG: This function should verify that the resoruces fit
  2509. // the bus requirements - for now we will assume that the bus
  2510. // can support anything the device may ask for.
  2511. //
  2512. return STATUS_SUCCESS;
  2513. }
  2514. ULONG
  2515. HalpReadEisaData (
  2516. IN ULONG BusNumber,
  2517. IN ULONG SlotNumber,
  2518. IN PVOID Buffer,
  2519. IN ULONG Offset,
  2520. IN ULONG Length
  2521. )
  2522. /*++
  2523. Routine Description:
  2524. The function returns the Eisa bus data for a slot or address.
  2525. Arguments:
  2526. BusDataType - Supplies the type of bus.
  2527. BusNumber - Indicates which bus.
  2528. Buffer - Supplies the space to store the data.
  2529. Length - Supplies a count in bytes of the maximum amount to return.
  2530. Return Value:
  2531. Returns the amount of data stored into the buffer.
  2532. --*/
  2533. {
  2534. OBJECT_ATTRIBUTES ObjectAttributes;
  2535. OBJECT_ATTRIBUTES BusObjectAttributes;
  2536. PWSTR EisaPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\EisaAdapter";
  2537. PWSTR ConfigData = L"Configuration Data";
  2538. ANSI_STRING TmpString;
  2539. UCHAR BusString[] = "00";
  2540. UNICODE_STRING RootName, BusName;
  2541. UNICODE_STRING ConfigDataName;
  2542. NTSTATUS NtStatus;
  2543. PKEY_VALUE_FULL_INFORMATION ValueInformation;
  2544. PCM_FULL_RESOURCE_DESCRIPTOR Descriptor;
  2545. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource;
  2546. PCM_EISA_SLOT_INFORMATION SlotInformation;
  2547. ULONG PartialCount;
  2548. ULONG TotalDataSize, SlotDataSize;
  2549. HANDLE EisaHandle, BusHandle;
  2550. ULONG BytesWritten, BytesNeeded;
  2551. PUCHAR KeyValueBuffer;
  2552. ULONG i;
  2553. ULONG DataLength = 0;
  2554. PUCHAR DataBuffer = Buffer;
  2555. BOOLEAN Found = FALSE;
  2556. RtlInitUnicodeString(
  2557. &RootName,
  2558. EisaPath
  2559. );
  2560. InitializeObjectAttributes(
  2561. &ObjectAttributes,
  2562. &RootName,
  2563. OBJ_CASE_INSENSITIVE,
  2564. (HANDLE)NULL,
  2565. NULL
  2566. );
  2567. //
  2568. // Open the EISA root
  2569. //
  2570. NtStatus = ZwOpenKey(
  2571. &EisaHandle,
  2572. KEY_READ,
  2573. &ObjectAttributes
  2574. );
  2575. if (!NT_SUCCESS(NtStatus)) {
  2576. KdPrint(("HAL: Open Status = %x\n",NtStatus));
  2577. return(0);
  2578. }
  2579. //
  2580. // Init bus number path
  2581. //
  2582. if (BusNumber > 99) {
  2583. return (0);
  2584. }
  2585. if (BusNumber > 9) {
  2586. BusString[0] += (UCHAR) (BusNumber/10);
  2587. BusString[1] += (UCHAR) (BusNumber % 10);
  2588. } else {
  2589. BusString[0] += (UCHAR) BusNumber;
  2590. BusString[1] = '\0';
  2591. }
  2592. RtlInitAnsiString(
  2593. &TmpString,
  2594. BusString
  2595. );
  2596. RtlAnsiStringToUnicodeString(
  2597. &BusName,
  2598. &TmpString,
  2599. TRUE
  2600. );
  2601. InitializeObjectAttributes(
  2602. &BusObjectAttributes,
  2603. &BusName,
  2604. OBJ_CASE_INSENSITIVE,
  2605. (HANDLE)EisaHandle,
  2606. NULL
  2607. );
  2608. //
  2609. // Open the EISA root + Bus Number
  2610. //
  2611. NtStatus = ZwOpenKey(
  2612. &BusHandle,
  2613. KEY_READ,
  2614. &BusObjectAttributes
  2615. );
  2616. if (!NT_SUCCESS(NtStatus)) {
  2617. KdPrint(("HAL: Opening Bus Number: Status = %x\n",NtStatus));
  2618. return(0);
  2619. }
  2620. //
  2621. // opening the configuration data. This first call tells us how
  2622. // much memory we need to allocate
  2623. //
  2624. RtlInitUnicodeString(
  2625. &ConfigDataName,
  2626. ConfigData
  2627. );
  2628. //
  2629. // This should fail. We need to make this call so we can
  2630. // get the actual size of the buffer to allocate.
  2631. //
  2632. NtStatus = ZwQueryValueKey(
  2633. BusHandle,
  2634. &ConfigDataName,
  2635. KeyValueFullInformation,
  2636. ValueInformation,
  2637. 0,
  2638. &BytesNeeded
  2639. );
  2640. KeyValueBuffer = ExAllocatePool(
  2641. NonPagedPool,
  2642. BytesNeeded
  2643. );
  2644. if (KeyValueBuffer == NULL) {
  2645. KdPrint(("HAL: Cannot allocate Key Value Buffer\n"));
  2646. ZwClose(BusHandle);
  2647. return(0);
  2648. }
  2649. ValueInformation = (PKEY_VALUE_FULL_INFORMATION)KeyValueBuffer;
  2650. NtStatus = ZwQueryValueKey(
  2651. BusHandle,
  2652. &ConfigDataName,
  2653. KeyValueFullInformation,
  2654. ValueInformation,
  2655. BytesNeeded,
  2656. &BytesWritten
  2657. );
  2658. ZwClose(BusHandle);
  2659. if (!NT_SUCCESS(NtStatus) || ValueInformation->DataLength == 0) {
  2660. KdPrint(("HAL: Query Config Data: Status = %x\n",NtStatus));
  2661. ExFreePool(KeyValueBuffer);
  2662. return(0);
  2663. }
  2664. //
  2665. // We get back a Full Resource Descriptor List
  2666. //
  2667. Descriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PUCHAR)ValueInformation +
  2668. ValueInformation->DataOffset);
  2669. PartialResource = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
  2670. &(Descriptor->PartialResourceList.PartialDescriptors);
  2671. PartialCount = Descriptor->PartialResourceList.Count;
  2672. for (i = 0; i < PartialCount; i++) {
  2673. //
  2674. // Do each partial Resource
  2675. //
  2676. switch (PartialResource->Type) {
  2677. case CmResourceTypeNull:
  2678. case CmResourceTypePort:
  2679. case CmResourceTypeInterrupt:
  2680. case CmResourceTypeMemory:
  2681. case CmResourceTypeDma:
  2682. //
  2683. // We dont care about these.
  2684. //
  2685. PartialResource++;
  2686. break;
  2687. case CmResourceTypeDeviceSpecific:
  2688. //
  2689. // Bingo!
  2690. //
  2691. TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize;
  2692. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  2693. ((PUCHAR)PartialResource +
  2694. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  2695. while (((LONG)TotalDataSize) > 0) {
  2696. if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
  2697. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
  2698. } else {
  2699. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
  2700. SlotInformation->NumberFunctions *
  2701. sizeof(CM_EISA_FUNCTION_INFORMATION);
  2702. }
  2703. if (SlotDataSize > TotalDataSize) {
  2704. //
  2705. // Something is wrong again
  2706. //
  2707. ExFreePool(KeyValueBuffer);
  2708. return(0);
  2709. }
  2710. if (SlotNumber != 0) {
  2711. SlotNumber--;
  2712. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  2713. ((PUCHAR)SlotInformation + SlotDataSize);
  2714. TotalDataSize -= SlotDataSize;
  2715. continue;
  2716. }
  2717. //
  2718. // This is our slot
  2719. //
  2720. Found = TRUE;
  2721. break;
  2722. }
  2723. //
  2724. // End loop
  2725. //
  2726. i = PartialCount;
  2727. break;
  2728. default:
  2729. KdPrint(("Bad Data in registry!\n"));
  2730. ExFreePool(KeyValueBuffer);
  2731. return(0);
  2732. }
  2733. }
  2734. if (Found) {
  2735. i = Length + Offset;
  2736. if (i > SlotDataSize) {
  2737. i = SlotDataSize;
  2738. }
  2739. DataLength = i - Offset;
  2740. RtlMoveMemory ((PVOID)Buffer, (PVOID)((PUCHAR)SlotInformation + Offset), (ULONG)DataLength);
  2741. }
  2742. ExFreePool(KeyValueBuffer);
  2743. return DataLength;
  2744. }
  2745. #endif
  2746. ULONG
  2747. HalReadDmaCounter(
  2748. IN PADAPTER_OBJECT AdapterObject
  2749. )
  2750. /*++
  2751. Routine Description:
  2752. This function reads the DMA counter and returns the number of bytes left
  2753. to be transfered.
  2754. Arguments:
  2755. AdapterObject - Supplies a pointer to the adapter object to be read.
  2756. Return Value:
  2757. Returns the number of bytes still be be transfered.
  2758. --*/
  2759. {
  2760. ULONG i;
  2761. ULONG saveEnable;
  2762. ULONG count;
  2763. ULONG high;
  2764. if (AdapterObject->PagePort) {
  2765. //
  2766. // Determine the controller number based on the Adapter number.
  2767. //
  2768. if (AdapterObject->AdapterNumber == 1) {
  2769. //
  2770. // This request is for DMA controller 1
  2771. //
  2772. PDMA1_CONTROL dmaControl;
  2773. dmaControl = AdapterObject->AdapterBaseVa;
  2774. //
  2775. // Initialize count to a value which will not match.
  2776. //
  2777. count = 0xFFFF00;
  2778. //
  2779. // Loop until the same high byte is read twice.
  2780. //
  2781. do {
  2782. high = count;
  2783. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2784. //
  2785. // Read the current DMA count.
  2786. //
  2787. count = READ_PORT_UCHAR(
  2788. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2789. .DmaBaseCount
  2790. );
  2791. count |= READ_PORT_UCHAR(
  2792. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2793. .DmaBaseCount
  2794. ) << 8;
  2795. } while ((count & 0xFFFF00) != (high & 0xFFFF00));
  2796. } else {
  2797. //
  2798. // This request is for DMA controller 2
  2799. //
  2800. PDMA2_CONTROL dmaControl;
  2801. dmaControl = AdapterObject->AdapterBaseVa;
  2802. //
  2803. // Initialize count to a value which will not match.
  2804. //
  2805. count = 0xFFFF00;
  2806. //
  2807. // Loop until the same high byte is read twice.
  2808. //
  2809. do {
  2810. high = count;
  2811. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  2812. //
  2813. // Read the current DMA count.
  2814. //
  2815. count = READ_PORT_UCHAR(
  2816. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2817. .DmaBaseCount
  2818. );
  2819. count |= READ_PORT_UCHAR(
  2820. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  2821. .DmaBaseCount
  2822. ) << 8;
  2823. } while ((count & 0xFFFF00) != (high & 0xFFFF00));
  2824. }
  2825. //
  2826. // The DMA counter has a bias of one and can only be 16 bit long.
  2827. //
  2828. count = (count + 1) & 0xFFFF;
  2829. } else {
  2830. //
  2831. // Disable the DMA
  2832. //
  2833. i = READ_REGISTER_ULONG(
  2834. &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long
  2835. );
  2836. saveEnable = i;
  2837. ((PDMA_CHANNEL_ENABLE) &i)->ChannelEnable = 0;
  2838. WRITE_REGISTER_ULONG(
  2839. &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long,
  2840. i
  2841. );
  2842. //
  2843. // Read the transfer count.
  2844. //
  2845. count = 0xfffff & READ_REGISTER_ULONG(&((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->ByteCount.Long); // beta typhoon errata// M0009
  2846. //
  2847. // Reset the Enable register.
  2848. //
  2849. WRITE_REGISTER_ULONG(
  2850. &((PDMA_CHANNEL) AdapterObject->AdapterBaseVa)->Enable.Long,
  2851. saveEnable
  2852. );
  2853. }
  2854. return(count);
  2855. }
  2856. BOOLEAN
  2857. HalpDmaChannel(
  2858. IN PKINTERRUPT Interrupt,
  2859. IN PVOID ServiceContext
  2860. )
  2861. /*++
  2862. Routine Description:
  2863. This routine is called when a DMA channel interrupt occurs.
  2864. These should never occur. Bugcheck is called if an error does occur.
  2865. Arguments:
  2866. Interrupt - Supplies a pointer to the interrupt object
  2867. ServiceContext - Bug number to call bugcheck with.
  2868. Return Value:
  2869. Returns TRUE.
  2870. --*/
  2871. {
  2872. ULONG DataWord;
  2873. ULONG Channel;
  2874. DMA_CHANNEL_ENABLE ChannelWord;
  2875. ULONG ErrorFlag = 0; /* M0003 */
  2876. #if defined(_JAZZ_)
  2877. //
  2878. // Read the DMA channel interrupt source register.
  2879. //
  2880. DataWord = READ_REGISTER_ULONG(&DMA_CONTROL->InterruptSource.Long);
  2881. for (Channel = 0; Channel < 8; Channel++) {
  2882. //
  2883. // Determine which channel is interrupting.
  2884. //
  2885. if (!(DataWord & ( 1 << Channel))) {
  2886. continue;
  2887. }
  2888. DmaChannelMsg[18] = (CHAR) Channel + '0';
  2889. HalDisplayString(DmaChannelMsg);
  2890. *((PULONG) &ChannelWord) =
  2891. READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Enable.Long);
  2892. if (ChannelWord.TerminalCount) {
  2893. HalDisplayString("Terminal count was reached.\n");
  2894. }
  2895. if (ChannelWord.MemoryError) {
  2896. HalDisplayString("A memory error was detected.\n");
  2897. }
  2898. if (ChannelWord.TranslationError) {
  2899. HalDisplayString("A translation error occured.\n");
  2900. }
  2901. }
  2902. KeBugCheck(NMI_HARDWARE_FAILURE);
  2903. #endif
  2904. /* start M0001 */
  2905. #if defined(_R94A_)
  2906. HalpChangePanicFlag(16, 0x01, 0x10); // S0023
  2907. //
  2908. // Read the DMA channel interrupt source register.
  2909. //
  2910. DataWord = READ_REGISTER_ULONG(&DMA_CONTROL->ChannelInterruptAcknowledge.Long);
  2911. for (Channel = 0; Channel < 4; Channel++) {
  2912. //
  2913. // Determine which channel is interrupting.
  2914. //
  2915. if (!(DataWord & ( 1 << Channel))) {
  2916. continue;
  2917. }
  2918. DmaChannelMsg[18] = (CHAR) Channel + '0';
  2919. *((PULONG) &ChannelWord) =
  2920. READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Enable.Long);
  2921. /* start M0002 */
  2922. if (ChannelWord.TerminalCount) {
  2923. if ((0xfffff & READ_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].ByteCount.Long)) != 0) { // beta typhoon errta // M0009
  2924. HalDisplayString(DmaChannelMsg);
  2925. HalDisplayString("Terminal count was reached."); // S0011
  2926. ErrorFlag++;
  2927. }
  2928. }
  2929. if (ChannelWord.MemoryError) {
  2930. HalDisplayString(DmaChannelMsg);
  2931. HalDisplayString("A memory error was detected."); // S0011
  2932. ErrorFlag++;
  2933. }
  2934. if (ChannelWord.ParityError) {
  2935. HalDisplayString(DmaChannelMsg);
  2936. HalDisplayString("A Parity error occured."); // S0011
  2937. ErrorFlag++;
  2938. }
  2939. if (ChannelWord.MasterAbort) {
  2940. HalDisplayString(DmaChannelMsg);
  2941. HalDisplayString("A PCIBus Master Abort error occured."); // S0011
  2942. ErrorFlag++;
  2943. }
  2944. // Clear Dma Channel Interrupt
  2945. WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[Channel].Enable.Long, 0x00000100); // M0009
  2946. /* end M0002 */
  2947. }
  2948. if (ErrorFlag != 0) {
  2949. KeBugCheck(NMI_HARDWARE_FAILURE);
  2950. }
  2951. #endif // _R94A_
  2952. /* end M0001 */
  2953. return(TRUE);
  2954. }
  2955. VOID
  2956. HalpAllocateMapRegisters(
  2957. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  2958. )
  2959. /*++
  2960. Routine Description:
  2961. This routine allocates memory for map registers directly from the loader
  2962. block information. This memory must be non-cached and contiguous.
  2963. Arguments:
  2964. LoaderBlock - Pointer to the loader block which contains the memory descriptors.
  2965. Return Value:
  2966. None.
  2967. --*/
  2968. {
  2969. PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
  2970. PLIST_ENTRY NextMd;
  2971. ULONG MaxPageAddress;
  2972. ULONG PhysicalAddress;
  2973. ULONG MapRegisterSize;
  2974. MapRegisterSize = DMA_TRANSLATION_LIMIT;
  2975. MapRegisterSize = BYTES_TO_PAGES(MapRegisterSize);
  2976. //
  2977. // The address must be in KSEG 0.
  2978. //
  2979. MaxPageAddress = (KSEG1_BASE >> PAGE_SHIFT) - 1 ;
  2980. //
  2981. // Scan the memory allocation descriptors and allocate map buffers
  2982. //
  2983. NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
  2984. while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
  2985. Descriptor = CONTAINING_RECORD(NextMd,
  2986. MEMORY_ALLOCATION_DESCRIPTOR,
  2987. ListEntry);
  2988. //
  2989. // Search for a block of memory which is contains a memory chuck
  2990. // that is greater than size pages, and has a physical address less
  2991. // than MAXIMUM_PHYSICAL_ADDRESS.
  2992. //
  2993. if ((Descriptor->MemoryType == LoaderFree ||
  2994. Descriptor->MemoryType == MemoryFirmwareTemporary) &&
  2995. (Descriptor->BasePage) &&
  2996. (Descriptor->PageCount >= MapRegisterSize) &&
  2997. (Descriptor->BasePage + MapRegisterSize < MaxPageAddress)) {
  2998. PhysicalAddress = Descriptor->BasePage << PAGE_SHIFT;
  2999. break;
  3000. }
  3001. NextMd = NextMd->Flink;
  3002. }
  3003. //
  3004. // Use the extra descriptor to define the memory at the end of the
  3005. // original block.
  3006. //
  3007. ASSERT(NextMd != &LoaderBlock->MemoryDescriptorListHead);
  3008. if (NextMd == &LoaderBlock->MemoryDescriptorListHead)
  3009. return;
  3010. //
  3011. // Adjust the memory descriptors.
  3012. //
  3013. Descriptor->BasePage += MapRegisterSize;
  3014. Descriptor->PageCount -= MapRegisterSize;
  3015. if (Descriptor->PageCount == 0) {
  3016. //
  3017. // The whole block was allocated,
  3018. // Remove the entry from the list completely.
  3019. //
  3020. RemoveEntryList(&Descriptor->ListEntry);
  3021. }
  3022. //
  3023. // Save the map register base.
  3024. //
  3025. HalpMapRegisterPhysicalBase = PhysicalAddress;
  3026. #if defined(_BBM_DMA_)
  3027. /* start kuriyama TLB fill 0xff */ // D001
  3028. RtlFillMemory( (HalpMapRegisterPhysicalBase | KSEG1_BASE), 0x2000, 0xff);
  3029. /* end kuriyama TLB fill 0xff */
  3030. #endif // _BBM_DMA_
  3031. /* start M0004 */
  3032. #if defined(_BBM_DMA_)
  3033. HalpAllocateCopyBuffer(LoaderBlock);
  3034. #endif // _BBM_DMA_
  3035. /* end M0004 */
  3036. }
  3037. /* start M0001 */
  3038. #if defined(_R94A_)
  3039. BOOLEAN
  3040. HalpCreateTyphoonErrorStructures (
  3041. VOID
  3042. )
  3043. /*++
  3044. Routine Description:
  3045. This routine initializes the structures necessary for Typhoon Error
  3046. interrupt dispatcher. It also connects an interrupt handler to the
  3047. Typhoon Error interrupt.
  3048. Arguments:
  3049. None.
  3050. Return Value:
  3051. If the second level interrupt dispatcher is connected, then a value of
  3052. TRUE is returned. Otherwise, a value of FALSE is returned.
  3053. --*/
  3054. {
  3055. //
  3056. // Initialize the Typhoon Error interrupt dispatcher for I/O interrupts.
  3057. //
  3058. KeInitializeInterrupt( &HalpTyphoonErrorInterrupt,
  3059. HalpTyphoonError,
  3060. (PVOID) NULL,
  3061. (PKSPIN_LOCK) NULL,
  3062. TYPHOON_ERROR_INTERRUPT_VECTOR,
  3063. DEVICE_LEVEL,
  3064. DEVICE_LEVEL,
  3065. LevelSensitive,
  3066. FALSE,
  3067. 0,
  3068. FALSE
  3069. );
  3070. //
  3071. // Don't fail if the interrupt cannot be connected.
  3072. //
  3073. return KeConnectInterrupt( &HalpTyphoonErrorInterrupt );
  3074. }
  3075. #endif // _R94A_
  3076. /* end M0001 */
  3077. /* start M0001 */
  3078. #if defined(_R94A_)
  3079. BOOLEAN
  3080. HalpTyphoonError(
  3081. IN PKINTERRUPT Interrupt,
  3082. IN PVOID ServiceContext
  3083. )
  3084. /*++
  3085. Routine Description:
  3086. This routine is called when a Typhoon Error interrupt occurs.
  3087. This error is cretical. Bugcheck is called if an error does occur.
  3088. Arguments:
  3089. Interrupt - Supplies a pointer to the interrupt object
  3090. ServiceContext - Bug number to call bugcheck with.
  3091. Return Value:
  3092. Returns TRUE.
  3093. Note. This function never return. This function call always KeBugCheck().
  3094. --*/
  3095. {
  3096. ULONG DataWord;
  3097. HalpChangePanicFlag(16, 0x01, 0x10); // S0023
  3098. //
  3099. // Read the Typhoon Error Status register.
  3100. //
  3101. DataWord = READ_REGISTER_ULONG(&DMA_CONTROL->TyphoonErrorStatus);
  3102. HalDisplayString("\nHAL: Internal master error occurred.\n"); // S0022
  3103. if ( DataWord & 2) {
  3104. HalDisplayString("ethernet bus master error\n");
  3105. }
  3106. if ( DataWord & 4) {
  3107. HalDisplayString("SCSI port 1 bus master error\n");
  3108. }
  3109. KeBugCheck(NMI_HARDWARE_FAILURE);
  3110. return(TRUE);
  3111. }
  3112. #endif // _R94A_
  3113. /* end M0001 */
  3114. #if defined(_BBM_DMA_)
  3115. VOID
  3116. HalpAllocateCopyBuffer(
  3117. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  3118. )
  3119. /*++
  3120. Routine Description:
  3121. This routine allocates memory for copybuffer directly from the loader
  3122. block information. This memory must be non-cached and contiguous.
  3123. Arguments:
  3124. LoaderBlock - Pointer to the loader block which contains the memory descriptors.
  3125. Return Value:
  3126. None.
  3127. --*/
  3128. {
  3129. PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
  3130. PLIST_ENTRY NextMd;
  3131. ULONG MaxPageAddress;
  3132. ULONG PhysicalAddress;
  3133. ULONG MapRegisterSize;
  3134. MapRegisterSize = 0x400000;
  3135. MapRegisterSize = BYTES_TO_PAGES(MapRegisterSize);
  3136. //
  3137. // The address must be in KSEG 0.
  3138. //
  3139. MaxPageAddress = (KSEG1_BASE >> PAGE_SHIFT) - 1 ;
  3140. //
  3141. // Scan the memory allocation descriptors and allocate map buffers
  3142. //
  3143. NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
  3144. while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
  3145. Descriptor = CONTAINING_RECORD(NextMd,
  3146. MEMORY_ALLOCATION_DESCRIPTOR,
  3147. ListEntry);
  3148. //
  3149. // Search for a block of memory which is contains a memory chuck
  3150. // that is greater than size pages, and has a physical address less
  3151. // than MAXIMUM_PHYSICAL_ADDRESS.
  3152. //
  3153. if ((Descriptor->MemoryType == LoaderFree ||
  3154. Descriptor->MemoryType == MemoryFirmwareTemporary) &&
  3155. (Descriptor->BasePage) &&
  3156. (Descriptor->PageCount >= MapRegisterSize) &&
  3157. (Descriptor->BasePage + MapRegisterSize < MaxPageAddress)) {
  3158. PhysicalAddress = Descriptor->BasePage << PAGE_SHIFT;
  3159. break;
  3160. }
  3161. NextMd = NextMd->Flink;
  3162. }
  3163. //
  3164. // Use the extra descriptor to define the memory at the end of the
  3165. // original block.
  3166. //
  3167. ASSERT(NextMd != &LoaderBlock->MemoryDescriptorListHead);
  3168. if (NextMd == &LoaderBlock->MemoryDescriptorListHead)
  3169. return;
  3170. //
  3171. // Adjust the memory descriptors.
  3172. //
  3173. Descriptor->BasePage += MapRegisterSize;
  3174. Descriptor->PageCount -= MapRegisterSize;
  3175. if (Descriptor->PageCount == 0) {
  3176. //
  3177. // The whole block was allocated,
  3178. // Remove the entry from the list completely.
  3179. //
  3180. RemoveEntryList(&Descriptor->ListEntry);
  3181. }
  3182. //
  3183. // Save the map register base.
  3184. //
  3185. CopyBufferPhysicalBase = PhysicalAddress;
  3186. HalDump("Common Buffer Physical = %x\n",CopyBufferPhysicalBase);
  3187. CopyBufferVirtualAddress = PhysicalAddress | KSEG1_BASE;
  3188. HalDump("Common Buffer Virtual = %x\n",CopyBufferVirtualAddress);
  3189. }
  3190. #endif // _BBM_DMA_
  3191. /* end M0004 */