Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1523 lines
37 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. ixhwsup.c
  5. Abstract:
  6. This module contains the IoXxx routines for the NT I/O system that
  7. are hardware dependent. Were these routines not hardware dependent,
  8. they would reside in the iosubs.c module.
  9. Author:
  10. Darryl E. Havens (darrylh) 11-Apr-1990
  11. Environment:
  12. Kernel mode
  13. Revision History:
  14. --*/
  15. #include "bootia64.h"
  16. #include "arc.h"
  17. #include "ixfwhal.h"
  18. #include "eisa.h"
  19. #include "ntconfig.h"
  20. #if !defined(NO_LEGACY_DRIVERS)
  21. //
  22. // This isn't used under EFI -- the HalPT is only setup immediately
  23. // before calling ExitBootServices(), and is only necessary if you are
  24. // using ntbootdd.sys
  25. //
  26. extern PHARDWARE_PTE HalPT;
  27. #endif
  28. PVOID HalpEisaControlBase;
  29. //
  30. // Define save area for ESIA adapter objects.
  31. //
  32. PADAPTER_OBJECT HalpEisaAdapter[8];
  33. VOID
  34. HalpCopyBufferMap(
  35. IN PMDL Mdl,
  36. IN PTRANSLATION_ENTRY TranslationEntry,
  37. IN PVOID CurrentVa,
  38. IN ULONG Length,
  39. IN BOOLEAN WriteToDevice
  40. );
  41. VOID
  42. HalpCopyBufferMap(
  43. IN PMDL Mdl,
  44. IN PTRANSLATION_ENTRY TranslationEntry,
  45. IN PVOID CurrentVa,
  46. IN ULONG Length,
  47. IN BOOLEAN WriteToDevice
  48. )
  49. /*++
  50. Routine Description:
  51. This routine copies the speicific data between the user's buffer and the
  52. map register buffer. First a the user buffer is mapped if necessary, then
  53. the data is copied. Finally the user buffer will be unmapped if
  54. neccessary.
  55. Arguments:
  56. Mdl - Pointer to the MDL that describes the pages of memory that are
  57. being read or written.
  58. TranslationEntry - The address of the base map register that has been
  59. allocated to the device driver for use in mapping the transfer.
  60. CurrentVa - Current virtual address in the buffer described by the MDL
  61. that the transfer is being done to or from.
  62. Length - The length of the transfer. This determines the number of map
  63. registers that need to be written to map the transfer.
  64. WriteToDevice - Boolean value that indicates whether this is a write
  65. to the device from memory (TRUE), or vice versa.
  66. Return Value:
  67. None.
  68. --*/
  69. {
  70. PCCHAR bufferAddress;
  71. BOOLEAN mapped;
  72. //
  73. // Check to see if the buffer needs to be mapped.
  74. //
  75. if ((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0) {
  76. //
  77. // Map the buffer into system space.
  78. //
  79. bufferAddress = MmGetMdlVirtualAddress(Mdl);
  80. mapped = TRUE;
  81. } else {
  82. bufferAddress = Mdl->MappedSystemVa;
  83. mapped = FALSE;
  84. }
  85. //
  86. // Calculate the actual start of the buffer based on the system VA and
  87. // the current VA.
  88. //
  89. bufferAddress += (PCCHAR) CurrentVa - (PCCHAR) MmGetMdlVirtualAddress(Mdl);
  90. //
  91. // Copy the data between the user buffer and map buffer
  92. //
  93. if (WriteToDevice) {
  94. RtlMoveMemory( TranslationEntry->VirtualAddress, bufferAddress, Length);
  95. } else {
  96. RtlMoveMemory(bufferAddress, TranslationEntry->VirtualAddress, Length);
  97. }
  98. }
  99. PADAPTER_OBJECT
  100. HalGetAdapter(
  101. IN PDEVICE_DESCRIPTION DeviceDescriptor,
  102. OUT PULONG NumberOfMapRegisters
  103. )
  104. /*++
  105. Routine Description:
  106. This function returns the appropriate adapter object for the device defined
  107. in the device description structure. This code works for Isa and Eisa
  108. systems.
  109. Arguments:
  110. DeviceDescriptor - Supplies a description of the deivce.
  111. NumberOfMapRegisters - Returns the maximum number of map registers which
  112. may be allocated by the device driver.
  113. Return Value:
  114. A pointer to the requested adpater object or NULL if an adapter could not
  115. be created.
  116. --*/
  117. {
  118. PADAPTER_OBJECT adapterObject;
  119. PVOID adapterBaseVa;
  120. ULONG channelNumber;
  121. ULONG controllerNumber;
  122. DMA_EXTENDED_MODE extendedMode;
  123. UCHAR adapterMode;
  124. ULONG numberOfMapRegisters;
  125. BOOLEAN useChannel;
  126. ULONG maximumLength;
  127. //
  128. // Determine if the the channel number is important. Master cards on
  129. // Eisa and Mca do not use a channel number.
  130. //
  131. if (DeviceDescriptor->InterfaceType != Isa &&
  132. DeviceDescriptor->Master) {
  133. useChannel = FALSE;
  134. } else {
  135. useChannel = TRUE;
  136. }
  137. //
  138. // Support for ISA local bus machines:
  139. // If the driver is a Master but really does not want a channel since it
  140. // is using the local bus DMA, just don't use an ISA channel.
  141. //
  142. if (DeviceDescriptor->InterfaceType == Isa &&
  143. DeviceDescriptor->DmaChannel > 7) {
  144. useChannel = FALSE;
  145. }
  146. //
  147. // Limit the maximum length to 2 GB this is done so that the BYTES_TO_PAGES
  148. // macro works correctly.
  149. //
  150. maximumLength = DeviceDescriptor->MaximumLength & 0x7fffffff;
  151. //
  152. // Channel 4 cannot be used since it is used for chaining. Return null if
  153. // it is requested.
  154. //
  155. if (DeviceDescriptor->DmaChannel == 4 && useChannel &&
  156. DeviceDescriptor->InterfaceType != MicroChannel) {
  157. return(NULL);
  158. }
  159. //
  160. // Determine the number of map registers for this device.
  161. //
  162. if (DeviceDescriptor->ScatterGather && DeviceDescriptor->InterfaceType == Eisa) {
  163. //
  164. // Since the device support scatter/Gather then map registers are not
  165. // required.
  166. //
  167. numberOfMapRegisters = 0;
  168. } else {
  169. //
  170. // Determine the number of map registers required based on the maximum
  171. // transfer length, up to a maximum number.
  172. //
  173. numberOfMapRegisters = BYTES_TO_PAGES(maximumLength)
  174. + 1;
  175. numberOfMapRegisters = numberOfMapRegisters > MAXIMUM_ISA_MAP_REGISTER ?
  176. MAXIMUM_ISA_MAP_REGISTER : numberOfMapRegisters;
  177. }
  178. //
  179. // Set the channel number number.
  180. //
  181. channelNumber = DeviceDescriptor->DmaChannel & 0x03;
  182. //
  183. // Set the adapter base address to the Base address register and controller
  184. // number.
  185. //
  186. if (!(DeviceDescriptor->DmaChannel & 0x04)) {
  187. controllerNumber = 1;
  188. adapterBaseVa = (PVOID) &((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort;
  189. } else {
  190. controllerNumber = 2;
  191. #if defined(NEC_98)
  192. adapterBaseVa = &((PEISA_CONTROL) HalpEisaControlBase)->InDirectAddress;
  193. #else //NEC_98
  194. adapterBaseVa = &((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort;
  195. #endif //NEC_98
  196. }
  197. //
  198. // Determine if a new adapter object is necessary. If so then allocate it.
  199. //
  200. if (useChannel && HalpEisaAdapter[DeviceDescriptor->DmaChannel] != NULL) {
  201. adapterObject = HalpEisaAdapter[DeviceDescriptor->DmaChannel];
  202. } else {
  203. //
  204. // Allocate an adapter object.
  205. //
  206. adapterObject = (PADAPTER_OBJECT) IopAllocateAdapter(
  207. numberOfMapRegisters,
  208. adapterBaseVa,
  209. NULL
  210. );
  211. if (adapterObject == NULL) {
  212. return(NULL);
  213. }
  214. if (useChannel) {
  215. HalpEisaAdapter[DeviceDescriptor->DmaChannel] = adapterObject;
  216. }
  217. //
  218. // We never need map registers.
  219. //
  220. adapterObject->NeedsMapRegisters = FALSE;
  221. //
  222. // Set the maximum number of map registers for this channel bus on
  223. // the number requested and the type of device.
  224. //
  225. if (numberOfMapRegisters) {
  226. //
  227. // The speicified number of registers are actually allowed to be
  228. // allocated.
  229. //
  230. adapterObject->MapRegistersPerChannel = numberOfMapRegisters;
  231. } else {
  232. //
  233. // No real map registers were allocated. If this is a master
  234. // device, then the device can have as may registers as it wants.
  235. //
  236. if (DeviceDescriptor->Master) {
  237. adapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(
  238. maximumLength
  239. )
  240. + 1;
  241. } else {
  242. //
  243. // The device only gets one register. It must call
  244. // IoMapTransfer repeatedly to do a large transfer.
  245. //
  246. adapterObject->MapRegistersPerChannel = 1;
  247. }
  248. }
  249. }
  250. *NumberOfMapRegisters = adapterObject->MapRegistersPerChannel;
  251. //
  252. // If the channel number is not used then we are finished. The rest of
  253. // the work deals with channels.
  254. //
  255. if (!useChannel) {
  256. return(adapterObject);
  257. }
  258. //
  259. // Setup the pointers to all the random registers.
  260. //
  261. adapterObject->ChannelNumber = (UCHAR) channelNumber;
  262. if (controllerNumber == 1) {
  263. switch ((UCHAR)channelNumber) {
  264. case 0:
  265. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel0;
  266. break;
  267. case 1:
  268. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel1;
  269. break;
  270. case 2:
  271. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel2;
  272. break;
  273. case 3:
  274. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel3;
  275. break;
  276. }
  277. //
  278. // Set the adapter number.
  279. //
  280. adapterObject->AdapterNumber = 1;
  281. #if defined(NEC_98)
  282. #else
  283. //
  284. // Save the extended mode register address.
  285. //
  286. adapterBaseVa =
  287. &((PEISA_CONTROL) HalpEisaControlBase)->Dma1ExtendedModePort;
  288. #endif // !NEC_98
  289. } else {
  290. #if defined(NEC_98)
  291. #else //NEC_98
  292. switch (channelNumber) {
  293. case 1:
  294. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel5;
  295. break;
  296. case 2:
  297. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel6;
  298. break;
  299. case 3:
  300. adapterObject->PagePort = (PUCHAR) &((PDMA_PAGE) 0)->Channel7;
  301. break;
  302. }
  303. //
  304. // Set the adapter number.
  305. //
  306. adapterObject->AdapterNumber = 2;
  307. //
  308. // Save the extended mode register address.
  309. //
  310. adapterBaseVa =
  311. &((PEISA_CONTROL) HalpEisaControlBase)->Dma2ExtendedModePort;
  312. #endif //NEC_98
  313. }
  314. adapterObject->Width16Bits = FALSE;
  315. if (MachineType == MACHINE_TYPE_EISA) {
  316. //
  317. // Initialzie the extended mode port.
  318. //
  319. *((PUCHAR) &extendedMode) = 0;
  320. extendedMode.ChannelNumber = (UCHAR)channelNumber;
  321. switch (DeviceDescriptor->DmaSpeed) {
  322. case Compatible:
  323. extendedMode.TimingMode = COMPATIBLITY_TIMING;
  324. break;
  325. case TypeA:
  326. extendedMode.TimingMode = TYPE_A_TIMING;
  327. break;
  328. case TypeB:
  329. extendedMode.TimingMode = TYPE_B_TIMING;
  330. break;
  331. case TypeC:
  332. extendedMode.TimingMode = BURST_TIMING;
  333. break;
  334. default:
  335. return(NULL);
  336. }
  337. switch (DeviceDescriptor->DmaWidth) {
  338. case Width8Bits:
  339. extendedMode.TransferSize = BY_BYTE_8_BITS;
  340. break;
  341. case Width16Bits:
  342. extendedMode.TransferSize = BY_BYTE_16_BITS;
  343. //
  344. // Note Width16bits should not be set here because there is no need
  345. // to shift the address and the transfer count.
  346. //
  347. break;
  348. case Width32Bits:
  349. extendedMode.TransferSize = BY_BYTE_32_BITS;
  350. break;
  351. default:
  352. return(NULL);
  353. }
  354. WRITE_PORT_UCHAR( adapterBaseVa, *((PUCHAR) &extendedMode));
  355. } else if (!DeviceDescriptor->Master) {
  356. #if defined(NEC_98)
  357. #else
  358. switch (DeviceDescriptor->DmaWidth) {
  359. case Width8Bits:
  360. //
  361. // The channel must use controller 1.
  362. //
  363. if (controllerNumber != 1) {
  364. return(NULL);
  365. }
  366. break;
  367. case Width16Bits:
  368. //
  369. // The channel must use controller 2.
  370. //
  371. if (controllerNumber != 2) {
  372. return(NULL);
  373. }
  374. adapterObject->Width16Bits = TRUE;
  375. break;
  376. default:
  377. return(NULL);
  378. }
  379. #endif //!NEC_98
  380. }
  381. //
  382. // Determine if this is an Isa adapter.
  383. //
  384. if (DeviceDescriptor->InterfaceType == Isa) {
  385. adapterObject->IsaDevice = TRUE;
  386. }
  387. //
  388. // Initialize the adapter mode register value to the correct parameters,
  389. // and save them in the adapter object.
  390. //
  391. adapterMode = 0;
  392. ((PDMA_EISA_MODE) &adapterMode)->Channel = adapterObject->ChannelNumber;
  393. adapterObject->MasterDevice = FALSE;
  394. if (DeviceDescriptor->Master) {
  395. adapterObject->MasterDevice = TRUE;
  396. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = CASCADE_REQUEST_MODE;
  397. //
  398. // Set the mode, and enable the request.
  399. //
  400. if (adapterObject->AdapterNumber == 1) {
  401. //
  402. // This request is for DMA controller 1
  403. //
  404. PDMA1_CONTROL dmaControl;
  405. dmaControl = adapterObject->AdapterBaseVa;
  406. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  407. //
  408. // Unmask the DMA channel.
  409. //
  410. WRITE_PORT_UCHAR(
  411. &dmaControl->SingleMask,
  412. (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
  413. );
  414. } else {
  415. #if defined(NEC_98)
  416. #else //NEC_98
  417. //
  418. // This request is for DMA controller 1
  419. //
  420. PDMA2_CONTROL dmaControl;
  421. dmaControl = adapterObject->AdapterBaseVa;
  422. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  423. //
  424. // Unmask the DMA channel.
  425. //
  426. WRITE_PORT_UCHAR(
  427. &dmaControl->SingleMask,
  428. (UCHAR) (DMA_CLEARMASK | adapterObject->ChannelNumber)
  429. );
  430. #endif //NEC_98
  431. }
  432. } else if (DeviceDescriptor->DemandMode) {
  433. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = DEMAND_REQUEST_MODE;
  434. } else {
  435. ((PDMA_EISA_MODE) &adapterMode)->RequestMode = SINGLE_REQUEST_MODE;
  436. }
  437. if (DeviceDescriptor->AutoInitialize) {
  438. ((PDMA_EISA_MODE) &adapterMode)->AutoInitialize = 1;
  439. }
  440. adapterObject->AdapterMode = adapterMode;
  441. return(adapterObject);
  442. }
  443. NTSTATUS
  444. IoAllocateAdapterChannel(
  445. IN PADAPTER_OBJECT AdapterObject,
  446. IN PDEVICE_OBJECT DeviceObject,
  447. IN ULONG NumberOfMapRegisters,
  448. IN PDRIVER_CONTROL ExecutionRoutine,
  449. IN PVOID Context
  450. )
  451. /*++
  452. Routine Description:
  453. This routine allocates the adapter channel specified by the adapter object.
  454. This is accomplished by placing the device object of the driver that wants
  455. to allocate the adapter on the adapter's queue. If the queue is already
  456. "busy", then the adapter has already been allocated, so the device object
  457. is simply placed onto the queue and waits until the adapter becomes free.
  458. Once the adapter becomes free (or if it already is), then the driver's
  459. execution routine is invoked.
  460. Also, a number of map registers may be allocated to the driver by specifying
  461. a non-zero value for NumberOfMapRegisters. If this is the case, then the
  462. base address of the allocated map registers in the adapter is also passed
  463. to the driver's execution routine.
  464. Arguments:
  465. AdapterObject - Pointer to the adapter control object to allocate to the
  466. driver.
  467. DeviceObject - Pointer to the driver's device object that represents the
  468. device allocating the adapter.
  469. NumberOfMapRegisters - The number of map registers that are to be allocated
  470. from the channel, if any.
  471. ExecutionRoutine - The address of the driver's execution routine that is
  472. invoked once the adapter channel (and possibly map registers) have been
  473. allocated.
  474. Context - An untyped longword context parameter passed to the driver's
  475. execution routine.
  476. Return Value:
  477. Returns STATUS_SUCESS unless too many map registers are requested.
  478. Notes:
  479. Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
  480. --*/
  481. {
  482. IO_ALLOCATION_ACTION action;
  483. //
  484. // Make sure the adapter if free.
  485. //
  486. #if defined(ENABLE_LOADER_EBUG)
  487. if (AdapterObject->AdapterInUse) {
  488. DbgPrint("IoAllocateAdapterChannel: Called while adapter in use.\n");
  489. }
  490. #endif
  491. //
  492. // Make sure there are enough map registers.
  493. //
  494. if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) {
  495. #if defined(ENABLE_LOADER_EBUG)
  496. DbgPrint("IoAllocateAdapterChannel: Out of map registers.\n");
  497. #endif
  498. return(STATUS_INSUFFICIENT_RESOURCES);
  499. }
  500. action = ExecutionRoutine( DeviceObject,
  501. DeviceObject->CurrentIrp,
  502. AdapterObject->MapRegisterBase,
  503. Context );
  504. //
  505. // If the driver wishes to keep the map registers then
  506. // increment the current base and decrease the number of existing map
  507. // registers.
  508. //
  509. if (action == DeallocateObjectKeepRegisters &&
  510. AdapterObject->MapRegisterBase != NULL) {
  511. AdapterObject->MapRegistersPerChannel -= NumberOfMapRegisters;
  512. AdapterObject->MapRegisterBase = (PVOID)((PTRANSLATION_ENTRY)AdapterObject->MapRegisterBase +
  513. NumberOfMapRegisters);
  514. } else if (action == KeepObject) {
  515. AdapterObject->AdapterInUse = TRUE;
  516. }
  517. return(STATUS_SUCCESS);
  518. }
  519. VOID
  520. IoFreeAdapterChannel(
  521. IN PADAPTER_OBJECT AdapterObject
  522. )
  523. /*++
  524. Routine Description:
  525. This routine is invoked to deallocate the specified adapter object.
  526. Any map registers that were allocated are also automatically deallocated.
  527. No checks are made to ensure that the adapter is really allocated to
  528. a device object. However, if it is not, then kernel will bugcheck.
  529. If another device is waiting in the queue to allocate the adapter object
  530. it will be pulled from the queue and its execution routine will be
  531. invoked.
  532. Arguments:
  533. AdapterObject - Pointer to the adapter object to be deallocated.
  534. Return Value:
  535. None.
  536. --*/
  537. {
  538. AdapterObject->AdapterInUse = FALSE;
  539. }
  540. PHYSICAL_ADDRESS
  541. IoMapTransfer(
  542. IN PADAPTER_OBJECT AdapterObject,
  543. IN PMDL Mdl,
  544. IN PVOID MapRegisterBase,
  545. IN PVOID CurrentVa,
  546. IN OUT PULONG Length,
  547. IN BOOLEAN WriteToDevice
  548. )
  549. /*++
  550. Routine Description:
  551. This routine is invoked to set up the map registers in the DMA controller
  552. to allow a transfer to or from a device.
  553. Arguments:
  554. AdapterObject - Pointer to the adapter object representing the DMA
  555. controller channel that has been allocated.
  556. Mdl - Pointer to the MDL that describes the pages of memory that are
  557. being read or written.
  558. MapRegisterBase - The address of the base map register that has been
  559. allocated to the device driver for use in mapping the transfer.
  560. CurrentVa - Current virtual address in the buffer described by the MDL
  561. that the transfer is being done to or from.
  562. Length - Supplies the length of the transfer. This determines the
  563. number of map registers that need to be written to map the transfer.
  564. Returns the length of the transfer which was actually mapped.
  565. WriteToDevice - Boolean value that indicates whether this is a write
  566. to the device from memory (TRUE), or vice versa.
  567. Return Value:
  568. Returns the logical address that should be used bus master controllers.
  569. --*/
  570. {
  571. BOOLEAN useBuffer;
  572. ULONG transferLength;
  573. ULONG logicalAddress;
  574. PULONG pageFrame;
  575. PUCHAR bytePointer;
  576. UCHAR adapterMode;
  577. UCHAR dataByte;
  578. PTRANSLATION_ENTRY translationEntry;
  579. BOOLEAN masterDevice;
  580. PHYSICAL_ADDRESS ReturnAddress;
  581. masterDevice = AdapterObject == NULL || AdapterObject->MasterDevice ?
  582. TRUE : FALSE;
  583. translationEntry = MapRegisterBase;
  584. transferLength = *Length;
  585. //
  586. // Determine if the data transfer needs to use the map buffer.
  587. //
  588. if (translationEntry && !masterDevice &&
  589. ADDRESS_AND_SIZE_TO_SPAN_PAGES(CurrentVa, transferLength) > 1) {
  590. logicalAddress = translationEntry->PhysicalAddress;
  591. useBuffer = TRUE;
  592. } else {
  593. //
  594. // The transfer can only be done for one page.
  595. //
  596. transferLength = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
  597. pageFrame = (PULONG)(Mdl+1);
  598. pageFrame += ((ULONG_PTR) CurrentVa - (ULONG_PTR) Mdl->StartVa) / PAGE_SIZE;
  599. logicalAddress = (*pageFrame << PAGE_SHIFT) + BYTE_OFFSET(CurrentVa);
  600. //
  601. // If the buffer is contigous and does not cross a 64 K bountry then
  602. // just extend the buffer.
  603. //
  604. while( transferLength < *Length ){
  605. if ( (*pageFrame + 1) != *(pageFrame + 1) ||
  606. (*pageFrame & ~0x0ffff) != (*(pageFrame + 1) & ~0x0ffff)) {
  607. break;
  608. }
  609. transferLength += PAGE_SIZE;
  610. pageFrame++;
  611. }
  612. transferLength = transferLength > *Length ? *Length : transferLength;
  613. useBuffer = FALSE;
  614. }
  615. //
  616. // Check to see if this device has any map registers allocated. If it
  617. // does, then it must require memory to be at less than 16 MB. If the
  618. // logical address is greater than 16MB then map registers must be used
  619. //
  620. if (translationEntry && logicalAddress >= MAXIMUM_PHYSICAL_ADDRESS) {
  621. logicalAddress = (translationEntry + translationEntry->Index)->
  622. PhysicalAddress;
  623. useBuffer = TRUE;
  624. }
  625. //
  626. // Return the length.
  627. //
  628. *Length = transferLength;
  629. //
  630. // Copy the data if necessary.
  631. //
  632. if (useBuffer && WriteToDevice) {
  633. HalpCopyBufferMap(
  634. Mdl,
  635. translationEntry + translationEntry->Index,
  636. CurrentVa,
  637. *Length,
  638. WriteToDevice
  639. );
  640. }
  641. //
  642. // If there are map registers, then update the index to indicate
  643. // how many have been used.
  644. //
  645. if (translationEntry) {
  646. translationEntry->Index += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
  647. CurrentVa,
  648. transferLength
  649. );
  650. }
  651. //
  652. // If no adapter was specificed then there is no more work to do so
  653. // return.
  654. //
  655. if (masterDevice) {
  656. //
  657. // We only support 32 bits, but the return is 64. Just
  658. // zero extend
  659. //
  660. ReturnAddress.QuadPart = logicalAddress;
  661. return(ReturnAddress);
  662. }
  663. //
  664. // Determine the mode based on the transfer direction.
  665. //
  666. adapterMode = AdapterObject->AdapterMode;
  667. ((PDMA_EISA_MODE) &adapterMode)->TransferType = (UCHAR) (WriteToDevice ?
  668. WRITE_TRANSFER : READ_TRANSFER);
  669. ReturnAddress.QuadPart = logicalAddress;
  670. bytePointer = (PUCHAR) &logicalAddress;
  671. #if defined(NEC_98)
  672. #else
  673. if (AdapterObject->Width16Bits) {
  674. //
  675. // If this is a 16 bit transfer then adjust the length and the address
  676. // for the 16 bit DMA mode.
  677. //
  678. transferLength >>= 1;
  679. //
  680. // In 16 bit DMA mode the low 16 bits are shifted right one and the
  681. // page register value is unchanged. So save the page register value
  682. // and shift the logical address then restore the page value.
  683. //
  684. dataByte = bytePointer[2];
  685. logicalAddress >>= 1;
  686. bytePointer[2] = dataByte;
  687. }
  688. #endif //NEC_98
  689. //
  690. // Determine the controller number based on the Adapter number.
  691. //
  692. if (AdapterObject->AdapterNumber == 1) {
  693. //
  694. // This request is for DMA controller 1
  695. //
  696. PDMA1_CONTROL dmaControl;
  697. dmaControl = AdapterObject->AdapterBaseVa;
  698. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  699. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  700. WRITE_PORT_UCHAR(
  701. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  702. .DmaBaseAddress,
  703. bytePointer[0]
  704. );
  705. WRITE_PORT_UCHAR(
  706. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  707. .DmaBaseAddress,
  708. bytePointer[1]
  709. );
  710. WRITE_PORT_UCHAR(
  711. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
  712. (ULONGLONG)AdapterObject->PagePort,
  713. bytePointer[2]
  714. );
  715. #if 0
  716. //
  717. // Write the high page register with zero value. This enable a special mode
  718. // which allows ties the page register and base count into a single 24 bit
  719. // address register.
  720. //
  721. WRITE_PORT_UCHAR(
  722. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
  723. (ULONG)AdapterObject->PagePort,
  724. 0
  725. );
  726. #endif
  727. //
  728. // Notify DMA chip of the length to transfer.
  729. //
  730. WRITE_PORT_UCHAR(
  731. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  732. .DmaBaseCount,
  733. (UCHAR) ((transferLength - 1) & 0xff)
  734. );
  735. WRITE_PORT_UCHAR(
  736. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  737. .DmaBaseCount,
  738. (UCHAR) ((transferLength - 1) >> 8)
  739. );
  740. //
  741. // Set the DMA chip to read or write mode; and unmask it.
  742. //
  743. WRITE_PORT_UCHAR(
  744. &dmaControl->SingleMask,
  745. (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
  746. );
  747. } else {
  748. #if defined(NEC_98)
  749. #else //NEC_98
  750. //
  751. // This request is for DMA controller 2
  752. //
  753. PDMA2_CONTROL dmaControl;
  754. dmaControl = AdapterObject->AdapterBaseVa;
  755. WRITE_PORT_UCHAR( &dmaControl->ClearBytePointer, 0 );
  756. WRITE_PORT_UCHAR( &dmaControl->Mode, adapterMode );
  757. WRITE_PORT_UCHAR(
  758. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  759. .DmaBaseAddress,
  760. bytePointer[0]
  761. );
  762. WRITE_PORT_UCHAR(
  763. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  764. .DmaBaseAddress,
  765. bytePointer[1]
  766. );
  767. WRITE_PORT_UCHAR(
  768. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageLowPort) +
  769. (ULONGLONG)AdapterObject->PagePort,
  770. bytePointer[2]
  771. );
  772. #if 0
  773. //
  774. // Write the high page register with zero value. This enable a special mode
  775. // which allows ties the page register and base count into a single 24 bit
  776. // address register.
  777. //
  778. WRITE_PORT_UCHAR(
  779. ((PUCHAR) &((PEISA_CONTROL) HalpEisaControlBase)->DmaPageHighPort) +
  780. (ULONG)AdapterObject->PagePort,
  781. 0
  782. );
  783. #endif
  784. //
  785. // Notify DMA chip of the length to transfer.
  786. //
  787. WRITE_PORT_UCHAR(
  788. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  789. .DmaBaseCount,
  790. (UCHAR) ((transferLength - 1) & 0xff)
  791. );
  792. WRITE_PORT_UCHAR(
  793. &dmaControl->DmaAddressCount[AdapterObject->ChannelNumber]
  794. .DmaBaseCount,
  795. (UCHAR) ((transferLength - 1) >> 8)
  796. );
  797. //
  798. // Set the DMA chip to read or write mode; and unmask it.
  799. //
  800. WRITE_PORT_UCHAR(
  801. &dmaControl->SingleMask,
  802. (UCHAR) (DMA_CLEARMASK | AdapterObject->ChannelNumber)
  803. );
  804. #endif //NEC_98
  805. }
  806. return(ReturnAddress);
  807. }
  808. BOOLEAN
  809. IoFlushAdapterBuffers(
  810. IN PADAPTER_OBJECT AdapterObject,
  811. IN PMDL Mdl,
  812. IN PVOID MapRegisterBase,
  813. IN PVOID CurrentVa,
  814. IN ULONG Length,
  815. IN BOOLEAN WriteToDevice
  816. )
  817. /*++
  818. Routine Description:
  819. This routine flushes the DMA adpater object buffers. For the Jazz system
  820. its clears the enable flag which aborts the dma.
  821. Arguments:
  822. AdapterObject - Pointer to the adapter object representing the DMA
  823. controller channel.
  824. Mdl - A pointer to a Memory Descriptor List (MDL) that maps the locked-down
  825. buffer to/from which the I/O occured.
  826. MapRegisterBase - A pointer to the base of the map registers in the adapter
  827. or DMA controller.
  828. CurrentVa - The current virtual address in the buffer described the the Mdl
  829. where the I/O operation occurred.
  830. Length - Supplies the length of the transfer.
  831. WriteToDevice - Supplies a BOOLEAN value that indicates the direction of
  832. the data transfer was to the device.
  833. Return Value:
  834. TRUE - No errors are detected so the transfer must succeed.
  835. --*/
  836. {
  837. PTRANSLATION_ENTRY translationEntry;
  838. PULONG pageFrame;
  839. ULONG transferLength;
  840. ULONG partialLength;
  841. BOOLEAN masterDevice;
  842. BOOLEAN mapped = FALSE;
  843. masterDevice = AdapterObject == NULL || AdapterObject->MasterDevice ?
  844. TRUE : FALSE;
  845. translationEntry = MapRegisterBase;
  846. //
  847. // Clear the index of used buffers.
  848. //
  849. if (translationEntry) {
  850. translationEntry->Index = 0;
  851. }
  852. //
  853. // Determine if the data needs to be copied to the orginal buffer.
  854. // This only occurs if the data tranfer is from the device, the
  855. // MapReisterBase is not NULL and the transfer spans a page.
  856. //
  857. if (!WriteToDevice && translationEntry) {
  858. //
  859. // If this is not a master device, then just transfer the buffer.
  860. //
  861. if (ADDRESS_AND_SIZE_TO_SPAN_PAGES(CurrentVa, Length) > 1 &&
  862. !masterDevice) {
  863. HalpCopyBufferMap(
  864. Mdl,
  865. translationEntry,
  866. CurrentVa,
  867. Length,
  868. WriteToDevice
  869. );
  870. } else {
  871. //
  872. // Cycle through the pages of the transfer to determine if there
  873. // are any which need to be copied back.
  874. //
  875. transferLength = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
  876. partialLength = transferLength;
  877. pageFrame = (PULONG)(Mdl+1);
  878. pageFrame += ((ULONG_PTR) CurrentVa - (ULONG_PTR) Mdl->StartVa) / PAGE_SIZE;
  879. while( transferLength <= Length ){
  880. if (*pageFrame >= BYTES_TO_PAGES(MAXIMUM_PHYSICAL_ADDRESS)) {
  881. //
  882. // Check to see that the MDL is mapped in system space.
  883. // If is not mapped, then map it. This ensures that the
  884. // buffer will only have to be mapped at most once per I/O.
  885. //
  886. if ((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0) {
  887. Mdl->MappedSystemVa = MmGetMdlVirtualAddress(Mdl);
  888. Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
  889. mapped = TRUE;
  890. }
  891. HalpCopyBufferMap(
  892. Mdl,
  893. translationEntry,
  894. CurrentVa,
  895. partialLength,
  896. WriteToDevice
  897. );
  898. }
  899. CurrentVa = (PCCHAR) CurrentVa + partialLength;
  900. partialLength = PAGE_SIZE;
  901. //
  902. // Note that transferLength indicates the amount which will be
  903. // transfered after the next loop; thus, it is updated with the
  904. // new partial length.
  905. //
  906. transferLength += partialLength;
  907. pageFrame++;
  908. translationEntry++;
  909. }
  910. //
  911. // Process the any remaining residue.
  912. //
  913. partialLength = Length - transferLength + partialLength;
  914. if (partialLength && *pageFrame >= BYTES_TO_PAGES(MAXIMUM_PHYSICAL_ADDRESS)) {
  915. HalpCopyBufferMap(
  916. Mdl,
  917. translationEntry,
  918. CurrentVa,
  919. partialLength,
  920. WriteToDevice
  921. );
  922. }
  923. }
  924. }
  925. //
  926. // If this is a master device, then there is nothing more to do so return
  927. // TRUE.
  928. //
  929. if (masterDevice) {
  930. return(TRUE);
  931. }
  932. //
  933. // Mask the DMA request line so that DMA requests cannot occur.
  934. //
  935. if (AdapterObject->AdapterNumber == 1) {
  936. //
  937. // This request is for DMA controller 1
  938. //
  939. PDMA1_CONTROL dmaControl;
  940. dmaControl = AdapterObject->AdapterBaseVa;
  941. WRITE_PORT_UCHAR(
  942. &dmaControl->SingleMask,
  943. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  944. );
  945. } else {
  946. //
  947. // This request is for DMA controller 2
  948. //
  949. #if defined(NEC_98)
  950. #else //NEC_98
  951. PDMA2_CONTROL dmaControl;
  952. dmaControl = AdapterObject->AdapterBaseVa;
  953. WRITE_PORT_UCHAR(
  954. &dmaControl->SingleMask,
  955. (UCHAR) (DMA_SETMASK | AdapterObject->ChannelNumber)
  956. );
  957. #endif //NEC_98
  958. }
  959. return TRUE;
  960. }
  961. VOID
  962. IoFreeMapRegisters(
  963. PADAPTER_OBJECT AdapterObject,
  964. PVOID MapRegisterBase,
  965. ULONG NumberOfMapRegisters
  966. )
  967. /*++
  968. Routine Description:
  969. This routine deallocates the map registers for the adapter. If there are
  970. any queued adapter waiting for an attempt is made to allocate the next
  971. entry.
  972. Arguments:
  973. AdapterObject - The adapter object to where the map register should be
  974. returned.
  975. MapRegisterBase - The map register base of the registers to be deallocated.
  976. NumberOfMapRegisters - The number of registers to be deallocated.
  977. Return Value:
  978. None
  979. --+*/
  980. {
  981. PTRANSLATION_ENTRY translationEntry;
  982. //
  983. // Determine if this was the last allocation from the adapter. If is was
  984. // then free the map registers by restoring the map register base and the
  985. // channel count; otherwise the registers are lost. This handles the
  986. // normal case.
  987. //
  988. translationEntry = AdapterObject->MapRegisterBase;
  989. translationEntry -= NumberOfMapRegisters;
  990. if (translationEntry == MapRegisterBase) {
  991. //
  992. // The last allocated registers are being freed.
  993. //
  994. AdapterObject->MapRegisterBase = (PVOID) translationEntry;
  995. AdapterObject->MapRegistersPerChannel += NumberOfMapRegisters;
  996. }
  997. }
  998. PHYSICAL_ADDRESS
  999. MmGetPhysicalAddress (
  1000. IN PVOID BaseAddress
  1001. )
  1002. /*++
  1003. Routine Description:
  1004. This function returns the corresponding physical address for a
  1005. valid virtual address.
  1006. Arguments:
  1007. BaseAddress - Supplies the virtual address for which to return the
  1008. physical address.
  1009. Return Value:
  1010. Returns the corresponding physical address.
  1011. Environment:
  1012. Kernel mode. Any IRQL level.
  1013. --*/
  1014. {
  1015. PHYSICAL_ADDRESS PhysicalAddress;
  1016. #if !defined(NO_LEGACY_DRIVERS)
  1017. ULONG Index;
  1018. #endif
  1019. PhysicalAddress.QuadPart = (ULONG_PTR)BaseAddress & ~KSEG0_BASE;
  1020. #if !defined(NO_LEGACY_DRIVERS)
  1021. //
  1022. // This is not used under EFI -- the HalPT is only setup immediately
  1023. // before calling ExitBootServices(), and this routine is really only
  1024. // necessary if you are using ntbootdd.sys.
  1025. //
  1026. //
  1027. // If the address is in the hal map range, get the physical
  1028. // addressed mapped by the pte
  1029. //
  1030. if (((ULONG_PTR) BaseAddress) >= 0xe0000000ffc00000) {
  1031. Index = (ULONG) ((PhysicalAddress.QuadPart >> PAGE_SHIFT) & 0x3ff);
  1032. PhysicalAddress.QuadPart = HalPT[Index].PageFrameNumber << PAGE_SHIFT;
  1033. PhysicalAddress.QuadPart |= (ULONG_PTR)BaseAddress & (PAGE_SIZE-1);
  1034. }
  1035. #endif
  1036. return(PhysicalAddress);
  1037. }
  1038. PVOID
  1039. MmAllocateNonCachedMemory (
  1040. IN SIZE_T NumberOfBytes
  1041. )
  1042. /*++
  1043. Routine Description:
  1044. This function allocates a range of noncached memory in
  1045. the non-paged portion of the system address space.
  1046. This routine is designed to be used by a driver's initialization
  1047. routine to allocate a noncached block of virtual memory for
  1048. various device specific buffers.
  1049. Arguments:
  1050. NumberOfBytes - Supplies the number of bytes to allocate.
  1051. Return Value:
  1052. NULL - the specified request could not be satisfied.
  1053. NON-NULL - Returns a pointer (virtual address in the nonpaged portion
  1054. of the system) to the allocated phyiscally contiguous
  1055. memory.
  1056. Environment:
  1057. Kernel mode, IRQL of APC_LEVEL or below.
  1058. --*/
  1059. {
  1060. PVOID BaseAddress;
  1061. ULONG bytesToAllocate;
  1062. bytesToAllocate = (ULONG)NumberOfBytes;
  1063. //
  1064. // Allocated the memory.
  1065. //
  1066. BaseAddress = BlAllocateHeap(bytesToAllocate);
  1067. return BaseAddress;
  1068. }