Source code of Windows XP (NT5)
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.

3235 lines
120 KiB

  1. /************************************************************************/
  2. /* */
  3. /* ATIMP.C */
  4. /* */
  5. /* Copyright (c) 1992, ATI Technologies Inc. */
  6. /************************************************************************/
  7. // Brades: Changes to be merged into Rob's source
  8. //
  9. // 904 -- frame address stored in dar[0]. we are rgistering our LFB addres
  10. // in DriverIORanges, but assigning to frameaddress.
  11. // Is this used, or needed????
  12. /********************** PolyTron RCS Utilities
  13. $Revision: 1.43 $
  14. $Date: 15 May 1996 16:29:52 $
  15. $Author: RWolff $
  16. $Log: S:/source/wnt/ms11/miniport/archive/atimp.c_v $
  17. *
  18. * Rev 1.43 15 May 1996 16:29:52 RWolff
  19. * Added workaround for Alpha hang on PCI bus greater than 0, now reports
  20. * failure of mode set on Mach 64.
  21. *
  22. * Rev 1.42 01 May 1996 14:07:52 RWolff
  23. * Calls new routine DenseOnAlpha() to determine dense space support rather
  24. * than assuming all PCI cards support dense space.
  25. *
  26. * Rev 1.41 23 Apr 1996 17:16:38 RWolff
  27. * Now reports 1M cards with SDRAM (needs special alignment in display
  28. * driver), separated "internal DAC cursor double buffering needed"
  29. * from "this is a CT".
  30. *
  31. * Rev 1.40 15 Mar 1996 16:27:08 RWolff
  32. * IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES now only frees the I/O mapped
  33. * registers in NT 4.0 and above. This is because the mapped values for
  34. * the permanent and test screens use the same virtual address, and
  35. * in 3.51 VideoPortUnmapMemory() refuses to unmap them.
  36. *
  37. * Rev 1.39 12 Mar 1996 17:41:50 RWolff
  38. * Made IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES work under new source
  39. * stream display driver, removed debug print statements from ATIMPResetHw()
  40. * since this routine can't call pageable routines and debug print
  41. * statements are pageable.
  42. *
  43. * Rev 1.38 29 Jan 1996 16:53:30 RWolff
  44. * Now uses VideoPortInt10() rather than no-BIOS code on PPC, removed
  45. * dead code.
  46. *
  47. * Rev 1.37 23 Jan 1996 11:41:10 RWolff
  48. * Eliminated level 3 warnings, added debug print statements.
  49. *
  50. * Rev 1.36 22 Dec 1995 14:51:42 RWolff
  51. * Added support for Mach 64 GT internal DAC, switched to TARGET_BUILD
  52. * to identify the NT version for which the driver is being built.
  53. *
  54. * Rev 1.35 23 Nov 1995 11:24:40 RWolff
  55. * Added multihead support.
  56. *
  57. * Rev 1.34 17 Nov 1995 13:41:02 RWolff
  58. * Temporary fallback until problem with VideoPortGetBaseAddress() is
  59. * resolved. This should have gone in as branch revision 1.33.1.0, but
  60. * the @#$%^&* configuration doesn't allow branches.
  61. *
  62. * Rev 1.33 27 Oct 1995 14:20:06 RWolff
  63. * Fixes to bring up NT 3.51 on PPC, no longer makes mapped LFB part of
  64. * hardware device extension.
  65. *
  66. * Rev 1.32 08 Sep 1995 16:36:04 RWolff
  67. * Added support for AT&T 408 DAC (STG1703 equivalent).
  68. *
  69. * Rev 1.31 28 Aug 1995 16:37:36 RWolff
  70. * No longer restores memory size on x86 boxes in ATIMPResetHw(). This
  71. * is a fix for EPR 7839 - the restoration is not necessary on x86
  72. * machines, but on some non-x86 boxes the memory size is not restored
  73. * on a warm boot, so we must do it to allow the use of modes needing
  74. * more than 1M after booting out of a 4BPP mode.
  75. *
  76. * Rev 1.30 24 Aug 1995 15:39:42 RWolff
  77. * Changed detection of block I/O cards to match Microsoft's standard for
  78. * plug-and-play, now reports CT and VT ASICs to the display driver.
  79. *
  80. * Rev 1.29 03 Aug 1995 16:22:42 RWOLFF
  81. * Reverted to old bus ordering (PCI last) for non-Alpha machines under
  82. * NT 3.5. Using the new ordering (PCI first) on an x86 under 3.5
  83. * resulted in the display applet rejecting attempts to test 16 and 24 BPP
  84. * on a Mach 32 (PCI or ISA) in a PCI machine.
  85. *
  86. * Rev 1.28 02 Jun 1995 14:19:14 RWOLFF
  87. * Rearranged bus test order to put PCI first, added CT internal to
  88. * DACs supported in no-BIOS version.
  89. *
  90. * Rev 1.27 31 Mar 1995 11:55:18 RWOLFF
  91. * Changed from all-or-nothing debug print statements to thresholds
  92. * depending on importance of the message.
  93. *
  94. * Rev 1.26 08 Mar 1995 11:33:18 ASHANMUG
  95. * The pitch in 24bpp should be the pitch in engine pixels and not true pixels
  96. *
  97. * Rev 1.25 27 Feb 1995 17:51:50 RWOLFF
  98. * Now reports (Mach 64 only) whether I/O space is packed (relocatable)
  99. * or not, reports number of lines of offscreen memory for 4BPP as if
  100. * the card has 1M of video memory, since we set the card to 1M for
  101. * this depth.
  102. *
  103. * Rev 1.24 24 Feb 1995 12:24:40 RWOLFF
  104. * Now adds text banding to the ATIModeInformation->ModeFlags bits
  105. * that are filled in.
  106. *
  107. * Rev 1.23 20 Feb 1995 18:03:30 RWOLFF
  108. * Reporting of screen tearing on 2M boundary is now DAC-independant, added
  109. * 1600x1200 16BPP to modes which experience this tearing.
  110. *
  111. * Rev 1.22 03 Feb 1995 15:13:50 RWOLFF
  112. * Added packets to support DCI.
  113. *
  114. * Rev 1.21 30 Jan 1995 12:16:24 RWOLFF
  115. * Made definition of IBM DAC special cursor flag consistent with
  116. * similar flag for TVP DAC.
  117. *
  118. * Rev 1.20 18 Jan 1995 15:38:46 RWOLFF
  119. * Now looks for Mach64 before looking for our older accelerators, Chrontel
  120. * DAC is now supported as a separate type rather than being lumped in
  121. * with STG1702.
  122. *
  123. * Rev 1.19 11 Jan 1995 13:54:00 RWOLFF
  124. * ATIMPResetHw() now restores the memory size on Mach64 cards. This is
  125. * a fix for a problem that showed up on the DEC Alpha, but may affect
  126. * other platforms as well. In 4BPP modes, we must tell the card that it
  127. * has only 1M of memory, but on a warm boot, the x86 emulation did not
  128. * re-initialize the memory size, so until the next cold boot, only modes
  129. * available in 1M were listed.
  130. *
  131. * Rev 1.18 04 Jan 1995 11:59:28 RWOLFF
  132. * ATIMPFindAdapter() will only detect ATI cards on the first invocation,
  133. * to avoid the same card being detected once per bus and causing problems
  134. * when Windows NT thinks it's multiple cards.
  135. *
  136. * Rev 1.17 23 Dec 1994 10:48:10 ASHANMUG
  137. * ALPHA/Chrontel-DAC
  138. *
  139. * Rev 1.16 18 Nov 1994 11:36:52 RWOLFF
  140. * Now checks for PCI bus, cleaned up temporary debug print statements,
  141. * fixed non-x86 Mach 64 handling, added support for Power PC and
  142. * STG1703 DAC.
  143. *
  144. * Rev 1.15 31 Aug 1994 16:14:00 RWOLFF
  145. * IOCTL_VIDEO_ATI_GET_VERSION packet now reports TVP3026 DAC (different
  146. * cursor handling needed in display driver),
  147. * IOCTL_VIDEO_ATI_GET_MODE_INFORMATION now reports 1152x864 24BPP as
  148. * having screen tearing at end of first 2M bank.
  149. *
  150. * Rev 1.14 22 Jul 1994 17:47:50 RWOLFF
  151. * Merged with Richard's non-x86 code stream.
  152. *
  153. * Rev 1.13 20 Jul 1994 13:04:06 RWOLFF
  154. * Changes required to support multiple I/O base addresses for Mach 64
  155. * accelerator registers, ATIMPInitialize() now leaves the adapter in
  156. * a state where an INT 10 can switch it to a VGA mode (fix for
  157. * showstopper bug on Landtrain machines), calls new routine
  158. * FillInRegistry() so the video applet can get information about
  159. * the graphics card.
  160. *
  161. * Rev 1.12 30 Jun 1994 18:11:36 RWOLFF
  162. * Changes to allow the new method of checking for aperture conflict.
  163. *
  164. * Rev 1.11 15 Jun 1994 11:04:24 RWOLFF
  165. * In IOCTL_VIDEO_ATI_GET_VERSION, now only sets
  166. * RequestPacket->StatusBlock->Information if the buffer is big enough.
  167. *
  168. * Rev 1.10 20 May 1994 19:18:00 RWOLFF
  169. * IOCTL_VIDEO_ATI_GET_VERSION old format packet now returns the highest
  170. * pixel depth for a given resolution even if it isn't the last mode
  171. * table for the resolution.
  172. *
  173. * Rev 1.9 20 May 1994 13:57:40 RWOLFF
  174. * Ajith's change: now saves in the query structure the bus type reported by NT.
  175. *
  176. * Rev 1.8 12 May 1994 11:04:24 RWOLFF
  177. * Now forces OEM handling on DEC ALPHA machines.
  178. *
  179. * Rev 1.7 04 May 1994 19:25:40 RWOLFF
  180. * Fixes for hanging and corrupting screen when display applet run.
  181. *
  182. * Rev 1.6 28 Apr 1994 10:59:56 RWOLFF
  183. * Moved mode-independent bug/feature flags to IOCTL_VIDEO_ATI_GET_VERSION
  184. * packet from IOCTL_VIDEO_ATI_GET_MODE_INFORMATION packet.
  185. *
  186. * Rev 1.5 27 Apr 1994 13:54:42 RWOLFF
  187. * IOCTL_VIDEO_ATI_GET_MODE_INFORMATION packet now reports whether MIO bug
  188. * is present on Mach 32 cards.
  189. *
  190. * Rev 1.4 31 Mar 1994 15:05:00 RWOLFF
  191. * Added DPMS support, brought ATIMPResetHw() up to latest specs, added
  192. * debugging code.
  193. *
  194. * Rev 1.3 14 Mar 1994 16:32:20 RWOLFF
  195. * Added ATIMPResetHw() function, fix for 2M boundary tearing, replaced
  196. * VCS logfile comments that were omitted in an earlier checkin.
  197. *
  198. * Rev 1.2 03 Mar 1994 12:36:56 ASHANMUG
  199. * Make pageable
  200. *
  201. * Rev 1.1 07 Feb 1994 13:56:18 RWOLFF
  202. * Added alloc_text() pragmas to allow miniport to be swapped out when
  203. * not needed, removed LookForSubstitute() since miniport is no longer
  204. * supposed to check whether mode has been substituted, no longer logs
  205. * a message when the miniport aborts due to no ATI card being found,
  206. * removed unused routine ATIMPQueryPointerCapabilities().
  207. *
  208. * Rev 1.0 31 Jan 1994 10:52:34 RWOLFF
  209. * Initial revision.
  210. Rev 1.6 14 Jan 1994 15:14:08 RWOLFF
  211. Removed commented-out code, packet announcements now all controlled by
  212. DEBUG_SWITCH, device reset for old cards now done by a single call,
  213. new format for IOCTL_VIDEO_ATI_GET_VERSION packet, reports block write
  214. capability in IOCTL_VIDEO_ATI_GET_MODE_INFORMATION packet, added
  215. 1600x1200 support.
  216. Rev 1.5 30 Nov 1993 18:10:04 RWOLFF
  217. Moved query of card capabilities (once type of card is known) from
  218. ATIMPFindAdapter() to ATIMPInitialize() because query for Mach 64 needs
  219. to use VideoPortInt10(), which can't be used in ATIMPFindAdapter().
  220. Rev 1.4 05 Nov 1993 13:22:12 RWOLFF
  221. Added initial Mach64 code (currently inactive).
  222. Rev 1.3 08 Oct 1993 11:00:24 RWOLFF
  223. Removed code specific to a particular family of ATI accelerators.
  224. Rev 1.2 24 Sep 1993 11:49:46 RWOLFF
  225. Removed cursor-specific IOCTLs (handled in display driver), now selects
  226. 24BPP colour order best suited to the DAC being used instead of forcing
  227. BGR.
  228. Rev 1.1 03 Sep 1993 14:20:46 RWOLFF
  229. Partway through CX isolation.
  230. Rev 1.0 16 Aug 1993 13:27:50 Robert_Wolff
  231. Initial revision.
  232. Rev 1.23 06 Jul 1993 15:46:14 RWOLFF
  233. Got rid of mach32_split_fixup special handling. This code was to support
  234. a non-production hardware combination.
  235. Rev 1.22 10 Jun 1993 15:58:32 RWOLFF
  236. Reading from registry now uses a static buffer rather than a dynamically
  237. allocated one (originated by Andre Vachon at Microsoft).
  238. Rev 1.21 07 Jun 1993 11:43:16 BRADES
  239. Rev 6 split transfer fixup.
  240. Rev 1.19 18 May 1993 14:04:00 RWOLFF
  241. Removed reference to obsolete header TTY.H, calls to wait_for_idle()
  242. no longer pass hardware device extension, since it's a global variable.
  243. Rev 1.18 12 May 1993 16:30:36 RWOLFF
  244. Now writes error messages to event log rather than blue screen,
  245. initializes "special handling" variables determined from BIOS
  246. to default values on cards with no BIOS. This revision contains
  247. code for experimental far call support, but it's "#if 0"ed out.
  248. Rev 1.17 10 May 1993 16:35:12 RWOLFF
  249. LookForSubstitute() now recognizes all cases of colour depth not
  250. supported by the DAC, unusable linear frame buffer now falls back
  251. to LFB disabled operation rather than aborting the miniport, removed
  252. unused variables and unnecessary passing of hardware device extension
  253. as a parameter.
  254. Rev 1.16 30 Apr 1993 17:58:50 BRADES
  255. ATIMP startio assign QueryPtr once at start of function.
  256. uses aVideoAddress virtual table for IO port addresses.
  257. Rev 1.15 30 Apr 1993 16:33:42 RWOLFF
  258. Updated to use NT build 438 initialization data structure.
  259. Registry read buffer is now dynamically allocated to fit data requested
  260. rather than being a fixed "hope it's big enough" size.
  261. Rev 1.14 21 Apr 1993 17:22:06 RWOLFF
  262. Now uses AMACH.H instead of 68800.H/68801.H.
  263. Accelerator detection now checks only for functionality, not our BIOS
  264. signature string which may not be present in OEM versions. Query
  265. structure now indicates whether extended BIOS functions and/or
  266. EEPROM are present. Added ability to switch between graphics and
  267. text modes using absolute far calls in BIOS. Removed handling
  268. of obsolete DriverOverride registry field.
  269. Rev 1.13 14 Apr 1993 18:30:22 RWOLFF
  270. 24BPP is now done as BGR (supported by both TI and Brooktree DACs)
  271. rather than RGB (only supported by TI DACs).
  272. Rev 1.12 08 Apr 1993 16:53:18 RWOLFF
  273. Revision level as checked in at Microsoft.
  274. Rev 1.9 25 Mar 1993 11:10:38 RWOLFF
  275. Cleaned up compile warnings, now returns failure if no EEPROM is present.
  276. Rev 1.8 16 Mar 1993 17:15:16 BRADES
  277. get_cursor uses screen_pitch instead of x_size.
  278. Rev 1.7 16 Mar 1993 17:04:58 BRADES
  279. Change ATI video to graphics message
  280. Rev 1.6 15 Mar 1993 22:20:30 BRADES
  281. use m_screen_pitch for the # pixels per display lines
  282. Rev 1.5 08 Mar 1993 19:23:44 BRADES
  283. update memory sizing to 256 increments, clean code.
  284. Rev 1.4 10 Feb 1993 13:01:28 Robert_Wolff
  285. IOCTL_VIDEO_MAP_VIDEO_MEMORY no longer assumes frame buffer length
  286. is equal to video memory size (linear aperture present). It can now
  287. accept 64k (uses VGA aperture) and 0 (no aperture available).
  288. Rev 1.3 06 Feb 1993 12:55:52 Robert_Wolff
  289. Now sets VIDEO_MODE_INFORMATION.ScreenStride to bytes per line (as listed
  290. in the documentation). In the October beta, it had to be pixels per line.
  291. Rev 1.2 05 Feb 1993 22:12:36 Robert_Wolff
  292. Adjusted MessageDelay() to compensate for short_delay() no longer being
  293. optimized out of existence.
  294. Rev 1.1 05 Feb 1993 16:15:28 Robert_Wolff
  295. Made it compatible with the new DDK, registry calls now use VideoPort
  296. functions rather than RTL functions. This version will work with the
  297. framebuffer driver.
  298. Rev 1.0 02 Feb 1993 13:36:50 Robert_Wolff
  299. Initial revision.
  300. Rev 1.2 26 Jan 1993 10:28:30 Robert_Wolff
  301. Now fills in Number<colour>Bits fields in VIDEO_MODE_INFORMATION structure.
  302. Rev 1.1 25 Jan 1993 13:31:52 Robert_Wolff
  303. Re-enabled forcing of shared VGA/accelerator memory for Mach 32
  304. cards with no aperture enabled.
  305. Rev 1.0 22 Jan 1993 16:44:42 Robert_Wolff
  306. Initial revision.
  307. Rev 1.26 21 Jan 1993 17:59:24 Robert_Wolff
  308. Eliminated multiple definition link warnings, updated comments
  309. in LookForSubstitute().
  310. Rev 1.25 20 Jan 1993 17:47:48 Robert_Wolff
  311. Now checks optional DriverOverride field in registry, and forces
  312. use of appropriate (engine, framebuffer, or VGAWonder) driver
  313. if the field is present and nonzero. If field is missing or zero,
  314. former behaviour is used.
  315. IOCTL_VIDEO_ATI_GET_VERSION packet now also returns the maximum
  316. pixel depth available at each resolution.
  317. Added mode substitution case for 16 BPP selected when using the
  318. engine-only (fixed 8 BPP colour depth) driver.
  319. Rev 1.24 15 Jan 1993 15:12:26 Robert_Wolff
  320. Added IOCTL_VIDEO_ATI_GET_VERSION packet in ATIMPStartIO() to
  321. return version number of the miniport.
  322. Rev 1.23 14 Jan 1993 17:49:40 Robert_Wolff
  323. Removed reference to blank screen in message printed before query
  324. structure filled in, moved printing of this message and the "Done."
  325. terminator so all checking for video cards is between them.
  326. Rev 1.22 14 Jan 1993 10:37:28 Robert_Wolff
  327. Re-inserted "fail if VGAWonder but no ATI accelerator" check due
  328. to lack of VGAWONDER .DLL file in late January driver package.
  329. Rev 1.21 13 Jan 1993 13:31:04 Robert_Wolff
  330. Added support for the Corsair and other machines which don't store
  331. their aperture location in the EEPROM, single miniport now handles
  332. VGAWonder in addition to accelerators.
  333. Rev 1.20 07 Jan 1993 18:20:34 Robert_Wolff
  334. Now checks to see if aperture is configured but unusable, and
  335. forces the use of the engine-only driver if this is the case.
  336. Added message to let users know that the black screen during
  337. EEPROM read is normal.
  338. Rev 1.19 06 Jan 1993 11:04:36 Robert_Wolff
  339. BIOS locations C0000-DFFFF now mapped as one block, cleaned up warnings.
  340. Rev 1.18 04 Jan 1993 14:39:50 Robert_Wolff
  341. Added card type as a parameter to setmode().
  342. Rev 1.17 24 Dec 1992 14:41:20 Chris_Brady
  343. fixup warnings
  344. Rev 1.16 15 Dec 1992 13:34:46 Robert_Wolff
  345. Writing of MEM_CFG when forcing 4M aperture now preserves all but
  346. the aperture size bits. This allows operation on Corsair as well
  347. as standard versions of the Mach 32 card.
  348. Rev 1.15 11 Dec 1992 14:45:44 Robert_Wolff
  349. Now forces the use of the FRAMEBUF driver if a 2M aperture is configured.
  350. Rev 1.14 11 Dec 1992 09:47:34 Robert_Wolff
  351. Now sets the "don't show the substitution message" flag no matter what
  352. the status of the first call to LookForSubstitute() was (sub, no sub,
  353. or error), rather than only when a substitution was made and the message
  354. was displayed.
  355. Rev 1.13 10 Dec 1992 14:24:16 Robert_Wolff
  356. Shortened mode substitution messages in LookForSubstitute(), messages
  357. are now displayed only on the first call to this routine, to avoid
  358. delays in switching back to graphics mode from a full-screen DOS box.
  359. Rev 1.12 09 Dec 1992 14:18:38 Robert_Wolff
  360. Eliminated uninitialized pointer in IOCTL_VIDEO_SET_CURRENT_MODE
  361. packet, moved initialization of QueryPtr and FirstMode pointers
  362. to before the switch on packet type, rather than being in all
  363. packets where the pointers are used. This should prevent similar
  364. problems if other packets are changed to use the pointers, and
  365. eliminates redundant code.
  366. Rev 1.11 09 Dec 1992 10:35:04 Robert_Wolff
  367. Added user-level "blue-screen" messages for fatal errors, checks BIOS
  368. revision to catch Mach 8 cards that can't do 1280x1024, forces the
  369. use of the engine-only driver if no aperture is configured, memory
  370. boundary and hardware cursor stuff is now done only for Mach 32 cards
  371. (since they're only available on Mach 32), sets split pixel mode for
  372. Mach 8 in 1280x1024, added mode substitution message for Mach 8 when
  373. registry is configured for 16 BPP or higher.
  374. Rev 1.10 01 Dec 1992 17:00:18 Robert_Wolff
  375. "I-beam" text insertion cursor no longer has left side filled with a
  376. solid black block.
  377. Rev 1.9 30 Nov 1992 17:34:38 Robert_Wolff
  378. Now allows 1M aperture if configured video mode uses less than 1M
  379. of video memory, prints message to user if Windows NT decides
  380. to use a video mode other than the one configured in the registry.
  381. Rev 1.8 27 Nov 1992 18:40:24 Chris_Brady
  382. VGA Wonder detect looks for signature in a range.
  383. Graphics Ultra Pro Microchannel version moved it.
  384. Rev 1.7 25 Nov 1992 09:47:36 Robert_Wolff
  385. Now tells GetCapMach32() to assume the VGA boundary is set to shared,
  386. since we will set it to this value later, and we don't want to lose
  387. access to modes which require some of the memory currently assigned
  388. to the VGA. Added delay in IOCTL_VIDEO_SET_CURRENT_MODE case of
  389. ATIMPStartIO() after calculating the hardware cursor offset. This delay
  390. may not be needed, but I didn't want to remove it since this is the
  391. source for the driver sent to QA and I wanted it to be rebuildable.
  392. Rev 1.6 20 Nov 1992 16:04:30 Robert_Wolff
  393. Now reads query information from Mach 8 cards instead of only
  394. from Mach 32 cards. Mach 8 cards still cause ATIMPFindAdapter()
  395. to return ERROR_INVALID_PARAMETER, since until we get an engine-only
  396. driver, we can't use a card that doesn't support an aperture.
  397. Rev 1.5 19 Nov 1992 09:53:36 GRACE
  398. after setting a mode do a wait for idle to let the pixel clock settle before
  399. using engine to draw.
  400. Rev 1.4 17 Nov 1992 14:07:52 GRACE
  401. changed framelength to reflect the size of memory on the board not the
  402. aperture size.
  403. In the StartIO section, only set up QueryPtr and FirstMode when necessary
  404. Rev 1.3 12 Nov 1992 09:23:02 GRACE
  405. removed the struct definition for DeviceExtension to a68.h
  406. Not using DevInitATIMP, DevSetCursorShape, DevSetCursorPos or DevCursorOff.
  407. DevCursorOff changed to a define that turns cursor off with an OUTP.
  408. Also removed some excess junk that is left from the video program.
  409. Rev 1.2 06 Nov 1992 19:12:48 Robert_Wolff
  410. Fixed signed/unsigned bug in multiple calls to VideoPortInitialize().
  411. Now requests access to I/O ports and ROM addresses used for VGA-style
  412. EEPROM reads, and gets information about installed modes from the
  413. Mach32 card.
  414. NOTE: This is a checkpoint for further changes. Due to incompatibilities
  415. between the old (hardcoded resolution) code in other modules and the
  416. new (read from the card) code here, this revision will not produce a
  417. working driver.
  418. Rev 1.1 05 Nov 1992 12:02:18 Robert_Wolff
  419. Now reads query structure and mode tables from the MACH32 card
  420. rather than using hardcoded values for aperture size/location
  421. and supported modes.
  422. Rev 1.0 02 Nov 1992 20:47:58 Chris_Brady
  423. Initial revision.
  424. End of PolyTron RCS section *****************/
  425. #ifdef DOC
  426. DESCRIPTION
  427. ATI Windows NT Miniport driver for the Mach 64, Mach32, and Mach8
  428. families.
  429. This file will select the appropriate functions depending on the
  430. computer configuration.
  431. OTHER FILES
  432. ???
  433. #endif
  434. #include <stdio.h>
  435. #include <string.h>
  436. #include "dderror.h"
  437. #include "devioctl.h"
  438. #include "miniport.h"
  439. #include "ntddvdeo.h"
  440. #include "video.h"
  441. #include "stdtyp.h"
  442. #include "amach1.h"
  443. #include "vidlog.h"
  444. /*
  445. * To avoid multiple definition errors, pre-initialized variables
  446. * in ATIMP.H are initialized if INCLUDE_ATIMP is defined, but
  447. * are declared external if it is not defined. For consistency,
  448. * define this value here rather than in other files which also include
  449. * ATIMP.H so the variables are initialized by the source file with
  450. * the same root name as the header file.
  451. */
  452. #define INCLUDE_ATIMP
  453. #include "detect_m.h"
  454. #include "amachcx.h"
  455. #include "atimp.h"
  456. #include "atint.h"
  457. #include "atioem.h"
  458. #include "cvtddc.h"
  459. #include "dpms.h"
  460. #include "eeprom.h"
  461. #include "init_cx.h"
  462. #include "init_m.h"
  463. #include "modes_m.h"
  464. #include "query_cx.h"
  465. #include "query_m.h"
  466. #include "services.h"
  467. #include "setup_cx.h"
  468. #include "setup_m.h"
  469. //------------------------------------------------------------------
  470. /*
  471. * Initially assume we have not yet found a non-block card, and
  472. * have found no block relocatable cards.
  473. */
  474. BOOL FoundNonBlockCard = FALSE;
  475. USHORT NumBlockCardsFound = 0;
  476. /*------------------------------------------------------------------------
  477. *
  478. * Function Prototypes
  479. *
  480. * Functions that start with 'ATIMP' are entry points for the OS port driver.
  481. */
  482. ULONG
  483. DriverEntry (
  484. PVOID Context1,
  485. PVOID Context2
  486. );
  487. VP_STATUS
  488. ATIMPFindAdapter(
  489. PVOID HwDeviceExtension,
  490. PVOID HwContext,
  491. PWSTR ArgumentString,
  492. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  493. PUCHAR Again
  494. );
  495. BOOLEAN
  496. ATIMPInitialize(
  497. PVOID HwDeviceExtension
  498. );
  499. BOOLEAN
  500. ATIMPStartIO(
  501. PVOID HwDeviceExtension,
  502. PVIDEO_REQUEST_PACKET RequestPacket
  503. );
  504. BOOLEAN
  505. ATIMPResetHw(
  506. IN PVOID HwDeviceExtension,
  507. IN ULONG Columns,
  508. IN ULONG Rows
  509. );
  510. //
  511. // New entry points added for NT 5.0.
  512. //
  513. #if (TARGET_BUILD >= 500)
  514. //
  515. // Routine to set a desired DPMS power management state.
  516. //
  517. VP_STATUS
  518. ATIMPSetPower50(
  519. PHW_DEVICE_EXTENSION phwDeviceExtension,
  520. ULONG HwDeviceId,
  521. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  522. );
  523. //
  524. // Routine to retrieve possible DPMS power management states.
  525. //
  526. VP_STATUS
  527. ATIMPGetPower50(
  528. PHW_DEVICE_EXTENSION phwDeviceExtension,
  529. ULONG HwDeviceId,
  530. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  531. );
  532. //
  533. // Routine to retrieve the Enhanced Display ID structure via DDC
  534. //
  535. ULONG
  536. ATIMPGetVideoChildDescriptor(
  537. PVOID pHwDeviceExtension,
  538. PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  539. PVIDEO_CHILD_TYPE pChildType,
  540. PVOID pvChildDescriptor,
  541. PULONG pHwId,
  542. PULONG pUnused
  543. );
  544. #endif // TARGET_BUILD >= 500
  545. //
  546. // Routine to set the DPMS power management state.
  547. //
  548. BOOLEAN
  549. SetDisplayPowerState(
  550. PHW_DEVICE_EXTENSION phwDeviceExtension,
  551. VIDEO_POWER_STATE VideoPowerState
  552. );
  553. //
  554. // Routine to retrieve the current DPMS power management state.
  555. //
  556. VIDEO_POWER_STATE
  557. GetDisplayPowerState(
  558. PHW_DEVICE_EXTENSION phwDeviceExtension
  559. );
  560. /* */
  561. UCHAR RegistryBuffer[REGISTRY_BUFFER_SIZE]; /* Last value retrieved from the registry */
  562. ULONG RegistryBufferLength = 0; /* Size of last retrieved value */
  563. /*
  564. * Allow miniport to be swapped out when not needed.
  565. *
  566. * ATIMPResetHw() must be in the non-paged pool.
  567. *
  568. */
  569. #if defined (ALLOC_PRAGMA)
  570. #pragma alloc_text(PAGE_COM, DriverEntry)
  571. #pragma alloc_text(PAGE_COM, ATIMPFindAdapter)
  572. #pragma alloc_text(PAGE_COM, ATIMPInitialize)
  573. #pragma alloc_text(PAGE_COM, ATIMPStartIO)
  574. #if (TARGET_BUILD >= 500)
  575. #pragma alloc_text(PAGE_COM, ATIMPSetPower50)
  576. #pragma alloc_text(PAGE_COM, ATIMPGetPower50)
  577. #pragma alloc_text(PAGE_COM, ATIMPGetVideoChildDescriptor)
  578. #endif // TARGET_BUILD >= 500
  579. #pragma alloc_text(PAGE_COM, RegistryParameterCallback)
  580. #endif
  581. //------------------------------------------------------------------------
  582. ULONG
  583. DriverEntry (
  584. PVOID Context1,
  585. PVOID Context2
  586. )
  587. /*++
  588. Routine Description:
  589. Installable driver initialization entry point.
  590. This entry point is called directly by the I/O system.
  591. Arguments:
  592. Context1 - First context value passed by the operating system. This is
  593. the value with which the miniport driver calls VideoPortInitialize().
  594. Context2 - Second context value passed by the operating system. This is
  595. the value with which the miniport driver calls VideoPortInitialize().
  596. Return Value:
  597. Status from VideoPortInitialize()
  598. --*/
  599. {
  600. VIDEO_HW_INITIALIZATION_DATA hwInitData;
  601. /*
  602. * Most recently returned and lowest received so far return values
  603. * from VideoPortInitialize().
  604. *
  605. * BUGBUG: According to the docs and include files, these should
  606. * be of type VP_STATUS (maps to long). When tracing
  607. * through the code, however, I saw that a failed call
  608. * to VideoPortInitialize() due to submitting the wrong
  609. * bus type yields a code of 0xC00000C0 while one which
  610. * succeeds yields 0x00000000. When following the format
  611. * of the NTSTATUS (maps to unsigned long) type, these are
  612. * STATUS_DEVICE_DOES_NOT_EXIST and STATUS_SUCCESS respectively.
  613. * The docs on VideoPortInitialize() say to return the smallest
  614. * returned value if multiple calls are made (consistent with
  615. * the NTSTATUS format where the 2 most significant bits are
  616. * 00 for success, 01 for information, 10 for warning, and
  617. * 11 for error, since the multiple calls would be for mutually
  618. * exclusive bus types), presumably to return the best possible
  619. * outcome (fail only if we can't find any supported bus).
  620. *
  621. * If we use the VP_STATUS type as recommended, error conditions
  622. * will be seen as smaller than success, since they are negative
  623. * numbers (MSB set) and success is positive (MSB clear). Use
  624. * unsigned long values to avoid this problem.
  625. */
  626. ULONG ThisInitStatus;
  627. ULONG LowestInitStatus;
  628. VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
  629. hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
  630. /*
  631. * Set entry points.
  632. */
  633. hwInitData.HwFindAdapter = ATIMPFindAdapter;
  634. hwInitData.HwInitialize = ATIMPInitialize;
  635. hwInitData.HwInterrupt = NULL;
  636. hwInitData.HwStartIO = ATIMPStartIO;
  637. hwInitData.HwResetHw = ATIMPResetHw;
  638. #if (TARGET_BUILD >= 500)
  639. //
  640. // Set new entry points added for NT 5.0.
  641. //
  642. //
  643. // We can only enable these for a PnP driver, and this is not
  644. // a pnp driver. At least at the moment.
  645. //
  646. hwInitData.HwSetPowerState = ATIMPSetPower50;
  647. hwInitData.HwGetPowerState = ATIMPGetPower50;
  648. hwInitData.HwGetVideoChildDescriptor = ATIMPGetVideoChildDescriptor;
  649. #endif // TARGET_BUILD >= 500
  650. hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
  651. /*
  652. * Call VideoPortInitialize() once for each type of interface we support.
  653. * As documented in the DDK, return the lowest status value returned
  654. * by this function.
  655. *
  656. * The DEC Alpha requires the new ordering (PCI first) in both
  657. * 3.5 and 3.51, while the x86 requires the new ordering in 3.51
  658. * and the old ordering in 3.5. I haven't built a new miniport
  659. * for either Power PC or MIPS since implementing the new order,
  660. * so for now assume that they require the old order.
  661. *
  662. * On the x86, using the new order in 3.5 will result in the
  663. * IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES packet failing on
  664. * the Mach 32 in PCI systems, which leaves 16 and 24 BPP
  665. * listed as available in the video applet but being rejected
  666. * when they are tested.
  667. */
  668. #if !defined(_ALPHA_) && !defined(IOCTL_VIDEO_SHARE_VIDEO_MEMORY)
  669. hwInitData.AdapterInterfaceType = Eisa;
  670. LowestInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  671. hwInitData.AdapterInterfaceType = Isa;
  672. ThisInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  673. if (ThisInitStatus < LowestInitStatus)
  674. LowestInitStatus = ThisInitStatus;
  675. hwInitData.AdapterInterfaceType = MicroChannel;
  676. ThisInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  677. if (ThisInitStatus < LowestInitStatus)
  678. LowestInitStatus = ThisInitStatus;
  679. hwInitData.AdapterInterfaceType = PCIBus;
  680. ThisInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  681. if (ThisInitStatus < LowestInitStatus)
  682. LowestInitStatus = ThisInitStatus;
  683. #else
  684. hwInitData.AdapterInterfaceType = PCIBus;
  685. LowestInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  686. hwInitData.AdapterInterfaceType = Eisa;
  687. ThisInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  688. if (ThisInitStatus < LowestInitStatus)
  689. LowestInitStatus = ThisInitStatus;
  690. hwInitData.AdapterInterfaceType = Isa;
  691. ThisInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  692. if (ThisInitStatus < LowestInitStatus)
  693. LowestInitStatus = ThisInitStatus;
  694. hwInitData.AdapterInterfaceType = MicroChannel;
  695. ThisInitStatus = (ULONG) VideoPortInitialize(Context1, Context2, &hwInitData, NULL);
  696. if (ThisInitStatus < LowestInitStatus)
  697. LowestInitStatus = ThisInitStatus;
  698. #endif
  699. return LowestInitStatus;
  700. } /* end DriverEntry() */
  701. //------------------------------------------------------------------------
  702. VP_STATUS
  703. ATIMPFindAdapter(
  704. PVOID HwDeviceExtension,
  705. PVOID HwContext,
  706. PWSTR ArgumentString,
  707. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  708. PUCHAR Again
  709. )
  710. /*++
  711. Routine Description:
  712. This routine is the main execution entry point for the miniport driver.
  713. It accepts a Video Request Packet, performs the request, and then
  714. returns with the appropriate status.
  715. Arguments:
  716. HwDeviceExtension - Supplies the miniport driver's adapter storage. This
  717. storage is initialized to zero before this call.
  718. HwContext - Supplies the context value which was passed to
  719. VideoPortInitialize().
  720. ArgumentString - Suuplies a NYLL terminated ASCII string. This string
  721. originates from the user.
  722. ConfigInfo - Returns the configuration information structure which is
  723. filled by the miniport driver . This structure is initialized with
  724. any knwon configuration information (such as SystemIoBusNumber) by
  725. the port driver. Where possible, drivers should have one set of
  726. defaults which do not require any supplied configuration information.
  727. Again - Indicates if the miniport driver wants the port driver to call
  728. its VIDEO_HW_FIND_ADAPTER function again with a new device extension
  729. and the same config info. This is used by the miniport drivers which
  730. can search for several adapters on a bus.
  731. Return Value:
  732. This routine must return:
  733. NO_ERROR - Indicates a host adapter was found and the
  734. configuration information was successfully determined.
  735. ERROR_INVALID_PARAMETER - Indicates a host adapter was found but there was an
  736. error obtaining the configuration information. If possible an error
  737. should be logged.
  738. ERROR_INVALID_PARAMETER - Indicates the supplied configuration was invalid.
  739. ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
  740. supplied configuration information.
  741. --*/
  742. {
  743. VP_STATUS status;
  744. struct query_structure *QueryPtr; /* Query information for the card */
  745. phwDeviceExtension = HwDeviceExtension;
  746. VideoDebugPrint((DEBUG_NORMAL, "ATI: FindAdapter\n"));
  747. /*
  748. * On systems with multiple buses (i.e. any PCI/ISA system), this
  749. * routine will be called once for each bus, and each invocation
  750. * will detect the ATI card. To keep Windows NT from thinking that
  751. * there are multiple cards, check to see if we have found an ATI
  752. * card on a previous invocation, and if we have, report that there
  753. * is no ATI card.
  754. */
  755. if (ConfigInfo->AdapterInterfaceType == PCIBus)
  756. {
  757. VIDEO_ACCESS_RANGE AccessRange3C0 = { 0x3C0, 0, 1, 1, 1, 1};
  758. VideoDebugPrint((DEBUG_NORMAL, "PCI bus\n"));
  759. #if defined(ALPHA) || defined(_ALPHA_)
  760. /*
  761. * On the DEC Alpha, our card detection runs into trouble
  762. * on all but the first (bridged to ISA/EISA, supports
  763. * VGA BIOS emulation) PCI bus.
  764. */
  765. if (ConfigInfo->SystemIoBusNumber > 0)
  766. {
  767. VideoDebugPrint((DEBUG_NORMAL, "Alpha, not first PCI bus - skipping\n"));
  768. return ERROR_DEV_NOT_EXIST;
  769. }
  770. #endif
  771. //
  772. // AndreVa.
  773. // Since we have a PnP driver, all detection is done throught the
  774. // inf - no slot searching.
  775. // Fix code that is lower in DetectMach64 later.
  776. //
  777. // For now, just make sure the card is enabled and fail if it's not,
  778. // so we don't any a different card via the searching mechanism.
  779. // This only happens if you have a disabled ATI card on the motherboard
  780. // and an active one in a slot
  781. //
  782. if (NO_ERROR != VideoPortVerifyAccessRanges(HwDeviceExtension,
  783. 1,
  784. &AccessRange3C0))
  785. {
  786. VideoDebugPrint((DEBUG_NORMAL, "ATI: PCI FindAdapter called for Disabled card\n"));
  787. *Again = 0; /* We don't want to be called again */
  788. return ERROR_DEV_NOT_EXIST;
  789. }
  790. }
  791. else if (ConfigInfo->AdapterInterfaceType == Isa)
  792. {
  793. VideoDebugPrint((DEBUG_NORMAL, "ISA bus\n"));
  794. }
  795. else if (ConfigInfo->AdapterInterfaceType == Eisa)
  796. {
  797. VideoDebugPrint((DEBUG_NORMAL, "EISA bus\n"));
  798. }
  799. else if (ConfigInfo->AdapterInterfaceType == MicroChannel)
  800. {
  801. VideoDebugPrint((DEBUG_NORMAL, "MicroChannel bus\n"));
  802. }
  803. if ((FoundNonBlockCard == TRUE) || (NumBlockCardsFound == ATI_MAX_BLOCK_CARDS))
  804. {
  805. VideoDebugPrint((DEBUG_NORMAL, "ATI: FindAdapter already found maximum number of supported cards\n"));
  806. *Again = 0; /* We don't want to be called again */
  807. return ERROR_DEV_NOT_EXIST;
  808. }
  809. /*
  810. * Get a formatted pointer into the query section of HwDeviceExtension.
  811. * The CardInfo[] field is an unformatted buffer.
  812. */
  813. QueryPtr = (struct query_structure *) (phwDeviceExtension->CardInfo);
  814. /*
  815. * Save the bus type reported by NT
  816. */
  817. QueryPtr->q_system_bus_type = ConfigInfo->AdapterInterfaceType;
  818. /*
  819. * Initially we don't know whether or not block write mode is available.
  820. */
  821. QueryPtr->q_BlockWrite = BLOCK_WRITE_UNKNOWN;
  822. /*
  823. * Make sure the size of the structure is at least as large as what we
  824. * are expecting (check version of the config info structure).
  825. * If this test fails, it's an unrecoverable error, so we don't want
  826. * to be called again.
  827. */
  828. if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO))
  829. {
  830. VideoPortLogError(HwDeviceExtension, NULL, VID_SMALL_BUFFER, 1);
  831. *Again = 0;
  832. return ERROR_INVALID_PARAMETER;
  833. }
  834. /********************************************************************/
  835. /* Find out which of our accelerators, if any, is present. */
  836. /********************************************************************/
  837. /*
  838. * Look for an ATI accelerator card. This test does not require
  839. * information retrieved from the BIOS or the EEPROM (which may not
  840. * be present in some versions of our cards).
  841. *
  842. * Initially assume that we are looking for a Mach 64 accelerator,
  843. * since the test for this family is less destructive (doesn't
  844. * black out the screen on DEC Alpha machines) than the test for
  845. * one of our 8514/A-compatible accelerators.
  846. *
  847. * Don't report failure if we are unable to map the I/O ranges
  848. * used by the Mach 64 accelerators, since if we are dealing with
  849. * one of our 8514/A-compatible accelerators this is irrelevant.
  850. *
  851. * CompatIORangesUsable_cx() calls DetectMach64() when it's checking
  852. * to see which base address to use for the accelerator registers,
  853. * so if this calll succeeds we know that a Mach 64 is present.
  854. * If the call fails, there is no need to unmap the I/O ranges
  855. * it has mapped, since it always cleans up after itself when it
  856. * finds that a particular base address is not being used for a
  857. * Mach 64. As a result, a failed call will not leave any addresses
  858. * mapped, since no available base address was used by a Mach 64.
  859. */
  860. if ((status = CompatIORangesUsable_cx(ConfigInfo->AdapterInterfaceType)) == NO_ERROR)
  861. {
  862. phwDeviceExtension->ModelNumber = MACH64_ULTRA;
  863. }
  864. else if (NumBlockCardsFound == 0)
  865. {
  866. /*
  867. * There is no Mach 64 present, so look for one of our
  868. * 8514/A-compatible accelerators (Mach 8 and Mach 32).
  869. * The check on NumBlockCardsFound is to catch the case
  870. * where we found a relocatable card on a previous bus
  871. * type, so we won't have dropped out due to FoundNonBlockCard
  872. * being TRUE but CompatIORangesUsable_cx() won't find
  873. * a Mach 64 on this bus type.
  874. */
  875. /*
  876. * Since we don't use PCI detection, don't look for these cards
  877. * on the PCI bus, except for the Mach 32 PCI AX
  878. */
  879. if (ConfigInfo->AdapterInterfaceType == PCIBus)
  880. {
  881. PCI_COMMON_CONFIG ConfigData;
  882. ULONG RetVal;
  883. RetVal = VideoPortGetBusData(phwDeviceExtension,
  884. PCIConfiguration,
  885. 0,
  886. &ConfigData,
  887. 0,
  888. PCI_COMMON_HDR_LENGTH);
  889. /*
  890. * If we received an error return, skip to the
  891. * next possible slot.
  892. */
  893. if ((RetVal == PCI_COMMON_HDR_LENGTH) &&
  894. (ConfigData.VendorID == 0x1002) &&
  895. (ConfigData.DeviceID == 0x4158))
  896. {
  897. VideoDebugPrint((DEBUG_NORMAL, "FOUND PnP Mach 32 AX card found\n"));
  898. }
  899. else
  900. {
  901. *Again = 0;
  902. return ERROR_DEV_NOT_EXIST;
  903. }
  904. }
  905. /* If we can't map the I/O base addresses used by these cards,
  906. * then there is no ATI accelerator present. Unmap any of
  907. * the ranges which may have been mapped, then report failure.
  908. *
  909. * In the event of failure to find a Mach 8 or Mach 32,
  910. * report that we don't want to be called again for the
  911. * current bus, but don't set LookForAnotherCard to zero.
  912. * This is because there may still be a block relocatable
  913. * card on a subsequent bus.
  914. */
  915. status = CompatIORangesUsable_m();
  916. if (status != NO_ERROR)
  917. {
  918. UnmapIORanges_m();
  919. VideoPortLogError(HwDeviceExtension, NULL, VID_CANT_MAP, 2);
  920. *Again = 0;
  921. return status;
  922. }
  923. #if !defined (i386) && !defined (_i386_)
  924. /*
  925. * ALPHA - The miniport will have to perform the ROM Bios functions
  926. * that are normally done on bootup in x86 machines.
  927. * For now we will initialize them the way they are specifically
  928. * on this card that we are currently using.
  929. */
  930. AlphaInit_m();
  931. #endif
  932. /*
  933. * Check which of our 8514/A-accelerators is present. If we
  934. * can't find one, unmap the I/O ranges and report failure.
  935. *
  936. * Don't log an error, because NT tries all the miniports
  937. * on initial setup to see which card is installed, and failure
  938. * to find an ATI card is a normal condition if another brand
  939. * of accelerator is present.
  940. *
  941. */
  942. phwDeviceExtension->ModelNumber = WhichATIAccelerator_m();
  943. if (phwDeviceExtension->ModelNumber == NO_ATI_ACCEL)
  944. {
  945. UnmapIORanges_m();
  946. *Again = 0;
  947. return ERROR_DEV_NOT_EXIST;
  948. }
  949. /*
  950. * We have found a Mach 8 or Mach 32. None of these cards are
  951. * block relocatable, so we must not look for another card
  952. * (since we don't support a mix of block and non-block
  953. * cards).
  954. */
  955. FoundNonBlockCard = TRUE;
  956. LookForAnotherCard = 0;
  957. } /* endif (no Mach 64) */
  958. else
  959. {
  960. /*
  961. * A relocatable Mach 64 was found on a previous bus type.
  962. * Since we can't handle a mix of relocatable and fixed
  963. * base cards, we have skipped the Mach 32 search (the
  964. * Mach 64 search doesn't look for fixed base cards if
  965. * a relocatable card has already been found), and must
  966. * report that no ATI cards were found.
  967. */
  968. *Again = 0;
  969. VideoDebugPrint((DEBUG_DETAIL, "Skipping 8514/A-compatible test because block cards found\n"));
  970. return ERROR_DEV_NOT_EXIST;
  971. }
  972. /*
  973. * We have found one of our accelerators, so check for the
  974. * BIOS signature string.
  975. */
  976. QueryPtr->q_bios = (char *) Get_BIOS_Seg();
  977. /*
  978. * If we can't find the signature string, we can't access either
  979. * the EEPROM (if present) or the extended BIOS functions. Since
  980. * the special handling functions (extended Mach 32 aperture calculation
  981. * and Mach 8 ignore 1280x1024) depend on BIOS data, assume that
  982. * they don't apply.
  983. *
  984. * If we found the signature string, check whether the EEPROM
  985. * and extended BIOS functions are available.
  986. */
  987. #if !defined (i386) && !defined (_i386_)
  988. /*
  989. * If we are using a Mach 64, we always use the extended BIOS
  990. * functions (either emulated x86 in the firmware, or an approximation
  991. * of the BIOS functions accessed through the same interface as
  992. * the BIOS functions would use). For this reason, we must have
  993. * the BIOS as non-FALSE. Since all searches that depend on the
  994. * q_bios field being a valid address are Mach 8/32 specific,
  995. * we can just set it to TRUE for Mach 64. For Mach 8 and 32,
  996. * still assume that we don't have a BIOS.
  997. */
  998. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  999. {
  1000. VideoDebugPrint((DEBUG_NORMAL, "Non-x86 machine with Mach64, assuming BIOS is available\n"));
  1001. QueryPtr->q_bios = (PUCHAR)TRUE;
  1002. }
  1003. else
  1004. {
  1005. VideoDebugPrint((DEBUG_NORMAL, "Non-x86 machine with Mach8/Mach32, forcing no-BIOS handling\n"));
  1006. QueryPtr->q_bios = FALSE;
  1007. }
  1008. #endif
  1009. if (QueryPtr->q_bios == FALSE)
  1010. {
  1011. QueryPtr->q_eeprom = FALSE;
  1012. QueryPtr->q_ext_bios_fcn = FALSE;
  1013. QueryPtr->q_m32_aper_calc = FALSE;
  1014. QueryPtr->q_ignore1280 = FALSE;
  1015. }
  1016. else{
  1017. /*
  1018. * Get additional data required by the graphics card being used.
  1019. */
  1020. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1021. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1022. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1023. {
  1024. GetExtraData_m();
  1025. }
  1026. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1027. {
  1028. /*
  1029. * Mach 64 cards always have extended BIOS functions
  1030. * available. The EEPROM (normally present) is irrelevant,
  1031. * since we can query the card's status using the BIOS.
  1032. */
  1033. QueryPtr->q_ext_bios_fcn = TRUE;
  1034. }
  1035. } /* BIOS signature string found */
  1036. /*
  1037. * We must map the VGA aperture (graphics, colour text, and mono
  1038. * text) into the VDM's address space to use VideoPortInt10()
  1039. * (function is only available on 80x86).
  1040. */
  1041. #ifdef i386
  1042. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x000A0000;
  1043. ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
  1044. ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00020000;
  1045. #else
  1046. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
  1047. ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
  1048. ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
  1049. #endif
  1050. /*
  1051. * If we get this far, we have enough information to be able to set
  1052. * the video mode we want. ATI accelerator cards need the
  1053. * Emulator entries and state size cleared
  1054. */
  1055. ConfigInfo->NumEmulatorAccessEntries = 0;
  1056. ConfigInfo->EmulatorAccessEntries = NULL;
  1057. ConfigInfo->EmulatorAccessEntriesContext = 0;
  1058. ConfigInfo->HardwareStateSize = 0;
  1059. /*
  1060. * Setting *Again to 0 tells Windows NT not to call us again for
  1061. * the same bus, while setting it to 1 indicates that we want to
  1062. * look for another card on the current bus. LookForAnotherCard
  1063. * will have been set to 0 if we have found the maximum number
  1064. * of block-relocatable cards or a single non-relocatable card.
  1065. */
  1066. *Again = LookForAnotherCard;
  1067. /*
  1068. * Since ATIMPFindAdapter() is called before ATIMPInitialize(),
  1069. * this card has not yet had ATIMPInitialize() called.
  1070. */
  1071. phwDeviceExtension->CardInitialized = FALSE;
  1072. return NO_ERROR;
  1073. } /* end ATIMPFindAdapter() */
  1074. //------------------------------------------------------------------------
  1075. /***************************************************************************
  1076. *
  1077. * BOOLEAN ATIMPInitialize(HwDeviceExtension);
  1078. *
  1079. * PVOID HwDeviceExtension; Pointer to the miniport's device extension.
  1080. *
  1081. * DESCRIPTION:
  1082. * Query the capabilities of the graphics card, then initialize it. This
  1083. * routine is called once an adapter has been found and all the required
  1084. * data structures for it have been created.
  1085. *
  1086. * We can't query the capabilities of the card in ATIMPFindAdapter()
  1087. * because some families of card use VideoPortInt10() in the query
  1088. * routine, and this system service will fail if called in ATIMPFindAdapter().
  1089. *
  1090. * RETURN VALUE:
  1091. * TRUE if we are able to obtain the query information for the card
  1092. * FALSE if we can't query the card's capabilities.
  1093. *
  1094. * GLOBALS CHANGED:
  1095. * phwDeviceExtension This global variable is set in every entry point routine.
  1096. *
  1097. * CALLED BY:
  1098. * This is one of the entry point routines for Windows NT.
  1099. *
  1100. * AUTHOR:
  1101. * Robert Wolff
  1102. *
  1103. * CHANGE HISTORY:
  1104. *
  1105. * TEST HISTORY:
  1106. *
  1107. ***************************************************************************/
  1108. BOOLEAN ATIMPInitialize(PVOID HwDeviceExtension)
  1109. {
  1110. struct st_mode_table *CrtTable; /* Pointer to current mode */
  1111. struct query_structure *QueryPtr; /* Query information for the card */
  1112. VP_STATUS QueryStatus;
  1113. phwDeviceExtension = HwDeviceExtension;
  1114. /*
  1115. * We only need to keep track of which I/O base address is involved
  1116. * in multi-headed setups. In some single-headed setups, the
  1117. * additional data is not available.
  1118. */
  1119. if (NumBlockCardsFound >= 2)
  1120. VideoDebugPrint((DEBUG_NORMAL, "\nATIMPInitialize() called for base address 0x%X\n\n", phwDeviceExtension->BaseIOAddress));
  1121. else
  1122. VideoDebugPrint((DEBUG_NORMAL, "ATIMPInitialize: start\n"));
  1123. /*
  1124. * This function should only be called once for any card. Since
  1125. * we have no way of knowing whether or not the display driver
  1126. * will make multiple calls to the IOCTL_VIDEO_ATI_INIT_AUX_CARD
  1127. * packet, we must ensure that only the first call for any card
  1128. * actually does anything.
  1129. */
  1130. if (phwDeviceExtension->CardInitialized != FALSE)
  1131. {
  1132. VideoDebugPrint((DEBUG_ERROR, "This card already initialized, no further action needed\n"));
  1133. return TRUE;
  1134. }
  1135. phwDeviceExtension->CardInitialized = TRUE;
  1136. /*
  1137. * Get a formatted pointer into the query section of HwDeviceExtension,
  1138. * and another pointer to the first mode table. The CardInfo[] field
  1139. * is an unformatted buffer.
  1140. */
  1141. QueryPtr = (struct query_structure *) (phwDeviceExtension->CardInfo);
  1142. CrtTable = (struct st_mode_table *)QueryPtr;
  1143. ((struct query_structure *)CrtTable)++;
  1144. /*
  1145. * Indicate that the next IOCTL_VIDEO_SET_CURRENT_MODE call
  1146. * is the first. On the first call, video memory is cleared.
  1147. * On subsequent calls, the palette is re-initialized but
  1148. * video memory is not cleared.
  1149. */
  1150. phwDeviceExtension->ReInitializing = FALSE;
  1151. /*
  1152. * ASSERT: We are dealing with an ATI accelerator card
  1153. * whose model is known, and we know whether or not
  1154. * any special handling is needed for the card.
  1155. *
  1156. * Fill in the query structure for the card, using a method
  1157. * appropriate to the card type.
  1158. */
  1159. switch(phwDeviceExtension->ModelNumber)
  1160. {
  1161. case _8514_ULTRA:
  1162. VideoDebugPrint((DEBUG_NORMAL, "8514/ULTRA found\n"));
  1163. QueryStatus = Query8514Ultra(QueryPtr);
  1164. break;
  1165. case GRAPHICS_ULTRA:
  1166. VideoDebugPrint((DEBUG_NORMAL, "Mach 8 combo found\n"));
  1167. QueryStatus = QueryGUltra(QueryPtr);
  1168. break;
  1169. case MACH32_ULTRA:
  1170. VideoDebugPrint((DEBUG_NORMAL, "Mach 32 found\n"));
  1171. QueryStatus = QueryMach32(QueryPtr, TRUE);
  1172. if (QueryStatus == ERROR_INSUFFICIENT_BUFFER)
  1173. {
  1174. VideoPortLogError(HwDeviceExtension, NULL, VID_SMALL_BUFFER, 3);
  1175. return FALSE;
  1176. }
  1177. break;
  1178. case MACH64_ULTRA:
  1179. VideoDebugPrint((DEBUG_NORMAL, "Mach 64 found\n"));
  1180. QueryStatus = QueryMach64(QueryPtr);
  1181. if (QueryStatus == ERROR_INSUFFICIENT_BUFFER)
  1182. {
  1183. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() failed due to small buffer\n"));
  1184. VideoPortLogError(HwDeviceExtension, NULL, VID_SMALL_BUFFER, 4);
  1185. return FALSE;
  1186. }
  1187. else if (QueryStatus != NO_ERROR)
  1188. {
  1189. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() failed due to unknown cause\n"));
  1190. VideoPortLogError(HwDeviceExtension, NULL, VID_QUERY_FAIL, 5);
  1191. return FALSE;
  1192. }
  1193. break;
  1194. }
  1195. /*
  1196. * If we have access to the extended BIOS functions, we can
  1197. * use them to switch into the desired video mode. If we don't
  1198. * have access to these functions, but were able to read
  1199. * the EEPROM, we can switch into the desired mode by writing
  1200. * CRT parameters directly to the accelerator registers.
  1201. *
  1202. * If we don't have access to the extended BIOS functions, and
  1203. * we couldn't find an EEPROM, attempt to retrieve the CRT
  1204. * parameters based on the contents of the ATIOEM field in
  1205. * the registry. If we can't do this, then we don't have enough
  1206. * information to be able to set the video mode we want.
  1207. */
  1208. if (!QueryPtr->q_ext_bios_fcn && !QueryPtr->q_eeprom)
  1209. {
  1210. QueryStatus = OEMGetParms(QueryPtr);
  1211. if (QueryStatus != NO_ERROR)
  1212. {
  1213. return FALSE;
  1214. }
  1215. }
  1216. phwDeviceExtension->VideoRamSize = QueryPtr->q_memory_size * QUARTER_MEG;
  1217. // Subtract the amount of memory reserved for the VGA.
  1218. phwDeviceExtension->VideoRamSize -= (QueryPtr->q_VGA_boundary * QUARTER_MEG);
  1219. phwDeviceExtension->PhysicalFrameAddress.HighPart = 0;
  1220. phwDeviceExtension->PhysicalFrameAddress.LowPart = QueryPtr->q_aperture_addr*ONE_MEG;
  1221. /*
  1222. * If the linear aperture is available, the frame buffer size
  1223. * is equal to the amount of accelerator-accessible video memory.
  1224. */
  1225. if (QueryPtr->q_aperture_cfg)
  1226. {
  1227. phwDeviceExtension->FrameLength = phwDeviceExtension->VideoRamSize;
  1228. VideoDebugPrint((DEBUG_DETAIL, "LFB size = 0x%X bytes\n", phwDeviceExtension->FrameLength));
  1229. }
  1230. /*
  1231. * Call the hardware-specific initialization routine for the
  1232. * card we are using.
  1233. */
  1234. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1235. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1236. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1237. {
  1238. /*
  1239. * If the LFB is not usable, set up the LFB configuration
  1240. * variables to show that there is no linear frame buffer.
  1241. * The decision as to whether to use the 64k VGA aperture
  1242. * or go with the graphics engine only is made in the
  1243. * IOCTL_VIDEO_MAP_VIDEO_MEMORY packet.
  1244. */
  1245. if (QueryPtr->q_aperture_cfg)
  1246. {
  1247. if (IsApertureConflict_m(QueryPtr))
  1248. {
  1249. VideoPortLogError(HwDeviceExtension, NULL, VID_LFB_CONFLICT, 7);
  1250. QueryPtr->q_aperture_cfg = 0;
  1251. phwDeviceExtension->FrameLength = 0;
  1252. }
  1253. else
  1254. {
  1255. /*
  1256. * On Mach 32 cards that can use memory mapped registers,
  1257. * map them in. We already know that we are dealing with
  1258. * a Mach 32, since this is the only card in the family
  1259. * of 8514/A-compatible ATI accelerators that can use
  1260. * a linear framebuffer.
  1261. */
  1262. if ((QueryPtr->q_asic_rev == CI_68800_6) || (QueryPtr->q_asic_rev == CI_68800_AX))
  1263. {
  1264. CompatMMRangesUsable_m();
  1265. }
  1266. }
  1267. }
  1268. /*
  1269. * On Mach 32 cards with the aperture disabled (either as configured
  1270. * or because a conflict was detected), try to claim the VGA aperture.
  1271. * If we can't (unlikely), report failure, since some of our Mach 32
  1272. * chips run into trouble in engine-only (neither linear nor paged
  1273. * aperture available) mode.
  1274. */
  1275. if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
  1276. (QueryPtr->q_aperture_cfg == 0) &&
  1277. (QueryPtr->q_VGA_type == 1))
  1278. {
  1279. if (IsVGAConflict_m())
  1280. return FALSE;
  1281. }
  1282. Initialize_m();
  1283. /*
  1284. * This routine must leave the card in a state where an INT 10
  1285. * can set it to a VGA mode. Only the Mach 8 and Mach 32 need
  1286. * a special setup (the Mach 64 can always be set into VGA mode
  1287. * by an INT 10).
  1288. */
  1289. ResetDevice_m();
  1290. }
  1291. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1292. {
  1293. /*
  1294. * If the LFB is not usable, set up the LFB configuration
  1295. * variables to show that there is no linear frame buffer.
  1296. */
  1297. if (QueryPtr->q_aperture_cfg)
  1298. {
  1299. if (IsApertureConflict_cx(QueryPtr))
  1300. {
  1301. VideoDebugPrint((DEBUG_NORMAL, "Found LFB conflict, must use VGA aperture instead\n"));
  1302. VideoPortLogError(HwDeviceExtension, NULL, VID_LFB_CONFLICT, 8);
  1303. QueryPtr->q_aperture_cfg = 0;
  1304. phwDeviceExtension->FrameLength = 0;
  1305. }
  1306. }
  1307. else
  1308. {
  1309. phwDeviceExtension->FrameLength = 0;
  1310. }
  1311. /*
  1312. * Mach 64 drawing registers only exist in memory mapped form.
  1313. * If the linear aperture is not available, they will be
  1314. * available through the VGA aperture (unlike Mach 32,
  1315. * where memory mapped registers are only in the linear
  1316. * aperture). If memory mapped registers are unavailable,
  1317. * we can't run.
  1318. */
  1319. QueryStatus = CompatMMRangesUsable_cx();
  1320. if (QueryStatus != NO_ERROR)
  1321. {
  1322. VideoDebugPrint((DEBUG_ERROR, "Can't use memory-mapped registers, aborting\n"));
  1323. VideoPortLogError(HwDeviceExtension, NULL, VID_CANT_MAP, 9);
  1324. return FALSE;
  1325. }
  1326. Initialize_cx();
  1327. } /* end if (Mach 64) */
  1328. /*
  1329. * Initialize the monitor parameters.
  1330. */
  1331. phwDeviceExtension->ModeIndex = 0;
  1332. /*
  1333. * Set CrtTable to point to the mode table associated with the
  1334. * selected mode.
  1335. *
  1336. * When a pointer to a structure is incremented by an integer,
  1337. * the integer represents the number of structure-sized blocks
  1338. * to skip over, not the number of bytes to skip over.
  1339. */
  1340. CrtTable += phwDeviceExtension->ModeIndex;
  1341. QueryPtr->q_desire_x = CrtTable->m_x_size;
  1342. QueryPtr->q_desire_y = CrtTable->m_y_size;
  1343. QueryPtr->q_pix_depth = CrtTable->m_pixel_depth;
  1344. #if (TARGET_BUILD >= 350)
  1345. /*
  1346. * In Windows NT 3.5 and higher, fill in regsistry fields used
  1347. * by the display applet to report card specifics to the user.
  1348. */
  1349. FillInRegistry(QueryPtr);
  1350. #endif
  1351. VideoDebugPrint((DEBUG_NORMAL, "End of ATIMPInitialize()\n"));
  1352. return TRUE;
  1353. } /* end ATIMPInitialize() */
  1354. //------------------------------------------------------------------------
  1355. BOOLEAN
  1356. ATIMPStartIO(
  1357. PVOID HwDeviceExtension,
  1358. PVIDEO_REQUEST_PACKET RequestPacket
  1359. )
  1360. /*++
  1361. Routine Description:
  1362. This routine is the main execution routine for the miniport driver. It
  1363. accepts a Video Request Packet, performs the request, and then returns
  1364. with the appropriate status.
  1365. Arguments:
  1366. HwDeviceExtension - Supplies a pointer to the miniport's device extension.
  1367. RequestPacket - Pointer to the video request packet. This structure
  1368. contains all the parameters passed to the VideoIoControl function.
  1369. Return Value:
  1370. --*/
  1371. {
  1372. VP_STATUS status;
  1373. PVIDEO_NUM_MODES NumModes;
  1374. PVERSION_NT VersionInformation;
  1375. PENH_VERSION_NT EnhVersionInformation;
  1376. PATI_MODE_INFO ATIModeInformation;
  1377. PVIDEO_CLUT clutBuffer;
  1378. PVIDEO_MEMORY MappedMemory;
  1379. UCHAR ModesLookedAt; /* Number of mode tables we have already examined */
  1380. short LastXRes; /* X-resolution of last mode table examined */
  1381. short ResolutionsDone; /* Number of resolutions we have finished with */
  1382. ULONG ulScratch; /* Temporary variable */
  1383. int i;
  1384. ULONG *pSrc;
  1385. struct query_structure *QueryPtr; /* Query information for the card */
  1386. struct st_mode_table *FirstMode; /* Pointer to first mode table */
  1387. struct st_mode_table *CrtTable; /* Pointer to current mode */
  1388. phwDeviceExtension = HwDeviceExtension;
  1389. /*
  1390. * We only need to keep track of which I/O base address is involved
  1391. * in multi-headed setups. In some single-headed setups, the
  1392. * additional data is not available.
  1393. */
  1394. if (NumBlockCardsFound >= 2)
  1395. VideoDebugPrint((DEBUG_NORMAL, "\nATIMPStartIO() called for base address 0x%X\n\n", phwDeviceExtension->BaseIOAddress));
  1396. // * Get a formatted pointer into the query section of HwDeviceExtension.
  1397. QueryPtr = (struct query_structure *) (phwDeviceExtension->CardInfo);
  1398. //
  1399. // Switch on the IoControlCode in the RequestPacket. It indicates which
  1400. // function must be performed by the driver.
  1401. //
  1402. switch (RequestPacket->IoControlCode)
  1403. {
  1404. case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
  1405. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - MapVideoMemory\n"));
  1406. if ( (RequestPacket->OutputBufferLength <
  1407. (RequestPacket->StatusBlock->Information =
  1408. sizeof(VIDEO_MEMORY_INFORMATION))) ||
  1409. (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) )
  1410. {
  1411. status = ERROR_INSUFFICIENT_BUFFER;
  1412. break;
  1413. }
  1414. /*
  1415. * Map the video memory in the manner appropriate to the
  1416. * card we are using.
  1417. */
  1418. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1419. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1420. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1421. {
  1422. status = MapVideoMemory_m(RequestPacket, QueryPtr);
  1423. }
  1424. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1425. {
  1426. status = MapVideoMemory_cx(RequestPacket, QueryPtr);
  1427. }
  1428. else // handling a case which should never
  1429. { // happen: unknown ModelNumber
  1430. VideoDebugPrint((DEBUG_ERROR, "ati.sys ATIMPStartIO: Unknown ModelNumber\n"));
  1431. ASSERT(FALSE);
  1432. status = ERROR_INVALID_PARAMETER;
  1433. }
  1434. break;
  1435. case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
  1436. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - UnMapVideoMemory\n"));
  1437. if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
  1438. {
  1439. status = ERROR_INSUFFICIENT_BUFFER;
  1440. break;
  1441. }
  1442. //
  1443. // Note that in MapVideoMemory_m, the VP routine VideoMapMemory
  1444. // is not called, so don't try to call unmap here!
  1445. //
  1446. if ((QueryPtr->q_aperture_cfg == 0) &&
  1447. !((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
  1448. (QueryPtr->q_VGA_type == 1)))
  1449. status = NO_ERROR;
  1450. else
  1451. {
  1452. status = NO_ERROR;
  1453. if ( ((PVIDEO_MEMORY)(RequestPacket->InputBuffer))->RequestedVirtualAddress != NULL )
  1454. {
  1455. status = VideoPortUnmapMemory(phwDeviceExtension,
  1456. ((PVIDEO_MEMORY) (RequestPacket->InputBuffer))->RequestedVirtualAddress, 0);
  1457. }
  1458. }
  1459. break;
  1460. case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
  1461. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - QueryPublicAccessRanges\n"));
  1462. // HACKHACK - This is a temporary hack for ALPHA until we really
  1463. // decide how to do this.
  1464. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1465. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1466. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1467. {
  1468. status = QueryPublicAccessRanges_m(RequestPacket);
  1469. }
  1470. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1471. {
  1472. status = QueryPublicAccessRanges_cx(RequestPacket);
  1473. }
  1474. break;
  1475. case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
  1476. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - FreePublicAccessRanges\n"));
  1477. if (RequestPacket->InputBufferLength < 2 * sizeof(VIDEO_MEMORY))
  1478. {
  1479. VideoDebugPrint((DEBUG_ERROR, "Received length %d, need length %d\n", RequestPacket->InputBufferLength, sizeof(VIDEO_PUBLIC_ACCESS_RANGES)));
  1480. status = ERROR_INSUFFICIENT_BUFFER;
  1481. break;
  1482. }
  1483. status = NO_ERROR;
  1484. MappedMemory = RequestPacket->InputBuffer;
  1485. if (MappedMemory->RequestedVirtualAddress != NULL)
  1486. {
  1487. #if (TARGET_BUILD >= 400)
  1488. /*
  1489. * This packet will be called as part of the cleanup
  1490. * for the test of a new graphics mode. The packet
  1491. * IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES will have
  1492. * generated the same virtual address for the test
  1493. * screen as was generated for the main Windows session.
  1494. *
  1495. * In NT 3.51 (and presumably earlier versions), the
  1496. * call to VideoPortUnmapMemory() will refuse to release
  1497. * the mapping, while in NT 4.0 (and presumably subsequent
  1498. * versions) it will release the mapping. This is probably
  1499. * due to the routine being able to distinguish between
  1500. * the test and permanent screens in 4.0, but not being
  1501. * able to disginguish between them (and therefore refusing
  1502. * to free resources which it thinks are currently in use
  1503. * by the permanent screen) in 3.51.
  1504. *
  1505. * Freeing resources will be necessary if "on-the-fly"
  1506. * mode switching is added to Windows NT, but this will
  1507. * almost certainly not be added to 3.51 (if it is added,
  1508. * it would be to the then-current version). Since we
  1509. * don't really need to free the mapped I/O ranges under
  1510. * 3.51 (under the old display driver source stream, this
  1511. * packet didn't get called), let 3.51 and earlier think
  1512. * that the resources were freed successfully to avoid
  1513. * generating an error condition, and only attempt to
  1514. * unmap the I/O registers under NT 4.0 and later.
  1515. */
  1516. status = VideoPortUnmapMemory(phwDeviceExtension,
  1517. MappedMemory->RequestedVirtualAddress,
  1518. 0);
  1519. #endif
  1520. VideoDebugPrint((DEBUG_DETAIL, "VideoPortUnmapMemory() returned 0x%X\n", status));
  1521. }
  1522. else
  1523. {
  1524. VideoDebugPrint((DEBUG_DETAIL, "Address was NULL, no need to unmap\n"));
  1525. }
  1526. /*
  1527. * We have just unmapped the I/O mapped registers. Since our
  1528. * memory-mapped registers are contained in the block which
  1529. * is mapped by IOCTL_VIDEO_MAP_VIDEO_MEMORY, they will have
  1530. * already been freed by IOCTL_VIDEO_UNMAP_VIDEO_MEMORY, so
  1531. * there is no need to free them here.
  1532. */
  1533. break;
  1534. case IOCTL_VIDEO_QUERY_CURRENT_MODE:
  1535. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - QueryCurrentModes\n"));
  1536. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1537. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1538. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1539. {
  1540. status = QueryCurrentMode_m(RequestPacket, QueryPtr);
  1541. }
  1542. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1543. {
  1544. status = QueryCurrentMode_cx(RequestPacket, QueryPtr);
  1545. }
  1546. break;
  1547. case IOCTL_VIDEO_QUERY_AVAIL_MODES:
  1548. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - QueryAvailableModes\n"));
  1549. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1550. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1551. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1552. {
  1553. status = QueryAvailModes_m(RequestPacket, QueryPtr);
  1554. }
  1555. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1556. {
  1557. status = QueryAvailModes_cx(RequestPacket, QueryPtr);
  1558. }
  1559. break;
  1560. case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
  1561. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - QueryNumAvailableModes\n"));
  1562. /*
  1563. * Find out the size of the data to be put in the buffer and
  1564. * return that in the status information
  1565. */
  1566. if (RequestPacket->OutputBufferLength <
  1567. (RequestPacket->StatusBlock->Information = sizeof(VIDEO_NUM_MODES)) )
  1568. {
  1569. status = ERROR_INSUFFICIENT_BUFFER;
  1570. }
  1571. else{
  1572. NumModes = (PVIDEO_NUM_MODES)RequestPacket->OutputBuffer;
  1573. NumModes->NumModes = QueryPtr->q_number_modes;
  1574. NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
  1575. status = NO_ERROR;
  1576. }
  1577. break;
  1578. case IOCTL_VIDEO_SET_CURRENT_MODE:
  1579. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - SetCurrentMode\n"));
  1580. /*
  1581. * Verify that the mode we've been asked to set is less
  1582. * than or equal to the highest mode number for which we
  1583. * have a mode table (mode number is zero-based, so highest
  1584. * mode number is 1 less than number of modes).
  1585. */
  1586. if (((PVIDEO_MODE)(RequestPacket->InputBuffer))->RequestedMode
  1587. >= QueryPtr->q_number_modes)
  1588. {
  1589. status = ERROR_INVALID_PARAMETER;
  1590. break;
  1591. }
  1592. phwDeviceExtension->ModeIndex = *(ULONG *)(RequestPacket->InputBuffer);
  1593. CrtTable = (struct st_mode_table *)QueryPtr;
  1594. ((struct query_structure *)CrtTable)++;
  1595. CrtTable += phwDeviceExtension->ModeIndex;
  1596. // * Set resolution and pixel depth of new current mode.
  1597. QueryPtr->q_desire_x = CrtTable->m_x_size;
  1598. QueryPtr->q_desire_y = CrtTable->m_y_size;
  1599. QueryPtr->q_pix_depth = CrtTable->m_pixel_depth;
  1600. QueryPtr->q_screen_pitch = CrtTable->m_screen_pitch;
  1601. /*
  1602. * If we are using the extended BIOS functions to switch modes,
  1603. * do it now. The Mach 32 uses the extended BIOS functions to
  1604. * read in the CRT parameters for a direct-register mode switch,
  1605. * rather than using a BIOS mode switch.
  1606. */
  1607. if ((QueryPtr->q_ext_bios_fcn) && (phwDeviceExtension->ModelNumber != MACH32_ULTRA))
  1608. {
  1609. /*
  1610. * Do the mode switch through the BIOS.
  1611. */
  1612. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1613. {
  1614. status = SetCurrentMode_cx(QueryPtr, CrtTable);
  1615. }
  1616. }
  1617. else{
  1618. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1619. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1620. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1621. {
  1622. SetCurrentMode_m(QueryPtr, CrtTable);
  1623. status = NO_ERROR;
  1624. }
  1625. } /* end if (not using BIOS call for mode switch) */
  1626. break;
  1627. case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
  1628. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - SetPaletteRegs\n"));
  1629. status = NO_ERROR;
  1630. break;
  1631. case IOCTL_VIDEO_SET_COLOR_REGISTERS:
  1632. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - SetColorRegs\n"));
  1633. CrtTable = (struct st_mode_table *)QueryPtr;
  1634. ((struct query_structure *)CrtTable)++;
  1635. clutBuffer = RequestPacket->InputBuffer;
  1636. phwDeviceExtension->ReInitializing = TRUE;
  1637. /*
  1638. * Check if the size of the data in the input
  1639. * buffer is large enough.
  1640. */
  1641. if ( (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) - sizeof(ULONG))
  1642. || (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) +
  1643. (sizeof(ULONG) * (clutBuffer->NumEntries - 1)) ) )
  1644. {
  1645. status = ERROR_INSUFFICIENT_BUFFER;
  1646. break;
  1647. }
  1648. CrtTable += phwDeviceExtension->ModeIndex;
  1649. if (CrtTable->m_pixel_depth <= 8)
  1650. {
  1651. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1652. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA) ||
  1653. (phwDeviceExtension->ModelNumber == MACH32_ULTRA))
  1654. {
  1655. SetPalette_m((PULONG)clutBuffer->LookupTable,
  1656. clutBuffer->FirstEntry,
  1657. clutBuffer->NumEntries);
  1658. }
  1659. else if(phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1660. {
  1661. SetPalette_cx((PULONG)clutBuffer->LookupTable,
  1662. clutBuffer->FirstEntry,
  1663. clutBuffer->NumEntries);
  1664. }
  1665. status = NO_ERROR;
  1666. }
  1667. /*
  1668. * Remember the most recent palette we were given so we
  1669. * can re-initialize it in subsequent calls to the
  1670. * IOCTL_VIDEO_SET_CURRENT_MODE packet.
  1671. */
  1672. phwDeviceExtension->FirstEntry = clutBuffer->FirstEntry;
  1673. phwDeviceExtension->NumEntries = clutBuffer->NumEntries;
  1674. pSrc = (ULONG *) clutBuffer->LookupTable;
  1675. for (i = clutBuffer->FirstEntry; i < (int) clutBuffer->NumEntries; i++)
  1676. {
  1677. /*
  1678. * Save palette colours.
  1679. */
  1680. phwDeviceExtension->Clut[i] = *pSrc;
  1681. pSrc++;
  1682. }
  1683. break;
  1684. case IOCTL_VIDEO_RESET_DEVICE:
  1685. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - RESET_DEVICE\n"));
  1686. /*
  1687. * If we are using the extended BIOS functions to switch modes,
  1688. * do it now. The Mach 32 uses the extended BIOS functions to
  1689. * read in the CRT parameters for a direct-register mode switch,
  1690. * rather than using a BIOS mode switch.
  1691. */
  1692. if ((QueryPtr->q_ext_bios_fcn) && (phwDeviceExtension->ModelNumber != MACH32_ULTRA))
  1693. {
  1694. /*
  1695. * Do the mode switch through the BIOS (hook not yet present
  1696. * in Windows NT).
  1697. */
  1698. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1699. {
  1700. ResetDevice_cx();
  1701. }
  1702. }
  1703. else{
  1704. ResetDevice_m();
  1705. }
  1706. status = NO_ERROR;
  1707. break;
  1708. case IOCTL_VIDEO_SET_POWER_MANAGEMENT:
  1709. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - SET_POWER_MANAGEMENT\n"));
  1710. /*
  1711. * If the VIDEO_POWER_MANAGEMENT structure is the wrong size
  1712. * (miniport and display driver using different versions),
  1713. * report the error.
  1714. */
  1715. if (((PVIDEO_POWER_MANAGEMENT)(RequestPacket->InputBuffer))->Length
  1716. != sizeof(struct _VIDEO_POWER_MANAGEMENT))
  1717. {
  1718. status = ERROR_INVALID_PARAMETER;
  1719. break;
  1720. }
  1721. ulScratch = ((PVIDEO_POWER_MANAGEMENT)(RequestPacket->InputBuffer))->PowerState;
  1722. switch (ulScratch)
  1723. {
  1724. case VideoPowerOn:
  1725. VideoDebugPrint((DEBUG_DETAIL, "DPMS ON selected\n"));
  1726. break;
  1727. case VideoPowerStandBy:
  1728. VideoDebugPrint((DEBUG_DETAIL, "DPMS STAND-BY selected\n"));
  1729. break;
  1730. case VideoPowerSuspend:
  1731. VideoDebugPrint((DEBUG_DETAIL, "DPMS SUSPEND selected\n"));
  1732. break;
  1733. case VideoPowerOff:
  1734. VideoDebugPrint((DEBUG_DETAIL, "DPMS OFF selected\n"));
  1735. break;
  1736. default:
  1737. VideoDebugPrint((DEBUG_ERROR, "DPMS invalid state selected\n"));
  1738. break;
  1739. }
  1740. /*
  1741. * Different card families need different routines to set
  1742. * the power management state.
  1743. */
  1744. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1745. status = SetPowerManagement_cx(ulScratch);
  1746. else
  1747. status = SetPowerManagement_m(QueryPtr, ulScratch);
  1748. break;
  1749. /*
  1750. * Packets used in DCI support. They were added some time after
  1751. * the initial release of Windows NT 3.5, so not all versions of
  1752. * the DDK will support them. Make the packet code conditional on
  1753. * our building a driver for NT version 3.51 or later in order to
  1754. * avoid the need for a SOURCES flag to identify DCI vs. non-DCI builds.
  1755. */
  1756. #if (TARGET_BUILD >= 351)
  1757. case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
  1758. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - SHARE_VIDEO_MEMORY\n"));
  1759. if ((RequestPacket->OutputBufferLength < sizeof(VIDEO_SHARE_MEMORY_INFORMATION)) ||
  1760. (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)))
  1761. {
  1762. VideoDebugPrint((DEBUG_ERROR, "IOCTL_VIDEO_SHARE_VIDEO_MEMORY - ERROR_INSUFFICIENT_BUFFER\n"));
  1763. status = ERROR_INSUFFICIENT_BUFFER;
  1764. break;
  1765. }
  1766. /*
  1767. * Share the video memory in the manner appropriate to the
  1768. * card we are using. We can only share memory if the
  1769. * card supports an aperture - Mach 8 cards never support
  1770. * an aperture, so if we are working with one, we know
  1771. * that we can't share the memory. The card-specific
  1772. * routines will identify no-aperture and other cases
  1773. * where we can't share video memory on Mach 32 and
  1774. * Mach 64 cards.
  1775. */
  1776. if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) ||
  1777. (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA))
  1778. {
  1779. VideoDebugPrint((DEBUG_ERROR, "IOCTL_VIDEO_SHARE_VIDEO_MEMORY - Mach 8 can't share memory\n"));
  1780. status = ERROR_INVALID_FUNCTION;
  1781. }
  1782. else if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  1783. {
  1784. status = ShareVideoMemory_m(RequestPacket, QueryPtr);
  1785. }
  1786. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  1787. {
  1788. status = ShareVideoMemory_cx(RequestPacket, QueryPtr);
  1789. }
  1790. break;
  1791. case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
  1792. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - UNSHARE_VIDEO_MEMORY\n"));
  1793. if (RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY))
  1794. {
  1795. status = ERROR_INSUFFICIENT_BUFFER;
  1796. break;
  1797. }
  1798. status = VideoPortUnmapMemory(phwDeviceExtension,
  1799. ((PVIDEO_SHARE_MEMORY)(RequestPacket->InputBuffer))->RequestedVirtualAddress,
  1800. ((PVIDEO_SHARE_MEMORY)(RequestPacket->InputBuffer))->ProcessHandle);
  1801. break;
  1802. #endif /* TARGET_BUILD >= 350 */
  1803. // ------ * ATI-specific packets start here. -------------
  1804. /*
  1805. * Get the version number of the miniport, and the
  1806. * resolutions supported (including maximum colour
  1807. * depth).
  1808. */
  1809. case IOCTL_VIDEO_ATI_GET_VERSION:
  1810. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - ATIGetVersion\n"));
  1811. /*
  1812. * Two versions of this packet exist, depending on which display
  1813. * driver is used. Display drivers which use the old version do
  1814. * not send information to the miniport, so the input buffer is
  1815. * null. Drivers which use the new version pass a non-null input
  1816. * buffer.
  1817. */
  1818. if (RequestPacket->InputBufferLength == 0)
  1819. {
  1820. /*
  1821. * Old packet.
  1822. */
  1823. if (RequestPacket->OutputBufferLength < sizeof(VERSION_NT))
  1824. {
  1825. status = ERROR_INSUFFICIENT_BUFFER;
  1826. break;
  1827. }
  1828. RequestPacket->StatusBlock->Information = sizeof(VERSION_NT);
  1829. FirstMode = (struct st_mode_table *)QueryPtr;
  1830. ((struct query_structure *)FirstMode)++;
  1831. VersionInformation = RequestPacket->OutputBuffer;
  1832. VersionInformation->miniport =
  1833. (MINIPORT_BUILD << 16) | (MINIPORT_VERSION_MAJOR << 8) | MINIPORT_VERSION_MINOR;
  1834. /*
  1835. * Get the capabilities of the video card. The capcard field
  1836. * holds the following information:
  1837. *
  1838. * Bits 0-3 Bus type (defined values from AMACH.H)
  1839. * Bits 4-7 Product identifier (defined values from AMACH.H)
  1840. * Bit 8 No aperture is available
  1841. * Bit 9 64k VGA aperture is available
  1842. * Bit 10 Linear aperture is available
  1843. *
  1844. * NOTE: Bits 9 and 10 are NOT mutually exclusive.
  1845. */
  1846. VersionInformation->capcard = QueryPtr->q_bus_type;
  1847. VersionInformation->capcard |= (phwDeviceExtension->ModelNumber) << 4;
  1848. if (QueryPtr->q_aperture_cfg)
  1849. VersionInformation->capcard |= ATIC_APERTURE_LFB;
  1850. /*
  1851. * 64k VGA aperture is available on the VGAWonder, and on
  1852. * accelerator cards with the VGA enabled and the VGA boundary
  1853. * set to shared memory.
  1854. */
  1855. if ((phwDeviceExtension->ModelNumber == WONDER) ||
  1856. ((QueryPtr->q_VGA_type) && !(QueryPtr->q_VGA_boundary)))
  1857. VersionInformation->capcard |= ATIC_APERTURE_VGA;
  1858. /*
  1859. * If neither aperture is available, set the "no aperture" bit.
  1860. */
  1861. if (!(VersionInformation->capcard & ATIC_APERTURE_LFB) &&
  1862. !(VersionInformation->capcard & ATIC_APERTURE_VGA))
  1863. VersionInformation->capcard |= ATIC_APERTURE_NONE;
  1864. // Get the available resolutions and maximum colour depth for
  1865. // each. init to a value which does not correspond to any
  1866. // resolution.
  1867. CrtTable = FirstMode;
  1868. LastXRes = -1;
  1869. ResolutionsDone = -1;
  1870. for (ModesLookedAt = 0; ModesLookedAt < QueryPtr->q_number_modes; ModesLookedAt++)
  1871. {
  1872. // do we have a new resolution?
  1873. if (LastXRes != CrtTable->m_x_size)
  1874. {
  1875. ResolutionsDone++;
  1876. LastXRes = CrtTable->m_x_size;
  1877. VersionInformation->resolution[ResolutionsDone].color = 0;
  1878. }
  1879. /*
  1880. * Write the desired information from the current mode table
  1881. * in the query structure into the current mode table in
  1882. * the OUTPut buffer.
  1883. * Leave the OUTPut buffer with the highest colour depth in
  1884. * each supported resolution.
  1885. */
  1886. if (CrtTable->m_pixel_depth > VersionInformation->resolution[ResolutionsDone].color)
  1887. {
  1888. VersionInformation->resolution[ResolutionsDone].xres = CrtTable->m_x_size;
  1889. VersionInformation->resolution[ResolutionsDone].yres = CrtTable->m_y_size;
  1890. VersionInformation->resolution[ResolutionsDone].color= CrtTable->m_pixel_depth;
  1891. }
  1892. CrtTable++; // Advance to the next mode table
  1893. }
  1894. status = NO_ERROR;
  1895. }
  1896. else if((RequestPacket->InputBuffer == RequestPacket->OutputBuffer) &&
  1897. (((PENH_VERSION_NT)(RequestPacket->InputBuffer))->StructureVersion == 0) &&
  1898. (((PENH_VERSION_NT)(RequestPacket->InputBuffer))->InterfaceVersion == 0))
  1899. {
  1900. /*
  1901. * Interim packet
  1902. */
  1903. if (RequestPacket->OutputBufferLength < sizeof(ENH_VERSION_NT))
  1904. {
  1905. status = ERROR_INSUFFICIENT_BUFFER;
  1906. break;
  1907. }
  1908. RequestPacket->StatusBlock->Information = sizeof(ENH_VERSION_NT);
  1909. EnhVersionInformation = RequestPacket->OutputBuffer;
  1910. /*
  1911. * Report the miniport version we are using.
  1912. */
  1913. // EnhVersionInformation->InterfaceVersion = (MINIPORT_VERSION_MAJOR << 8) | MINIPORT_VERSION_MINOR;
  1914. EnhVersionInformation->InterfaceVersion = 0;
  1915. /*
  1916. * Remove the following line ONLY for official release versions
  1917. * of the miniport. This line indicates that this is an
  1918. * experimental (unsupported) version.
  1919. */
  1920. EnhVersionInformation->InterfaceVersion |= BETA_MINIPORT;
  1921. /*
  1922. * Report the chip used as both a numeric value and a flag.
  1923. */
  1924. EnhVersionInformation->ChipIndex = QueryPtr->q_asic_rev;
  1925. EnhVersionInformation->ChipFlag = 1 << (QueryPtr->q_asic_rev);
  1926. /*
  1927. * Report the best aperture configuration available.
  1928. *
  1929. * Linear Framebuffer is preferable to VGA aperture,
  1930. * which is preferable to engine-only.
  1931. *
  1932. * NOTE: VGA aperture will need to be split into
  1933. * 68800-style and 68800CX-style once we
  1934. * go from the emulator to silicon.
  1935. */
  1936. if (QueryPtr->q_aperture_cfg != 0)
  1937. EnhVersionInformation->ApertureType = AP_LFB;
  1938. else if ((QueryPtr->q_asic_rev != CI_38800_1) && (QueryPtr->q_VGA_type == 1))
  1939. EnhVersionInformation->ApertureType = AP_68800_VGA;
  1940. else
  1941. EnhVersionInformation->ApertureType = ENGINE_ONLY;
  1942. EnhVersionInformation->ApertureFlag = 1 << (EnhVersionInformation->ApertureType);
  1943. /*
  1944. * Report the bus type being used.
  1945. */
  1946. EnhVersionInformation->BusType = QueryPtr->q_bus_type;
  1947. EnhVersionInformation->BusFlag = 1 << (EnhVersionInformation->BusType);
  1948. /*
  1949. * For ASIC revisions that are capable of using memory mapped
  1950. * registers, check to see whether we are using them.
  1951. */
  1952. if ((QueryPtr->q_asic_rev == CI_68800_6) || (QueryPtr->q_asic_rev == CI_68800_AX))
  1953. {
  1954. if (MemoryMappedEnabled_m())
  1955. EnhVersionInformation->BusFlag |= FL_MM_REGS;
  1956. }
  1957. /*
  1958. * Report the number of ATI graphics cards in the system,
  1959. * so the display driver will know how many auxillary
  1960. * cards to initialize.
  1961. *
  1962. * Since multiheaded support requires all the ATI cards
  1963. * present to be block I/O cards, the global variable
  1964. * NumBlockCardsFound will always be 2 or higher in
  1965. * multiheaded systems. If it is 0 (non-block card found,
  1966. * since we will never get to this point if there are
  1967. * no ATI cards) or 1 (single block I/O card), report
  1968. * that there is 1 ATI card present.
  1969. */
  1970. if (NumBlockCardsFound >= 2)
  1971. EnhVersionInformation->NumCards = NumBlockCardsFound;
  1972. else
  1973. EnhVersionInformation->NumCards = 1;
  1974. VideoDebugPrint((DEBUG_DETAIL, "Reporting %d cards\n", EnhVersionInformation->NumCards));
  1975. /*
  1976. * Fill in the list of features this card supports.
  1977. *
  1978. * We can disable the sync signals even on cards that
  1979. * don't have registers dedicated to DPMS support, so
  1980. * all our cards support DPMS.
  1981. */
  1982. EnhVersionInformation->FeatureFlags = EVN_DPMS;
  1983. /*
  1984. * All platforms except the DEC Alpha are always
  1985. * capable of using dense space. On the Alpha,
  1986. * some machines with some of our cards are
  1987. * capable of using dense space, while others
  1988. * aren't.
  1989. */
  1990. #if defined(_ALPHA_)
  1991. if (DenseOnAlpha(QueryPtr) == TRUE)
  1992. {
  1993. EnhVersionInformation->FeatureFlags |= EVN_DENSE_CAPABLE;
  1994. VideoDebugPrint((DEBUG_DETAIL, "Reporting dense capable in FeatureFlags\n"));
  1995. }
  1996. #else
  1997. EnhVersionInformation->FeatureFlags |= EVN_DENSE_CAPABLE;
  1998. #endif
  1999. if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  2000. {
  2001. if ((QueryPtr->q_asic_rev == CI_68800_6) && (QueryPtr->q_aperture_cfg == 0)
  2002. && (QueryPtr->q_VGA_type == 1) && ((QueryPtr->q_memory_type == 5) ||
  2003. (QueryPtr->q_memory_type == 6)))
  2004. EnhVersionInformation->FeatureFlags |= EVN_SPLIT_TRANS;
  2005. if (IsMioBug_m(QueryPtr))
  2006. EnhVersionInformation->FeatureFlags |= EVN_MIO_BUG;
  2007. }
  2008. else if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  2009. {
  2010. if (IsPackedIO_cx())
  2011. EnhVersionInformation->FeatureFlags |= EVN_PACKED_IO;
  2012. if ((QueryPtr->q_memory_type == VMEM_SDRAM) &&
  2013. (QueryPtr->q_memory_size == VRAM_1mb))
  2014. EnhVersionInformation->FeatureFlags |= EVN_SDRAM_1M;
  2015. if (QueryPtr->q_DAC_type == DAC_TVP3026)
  2016. {
  2017. EnhVersionInformation->FeatureFlags |= EVN_TVP_DAC_CUR;
  2018. }
  2019. else if (QueryPtr->q_DAC_type == DAC_IBM514)
  2020. {
  2021. EnhVersionInformation->FeatureFlags |= EVN_IBM514_DAC_CUR;
  2022. }
  2023. else if (QueryPtr->q_DAC_type == DAC_INTERNAL_CT)
  2024. {
  2025. EnhVersionInformation->FeatureFlags |= EVN_INT_DAC_CUR;
  2026. EnhVersionInformation->FeatureFlags |= EVN_CT_ASIC;
  2027. }
  2028. else if (QueryPtr->q_DAC_type == DAC_INTERNAL_VT)
  2029. {
  2030. EnhVersionInformation->FeatureFlags |= EVN_INT_DAC_CUR;
  2031. EnhVersionInformation->FeatureFlags |= EVN_VT_ASIC;
  2032. }
  2033. else if (QueryPtr->q_DAC_type == DAC_INTERNAL_GT)
  2034. {
  2035. EnhVersionInformation->FeatureFlags |= EVN_INT_DAC_CUR;
  2036. EnhVersionInformation->FeatureFlags |= EVN_GT_ASIC;
  2037. }
  2038. }
  2039. /*
  2040. * Currently there are no feature flags specific to the Mach 8.
  2041. */
  2042. status = NO_ERROR;
  2043. }
  2044. else /* Final form of the packet is not yet defined */
  2045. {
  2046. status = ERROR_INVALID_FUNCTION;
  2047. }
  2048. break;
  2049. /*
  2050. * Packet to return information regarding the capabilities/bugs
  2051. * of the current mode.
  2052. */
  2053. case IOCTL_VIDEO_ATI_GET_MODE_INFORMATION:
  2054. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - ATIGetModeInformation\n"));
  2055. if (RequestPacket->OutputBufferLength <
  2056. (RequestPacket->StatusBlock->Information = sizeof(ENH_VERSION_NT)))
  2057. {
  2058. status = ERROR_INSUFFICIENT_BUFFER;
  2059. break;
  2060. }
  2061. ATIModeInformation = RequestPacket->OutputBuffer;
  2062. ATIModeInformation->ModeFlags = 0;
  2063. /*
  2064. * Information regarding the visible portion of the screen.
  2065. */
  2066. ATIModeInformation->VisWidthPix = QueryPtr->q_desire_x;
  2067. ATIModeInformation->VisHeight = QueryPtr->q_desire_y;
  2068. ATIModeInformation->BitsPerPixel = QueryPtr->q_pix_depth;
  2069. /*
  2070. * We require the true pitch in 24bpp
  2071. */
  2072. if (QueryPtr->q_pix_depth == 24)
  2073. {
  2074. ATIModeInformation->PitchPix = QueryPtr->q_screen_pitch * 3;
  2075. }
  2076. else
  2077. {
  2078. ATIModeInformation->PitchPix = QueryPtr->q_screen_pitch;
  2079. }
  2080. /*
  2081. * The FracBytesPerPixel field represents the first 3 places
  2082. * of decimal in the fractional part of bytes per pixel.
  2083. * No precision is lost, because the smallest granularity
  2084. * (one bit per pixel) is 0.125 bytes per pixel, and any
  2085. * multiple of this value does not extend beyond 3 places
  2086. * of decimal.
  2087. *
  2088. * Mach 8 1280x1024 4BPP is packed pixel, other 4BPP modes all
  2089. * ignore the upper 4 bits of each byte.
  2090. */
  2091. if ((QueryPtr->q_pix_depth == 4) &&
  2092. !((QueryPtr->q_asic_rev == CI_38800_1) && (QueryPtr->q_desire_x == 1280)))
  2093. {
  2094. ATIModeInformation->IntBytesPerPixel = 1;
  2095. ATIModeInformation->FracBytesPerPixel = 0;
  2096. }
  2097. else{
  2098. ATIModeInformation->IntBytesPerPixel = QueryPtr->q_pix_depth / 8;
  2099. switch (QueryPtr->q_pix_depth % 8)
  2100. {
  2101. case 0:
  2102. ATIModeInformation->FracBytesPerPixel = 0;
  2103. break;
  2104. case 1:
  2105. ATIModeInformation->FracBytesPerPixel = 125;
  2106. break;
  2107. case 2:
  2108. ATIModeInformation->FracBytesPerPixel = 250;
  2109. break;
  2110. case 3:
  2111. ATIModeInformation->FracBytesPerPixel = 375;
  2112. break;
  2113. case 4:
  2114. ATIModeInformation->FracBytesPerPixel = 500;
  2115. break;
  2116. case 5:
  2117. ATIModeInformation->FracBytesPerPixel = 625;
  2118. break;
  2119. case 6:
  2120. ATIModeInformation->FracBytesPerPixel = 750;
  2121. break;
  2122. case 7:
  2123. ATIModeInformation->FracBytesPerPixel = 875;
  2124. break;
  2125. }
  2126. }
  2127. ATIModeInformation->PitchByte = (QueryPtr->q_screen_pitch *
  2128. ((ATIModeInformation->IntBytesPerPixel * 1000) + ATIModeInformation->FracBytesPerPixel)) / 8000;
  2129. ATIModeInformation->VisWidthByte = (QueryPtr->q_desire_x *
  2130. ((ATIModeInformation->IntBytesPerPixel * 1000) + ATIModeInformation->FracBytesPerPixel)) / 8000;
  2131. /*
  2132. * Information regarding the offscreen memory to the right
  2133. * of the visible screen.
  2134. */
  2135. ATIModeInformation->RightWidthPix = ATIModeInformation->PitchPix - ATIModeInformation->VisWidthPix;
  2136. ATIModeInformation->RightWidthByte = ATIModeInformation->PitchByte - ATIModeInformation->VisWidthByte;
  2137. ATIModeInformation->RightStartOffPix = ATIModeInformation->VisWidthPix + 1;
  2138. ATIModeInformation->RightStartOffByte = ATIModeInformation->VisWidthByte + 1;
  2139. ATIModeInformation->RightEndOffPix = ATIModeInformation->PitchPix;
  2140. ATIModeInformation->RightEndOffByte = ATIModeInformation->PitchByte;
  2141. /*
  2142. * Information regarding the offscreen memory below the
  2143. * visible screen.
  2144. */
  2145. ATIModeInformation->BottomWidthPix = ATIModeInformation->PitchPix;
  2146. ATIModeInformation->BottomWidthByte = ATIModeInformation->PitchByte;
  2147. ATIModeInformation->BottomStartOff = ATIModeInformation->VisHeight + 1;
  2148. /*
  2149. * "Hard" values are the maximum Y coordinate which is backed by
  2150. * video memory. "Soft" values are the maximum Y coordinate which
  2151. * may be accessed without resetting the graphic engine offset
  2152. * into video memory.
  2153. *
  2154. * In 4BPP modes, we always force the card to think it has
  2155. * only 1M of memory.
  2156. */
  2157. if (QueryPtr->q_pix_depth == 4)
  2158. {
  2159. ATIModeInformation->BottomEndOffHard = ONE_MEG / ATIModeInformation->PitchByte;
  2160. }
  2161. else
  2162. {
  2163. ATIModeInformation->BottomEndOffHard = ((QueryPtr->q_memory_size - QueryPtr->q_VGA_boundary)
  2164. * QUARTER_MEG) / ATIModeInformation->PitchByte;
  2165. }
  2166. if ((QueryPtr->q_asic_rev == CI_88800_GX) && (ATIModeInformation->BottomEndOffHard > 16387))
  2167. ATIModeInformation->BottomEndOffSoft = 16387;
  2168. else if (ATIModeInformation->BottomEndOffHard > 1535)
  2169. ATIModeInformation->BottomEndOffSoft = 1535;
  2170. else
  2171. ATIModeInformation->BottomEndOffSoft = ATIModeInformation->BottomEndOffHard;
  2172. ATIModeInformation->BottomHeightHard = ATIModeInformation->BottomEndOffHard - ATIModeInformation->VisHeight;
  2173. ATIModeInformation->BottomHeightSoft = ATIModeInformation->BottomEndOffSoft - ATIModeInformation->VisHeight;
  2174. /*
  2175. * Fill in the list of "quirks" experienced by this particular mode.
  2176. */
  2177. if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  2178. {
  2179. if (((QueryPtr->q_desire_x == 1280) && (QueryPtr->q_desire_y == 1024)) ||
  2180. (((QueryPtr->q_DAC_type == DAC_STG1700) ||
  2181. (QueryPtr->q_DAC_type == DAC_STG1702) ||
  2182. (QueryPtr->q_DAC_type == DAC_STG1703)) && (QueryPtr->q_pix_depth >= 24)))
  2183. {
  2184. ATIModeInformation->ModeFlags |= AMI_ODD_EVEN;
  2185. }
  2186. /*
  2187. * The test for block write mode must be made after we
  2188. * switch into graphics mode, but it is not mode dependent.
  2189. *
  2190. * Because the test corrupts the screen, and is not
  2191. * mode dependent, only run it the first time this
  2192. * packet is called and save the result to report
  2193. * on subsequent calls.
  2194. */
  2195. if (QueryPtr->q_BlockWrite == BLOCK_WRITE_UNKNOWN)
  2196. {
  2197. if (BlockWriteAvail_m(QueryPtr))
  2198. QueryPtr->q_BlockWrite = BLOCK_WRITE_YES;
  2199. else
  2200. QueryPtr->q_BlockWrite = BLOCK_WRITE_NO;
  2201. }
  2202. if (QueryPtr->q_BlockWrite == BLOCK_WRITE_YES)
  2203. ATIModeInformation->ModeFlags |= AMI_BLOCK_WRITE;
  2204. }
  2205. else if(phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  2206. {
  2207. if (((QueryPtr->q_DAC_type == DAC_STG1700) ||
  2208. (QueryPtr->q_DAC_type == DAC_STG1702) ||
  2209. (QueryPtr->q_DAC_type == DAC_STG1703) ||
  2210. (QueryPtr->q_DAC_type == DAC_ATT408) ||
  2211. (QueryPtr->q_DAC_type == DAC_CH8398)) &&
  2212. (QueryPtr->q_pix_depth >= 24))
  2213. ATIModeInformation->ModeFlags |= AMI_ODD_EVEN;
  2214. if (((QueryPtr->q_pix_depth == 24) && (QueryPtr->q_desire_x == 1280)) ||
  2215. ((QueryPtr->q_pix_depth == 24) && (QueryPtr->q_desire_x == 1152)) ||
  2216. ((QueryPtr->q_pix_depth == 16) && (QueryPtr->q_desire_x == 1600)))
  2217. ATIModeInformation->ModeFlags |= AMI_2M_BNDRY;
  2218. if (TextBanding_cx(QueryPtr))
  2219. ATIModeInformation->ModeFlags |= AMI_TEXTBAND;
  2220. /*
  2221. * See Mach 32 section above for explanation.
  2222. */
  2223. if (QueryPtr->q_BlockWrite == BLOCK_WRITE_UNKNOWN)
  2224. {
  2225. if (BlockWriteAvail_cx(QueryPtr))
  2226. QueryPtr->q_BlockWrite = BLOCK_WRITE_YES;
  2227. else
  2228. QueryPtr->q_BlockWrite = BLOCK_WRITE_NO;
  2229. }
  2230. if (QueryPtr->q_BlockWrite == BLOCK_WRITE_YES)
  2231. ATIModeInformation->ModeFlags |= AMI_BLOCK_WRITE;
  2232. }
  2233. status = NO_ERROR;
  2234. break;
  2235. /*
  2236. * Packet to force initialization of auxillary card in multiheaded
  2237. * setup. Currently (NT 3.51 retail), only the primrary card
  2238. * receives a call to ATIMPInitialize().
  2239. *
  2240. * This packet must be called for all auxillary cards before
  2241. * IOCTL_VIDEO_SET_CURRENT_MODE is called for any card, since
  2242. * ATIMPInitialize() uses resources that are only available
  2243. * when the primrary (VGA enabled) card is in a VGA mode.
  2244. */
  2245. case IOCTL_VIDEO_ATI_INIT_AUX_CARD:
  2246. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO - ATIInitAuxCard\n"));
  2247. ATIMPInitialize(phwDeviceExtension);
  2248. status = NO_ERROR;
  2249. break;
  2250. default:
  2251. VideoDebugPrint((DEBUG_ERROR, "Fell through ATIMP startIO routine - invalid command\n"));
  2252. status = ERROR_INVALID_FUNCTION;
  2253. break;
  2254. }
  2255. RequestPacket->StatusBlock->Status = status;
  2256. VideoDebugPrint((DEBUG_NORMAL, "ATIMPStartIO: Returning with status=%d\n", status));
  2257. return TRUE;
  2258. } // end ATIMPStartIO()
  2259. /***************************************************************************
  2260. *
  2261. * BOOLEAN ATIMPResetHw(HwDeviceExtension, Columns, Rows);
  2262. *
  2263. * PVOID HwDeviceExtension; Pointer to the miniport's device extension.
  2264. * ULONG Columns; Number of character columns on text screen
  2265. * ULONG Rows; Number of character rows on text screen
  2266. *
  2267. * DESCRIPTION:
  2268. * Put the graphics card into either a text mode or a state where an
  2269. * INT 10 call will put it into a text mode.
  2270. *
  2271. * GLOBALS CHANGED:
  2272. * phwDeviceExtension This global variable is set in every entry point routine.
  2273. *
  2274. * CALLED BY:
  2275. * This is one of the entry point routines for Windows NT.
  2276. *
  2277. * AUTHOR:
  2278. * Robert Wolff
  2279. *
  2280. * CHANGE HISTORY:
  2281. *
  2282. * TEST HISTORY:
  2283. *
  2284. ***************************************************************************/
  2285. BOOLEAN ATIMPResetHw(PVOID HwDeviceExtension, ULONG Columns, ULONG Rows)
  2286. {
  2287. phwDeviceExtension = HwDeviceExtension;
  2288. /*
  2289. * On the Mach 64, an INT 10 to VGA text mode will work even
  2290. * when in accelerator mode, so we don't need to explicitly
  2291. * switch out of accelerator mode. On the Mach 8 and Mach 32,
  2292. * we must switch out of accelerator mode, and on the Mach 32
  2293. * we must load the VGA text font.
  2294. *
  2295. * On the Mach 64, some non-x86 machines (first noticed on the
  2296. * DEC Alpha) don't do the warm boot BIOS re-initialization that
  2297. * is done on the x86. Part of this re-initialization sets the
  2298. * memory size register to the correct amount of memory, which
  2299. * must be done if we were in a 4BPP mode (in 4BPP, we must force
  2300. * the memory size to 1M). To avoid locking out modes requiring
  2301. * over 1M (at least until the next cold boot) on these machines,
  2302. * we must restore the memory size to the correct value. Since this
  2303. * has the side effect of generating black vertical bands as a
  2304. * transient (due to interleaving of memory banks on 2M and higher
  2305. * configurations), only do this on non-x86 machines, since the
  2306. * BIOS will take care of it (without the visible side effect)
  2307. * on x86 platforms.
  2308. *
  2309. * Since this routine, and all routines it calls, must be
  2310. * nonpageable (in case the reason it is called is because
  2311. * there is a fatal error in the paging mechanism), and
  2312. * VideoDebugPrint() is pageable, we must not call VideoDebugPrint()
  2313. * from this routine. Temporary additions for testing are OK,
  2314. * but the calls must be removed before the code is released
  2315. * for production.
  2316. */
  2317. #if defined (i386) || defined (_i386_)
  2318. if (phwDeviceExtension->ModelNumber != MACH64_ULTRA)
  2319. SetTextMode_m();
  2320. #else
  2321. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  2322. RestoreMemSize_cx();
  2323. else
  2324. SetTextMode_m();
  2325. #endif
  2326. return FALSE;
  2327. } /* end ATIMPResetHw() */
  2328. #if (TARGET_BUILD >= 500)
  2329. #define QUERY_MONITOR_ID 0x22446688
  2330. #define QUERY_NONDDC_MONITOR_ID 0x11223344
  2331. VP_STATUS
  2332. ATIMPSetPower50(
  2333. PHW_DEVICE_EXTENSION pHwDeviceExtension,
  2334. ULONG HwDeviceId,
  2335. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  2336. )
  2337. //
  2338. // DESCRIPTION:
  2339. // Set the graphics card to the desired DPMS state.
  2340. //
  2341. // PARAMETERS:
  2342. // pHwDeviceExtension Points to per-adapter device extension.
  2343. // HwDeviceId id identifying the device.
  2344. // pVideoPowerMgmt Points to structure containing desired DPMS state.
  2345. //
  2346. // RETURN VALUE:
  2347. // Status code.
  2348. //
  2349. {
  2350. ULONG ulDesiredState;
  2351. ASSERT((pHwDeviceExtension != NULL) && (pVideoPowerMgmt != NULL));
  2352. VideoDebugPrint((DEBUG_NORMAL, "ati.sys ATIMPSetPower50: *** Entry point ***\n"));
  2353. ulDesiredState = pVideoPowerMgmt->PowerState;
  2354. //
  2355. // Check the ID passed down by the caller.
  2356. // We must handle setting the power for each of the devices specifically.
  2357. //
  2358. VideoDebugPrint((DEBUG_DETAIL, "ati.sys ATIMPSetPower50: Device Id = 0x%x\n", HwDeviceId));
  2359. if ((QUERY_MONITOR_ID == HwDeviceId) ||
  2360. (QUERY_NONDDC_MONITOR_ID == HwDeviceId))
  2361. {
  2362. VideoDebugPrint((DEBUG_DETAIL, "ati.sys ATIMPSetPower50: Device Id = Monitor\n"));
  2363. if (pVideoPowerMgmt->PowerState == VideoPowerHibernate) {
  2364. // We just leave the monitor powered on for Hibernate.
  2365. return NO_ERROR;
  2366. }
  2367. //
  2368. // This is the monitor -- we will use the standard BIOS DPMS call.
  2369. //
  2370. return SetMonitorPowerState(pHwDeviceExtension, ulDesiredState);
  2371. }
  2372. else if (DISPLAY_ADAPTER_HW_ID == HwDeviceId)
  2373. {
  2374. VP_STATUS status;
  2375. struct query_structure *QueryPtr =
  2376. (struct query_structure *) (phwDeviceExtension->CardInfo);
  2377. VideoDebugPrint((DEBUG_DETAIL, "ati.sys ATIMPSetPower50: Device Id = Graphics Adapter\n"));
  2378. switch (pVideoPowerMgmt->PowerState) {
  2379. case VideoPowerOn:
  2380. case VideoPowerHibernate:
  2381. status = NO_ERROR;
  2382. break;
  2383. case VideoPowerStandBy:
  2384. case VideoPowerSuspend:
  2385. case VideoPowerOff:
  2386. status = ERROR_INVALID_PARAMETER;
  2387. break;
  2388. default:
  2389. //
  2390. // We indicated in ATIGetPowerState that we couldn't
  2391. // do VideoPowerOff. So we should not get a call to
  2392. // do it here.
  2393. //
  2394. ASSERT(FALSE);
  2395. status = ERROR_INVALID_PARAMETER;
  2396. break;
  2397. }
  2398. return status;
  2399. }
  2400. else
  2401. {
  2402. VideoDebugPrint((DEBUG_ERROR, "ati.sys ATIMPSetPower50: Unknown pHwDeviceId\n"));
  2403. ASSERT(FALSE);
  2404. return ERROR_INVALID_PARAMETER;
  2405. }
  2406. } // ATIMPSetPower50()
  2407. VP_STATUS
  2408. ATIMPGetPower50(
  2409. PHW_DEVICE_EXTENSION pHwDeviceExtension,
  2410. ULONG HwDeviceId,
  2411. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  2412. )
  2413. //
  2414. // DESCRIPTION:
  2415. // Returns whether or not this particular DPMS state can be set on the
  2416. // graphics card or monitor
  2417. //
  2418. // PARAMETERS:
  2419. // pHwDeviceExtension Points to per-adapter device extension.
  2420. // HwDeviceId id identifying the device.
  2421. // pVideoPowerMgmt Points to DPMS state we wish to know is supported or not.
  2422. //
  2423. // RETURN VALUE:
  2424. // Status code.
  2425. //
  2426. {
  2427. ASSERT((pHwDeviceExtension != NULL) && (pVideoPowerMgmt != NULL));
  2428. VideoDebugPrint((DEBUG_NORMAL, "ati.sys ATIMPGetPower50: *** Entry point ***\n"));
  2429. //
  2430. // We currently only support settings the power on the monitor.
  2431. // Check that we get the private ID we passed back the system.
  2432. //
  2433. VideoDebugPrint((DEBUG_DETAIL, "ati.sys ATIMPGetPower50: Device Id = 0x%x\n", HwDeviceId));
  2434. if ((QUERY_MONITOR_ID == HwDeviceId) ||
  2435. (QUERY_NONDDC_MONITOR_ID == HwDeviceId))
  2436. {
  2437. VideoDebugPrint((DEBUG_DETAIL, "ati.sys ATIMPGetPower50: Device Id = Monitor, State = D%ld\n",
  2438. pVideoPowerMgmt->PowerState - 1));
  2439. switch (pVideoPowerMgmt->PowerState)
  2440. {
  2441. case VideoPowerOn:
  2442. case VideoPowerHibernate:
  2443. return NO_ERROR;
  2444. case VideoPowerStandBy:
  2445. case VideoPowerSuspend:
  2446. case VideoPowerOff:
  2447. return ERROR_INVALID_FUNCTION;
  2448. default:
  2449. return ERROR_INVALID_PARAMETER;
  2450. }
  2451. }
  2452. else if (DISPLAY_ADAPTER_HW_ID == HwDeviceId)
  2453. {
  2454. VideoDebugPrint((DEBUG_DETAIL, "ati.sys ATIMPGetPower50: Device Id = Graphics Adapter, State = D%ld\n",
  2455. pVideoPowerMgmt->PowerState - 1));
  2456. switch (pVideoPowerMgmt->PowerState) {
  2457. case VideoPowerOn:
  2458. case VideoPowerHibernate:
  2459. return NO_ERROR;
  2460. case VideoPowerStandBy:
  2461. case VideoPowerSuspend:
  2462. case VideoPowerOff:
  2463. //
  2464. // Indicate that we can't do VideoPowerOff, because
  2465. // we have no way of coming back when power is re-applied
  2466. // to the card.
  2467. //
  2468. return ERROR_INVALID_FUNCTION;
  2469. default:
  2470. ASSERT(FALSE);
  2471. return ERROR_INVALID_FUNCTION;
  2472. }
  2473. }
  2474. else
  2475. {
  2476. VideoDebugPrint((DEBUG_ERROR, "ati.sys ATIMPGetPower50: Unknown HwDeviceId\n"));
  2477. ASSERT(FALSE);
  2478. return ERROR_INVALID_PARAMETER;
  2479. }
  2480. } // ATIMPGetPower50()
  2481. ULONG
  2482. ATIMPGetVideoChildDescriptor(
  2483. PVOID pHwDeviceExtension,
  2484. PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  2485. PVIDEO_CHILD_TYPE pChildType,
  2486. PVOID pvChildDescriptor,
  2487. PULONG pHwId,
  2488. PULONG pUnused
  2489. )
  2490. //
  2491. // DESCRIPTION:
  2492. // Enumerate all devices controlled by the ATI graphics chip.
  2493. // This includes DDC monitors attached to the board, as well as other devices
  2494. // which may be connected to a proprietary bus.
  2495. //
  2496. // PARAMETERS:
  2497. // HwDeviceExtension Pointer to our hardware device extension structure.
  2498. // ChildEnumInfo Information about the device that should be enumerated.
  2499. // pvChildDescriptor Identification structure of the device (EDID, string).
  2500. // pHwId Private unique 32 bit ID to passed back to the miniport.
  2501. // pUnused Do not use.
  2502. //
  2503. // RETURN VALUE:
  2504. // ERROR_NO_MORE_DEVICES if no more child devices exist.
  2505. // ERROR_INVALID_NAME if the device could not be enumerated, but more devices
  2506. // exist.
  2507. // ERROR_MORE_DATA to be called again
  2508. //
  2509. // NOTE:
  2510. // In the event of a failure return, none of the fields are valid except for
  2511. // the return value and the pbMoreChildren field.
  2512. //
  2513. {
  2514. //
  2515. //
  2516. ULONG Status;
  2517. ASSERT(NULL != pHwDeviceExtension);
  2518. VideoDebugPrint((DEBUG_NORMAL, "ATI.SYS!AtiGetVideoChildDescriptor: *** Entry point ***\n"));
  2519. VideoDebugPrint((DEBUG_NORMAL, "ATI.SYS!AtiGetVideoChildDescriptor: pHwDeviceExtension = 0x%08X\n",
  2520. pHwDeviceExtension));
  2521. VideoDebugPrint((DEBUG_NORMAL, "ATI.SYS!AtiGetVideoChildDescriptor: ChildIndex = %ld\n", ChildEnumInfo->ChildIndex));
  2522. switch (ChildEnumInfo->ChildIndex) {
  2523. case 0:
  2524. //
  2525. // Case 0 is used to enumerate devices found by the ACPI firmware.
  2526. //
  2527. // Since we do not support ACPI devices yet, we must return failure.
  2528. //
  2529. Status = ERROR_NO_MORE_DEVICES;
  2530. break;
  2531. case 1:
  2532. //
  2533. // This is the last device we enumerate. Tell the system we don't
  2534. // have any more.
  2535. //
  2536. *pChildType = Monitor;
  2537. //
  2538. // Obtain the EDID structure via DDC.
  2539. //
  2540. if (DDC2Query50(pHwDeviceExtension,
  2541. pvChildDescriptor,
  2542. ChildEnumInfo->ChildDescriptorSize) == TRUE)
  2543. {
  2544. ASSERT(pChildType != NULL && pHwId != NULL);
  2545. *pHwId = QUERY_MONITOR_ID;
  2546. VideoDebugPrint((DEBUG_NORMAL, "ati.sys ATIMPGetVideoChildDescriptor: Successfully read EDID structure\n"));
  2547. } else {
  2548. //
  2549. // Alway return TRUE, since we always have a monitor output
  2550. // on the card and it just may not be a detectable device.
  2551. //
  2552. ASSERT(pChildType != NULL && pHwId != NULL);
  2553. *pHwId = QUERY_NONDDC_MONITOR_ID;
  2554. VideoDebugPrint((DEBUG_NORMAL, "ati.sys ATIMPGetVideoChildDescriptor: DDC not supported\n"));
  2555. }
  2556. Status = ERROR_MORE_DATA;
  2557. break;
  2558. case DISPLAY_ADAPTER_HW_ID:
  2559. {
  2560. PUSHORT pPnpDeviceDescription = NULL;
  2561. ULONG stringSize = sizeof(L"*PNPXXXX");
  2562. struct query_structure * QueryPtr =
  2563. (struct query_structure *) (phwDeviceExtension->CardInfo);
  2564. //
  2565. // Special ID to handle return legacy PnP IDs for root enumerated
  2566. // devices.
  2567. //
  2568. *pChildType = VideoChip;
  2569. *pHwId = DISPLAY_ADAPTER_HW_ID;
  2570. //
  2571. // Figure out which card type and set pPnpDeviceDescription at
  2572. // associated string.
  2573. //
  2574. // "ATI Graphics Ultra Pro (mach32)"
  2575. pPnpDeviceDescription = L"*PNP090A";
  2576. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  2577. {
  2578. // "ATI Graphics Pro Turbo (mach64)"
  2579. pPnpDeviceDescription = L"*PNP0916";
  2580. }
  2581. else if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  2582. {
  2583. if (QueryPtr->q_system_bus_type == Eisa)
  2584. {
  2585. // "ATI Graphics Ultra Pro EISA (mach32)"
  2586. pPnpDeviceDescription = L"*ATI4402";
  2587. }
  2588. }
  2589. else if (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA)
  2590. {
  2591. // "ATI Graphics Ultra (mach8)"
  2592. pPnpDeviceDescription = L"*PNP090B";
  2593. }
  2594. else if (phwDeviceExtension->ModelNumber == WONDER)
  2595. {
  2596. // "ATI VGA Wonder"
  2597. pPnpDeviceDescription = L"*PNP090D";
  2598. }
  2599. //
  2600. // Now just copy the string into memory provided.
  2601. //
  2602. memcpy(pvChildDescriptor, pPnpDeviceDescription, stringSize);
  2603. Status = ERROR_MORE_DATA;
  2604. break;
  2605. }
  2606. default:
  2607. Status = ERROR_NO_MORE_DEVICES;
  2608. break;
  2609. }
  2610. if (ERROR_MORE_DATA == Status)
  2611. {
  2612. VideoDebugPrint((DEBUG_NORMAL, "ATI.SYS!AtiGetVideoChildDescriptor: ChildType = %ld\n", *pChildType));
  2613. VideoDebugPrint((DEBUG_NORMAL, "ATI.SYS!AtiGetVideoChildDescriptor: pvHdId = 0x%x\n", *pHwId));
  2614. VideoDebugPrint((DEBUG_NORMAL, "ATI.SYS!AtiGetVideoChildDescriptor: *** Exit TRUE ***\n"));
  2615. }
  2616. else
  2617. {
  2618. VideoDebugPrint((DEBUG_NORMAL, "ATI.SYS!AtiGetVideoChildDescriptor: *** Exit FALSE ***\n"));
  2619. }
  2620. return Status;
  2621. } // AtiGetVideoChildDescriptor()
  2622. #endif // TARGET_BUILD >= 500
  2623. //------------------------------------------------------------------------
  2624. /*
  2625. * VP_STATUS RegistryParameterCallback(phwDeviceExtension, Context, Name, Data, Length);
  2626. *
  2627. * PHW_DEVICE_EXTENSION phwDeviceExtension; Miniport device extension
  2628. * PVOID Context; Context parameter passed to the callback routine
  2629. * PWSTR Name; Pointer to the name of the requested field
  2630. * PVOID Data; Pointer to a buffer containing the information
  2631. * ULONG Length; Length of the data
  2632. *
  2633. * Routine to process the information coming back from the registry.
  2634. *
  2635. * Return value:
  2636. * NO_ERROR if successful
  2637. * ERROR_INSUFFICIENT_BUFFER if too much data to store
  2638. */
  2639. VP_STATUS RegistryParameterCallback(PHW_DEVICE_EXTENSION phwDeviceExtension,
  2640. PVOID Context,
  2641. PWSTR Name,
  2642. PVOID Data,
  2643. ULONG Length)
  2644. {
  2645. if (Length > REGISTRY_BUFFER_SIZE)
  2646. {
  2647. return ERROR_INSUFFICIENT_BUFFER;
  2648. }
  2649. /*
  2650. * Copy the data to our local buffer so other routines
  2651. * can use it.
  2652. */
  2653. memcpy(RegistryBuffer, Data, Length);
  2654. RegistryBufferLength = Length;
  2655. return NO_ERROR;
  2656. } /* RegistryParameterCallback() */
  2657. BOOLEAN
  2658. SetDisplayPowerState(
  2659. PHW_DEVICE_EXTENSION phwDeviceExtension,
  2660. VIDEO_POWER_STATE VideoPowerState
  2661. )
  2662. //
  2663. // DESCRIPTION:
  2664. // Set the graphics card to the desired DPMS state under NT 3.51 and NT 4.0.
  2665. //
  2666. // PARAMETERS:
  2667. // phwDeviceExtension Pointer to our hardware device extension structure.
  2668. // VideoPowerState Desired DPMS state.
  2669. //
  2670. // RETURN VALUE:
  2671. // TRUE if successful.
  2672. // FALSE if unsuccessful.
  2673. //
  2674. {
  2675. ASSERT(phwDeviceExtension != NULL);
  2676. VideoDebugPrint((DEBUG_DETAIL, "ati.sys SetDisplayPowerState: Setting power state to %lu\n", VideoPowerState));
  2677. //
  2678. // Different card families need different routines to set the power management state.
  2679. //
  2680. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  2681. {
  2682. VIDEO_X86_BIOS_ARGUMENTS Registers;
  2683. //
  2684. // Invoke the BIOS call to set the desired DPMS state. The BIOS call
  2685. // enumeration of DPMS states is in the same order as that in
  2686. // VIDEO_POWER_STATE, but it is zero-based instead of one-based.
  2687. //
  2688. VideoPortZeroMemory(&Registers, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  2689. Registers.Eax = BIOS_SET_DPMS;
  2690. Registers.Ecx = VideoPowerState - 1;
  2691. VideoPortInt10(phwDeviceExtension, &Registers);
  2692. return TRUE;
  2693. }
  2694. else
  2695. {
  2696. VideoDebugPrint((DEBUG_ERROR, "ati.sys SetDisplayPowerState: Invalid adapter type\n"));
  2697. ASSERT(FALSE);
  2698. return FALSE;
  2699. }
  2700. } // SetDisplayPowerState()
  2701. VIDEO_POWER_STATE
  2702. GetDisplayPowerState(
  2703. PHW_DEVICE_EXTENSION phwDeviceExtension
  2704. )
  2705. //
  2706. // DESCRIPTION:
  2707. // Retrieve the current DPMS state from the graphics card.
  2708. //
  2709. // PARAMETERS:
  2710. // phwDeviceExtension Pointer to our hardware device extension structure.
  2711. //
  2712. // RETURN VALUE:
  2713. // Current power management state.
  2714. //
  2715. // NOTE:
  2716. // The enumerations VIDEO_DEVICE_POWER_MANAGEMENT (used by GetDisplayPowerState()) and VIDEO_POWER_MANAGEMENT
  2717. // (used by this IOCTL) have opposite orderings (VIDEO_POWER_MANAGEMENT values increase as power consumption
  2718. // decreases, while VIDEO_DEVICE_POWER_MANAGEMENT values increase as power consumption increases, and has
  2719. // a reserved value for "state unknown"), so we can't simply add a constant to translate between them.
  2720. //
  2721. {
  2722. VIDEO_POWER_STATE CurrentState = VideoPowerUnspecified; // Current DPMS state
  2723. ASSERT(phwDeviceExtension != NULL);
  2724. //
  2725. // Different card families need different routines to retrieve the power management state.
  2726. //
  2727. if (phwDeviceExtension->ModelNumber == MACH64_ULTRA)
  2728. CurrentState = GetPowerManagement_cx(phwDeviceExtension);
  2729. //
  2730. // VIDEO_POWER_STATE has 5 possible states and a
  2731. // reserved value to report that we can't read the state.
  2732. // Our cards support 3 levels of monitor power-down in
  2733. // addition to normal operation. Since the number of
  2734. // values which can be reported exceeds the number
  2735. // of states our cards can be in, we will never report
  2736. // one of the possible states (VPPowerDeviceD3).
  2737. //
  2738. switch (CurrentState)
  2739. {
  2740. case VideoPowerUnspecified:
  2741. VideoDebugPrint((DEBUG_DETAIL, "ati.sys GetDisplayPowerState: unknown videocard\n"));
  2742. break;
  2743. case VideoPowerOn:
  2744. VideoDebugPrint((DEBUG_DETAIL, "ati.sys GetDisplayPowerState: Currently set to DPMS ON\n"));
  2745. break;
  2746. case VideoPowerStandBy:
  2747. VideoDebugPrint((DEBUG_DETAIL, "ati.sys GetDisplayPowerState: Currently set to DPMS STAND-BY\n"));
  2748. break;
  2749. case VideoPowerSuspend:
  2750. VideoDebugPrint((DEBUG_DETAIL, "ati.sys GetDisplayPowerState: Currently set to DPMS SUSPEND\n"));
  2751. break;
  2752. case VideoPowerOff:
  2753. VideoDebugPrint((DEBUG_DETAIL, "ati.sys GetDisplayPowerState: Currently set to DPMS OFF\n"));
  2754. break;
  2755. default:
  2756. VideoDebugPrint((DEBUG_ERROR, "ati.sys GetDisplayPowerState: Currently set to invalid DPMS state\n"));
  2757. break;
  2758. }
  2759. return CurrentState;
  2760. } // GetDisplayPowerState()
  2761. // *********************** End of ATIMP.C ****************************