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.

875 lines
26 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: timing.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "intel.h"
  11. //
  12. // PiixTiming[Master Timing Mode][Slave Timing Mode]
  13. //
  14. PIIX_SPECIAL_TIMING_REGISTER PiixSpecialTiming[PiixMode_MaxMode] =
  15. {
  16. {
  17. PIIX_TIMING_DMA_TIMING_ENABLE(0) |
  18. PIIX_TIMING_PREFETCH_AND_POSTING_ENABLE(0) |
  19. PIIX_TIMING_IOREADY_SAMPLE_POINT_ENABLE(0) |
  20. PIIX_TIMING_FAST_TIMING_BANK_ENABLE(0)
  21. }, // not present
  22. {
  23. PIIX_TIMING_DMA_TIMING_ENABLE(0) |
  24. PIIX_TIMING_PREFETCH_AND_POSTING_ENABLE(0) |
  25. PIIX_TIMING_IOREADY_SAMPLE_POINT_ENABLE(0) |
  26. PIIX_TIMING_FAST_TIMING_BANK_ENABLE(0)
  27. }, // piix timing mode 0
  28. {
  29. PIIX_TIMING_DMA_TIMING_ENABLE(0) |
  30. PIIX_TIMING_PREFETCH_AND_POSTING_ENABLE(0) |
  31. PIIX_TIMING_IOREADY_SAMPLE_POINT_ENABLE(0) |
  32. PIIX_TIMING_FAST_TIMING_BANK_ENABLE(1)
  33. }, // piix timing mode 2
  34. {
  35. PIIX_TIMING_DMA_TIMING_ENABLE(0) |
  36. PIIX_TIMING_PREFETCH_AND_POSTING_ENABLE(0) |
  37. PIIX_TIMING_IOREADY_SAMPLE_POINT_ENABLE(1) |
  38. PIIX_TIMING_FAST_TIMING_BANK_ENABLE(1)
  39. }, // piix timing mode 3
  40. {
  41. PIIX_TIMING_DMA_TIMING_ENABLE(0) |
  42. PIIX_TIMING_PREFETCH_AND_POSTING_ENABLE(0) |
  43. PIIX_TIMING_IOREADY_SAMPLE_POINT_ENABLE(1) |
  44. PIIX_TIMING_FAST_TIMING_BANK_ENABLE(1)
  45. } // piix timing mode 4
  46. };
  47. UCHAR PiixIoReadySamplePointClockSetting[PiixMode_MaxMode] =
  48. {
  49. 0,
  50. 0,
  51. 1,
  52. 2,
  53. 2
  54. };
  55. UCHAR PiixRecoveryTimeClockSetting[PiixMode_MaxMode] =
  56. {
  57. 0,
  58. 0,
  59. 0,
  60. 1,
  61. 3
  62. };
  63. NTSTATUS
  64. PiixIdeUdmaModesSupported (
  65. IN IDENTIFY_DATA IdentifyData,
  66. IN OUT PULONG BestXferMode,
  67. IN OUT PULONG CurrentMode
  68. )
  69. {
  70. ULONG bestXferMode =0;
  71. ULONG currentMode = 0;
  72. if (IdentifyData.TranslationFieldsValid & (1 << 2)) {
  73. if (IdentifyData.UltraDMASupport) {
  74. GetHighestTransferMode( IdentifyData.UltraDMASupport,
  75. bestXferMode);
  76. *BestXferMode = bestXferMode;
  77. }
  78. if (IdentifyData.UltraDMAActive) {
  79. GetHighestTransferMode( IdentifyData.UltraDMAActive,
  80. currentMode);
  81. *CurrentMode = currentMode;
  82. }
  83. }
  84. return STATUS_SUCCESS;
  85. }
  86. NTSTATUS
  87. PiixIdeTransferModeSelect (
  88. IN PDEVICE_EXTENSION DeviceExtension,
  89. IN OUT PPCIIDE_TRANSFER_MODE_SELECT TransferModeSelect
  90. )
  91. {
  92. NTSTATUS status;
  93. ULONG driveBestXferMode[MAX_IDE_DEVICE];
  94. PIIX_TIMING_REGISTER piixTimingReg;
  95. PIIX3_SLAVE_TIMING_REGISTER piixSlaveTimingReg;
  96. PIIX4_UDMA_CONTROL_REGISTER piix4UdmaControlReg;
  97. PIIX4_UDMA_TIMING_REGISTER piix4UdmaTimingReg;
  98. ICH_IO_CONFIG_REGISTER ioConfigReg;
  99. USHORT dataMask;
  100. ULONG i;
  101. //
  102. // Store the identify data for later use.
  103. //
  104. for (i=0;i<MAX_IDE_DEVICE;i++) {
  105. DeviceExtension->IdentifyData[i]=TransferModeSelect->IdentifyData[i];
  106. }
  107. status = PiixIdepTransferModeSelect (
  108. DeviceExtension,
  109. TransferModeSelect,
  110. driveBestXferMode,
  111. &piixTimingReg,
  112. &piixSlaveTimingReg,
  113. &piix4UdmaControlReg,
  114. &piix4UdmaTimingReg,
  115. &ioConfigReg
  116. );
  117. if (NT_SUCCESS(status)) {
  118. #if DBG
  119. {
  120. PIIX_TIMING_REGISTER piixOldTimingReg[2];
  121. PIIX3_SLAVE_TIMING_REGISTER piixOldSlaveTimingReg;
  122. PIIX4_UDMA_CONTROL_REGISTER piix4OldUdmaControlReg;
  123. PIIX4_UDMA_TIMING_REGISTER piix4OldUdmaTimingReg;
  124. ICH_IO_CONFIG_REGISTER oldIoConfigReg;
  125. ULONG channel;
  126. #define BitSet(Data, Mask, NewData) Data = ((Data & ~Mask) | (Mask & NewData));
  127. piixOldSlaveTimingReg.AsUChar = 0;
  128. piix4OldUdmaControlReg.AsUChar = 0;
  129. piix4OldUdmaTimingReg.AsUChar = 0;
  130. channel = TransferModeSelect->Channel;
  131. PciIdeXGetBusData (
  132. DeviceExtension,
  133. piixOldTimingReg,
  134. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, Timing),
  135. sizeof (piixOldTimingReg)
  136. );
  137. PciIdeXDebugPrint ((1,
  138. "Old PIIX Timing Register Value (IDETIM = 0x%x",
  139. piixOldTimingReg[channel].AsUShort));
  140. if (!IS_PIIX(DeviceExtension->DeviceId)) {
  141. PciIdeXGetBusData (
  142. DeviceExtension,
  143. &piixOldSlaveTimingReg,
  144. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, SlaveTiming),
  145. sizeof (piixOldSlaveTimingReg)
  146. );
  147. PciIdeXDebugPrint ((1,
  148. " SIDETIM (0x%x)",
  149. piixOldSlaveTimingReg.AsUChar));
  150. }
  151. if (IS_UDMA_CONTROLLER(DeviceExtension->DeviceId)) {
  152. PciIdeXGetBusData (
  153. DeviceExtension,
  154. &piix4OldUdmaControlReg,
  155. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, UdmaControl),
  156. sizeof (piix4OldUdmaControlReg)
  157. );
  158. PciIdeXDebugPrint ((1,
  159. " SDMACTL (0x%x)",
  160. piix4OldUdmaControlReg.AsUChar));
  161. PciIdeXGetBusData (
  162. DeviceExtension,
  163. &piix4OldUdmaTimingReg,
  164. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, UdmaTiming[channel]),
  165. sizeof (piix4OldUdmaTimingReg)
  166. );
  167. PciIdeXDebugPrint ((1,
  168. " SDMATIM (0x%x)",
  169. piix4OldUdmaTimingReg.AsUChar));
  170. }
  171. if (IS_ICH_(DeviceExtension->DeviceId) ||
  172. IS_ICH0(DeviceExtension->DeviceId)) {
  173. PciIdeXGetBusData (
  174. DeviceExtension,
  175. &oldIoConfigReg,
  176. FIELD_OFFSET(ICH_PCI_CONFIG_DATA, IoConfig),
  177. sizeof (oldIoConfigReg)
  178. );
  179. PciIdeXDebugPrint ((1,
  180. " I/O Control (0x%x)",
  181. oldIoConfigReg.AsUShort));
  182. }
  183. PciIdeXDebugPrint ((1, "\n"));
  184. if (channel == 0) {
  185. BitSet (piixOldSlaveTimingReg.AsUChar, 0x0f, piixSlaveTimingReg.AsUChar);
  186. BitSet (piix4OldUdmaControlReg.AsUChar, 0x03, piix4UdmaControlReg.AsUChar);
  187. } else {
  188. BitSet (piixOldSlaveTimingReg.AsUChar, 0xf0, piixSlaveTimingReg.AsUChar);
  189. BitSet (piix4OldUdmaControlReg.AsUChar, 0x0c, piix4UdmaControlReg.AsUChar);
  190. }
  191. BitSet (oldIoConfigReg.AsUShort, 0x0f, ioConfigReg.AsUShort);
  192. PciIdeXDebugPrint ((1,
  193. "New PIIX/ICH Timing Register Value (IDETIM = 0x%x, SIDETIM (0x%x), SDMACTL (0x%x), SDMATIM (0x%x), IOCTRL (0x%x)\n",
  194. piixTimingReg.AsUShort,
  195. piixOldSlaveTimingReg.AsUChar,
  196. piix4OldUdmaControlReg.AsUChar,
  197. piix4UdmaTimingReg.AsUChar,
  198. oldIoConfigReg.AsUShort
  199. ));
  200. }
  201. #endif // DBG
  202. #ifndef PIIX_TIMING_REGISTER_SUPPORT
  203. status = STATUS_UNSUCCESSFUL;
  204. goto GetOut;
  205. #endif
  206. dataMask = 0xffff;
  207. status = PciIdeXSetBusData (
  208. DeviceExtension,
  209. &piixTimingReg,
  210. &dataMask,
  211. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, Timing) +
  212. sizeof(piixTimingReg) *
  213. TransferModeSelect->Channel,
  214. sizeof (piixTimingReg)
  215. );
  216. if (!NT_SUCCESS(status)) {
  217. goto GetOut;
  218. }
  219. if (!IS_PIIX(DeviceExtension->DeviceId)) {
  220. dataMask = TransferModeSelect->Channel == 0 ? 0x0f : 0xf0;
  221. status = PciIdeXSetBusData (
  222. DeviceExtension,
  223. &piixSlaveTimingReg,
  224. &dataMask,
  225. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, SlaveTiming),
  226. sizeof (piixSlaveTimingReg)
  227. );
  228. if (!NT_SUCCESS(status)) {
  229. ASSERT(!"Unable to set pci config data\n");
  230. goto GetOut;
  231. }
  232. }
  233. if (IS_UDMA_CONTROLLER(DeviceExtension->DeviceId)) {
  234. //
  235. // UDMA Control Register
  236. //
  237. dataMask = TransferModeSelect->Channel == 0 ? 0x03 : 0x0c;
  238. status = PciIdeXSetBusData (
  239. DeviceExtension,
  240. &piix4UdmaControlReg,
  241. &dataMask,
  242. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, UdmaControl),
  243. sizeof (piix4UdmaControlReg)
  244. );
  245. if (!NT_SUCCESS(status)) {
  246. ASSERT(!"Unable to set pci config data\n");
  247. goto GetOut;
  248. }
  249. //
  250. // UDMA Timing Register
  251. //
  252. dataMask = 0xff;
  253. status = PciIdeXSetBusData (
  254. DeviceExtension,
  255. &piix4UdmaTimingReg,
  256. &dataMask,
  257. FIELD_OFFSET(PIIX4_PCI_CONFIG_DATA, UdmaTiming) +
  258. sizeof(piix4UdmaTimingReg) *
  259. TransferModeSelect->Channel,
  260. sizeof (piix4UdmaTimingReg)
  261. );
  262. if (!NT_SUCCESS(status)) {
  263. ASSERT(!"Unable to set pci config data\n");
  264. goto GetOut;
  265. }
  266. }
  267. if (IS_ICH_(DeviceExtension->DeviceId) ||
  268. IS_ICH0(DeviceExtension->DeviceId) ||
  269. IS_ICH2(DeviceExtension->DeviceId)) {
  270. //
  271. // UDMA Control Register
  272. //
  273. dataMask = TransferModeSelect->Channel == 0 ? 0x0403 : 0x040c;
  274. status = PciIdeXSetBusData (
  275. DeviceExtension,
  276. &ioConfigReg,
  277. &dataMask,
  278. FIELD_OFFSET(ICH_PCI_CONFIG_DATA, IoConfig),
  279. sizeof (ioConfigReg)
  280. );
  281. if (!NT_SUCCESS(status)) {
  282. ASSERT(!"Unable to set pci config data\n");
  283. goto GetOut;
  284. }
  285. }
  286. }
  287. GetOut:
  288. if (NT_SUCCESS(status)) {
  289. for (i = 0; i < MAX_IDE_DEVICE; i++) {
  290. TransferModeSelect->DeviceTransferModeSelected[i] =
  291. driveBestXferMode[i];
  292. }
  293. }
  294. return status;
  295. }
  296. NTSTATUS
  297. PiixIdepTransferModeSelect (
  298. IN PDEVICE_EXTENSION DeviceExtension,
  299. IN PPCIIDE_TRANSFER_MODE_SELECT TransferModeSelect,
  300. OUT ULONG DriveBestXferMode[MAX_IDE_DEVICE],
  301. OUT PPIIX_TIMING_REGISTER PiixTimingReg,
  302. OUT PPIIX3_SLAVE_TIMING_REGISTER PiixSlaveTimingReg,
  303. OUT PPIIX4_UDMA_CONTROL_REGISTER Piix4UdmaControlReg,
  304. OUT PPIIX4_UDMA_TIMING_REGISTER Piix4UdmaTimingReg,
  305. OUT PICH_IO_CONFIG_REGISTER IoConfigReg
  306. )
  307. {
  308. ULONG i;
  309. ULONG xferMode;
  310. ULONG channel;
  311. NTSTATUS status;
  312. UCHAR ispClockSetting;
  313. UCHAR recoveryClockSetting;
  314. PIIX_TIMING_MODE piixTimingMode;
  315. PIIX_SPECIAL_TIMING_REGISTER piixSpecialTiming;
  316. ULONG driveBestXferMode[MAX_IDE_DEVICE];
  317. PIIX_TIMING_REGISTER piixTimingReg;
  318. PIIX3_SLAVE_TIMING_REGISTER piixSlaveTimingReg;
  319. PIIX4_UDMA_CONTROL_REGISTER piix4UdmaControlReg;
  320. PIIX4_UDMA_TIMING_REGISTER piix4UdmaTimingReg;
  321. ICH_IO_CONFIG_REGISTER ioConfigReg;
  322. ULONG transferModeSupported;
  323. PULONG transferModeTimingTable;
  324. channel = TransferModeSelect->Channel;
  325. piixTimingReg.AsUShort = 0;
  326. piixSlaveTimingReg.AsUChar = 0;
  327. transferModeTimingTable=TransferModeSelect->TransferModeTimingTable;
  328. ASSERT(transferModeTimingTable);
  329. for (i = 0; i < MAX_IDE_DEVICE; i++) {
  330. ULONG enableUdma66 = TransferModeSelect->EnableUDMA66;
  331. driveBestXferMode[i] = 0;
  332. if (TransferModeSelect->DevicePresent[i] == FALSE) {
  333. continue;
  334. }
  335. #if 1
  336. //
  337. // UDMA transfer mode
  338. //
  339. transferModeSupported=TransferModeSelect->DeviceTransferModeSupported[i];
  340. //
  341. // only upto udma 5 is supported
  342. //
  343. transferModeSupported &= 0x1ffff;
  344. //
  345. // translate drive reported udma settings to drive's best udma mode
  346. // UDMA_MASK masks out udma mode >2 if cableReady or enableUdma is not set for a
  347. // controller that supports modes > udma2. enableUdma flag is ignored for Udma100
  348. // controllers
  349. //
  350. UDMA_MASK(DeviceExtension->UdmaController, DeviceExtension->CableReady[channel][i],
  351. enableUdma66, transferModeSupported);
  352. GetHighestDMATransferMode(transferModeSupported, xferMode);
  353. if (xferMode >= UDMA0) {
  354. driveBestXferMode[i] = 1 << xferMode;
  355. }
  356. //
  357. // DMA transfer mode
  358. //
  359. //
  360. // Get the highest DMA mode (exclude UDMA)
  361. //
  362. transferModeSupported = TransferModeSelect->
  363. DeviceTransferModeSupported[i] & (MWDMA_SUPPORT | SWDMA_SUPPORT);
  364. GetHighestDMATransferMode(transferModeSupported, xferMode);
  365. //
  366. // if xfermode is mwdma2 or 1, select mwdma2 , 1 or swdma2 depending on the cycle time
  367. //
  368. if (xferMode >= MWDMA1) {
  369. while (xferMode >= SWDMA2) {
  370. //
  371. // MWDMA0 is not supported
  372. //
  373. if (xferMode == MWDMA0) {
  374. xferMode--;
  375. continue;
  376. }
  377. if (TransferModeSelect->BestMwDmaCycleTime[i] <= transferModeTimingTable[xferMode]) {
  378. driveBestXferMode[i] |= (1 << xferMode);
  379. break;
  380. }
  381. xferMode--;
  382. }
  383. } else if (xferMode == SWDMA2) {
  384. if (TransferModeSelect->BestSwDmaCycleTime[i] <= transferModeTimingTable[xferMode]) {
  385. driveBestXferMode[i] |= SWDMA_MODE2;
  386. } //else use PIO
  387. }
  388. //
  389. // Don't use SWDMA0 and SWDMA1
  390. //
  391. //
  392. // PIO transfer mode
  393. //
  394. transferModeSupported=TransferModeSelect->DeviceTransferModeSupported[i];
  395. GetHighestPIOTransferMode(transferModeSupported, xferMode);
  396. //
  397. // if PIO2 is the highest PIO mode supported, don't check the
  398. // bestPIOTiming reported by the device.
  399. //
  400. if (xferMode == PIO2) {
  401. driveBestXferMode[i] |= (1 << xferMode);
  402. } else {
  403. //
  404. // PIO1 is not supported
  405. //
  406. while (xferMode > PIO1) {
  407. if (TransferModeSelect->BestPioCycleTime[i] <= transferModeTimingTable[xferMode]) {
  408. driveBestXferMode[i] |= (1 << xferMode);
  409. break;
  410. }
  411. xferMode--;
  412. }
  413. //
  414. // default to PIO0
  415. //
  416. if (xferMode <= PIO1) {
  417. driveBestXferMode[i] |= (1 << PIO0);
  418. }
  419. }
  420. #endif
  421. }
  422. //
  423. // use the slower mode if we have a old piix and two devices on the channel
  424. //
  425. if (IS_PIIX(DeviceExtension->DeviceId)) {
  426. if (TransferModeSelect->DevicePresent[0] && TransferModeSelect->DevicePresent[1]) {
  427. ULONG mode;
  428. if ((driveBestXferMode[0] & PIO_SUPPORT) <=
  429. (driveBestXferMode[1] & PIO_SUPPORT)) {
  430. mode = driveBestXferMode[0] & PIO_SUPPORT;
  431. } else {
  432. mode = driveBestXferMode[1] & PIO_SUPPORT;
  433. }
  434. if ((driveBestXferMode[0] & SWDMA_SUPPORT) <=
  435. (driveBestXferMode[1] & SWDMA_SUPPORT)) {
  436. mode |= driveBestXferMode[0] & SWDMA_SUPPORT;
  437. } else {
  438. mode |= driveBestXferMode[1] & SWDMA_SUPPORT;
  439. }
  440. if ((driveBestXferMode[0] & MWDMA_SUPPORT) <=
  441. (driveBestXferMode[1] & MWDMA_SUPPORT)) {
  442. mode |= driveBestXferMode[0] & MWDMA_SUPPORT;
  443. } else {
  444. mode |= driveBestXferMode[1] & MWDMA_SUPPORT;
  445. }
  446. if ((driveBestXferMode[0] & UDMA_SUPPORT) <=
  447. (driveBestXferMode[1] & UDMA_SUPPORT)) {
  448. mode |= driveBestXferMode[0] & UDMA_SUPPORT;
  449. } else {
  450. mode |= driveBestXferMode[1] & UDMA_SUPPORT;
  451. }
  452. driveBestXferMode[0] = driveBestXferMode[1] = mode;
  453. }
  454. }
  455. //
  456. // translate device ATA timing mode to piix timing mode
  457. //
  458. for (i = 0; i < MAX_IDE_DEVICE; i++) {
  459. piixSpecialTiming.AsUChar = 0;
  460. if (TransferModeSelect->DevicePresent[i] == FALSE) {
  461. piixTimingMode = PiixMode_NotPresent;
  462. } else {
  463. //
  464. // default
  465. //
  466. piixTimingMode = PiixMode_Mode0;
  467. if (!(driveBestXferMode[i] & DMA_SUPPORT)) {
  468. //
  469. // pio only device
  470. //
  471. if (driveBestXferMode[i] & PIO_MODE0) {
  472. piixTimingMode = PiixMode_Mode0;
  473. } else if (driveBestXferMode[i] & PIO_MODE2) {
  474. piixTimingMode = PiixMode_Mode2;
  475. if (TransferModeSelect->IoReadySupported[i]) {
  476. piixSpecialTiming.AsUChar |= PIIX_TIMING_IOREADY_SAMPLE_POINT_ENABLE(1);
  477. }
  478. } else if (driveBestXferMode[i] & PIO_MODE3) {
  479. piixTimingMode = PiixMode_Mode3;
  480. } else if (driveBestXferMode[i] & PIO_MODE4) {
  481. piixTimingMode = PiixMode_Mode4;
  482. } else {
  483. ASSERT(FALSE);
  484. }
  485. } else if (driveBestXferMode[i] & SWDMA_MODE2) {
  486. piixTimingMode = PiixMode_Mode2;
  487. if (driveBestXferMode[i] & PIO_MODE0) {
  488. piixSpecialTiming.AsUChar |= PIIX_TIMING_DMA_TIMING_ENABLE(1);
  489. }
  490. if (TransferModeSelect->IoReadySupported[i]) {
  491. piixSpecialTiming.AsUChar |= PIIX_TIMING_IOREADY_SAMPLE_POINT_ENABLE(1);
  492. }
  493. } else if (driveBestXferMode[i] & MWDMA_MODE1) {
  494. piixTimingMode = PiixMode_Mode3;
  495. if (driveBestXferMode[i] & (PIO_MODE0 | PIO_MODE2)) {
  496. piixSpecialTiming.AsUChar |= PIIX_TIMING_DMA_TIMING_ENABLE(1);
  497. }
  498. } else if (driveBestXferMode[i] & MWDMA_MODE2) {
  499. if (driveBestXferMode[i] & PIO_MODE3) {
  500. piixTimingMode = PiixMode_Mode3;
  501. } else {
  502. piixTimingMode = PiixMode_Mode4;
  503. }
  504. if (driveBestXferMode[i] & (PIO_MODE0 | PIO_MODE2)) {
  505. piixSpecialTiming.AsUChar |= PIIX_TIMING_DMA_TIMING_ENABLE(1);
  506. }
  507. }
  508. if (TransferModeSelect->FixedDisk[i]) {
  509. piixSpecialTiming.AsUChar |= PIIX_TIMING_PREFETCH_AND_POSTING_ENABLE(1);
  510. }
  511. }
  512. piixSpecialTiming.AsUChar |= PiixSpecialTiming[piixTimingMode].AsUChar;
  513. if (i == 0) {
  514. //
  515. // master device
  516. //
  517. piixTimingReg.b.IoReadySamplePoint = PiixIoReadySamplePointClockSetting[piixTimingMode];
  518. piixTimingReg.b.RecoveryTime = PiixRecoveryTimeClockSetting[piixTimingMode];
  519. piixTimingReg.b.n.Device0SpecialTiming = piixSpecialTiming.AsUChar & 0xf;
  520. } else {
  521. //
  522. // slave device
  523. //
  524. if (channel == 0) {
  525. piixSlaveTimingReg.b.Channel0IoReadySamplePoint = PiixIoReadySamplePointClockSetting[piixTimingMode];
  526. piixSlaveTimingReg.b.Channel0RecoveryTime = PiixRecoveryTimeClockSetting[piixTimingMode];
  527. } else {
  528. piixSlaveTimingReg.b.Channel1IoReadySamplePoint = PiixIoReadySamplePointClockSetting[piixTimingMode];
  529. piixSlaveTimingReg.b.Channel1RecoveryTime = PiixRecoveryTimeClockSetting[piixTimingMode];
  530. }
  531. piixTimingReg.b.n.Device1SpecialTiming = piixSpecialTiming.AsUChar & 0xf;
  532. }
  533. }
  534. if (!IS_PIIX(DeviceExtension->DeviceId)) {
  535. //
  536. // enable the timing setting for the slave
  537. //
  538. piixTimingReg.b.SlaveTimingEnable = 1;
  539. } else {
  540. piixSlaveTimingReg.AsUChar = 0;
  541. }
  542. //
  543. // make sure the channel is enabled
  544. //
  545. piixTimingReg.b.ChannelEnable = 1;
  546. //
  547. // setup up udma
  548. //
  549. piix4UdmaControlReg.AsUChar = 0;
  550. piix4UdmaTimingReg.AsUChar = 0;
  551. ioConfigReg.AsUShort = 0;
  552. ioConfigReg.b.WriteBufferPingPongEnable = 1;
  553. for (i = 0; i < MAX_IDE_DEVICE; i++) {
  554. if (driveBestXferMode[i] & UDMA_SUPPORT) {
  555. UCHAR udmaTiming;
  556. if (driveBestXferMode[i] & UDMA_MODE5) {
  557. udmaTiming = ICH2_UDMA_MODE5_TIMING;
  558. } else if (driveBestXferMode[i] & UDMA_MODE4) {
  559. udmaTiming = ICH_UDMA_MODE4_TIMING;
  560. } else if (driveBestXferMode[i] & UDMA_MODE3) {
  561. udmaTiming = ICH_UDMA_MODE3_TIMING;
  562. } else if (driveBestXferMode[i] & UDMA_MODE2) {
  563. udmaTiming = PIIX4_UDMA_MODE2_TIMING;
  564. } else if (driveBestXferMode[i] & UDMA_MODE1) {
  565. udmaTiming = PIIX4_UDMA_MODE1_TIMING;
  566. } else if (driveBestXferMode[i] & UDMA_MODE0) {
  567. udmaTiming = PIIX4_UDMA_MODE0_TIMING;
  568. } else {
  569. ASSERT (!"intelide: Unknown UDMA MODE\n");
  570. //
  571. // we will use udma mode 5
  572. //
  573. udmaTiming = ICH2_UDMA_MODE5_TIMING;
  574. }
  575. if (i == 0) {
  576. if (channel == 0) {
  577. //
  578. // primary master
  579. //
  580. piix4UdmaControlReg.b.Channel0Drive0UdmaEnable = 1;
  581. if (driveBestXferMode[i] & UDMA66_SUPPORT) {
  582. ioConfigReg.b.PrimaryMasterBaseClock = 1;
  583. }
  584. if (driveBestXferMode[i] & UDMA100_SUPPORT) {
  585. ioConfigReg.b.FastPrimaryMasterBaseClock = 1;
  586. }
  587. } else {
  588. //
  589. // secondary master
  590. //
  591. piix4UdmaControlReg.b.Channel1Drive0UdmaEnable = 1;
  592. if (driveBestXferMode[i] & UDMA66_SUPPORT) {
  593. ioConfigReg.b.SecondaryMasterBaseClock = 1;
  594. }
  595. if (driveBestXferMode[i] & UDMA100_SUPPORT) {
  596. ioConfigReg.b.FastSecondaryMasterBaseClock = 1;
  597. }
  598. }
  599. piix4UdmaTimingReg.b.Drive0CycleTime = udmaTiming;
  600. } else {
  601. ASSERT(i==1);
  602. if (channel == 0) {
  603. //
  604. // primary slave
  605. //
  606. piix4UdmaControlReg.b.Channel0Drive1UdmaEnable = 1;
  607. if (driveBestXferMode[i] & UDMA66_SUPPORT) {
  608. ioConfigReg.b.PrimarySlaveBaseClock = 1;
  609. }
  610. if (driveBestXferMode[i] & UDMA100_SUPPORT) {
  611. ioConfigReg.b.FastPrimarySlaveBaseClock = 1;
  612. }
  613. } else {
  614. //
  615. // secondary slave
  616. //
  617. piix4UdmaControlReg.b.Channel1Drive1UdmaEnable = 1;
  618. if (driveBestXferMode[i] & UDMA66_SUPPORT) {
  619. ioConfigReg.b.SecondarySlaveBaseClock = 1;
  620. }
  621. if (driveBestXferMode[i] & UDMA100_SUPPORT) {
  622. ioConfigReg.b.FastSecondarySlaveBaseClock = 1;
  623. }
  624. }
  625. piix4UdmaTimingReg.b.Drive1CycleTime = udmaTiming;
  626. }
  627. //
  628. // if the drive support UDMA, use UDMA
  629. // turn off other DMA mode
  630. //
  631. driveBestXferMode[i] &= ~(MWDMA_SUPPORT | SWDMA_SUPPORT);
  632. }
  633. }
  634. //
  635. // setup the return data
  636. //
  637. for (i = 0; i < MAX_IDE_DEVICE; i++) {
  638. DriveBestXferMode[i] = driveBestXferMode[i];
  639. }
  640. *PiixTimingReg = piixTimingReg;
  641. *PiixSlaveTimingReg = piixSlaveTimingReg;
  642. *Piix4UdmaControlReg = piix4UdmaControlReg;
  643. *Piix4UdmaTimingReg = piix4UdmaTimingReg;
  644. *IoConfigReg = ioConfigReg;
  645. return STATUS_SUCCESS;
  646. }