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

443 lines
12 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1999 - 1999
  3. Module Name:
  4. init.c
  5. Abstract:
  6. Generic PCI IDE mini driver
  7. Revision History:
  8. --*/
  9. #include "pciide.h"
  10. //
  11. // Driver Entry Point
  12. //
  13. NTSTATUS
  14. DriverEntry(
  15. IN PDRIVER_OBJECT DriverObject,
  16. IN PUNICODE_STRING RegistryPath
  17. )
  18. {
  19. //
  20. // call system pci ide driver (pciidex)
  21. // for initializeation
  22. //
  23. return PciIdeXInitialize (
  24. DriverObject,
  25. RegistryPath,
  26. GenericIdeGetControllerProperties,
  27. sizeof (DEVICE_EXTENSION)
  28. );
  29. }
  30. //
  31. // Called on every I/O. Returns 1 if DMA is allowed.
  32. // Returns 0 if DMA is not allowed.
  33. //
  34. ULONG
  35. GenericIdeUseDma(
  36. IN PVOID DeviceExtension,
  37. IN PVOID cdbcmd,
  38. IN UCHAR slave)
  39. /**++
  40. * Arguments : DeviceExtension
  41. Cdb
  42. Slave =1, if slave
  43. =0, if master
  44. --**/
  45. {
  46. PDEVICE_EXTENSION deviceExtension = DeviceExtension;
  47. PUCHAR cdb= cdbcmd;
  48. return 1;
  49. }
  50. //
  51. // Query controller properties
  52. //
  53. NTSTATUS
  54. GenericIdeGetControllerProperties (
  55. IN PVOID DeviceExtension,
  56. IN PIDE_CONTROLLER_PROPERTIES ControllerProperties
  57. )
  58. {
  59. PDEVICE_EXTENSION deviceExtension = DeviceExtension;
  60. NTSTATUS status;
  61. ULONG i;
  62. ULONG j;
  63. ULONG xferMode;
  64. //
  65. // make sure we are in sync
  66. //
  67. if (ControllerProperties->Size != sizeof (IDE_CONTROLLER_PROPERTIES)) {
  68. return STATUS_REVISION_MISMATCH;
  69. }
  70. //
  71. // see what kind of PCI IDE controller we have
  72. //
  73. status = PciIdeXGetBusData (
  74. deviceExtension,
  75. &deviceExtension->pciConfigData,
  76. 0,
  77. sizeof (PCIIDE_CONFIG_HEADER)
  78. );
  79. if (!NT_SUCCESS(status)) {
  80. return status;
  81. }
  82. //
  83. // assume we support all DMA mode if PCI master bit is set
  84. //
  85. xferMode = PIO_SUPPORT;
  86. if ((deviceExtension->pciConfigData.MasterIde) &&
  87. (deviceExtension->pciConfigData.Command.b.MasterEnable)) {
  88. xferMode |= SWDMA_SUPPORT | MWDMA_SUPPORT | UDMA_SUPPORT;
  89. }
  90. // @@BEGIN_DDKSPLIT
  91. //
  92. // Run PIO by default for the Sis Chipset
  93. //
  94. if ((deviceExtension->pciConfigData.VendorID == 0x1039) &&
  95. (deviceExtension->pciConfigData.DeviceID == 0x5513)) {
  96. ControllerProperties->DefaultPIO = 1;
  97. }
  98. //
  99. // Run PIO by default for the Rcc Chipset
  100. //
  101. if ((deviceExtension->pciConfigData.VendorID == 0x1166) &&
  102. (deviceExtension->pciConfigData.DeviceID == 0x0211)) {
  103. ControllerProperties->DefaultPIO = 1;
  104. }
  105. //
  106. // continuous status register polling causes some ALI
  107. // controller to corrupt data if the controller internal
  108. // FIFO is enabled
  109. //
  110. // to play safe, we will always disable the FIFO
  111. // see the ALi IDE controller programming spec for details
  112. //
  113. if ((deviceExtension->pciConfigData.VendorID == 0x10b9) &&
  114. (deviceExtension->pciConfigData.DeviceID == 0x5229)) {
  115. USHORT pciData;
  116. USHORT pciDataMask;
  117. pciData = 0;
  118. pciDataMask = 0xcccc;
  119. status = PciIdeXSetBusData(
  120. DeviceExtension,
  121. &pciData,
  122. &pciDataMask,
  123. 0x54,
  124. 0x2);
  125. if (!NT_SUCCESS(status)) {
  126. return status;
  127. }
  128. }
  129. //
  130. // ALi IDE controllers have lots of busmaster problems
  131. // some versions of them can't do busmaster with ATAPI devices
  132. // and some other versions of them return bogus busmaster status values
  133. // (the busmaster active bit doesn't get cleared when it should be
  134. // during an end of busmaster interrupt)
  135. //
  136. if ((deviceExtension->pciConfigData.VendorID == 0x10b9) &&
  137. (deviceExtension->pciConfigData.DeviceID == 0x5229) &&
  138. ((deviceExtension->pciConfigData.RevisionID == 0x20) ||
  139. (deviceExtension->pciConfigData.RevisionID == 0xc1))) {
  140. PciIdeXDebugPrint ((0, "pciide: overcome the sticky BM active bit problem in ALi controller\n"));
  141. ControllerProperties->IgnoreActiveBitForAtaDevice = TRUE;
  142. }
  143. if ((deviceExtension->pciConfigData.VendorID == 0x0e11) &&
  144. (deviceExtension->pciConfigData.DeviceID == 0xae33) &&
  145. (deviceExtension->pciConfigData.Chan0OpMode ||
  146. deviceExtension->pciConfigData.Chan1OpMode)) {
  147. PciIdeXDebugPrint ((0, "pciide: overcome the bogus busmaster interrupt in CPQ controller\n"));
  148. ControllerProperties->AlwaysClearBusMasterInterrupt = TRUE;
  149. }
  150. // @@END_DDKSPLIT
  151. //
  152. // fill in the controller properties
  153. //
  154. for (i=0; i< MAX_IDE_CHANNEL; i++) {
  155. for (j=0; j< MAX_IDE_DEVICE; j++) {
  156. ControllerProperties->SupportedTransferMode[i][j] =
  157. deviceExtension->SupportedTransferMode[i][j] = xferMode;
  158. }
  159. }
  160. ControllerProperties->PciIdeChannelEnabled = GenericIdeChannelEnabled;
  161. ControllerProperties->PciIdeSyncAccessRequired = GenericIdeSyncAccessRequired;
  162. ControllerProperties->PciIdeTransferModeSelect = NULL;
  163. ControllerProperties->PciIdeUdmaModesSupported = GenericIdeUdmaModesSupported;
  164. ControllerProperties->PciIdeUseDma = GenericIdeUseDma;
  165. ControllerProperties->AlignmentRequirement=1;
  166. return STATUS_SUCCESS;
  167. }
  168. IDE_CHANNEL_STATE
  169. GenericIdeChannelEnabled (
  170. IN PDEVICE_EXTENSION DeviceExtension,
  171. IN ULONG Channel
  172. )
  173. {
  174. // @@BEGIN_DDKSPLIT
  175. NTSTATUS status;
  176. PCI_COMMON_CONFIG pciHeader;
  177. ULONG pciDataByte;
  178. UCHAR maskByte = 0;
  179. status = PciIdeXGetBusData (
  180. DeviceExtension,
  181. &pciHeader,
  182. 0,
  183. sizeof (pciHeader)
  184. );
  185. if (NT_SUCCESS(status)) {
  186. if ((pciHeader.VendorID == 0x0e11) &&
  187. (pciHeader.DeviceID == 0xae33)) {
  188. //
  189. // Compaq
  190. //
  191. status = PciIdeXGetBusData (
  192. DeviceExtension,
  193. &pciDataByte,
  194. 0x80,
  195. sizeof (pciDataByte)
  196. );
  197. if (NT_SUCCESS(status)) {
  198. if (pciDataByte & (1 << Channel)) {
  199. return ChannelEnabled;
  200. } else {
  201. return ChannelDisabled;
  202. }
  203. }
  204. } else if ((pciHeader.VendorID == 0x1095) &&
  205. ((pciHeader.DeviceID == 0x0646) || (pciHeader.DeviceID == 0x0643))) {
  206. //
  207. // CMD
  208. //
  209. status = PciIdeXGetBusData (
  210. DeviceExtension,
  211. &pciDataByte,
  212. 0x51,
  213. sizeof (pciDataByte)
  214. );
  215. if (NT_SUCCESS(status)) {
  216. if (pciHeader.RevisionID < 0x3) {
  217. //
  218. // early revision doesn't have a
  219. // bit to enable/disable primary
  220. // channel since it is always enabled
  221. // newer version does have a bit defined
  222. // for this purpose. to make the check
  223. // easier later. we will set primary enable bit
  224. // for the early revision
  225. pciDataByte |= 0x4;
  226. }
  227. if (Channel == 0) {
  228. maskByte = 0x4;
  229. } else {
  230. maskByte = 0x8;
  231. }
  232. if (pciDataByte & maskByte) {
  233. return ChannelEnabled;
  234. } else {
  235. return ChannelDisabled;
  236. }
  237. }
  238. } else if ((pciHeader.VendorID == 0x1039) &&
  239. (pciHeader.DeviceID == 0x5513)) {
  240. //
  241. // SiS
  242. //
  243. status = PciIdeXGetBusData (
  244. DeviceExtension,
  245. &pciDataByte,
  246. 0x4a,
  247. sizeof (pciDataByte)
  248. );
  249. if (Channel == 0) {
  250. maskByte = 0x2;
  251. } else {
  252. maskByte = 0x4;
  253. }
  254. if (pciDataByte & maskByte) {
  255. return ChannelEnabled;
  256. } else {
  257. return ChannelDisabled;
  258. }
  259. } else if ((pciHeader.VendorID == 0x110A) &&
  260. (pciHeader.DeviceID == 0x0002)) {
  261. //
  262. // Siemens
  263. //
  264. ULONG configOffset = (Channel == 0)?0x41:0x49;
  265. status = PciIdeXGetBusData (
  266. DeviceExtension,
  267. &pciDataByte,
  268. configOffset,
  269. sizeof (pciDataByte)
  270. );
  271. if (NT_SUCCESS(status)) {
  272. maskByte = 0x08;
  273. if (pciDataByte & maskByte) {
  274. return ChannelEnabled;
  275. } else {
  276. return ChannelDisabled;
  277. }
  278. }
  279. } else if ((pciHeader.VendorID == 0x1106) &&
  280. (pciHeader.DeviceID == 0x0571)) {
  281. //
  282. // VIA
  283. //
  284. status = PciIdeXGetBusData (
  285. DeviceExtension,
  286. &pciDataByte,
  287. 0x40,
  288. sizeof (pciDataByte)
  289. );
  290. if (NT_SUCCESS(status)) {
  291. maskByte = (Channel == 0)? 0x02:0x01;
  292. if (pciDataByte & maskByte) {
  293. return ChannelEnabled;
  294. } else {
  295. return ChannelDisabled;
  296. }
  297. }
  298. }
  299. }
  300. // @@END_DDKSPLIT
  301. //
  302. // Can't tell if a channel is enabled or not.
  303. //
  304. return ChannelStateUnknown;
  305. }
  306. // @@BEGIN_DDKSPLIT
  307. VENDOR_ID_DEVICE_ID SingleFifoController[] = {
  308. {0x1095, 0x0640}, // CMD 640
  309. {0x1039, 0x0601} // SiS ????
  310. };
  311. #define NUMBER_OF_SINGLE_FIFO_CONTROLLER (sizeof(SingleFifoController) / sizeof(VENDOR_ID_DEVICE_ID))
  312. // @@END_DDKSPLIT
  313. BOOLEAN
  314. GenericIdeSyncAccessRequired (
  315. IN PDEVICE_EXTENSION DeviceExtension
  316. )
  317. {
  318. ULONG i;
  319. // @@BEGIN_DDKSPLIT
  320. for (i=0; i<NUMBER_OF_SINGLE_FIFO_CONTROLLER; i++) {
  321. if ((DeviceExtension->pciConfigData.VendorID == SingleFifoController[i].VendorId) &&
  322. (DeviceExtension->pciConfigData.DeviceID == SingleFifoController[i].DeviceId)) {
  323. return TRUE;
  324. }
  325. }
  326. // @@END_DDKSPLIT
  327. return FALSE;
  328. }
  329. NTSTATUS
  330. GenericIdeUdmaModesSupported (
  331. IN IDENTIFY_DATA IdentifyData,
  332. IN OUT PULONG BestXferMode,
  333. IN OUT PULONG CurrentMode
  334. )
  335. {
  336. ULONG bestXferMode =0;
  337. ULONG currentMode = 0;
  338. if (IdentifyData.TranslationFieldsValid & (1 << 2)) {
  339. if (IdentifyData.UltraDMASupport) {
  340. GetHighestTransferMode( IdentifyData.UltraDMASupport,
  341. bestXferMode);
  342. *BestXferMode = bestXferMode;
  343. }
  344. if (IdentifyData.UltraDMAActive) {
  345. GetHighestTransferMode( IdentifyData.UltraDMAActive,
  346. currentMode);
  347. *CurrentMode = currentMode;
  348. }
  349. }
  350. return STATUS_SUCCESS;
  351. }