9ce765552bab5e15ae72d00068d58aeb9c33216b
[reactos.git] / drivers / storage / ide / uniata / id_dma.cpp
1 /*++
2
3 Copyright (c) 2002-2016 Alexander A. Telyatnikov (Alter)
4
5 Module Name:
6 id_dma.cpp
7
8 Abstract:
9 This is the miniport driver for ATAPI IDE controllers
10 With Busmaster DMA support
11
12 Author:
13 Alexander A. Telyatnikov (Alter)
14
15 Environment:
16 kernel mode only
17
18 Notes:
19
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 Revision History:
32
33 This module is a port from FreeBSD 4.3-6.1 ATA driver (ata-dma.c, ata-chipset.c) by
34 Søren Schmidt, Copyright (c) 1998-2008
35
36 Changed defaulting-to-generic-PIO/DMA policy
37 Added PIO settings for VIA
38 Optimized VIA/AMD/nVidia init part
39 Optimized Promise TX2 init part
40 Optimized Intel init part
41 by Alex A. Telyatnikov (Alter) (c) 2002-2007
42
43 Licence:
44 GPLv2
45
46
47 --*/
48
49 #include "stdafx.h"
50
51 static const ULONG valid_udma[7] = {0,0,2,0,4,5,6};
52
53 static const CHAR retry_Wdma[MAX_RETRIES+1] = {2, 2, 2,-1,-1,-1};
54 static const CHAR retry_Udma[MAX_RETRIES+1] = {6, 2,-1,-1,-1,-1};
55
56 PHYSICAL_ADDRESS ph4gb = {{0xFFFFFFFF, 0}};
57
58 VOID
59 NTAPI
60 cyrix_timing (
61 IN PHW_DEVICE_EXTENSION deviceExtension,
62 IN ULONG dev, // physical device number (0-3)
63 IN CHAR mode
64 );
65
66 VOID
67 NTAPI
68 promise_timing (
69 IN PHW_DEVICE_EXTENSION deviceExtension,
70 IN ULONG dev, // physical device number (0-3)
71 IN CHAR mode
72 );
73
74 VOID
75 NTAPI
76 hpt_timing (
77 IN PHW_DEVICE_EXTENSION deviceExtension,
78 IN ULONG dev, // physical device number (0-3)
79 IN CHAR mode
80 );
81
82 VOID
83 NTAPI
84 via82c_timing (
85 IN PHW_DEVICE_EXTENSION deviceExtension,
86 IN ULONG dev, // physical device number (0-3)
87 IN CHAR mode
88 );
89
90 ULONG
91 NTAPI
92 hpt_cable80(
93 IN PHW_DEVICE_EXTENSION deviceExtension,
94 IN ULONG channel // physical channel number (0-1)
95 );
96
97 ULONG
98 NTAPI
99 AtapiVirtToPhysAddr_(
100 IN PVOID HwDeviceExtension,
101 IN PSCSI_REQUEST_BLOCK Srb,
102 IN PUCHAR data,
103 OUT PULONG count, /* bytes */
104 OUT PULONG ph_addru
105 )
106 {
107 PHYSICAL_ADDRESS ph_addr;
108 ULONG addr;
109
110 *(volatile char*)data; // Touch memory, this will prevent condition of not-ready page table for valid addresses
111 // See ROS-11894 bug
112 ph_addr = MmGetPhysicalAddress(data);
113 KdPrint3((PRINT_PREFIX "AtapiVirtToPhysAddr_: %x -> %8.8x:%8.8x\n", data, ph_addr.HighPart, ph_addr.LowPart));
114 if(!ph_addru && ph_addr.HighPart) {
115 // do so until we add 64bit address support
116 // or some workaround
117 *count = 0;
118 return -1;
119 }
120
121 (*ph_addru) = ph_addr.HighPart;
122 //addr = ScsiPortConvertPhysicalAddressToUlong(ph_addr);
123 addr = ph_addr.LowPart;
124 if(!addr && !ph_addr.HighPart) {
125 *count = 0;
126 return 0;
127 }
128 if(!Srb) {
129 *count = sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES;
130 } else {
131 *count = PAGE_SIZE - (addr & (PAGE_SIZE-1));
132 }
133 return addr;
134 } // end AtapiVirtToPhysAddr_()
135
136 VOID
137 NTAPI
138 AtapiDmaAlloc(
139 IN PVOID HwDeviceExtension,
140 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
141 IN ULONG lChannel // logical channel,
142 )
143 {
144 #ifdef USE_OWN_DMA
145 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
146 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
147 ULONG c = lChannel;
148 ULONG i;
149 ULONG ph_addru;
150
151 deviceExtension->chan[c].CopyDmaBuffer = FALSE;
152
153 if(!deviceExtension->Host64 && (WinVer_Id() > WinVer_NT)) {
154 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: allocate tmp buffers below 4Gb\n"));
155 if(chan->DB_PRD) {
156 KdPrint2((PRINT_PREFIX " already initialized %x\n", chan->DB_PRD));
157 return;
158 }
159 chan->DB_PRD = MmAllocateContiguousMemory(sizeof(((PATA_REQ)NULL)->dma_tab), ph4gb);
160 if(chan->DB_PRD) {
161 chan->DB_PRD_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->DB_PRD), &i, &ph_addru);
162 if(!chan->DB_PRD_PhAddr || !i || ((LONG)(chan->DB_PRD_PhAddr) == -1)) {
163 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD BASE\n" ));
164 chan->DB_PRD = NULL;
165 chan->DB_PRD_PhAddr = 0;
166 return;
167 }
168 if(ph_addru) {
169 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD below 4Gb\n" ));
170 goto err_1;
171 }
172 }
173 chan->DB_IO = MmAllocateContiguousMemory(deviceExtension->MaximumDmaTransferLength, ph4gb);
174 if(chan->DB_IO) {
175 chan->DB_IO_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->DB_IO), &i, &ph_addru);
176 if(!chan->DB_IO_PhAddr || !i || ((LONG)(chan->DB_IO_PhAddr) == -1)) {
177 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB IO BASE\n" ));
178 err_1:
179 MmFreeContiguousMemory(chan->DB_PRD);
180 chan->DB_PRD = NULL;
181 chan->DB_PRD_PhAddr = 0;
182 chan->DB_IO = NULL;
183 chan->DB_IO_PhAddr = 0;
184 return;
185 }
186 if(ph_addru) {
187 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB IO below 4Gb\n" ));
188 MmFreeContiguousMemory(chan->DB_IO);
189 goto err_1;
190 }
191 }
192 }
193
194
195 if(deviceExtension->HwFlags & UNIATA_AHCI) {
196 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: AHCI\n" ));
197 if(chan->AhciCtlBlock) {
198 KdPrint2((PRINT_PREFIX " already initialized %x\n", chan->AhciCtlBlock));
199 return;
200 }
201 // Need 1K-byte alignment
202 chan->AhciCtlBlock0 = (PIDE_AHCI_CHANNEL_CTL_BLOCK)MmAllocateContiguousMemory(
203 sizeof(IDE_AHCI_CHANNEL_CTL_BLOCK)+AHCI_CLB_ALIGNEMENT_MASK,
204 ph4gb);
205 if(chan->AhciCtlBlock0) {
206 union {
207 PUCHAR AhciCtlBlock;
208 ULONGLONG AhciCtlBlock64;
209 };
210 AhciCtlBlock64 = 0;
211 AhciCtlBlock = (PUCHAR)chan->AhciCtlBlock0;
212
213 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: CLP BASE %I64x\n", AhciCtlBlock64));
214
215 AhciCtlBlock64 += AHCI_CLB_ALIGNEMENT_MASK;
216 AhciCtlBlock64 &= ~AHCI_CLB_ALIGNEMENT_MASK;
217
218 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: CLP BASE 1k-aligned %I64x\n", AhciCtlBlock64));
219
220 chan->AhciCtlBlock = (PIDE_AHCI_CHANNEL_CTL_BLOCK)AhciCtlBlock;
221
222 chan->AHCI_CTL_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->AhciCtlBlock), &i, &ph_addru);
223 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: CLP Phys BASE %I64x\n", chan->AHCI_CTL_PhAddr));
224 if(!chan->AHCI_CTL_PhAddr || !i || ((LONG)(chan->AHCI_CTL_PhAddr) == -1)) {
225 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No AHCI CLP BASE\n" ));
226 chan->AhciCtlBlock = NULL;
227 chan->AHCI_CTL_PhAddr = 0;
228 return;
229 }
230 if(ph_addru) {
231 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No AHCI CLP below 4Gb\n" ));
232 MmFreeContiguousMemory(chan->AhciCtlBlock0);
233 chan->AhciCtlBlock = NULL;
234 chan->AHCI_CTL_PhAddr = 0;
235 return;
236 }
237 } else {
238 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: Can't alloc AHCI CLP\n"));
239 }
240 }
241 #endif //USE_OWN_DMA
242 return;
243 } // end AtapiDmaAlloc()
244
245 BOOLEAN
246 NTAPI
247 AtapiDmaSetup(
248 IN PVOID HwDeviceExtension,
249 IN ULONG DeviceNumber,
250 IN ULONG lChannel, // logical channel,
251 IN PSCSI_REQUEST_BLOCK Srb,
252 IN PUCHAR data,
253 IN ULONG count /* bytes */
254 )
255 {
256 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
257 ULONG dma_count, dma_base, dma_baseu;
258 ULONG dma_count0, dma_base0;
259 ULONG i;
260 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
261 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
262 BOOLEAN use_DB_IO = FALSE;
263 BOOLEAN use_AHCI = (deviceExtension->HwFlags & UNIATA_AHCI) ? TRUE : FALSE;
264 ULONG orig_count = count;
265 ULONG max_entries = use_AHCI ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES;
266 //ULONG max_frag = use_AHCI ? (0x3fffff+1) : (4096); // DEBUG, replace 4096 for proper chipset-specific value
267 ULONG max_frag = deviceExtension->DmaSegmentLength;
268 ULONG seg_align = deviceExtension->DmaSegmentAlignmentMask;
269
270 if(AtaReq->dma_entries) {
271 AtaReq->Flags |= REQ_FLAG_DMA_OPERATION;
272 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: already setup, %d entries\n", AtaReq->dma_entries));
273 return TRUE;
274 }
275 AtaReq->ata.dma_base = 0;
276 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
277
278 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: mode %#x, data %x, count %x, lCh %x, dev %x\n",
279 chan->lun[DeviceNumber]->TransferMode,
280 data, count, lChannel, DeviceNumber ));
281 if(chan->lun[DeviceNumber]->TransferMode < ATA_DMA) {
282 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: Not DMA mode, assume this is just preparation\n" ));
283 //return FALSE;
284 }
285 //KdPrint2((PRINT_PREFIX " checkpoint 1\n" ));
286 if(!count) {
287 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: count=0\n" ));
288 return FALSE;
289 }
290 //KdPrint2((PRINT_PREFIX " checkpoint 2\n" ));
291 if(count > deviceExtension->MaximumDmaTransferLength) {
292 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: deviceExtension->MaximumDmaTransferLength > count\n" ));
293 return FALSE;
294 }
295 //KdPrint2((PRINT_PREFIX " checkpoint 3\n" ));
296 #ifdef __REACTOS__
297 if((ULONG_PTR)data & deviceExtension->AlignmentMask) {
298 #else
299 if((ULONG)data & deviceExtension->AlignmentMask) {
300 #endif
301 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: unaligned data: %#x (%#x)\n", data, deviceExtension->AlignmentMask));
302 return FALSE;
303 }
304
305 //KdPrint2((PRINT_PREFIX " checkpoint 4\n" ));
306 if(use_AHCI) {
307 KdPrint2((PRINT_PREFIX " get Phys(AHCI_CMD=%x)\n", AtaReq->ahci.ahci_cmd_ptr ));
308 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(AtaReq->ahci.ahci_cmd_ptr), &i, &dma_baseu);
309 AtaReq->ahci.ahci_base64 = 0; // clear before setup
310 } else {
311 KdPrint2((PRINT_PREFIX " get Phys(PRD=%x)\n", &(AtaReq->dma_tab) ));
312 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)&(AtaReq->dma_tab) /*chan->dma_tab*/, &i, &dma_baseu);
313 }
314 if(dma_baseu && i) {
315 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: SRB built-in PRD above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base));
316 if(!deviceExtension->Host64) {
317 dma_base = chan->DB_PRD_PhAddr;
318 AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD;
319 i = 1;
320 }
321 } else
322 if(!dma_base || !i || ((LONG)(dma_base) == -1)) {
323 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No BASE\n" ));
324 return FALSE;
325 }
326 AtaReq->ata.dma_base = dma_base; // aliased to AtaReq->ahci.ahci_base64
327
328 KdPrint2((PRINT_PREFIX " get Phys(data[0]=%x)\n", data ));
329 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu);
330 if(dma_baseu && dma_count) {
331 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: 1st block of buffer above 4Gb: %8.8x%8.8x cnt=%x\n", dma_baseu, dma_base, dma_count));
332 if(!deviceExtension->Host64) {
333 retry_DB_IO:
334 use_DB_IO = TRUE;
335 dma_base = chan->DB_IO_PhAddr;
336 data = (PUCHAR)(chan->DB_IO);
337 } else {
338 AtaReq->ahci.ahci_base64 = (ULONGLONG)dma_base | ((ULONGLONG)dma_baseu << 32);
339 }
340 } else
341 if(!dma_count || ((LONG)(dma_base) == -1)) {
342 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No 1st block\n" ));
343 //AtaReq->dma_base = NULL;
344 AtaReq->ahci.ahci_base64 = NULL;
345 return FALSE;
346 }
347
348 #ifdef __REACTOS__
349 dma_count = min(count, (PAGE_SIZE - ((ULONG_PTR)data & PAGE_MASK)));
350 #else
351 dma_count = min(count, (PAGE_SIZE - ((ULONG)data & PAGE_MASK)));
352 #endif
353 data += dma_count;
354 count -= dma_count;
355 i = 0;
356
357 dma_count0 = dma_count;
358 dma_base0 = dma_base;
359
360 while (count) {
361 /* KdPrint2((PRINT_PREFIX " segments %#x+%#x == %#x && %#x+%#x <= %#x\n",
362 dma_base0, dma_count0, dma_base,
363 dma_count0, dma_count, max_frag));*/
364 if(dma_base0+dma_count0 == dma_base &&
365 dma_count0+dma_count <= max_frag) {
366 // 'i' should be always > 0 here
367 // for BM we cannot cross 64k boundary
368 if(dma_base & seg_align) {
369 //KdPrint2((PRINT_PREFIX " merge segments\n" ));
370 ASSERT(i);
371 //BrutePoint();
372 i--;
373 dma_base = dma_base0;
374 dma_count += dma_count0;
375 }
376 }
377 if(use_AHCI) {
378 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].base = dma_base;
379 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].baseu = dma_baseu;
380 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved1 = 0;
381 *((PULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC_ULONG)) = ((dma_count-1) & 0x3fffff);
382 /* AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved2 = 0;
383 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].I = 0;*/
384 KdPrint2((PRINT_PREFIX " ph data[%d]=%x:%x (%x)\n", i, dma_baseu, dma_base, AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC));
385 } else {
386 AtaReq->dma_tab[i].base = dma_base;
387 AtaReq->dma_tab[i].count = (dma_count & 0xffff);
388 }
389 dma_count0 = dma_count;
390 dma_base0 = dma_base;
391 i++;
392 if (i >= max_entries) {
393 KdPrint2((PRINT_PREFIX "too many segments in DMA table\n" ));
394 //AtaReq->dma_base = NULL;
395 AtaReq->ahci.ahci_base64 = NULL;
396 return FALSE;
397 }
398 KdPrint2((PRINT_PREFIX " get Phys(data[n=%d+%x]=%x)\n", i, dma_count0, data ));
399 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu);
400 if(dma_baseu && dma_count) {
401 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: block of buffer above 4Gb: %8.8x%8.8x, cnt=%x\n", dma_baseu, dma_base, dma_count));
402 if(!deviceExtension->Host64) {
403 if(use_DB_IO) {
404 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: *ERROR* special buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base));
405 return FALSE;
406 }
407 count = orig_count;
408 goto retry_DB_IO;
409 }
410 } else
411 if(!dma_count || !dma_base || ((LONG)(dma_base) == -1)) {
412 //AtaReq->dma_base = NULL;
413 AtaReq->ahci.ahci_base64 = 0;
414 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No NEXT block\n" ));
415 return FALSE;
416 }
417
418 dma_count = min(count, PAGE_SIZE);
419 data += min(count, PAGE_SIZE);
420 count -= min(count, PAGE_SIZE);
421 }
422 KdPrint2((PRINT_PREFIX " set TERM\n" ));
423 /* KdPrint2((PRINT_PREFIX " segments %#x+%#x == %#x && #x+%#x <= %#x\n",
424 dma_base0, dma_count0, dma_base,
425 dma_count0, dma_count, max_frag));*/
426 if(dma_base0+dma_count0 == dma_base &&
427 dma_count0+dma_count <= max_frag) {
428 // 'i' should be always > 0 here
429 if(dma_base & seg_align) {
430 //KdPrint2((PRINT_PREFIX " merge segments\n" ));
431 //BrutePoint();
432 ASSERT(i);
433 i--;
434 dma_base = dma_base0;
435 dma_count += dma_count0;
436 }
437 }
438 if(use_AHCI) {
439 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].base = dma_base;
440 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].baseu = dma_baseu;
441 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved1 = 0;
442 //AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC = ((dma_count-1) & 0x3fffff);
443 //AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved2 = 0;
444 *((PULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC_ULONG)) = ((dma_count-1) & 0x3fffff);
445 //AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].I = 1; // interrupt when ready
446 KdPrint2((PRINT_PREFIX " ph data[%d]=%x:%x (%x)\n", i, dma_baseu, dma_base, AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC));
447 #ifdef __REACTOS__
448 if(((ULONG_PTR)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab) & ~PAGE_MASK) != ((ULONG_PTR)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i]) & ~PAGE_MASK)) {
449 #else
450 if(((ULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab) & ~PAGE_MASK) != ((ULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i]) & ~PAGE_MASK)) {
451 #endif
452 KdPrint2((PRINT_PREFIX "PRD table crosses page boundary! %x vs %x\n",
453 &AtaReq->ahci.ahci_cmd_ptr->prd_tab, &(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i]) ));
454 //AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD;
455 }
456 } else {
457 AtaReq->dma_tab[i].base = dma_base;
458 AtaReq->dma_tab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT;
459 #ifdef __REACTOS__
460 if(((ULONG_PTR)&(AtaReq->dma_tab) & ~PAGE_MASK) != ((ULONG_PTR)&(AtaReq->dma_tab[i]) & ~PAGE_MASK)) {
461 #else
462 if(((ULONG)&(AtaReq->dma_tab) & ~PAGE_MASK) != ((ULONG)&(AtaReq->dma_tab[i]) & ~PAGE_MASK)) {
463 #endif
464 KdPrint2((PRINT_PREFIX "DMA table crosses page boundary! %x vs %x\n",
465 &AtaReq->dma_tab, &(AtaReq->dma_tab[i]) ));
466 //AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD;
467 }
468 }
469 AtaReq->dma_entries = i+1;
470
471 if(use_DB_IO) {
472 AtaReq->Flags |= REQ_FLAG_DMA_DBUF;
473 }
474 AtaReq->Flags |= REQ_FLAG_DMA_OPERATION;
475
476 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: OK\n" ));
477 return TRUE;
478
479 } // end AtapiDmaSetup()
480
481 BOOLEAN
482 NTAPI
483 AtapiDmaPioSync(
484 PVOID HwDeviceExtension,
485 PSCSI_REQUEST_BLOCK Srb,
486 PUCHAR data,
487 ULONG count
488 )
489 {
490 #ifndef USE_OWN_DMA
491 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
492 ULONG dma_base;
493 PUCHAR DmaBuffer;
494 ULONG dma_count;
495 ULONG len;
496 PATA_REQ AtaReq;
497
498 // This must never be called after DMA operation !!!
499 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: data %#x, len %#x\n", data, count));
500
501 if(!Srb) {
502 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !Srb\n" ));
503 return FALSE;
504 }
505
506 AtaReq = (PATA_REQ)(Srb->SrbExtension);
507
508 // do nothing on PCI (This can be changed. We cannot guarantee,
509 // that CommonBuffer will always point to User's buffer,
510 // however, this usually happens on PCI-32)
511 if(deviceExtension->OrigAdapterInterfaceType == PCIBus) {
512 return TRUE;
513 }
514 // do nothing for DMA
515 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
516 return TRUE;
517 }
518
519 if(!data) {
520 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !data\n" ));
521 return FALSE;
522 }
523
524 while(count) {
525 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count);
526 if(!dma_base) {
527 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !dma_base for data %#x\n", data));
528 return FALSE;
529 }
530 DmaBuffer = (PUCHAR)ScsiPortGetVirtualAddress(HwDeviceExtension,
531 ScsiPortConvertUlongToPhysicalAddress(dma_base));
532 if(!DmaBuffer) {
533 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !DmaBuffer for dma_base %#x\n", dma_base));
534 return FALSE;
535 }
536 len = min(dma_count, count);
537 memcpy(DmaBuffer, data, len);
538 count -= len;
539 data += len;
540 }
541 #endif //USE_OWN_DMA
542
543 return TRUE;
544 } // end AtapiDmaPioSync()
545
546 BOOLEAN
547 NTAPI
548 AtapiDmaDBSync(
549 PHW_CHANNEL chan,
550 PSCSI_REQUEST_BLOCK Srb
551 )
552 {
553 PATA_REQ AtaReq;
554
555 AtaReq = (PATA_REQ)(Srb->SrbExtension);
556 if((Srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
557 (AtaReq->Flags & REQ_FLAG_DMA_DBUF)) {
558 KdPrint2((PRINT_PREFIX " AtapiDmaDBSync is issued.\n"));
559 ASSERT(FALSE);
560 KdPrint2((PRINT_PREFIX " DBUF (Read)\n"));
561 RtlCopyMemory(AtaReq->DataBuffer, chan->DB_IO,
562 Srb->DataTransferLength);
563 }
564 return TRUE;
565 } // end AtapiDmaDBSync()
566
567 BOOLEAN
568 NTAPI
569 AtapiDmaDBPreSync(
570 IN PVOID HwDeviceExtension,
571 PHW_CHANNEL chan,
572 PSCSI_REQUEST_BLOCK Srb
573 )
574 {
575 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
576 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
577
578 if(!AtaReq->ata.dma_base) {
579 KdPrint2((PRINT_PREFIX "AtapiDmaDBPreSync: *** !AtaReq->ata.dma_base\n"));
580 return FALSE;
581 }
582 // GetStatus(chan, statusByte2);
583 if(AtaReq->Flags & REQ_FLAG_DMA_DBUF_PRD) {
584 KdPrint2((PRINT_PREFIX " DBUF_PRD\n"));
585 ASSERT(FALSE);
586 if(deviceExtension->HwFlags & UNIATA_AHCI) {
587 RtlCopyMemory(chan->DB_PRD, AtaReq->ahci.ahci_cmd_ptr, sizeof(AtaReq->ahci_cmd0));
588 } else {
589 RtlCopyMemory(chan->DB_PRD, &(AtaReq->dma_tab), sizeof(AtaReq->dma_tab));
590 }
591 }
592 if(!(Srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
593 (AtaReq->Flags & REQ_FLAG_DMA_DBUF)) {
594 KdPrint2((PRINT_PREFIX " DBUF (Write)\n"));
595 ASSERT(FALSE);
596 RtlCopyMemory(chan->DB_IO, AtaReq->DataBuffer,
597 Srb->DataTransferLength);
598 }
599 return TRUE;
600 } // end AtapiDmaDBPreSync()
601
602 VOID
603 NTAPI
604 AtapiDmaStart(
605 IN PVOID HwDeviceExtension,
606 IN ULONG DeviceNumber,
607 IN ULONG lChannel, // logical channel,
608 IN PSCSI_REQUEST_BLOCK Srb
609 )
610 {
611 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
612 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM = deviceExtension->BaseIoAddressBM[lChannel];
613 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
614 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
615
616 ULONG VendorID = deviceExtension->DevID & 0xffff;
617 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
618 // UCHAR statusByte2;
619 /*
620 GetStatus(chan, statusByte2);
621 KdPrint2((PRINT_PREFIX "AtapiDmaStart: %s on %#x:%#x\n",
622 (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "read" : "write",
623 lChannel, DeviceNumber ));
624 */
625 if(!AtaReq->ata.dma_base) {
626 KdPrint2((PRINT_PREFIX "AtapiDmaStart: *** !AtaReq->ata.dma_base\n"));
627 return;
628 }
629 KdPrint2((PRINT_PREFIX "AtapiDmaStart: lchan=%d\n", lChannel));
630
631 /*
632 // GetStatus(chan, statusByte2);
633 if(AtaReq->Flags & REQ_FLAG_DMA_DBUF_PRD) {
634 KdPrint2((PRINT_PREFIX " DBUF_PRD\n"));
635 ASSERT(FALSE);
636 if(deviceExtension->HwFlags & UNIATA_AHCI) {
637 RtlCopyMemory(chan->DB_PRD, AtaReq->ahci.ahci_cmd_ptr, sizeof(AtaReq->ahci_cmd0));
638 } else {
639 RtlCopyMemory(chan->DB_PRD, &(AtaReq->dma_tab), sizeof(AtaReq->dma_tab));
640 }
641 }
642 if(!(Srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
643 (AtaReq->Flags & REQ_FLAG_DMA_DBUF)) {
644 KdPrint2((PRINT_PREFIX " DBUF (Write)\n"));
645 ASSERT(FALSE);
646 RtlCopyMemory(chan->DB_IO, AtaReq->DataBuffer,
647 Srb->DataTransferLength);
648 }
649 */
650 // set flag
651 chan->ChannelCtrlFlags |= CTRFLAGS_DMA_ACTIVE;
652
653 switch(VendorID) {
654 case ATA_PROMISE_ID:
655 if(ChipType == PRNEW) {
656 ULONG Channel = deviceExtension->Channel + lChannel;
657
658 if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) {
659 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(Channel ? 0x24 : 0x20),
660 ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x05000000 : 0x06000000) | (Srb->DataTransferLength >> 1)
661 );
662 }
663 /*
664 } else
665 if(deviceExtension->MemIo) {
666 // begin transaction
667 AtapiWritePort4(chan,
668 IDX_BM_Command,
669 (AtapiReadPort4(chan,
670 IDX_BM_Command) & ~0x000000c0) |
671 ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x00000080 : 0x000000c0) );
672 return;
673 */
674 }
675 break;
676 }
677
678 // set pointer to Pointer Table
679 AtapiWritePort4(chan, IDX_BM_PRD_Table,
680 AtaReq->ata.dma_base
681 );
682 // set transfer direction
683 AtapiWritePort1(chan, IDX_BM_Command,
684 (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? BM_COMMAND_READ : BM_COMMAND_WRITE);
685 // clear Error & Intr bits (writeing 1 clears bits)
686 // set DMA capability bit
687 AtapiWritePort1(chan, IDX_BM_Status,
688 AtapiReadPort1(chan, IDX_BM_Status) |
689 (BM_STATUS_INTR | BM_STATUS_ERR) /*|
690 (DeviceNumber ? BM_STATUS_DRIVE_1_DMA : BM_STATUS_DRIVE_0_DMA)*/);
691 // begin transaction
692 AtapiWritePort1(chan, IDX_BM_Command,
693 AtapiReadPort1(chan, IDX_BM_Command) |
694 BM_COMMAND_START_STOP);
695 return;
696
697 } // end AtapiDmaStart()
698
699 UCHAR
700 NTAPI
701 AtapiDmaDone(
702 IN PVOID HwDeviceExtension,
703 IN ULONG DeviceNumber,
704 IN ULONG lChannel, // logical channel,
705 IN PSCSI_REQUEST_BLOCK Srb
706 )
707 {
708 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
709 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM = deviceExtension->BaseIoAddressBM[lChannel];
710 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
711 UCHAR dma_status;
712
713 ULONG VendorID = deviceExtension->DevID & 0xffff;
714 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
715
716 KdPrint2((PRINT_PREFIX "AtapiDmaDone: dev %d\n", DeviceNumber));
717
718 if(deviceExtension->HwFlags & UNIATA_AHCI) {
719 KdPrint2((PRINT_PREFIX " ACHTUNG! should not be called for AHCI!\n"));
720 return IDE_STATUS_WRONG;
721 }
722
723 switch(VendorID) {
724 case ATA_PROMISE_ID:
725 if(ChipType == PRNEW) {
726 ULONG Channel = deviceExtension->Channel + lChannel;
727 /*
728 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
729 AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) &
730 ~(Channel ? 0x08 : 0x02));
731 */
732 if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) {
733 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(Channel ? 0x24 : 0x20),
734 0
735 );
736 }
737 /*
738 } else
739 if(deviceExtension->MemIo) {
740 // end transaction
741 AtapiWritePort4(chan,
742 IDX_BM_Command,
743 (AtapiReadPort4(chan,
744 IDX_BM_Command) & ~0x00000080) );
745 // clear flag
746 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_ACTIVE;
747 return 0;
748 */
749 }
750 break;
751 }
752
753 // get status
754 dma_status = AtapiReadPort1(chan, IDX_BM_Status) & BM_STATUS_MASK;
755 // end transaction
756 AtapiWritePort1(chan, IDX_BM_Command,
757 AtapiReadPort1(chan, IDX_BM_Command) &
758 ~BM_COMMAND_START_STOP);
759 // clear interrupt and error status
760 AtapiWritePort1(chan, IDX_BM_Status, BM_STATUS_ERR | BM_STATUS_INTR);
761 // clear flag
762 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_ACTIVE;
763
764 return dma_status;
765
766 } // end AtapiDmaDone()
767
768 VOID
769 NTAPI
770 AtapiDmaReinit(
771 IN PHW_DEVICE_EXTENSION deviceExtension,
772 IN PHW_LU_EXTENSION LunExt,
773 IN PATA_REQ AtaReq
774 )
775 {
776 SCHAR apiomode;
777
778 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
779 !(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
780 // skip unnecessary checks
781 KdPrint2((PRINT_PREFIX "AtapiDmaReinit: ahci, nothing to do for HDD\n"));
782 return;
783 }
784
785 apiomode = (CHAR)AtaPioMode(&(LunExt->IdentifyData));
786
787 if(!(AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) {
788 KdPrint2((PRINT_PREFIX
789 "AtapiDmaReinit: !(AtaReq->Flags & REQ_FLAG_DMA_OPERATION), fall to PIO on Device %d\n", LunExt->Lun));
790 goto limit_pio;
791 }
792 if(deviceExtension->HwFlags & UNIATA_AHCI) {
793 if(!AtaReq->ahci.ahci_base64) {
794 KdPrint2((PRINT_PREFIX
795 "AtapiDmaReinit: no AHCI PRD, fatal on Device %d\n", LunExt->Lun));
796 goto exit;
797 }
798 } else
799 if(!AtaReq->ata.dma_base) {
800 KdPrint2((PRINT_PREFIX
801 "AtapiDmaReinit: no PRD, fall to PIO on Device %d\n", LunExt->Lun));
802 goto limit_pio;
803 }
804
805 if((deviceExtension->HbaCtrlFlags & HBAFLAGS_DMA_DISABLED_LBA48) &&
806 (AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) &&
807 (LunExt->TransferMode > ATA_PIO5) ) {
808 KdPrint2((PRINT_PREFIX
809 "AtapiDmaReinit: FORCE_DOWNRATE on Device %d for LBA48\n", LunExt->Lun));
810 goto limit_lba48;
811 }
812
813
814 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
815 KdPrint2((PRINT_PREFIX
816 "AtapiDmaReinit: FORCE_DOWNRATE on Device %d\n", LunExt->Lun));
817 if(AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) {
818 limit_lba48:
819 LunExt->DeviceFlags |= REQ_FLAG_FORCE_DOWNRATE_LBA48;
820 limit_pio:
821 // do not make extra work if we already use PIO
822 if(/*LunExt->TransferMode >= ATA_DMA*/
823 (LunExt->TransferMode > ATA_PIO5) && (LunExt->TransferMode != ATA_PIO0+apiomode)
824 ) {
825 KdPrint2((PRINT_PREFIX
826 "AtapiDmaReinit: set PIO mode on Device %d (%x -> %x)\n", LunExt->Lun, LunExt->TransferMode, ATA_PIO0+apiomode));
827 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel,
828 apiomode,
829 -1,
830 -1 );
831 } else
832 if(LunExt->LimitedTransferMode < LunExt->TransferMode) {
833 KdPrint2((PRINT_PREFIX
834 "AtapiDmaReinit: set PIO mode on Device %d (%x -> %x) (2)\n", LunExt->Lun, LunExt->TransferMode, LunExt->LimitedTransferMode));
835 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel,
836 LunExt->LimitedTransferMode-ATA_PIO0,
837 -1,
838 -1 );
839 }
840
841 } else {
842 KdPrint2((PRINT_PREFIX
843 "AtapiDmaReinit: set MAX mode on Device %d\n", LunExt->Lun));
844 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel,
845 apiomode,
846 min( retry_Wdma[AtaReq->retry],
847 (CHAR)AtaWmode(&(LunExt->IdentifyData)) ),
848 min( retry_Udma[AtaReq->retry],
849 (CHAR)AtaUmode(&(LunExt->IdentifyData)) ) );
850 }
851 // LunExt->DeviceFlags &= ~DFLAGS_FORCE_DOWNRATE;
852 } else
853 if(/*!(LunExt->DeviceFlags & DFLAGS_FORCE_DOWNRATE) &&*/
854 (LunExt->LimitedTransferMode >
855 LunExt->TransferMode) ||
856 (LunExt->DeviceFlags & DFLAGS_REINIT_DMA) ||
857 ((deviceExtension->HwFlags & UNIATA_CHAN_TIMINGS) && ((ULONG)LunExt->Lun != LunExt->chan->last_cdev))) {
858 // restore IO mode
859 KdPrint2((PRINT_PREFIX
860 "AtapiDmaReinit: restore IO mode on Device %d, last dev %d\n", LunExt->Lun, LunExt->chan->last_cdev));
861 AtapiDmaInit__(deviceExtension, LunExt);
862 } else {
863 KdPrint2((PRINT_PREFIX
864 "AtapiDmaReinit: LimitedTransferMode == TransferMode = %x (%x), Device %d, last dev %d\n", LunExt->TransferMode, LunExt->DeviceFlags, LunExt->Lun, LunExt->chan->last_cdev));
865 }
866
867 exit:
868 return;
869 } // end AtapiDmaReinit()
870
871 VOID
872 NTAPI
873 AtapiDmaInit__(
874 IN PHW_DEVICE_EXTENSION deviceExtension,
875 IN PHW_LU_EXTENSION LunExt
876 )
877 {
878 if(LunExt->IdentifyData.SupportDma ||
879 (LunExt->IdentifyData.AtapiDMA.DMASupport && (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE))) {
880 KdPrint2((PRINT_PREFIX
881 "AtapiDmaInit__: Set (U)DMA on Device %d\n", LunExt->Lun));
882 /* for(i=AtaUmode(&(LunExt->IdentifyData)); i>=0; i--) {
883 AtapiDmaInit(deviceExtension, ldev & 1, ldev >> 1,
884 (CHAR)AtaPioMode(&(LunExt->IdentifyData)),
885 (CHAR)AtaWmode(&(LunExt->IdentifyData)),
886 UDMA_MODE0+(CHAR)i );
887 }
888 for(i=AtaWmode(&(LunExt->IdentifyData)); i>=0; i--) {
889 AtapiDmaInit(deviceExtension, ldev & 1, ldev >> 1,
890 (CHAR)AtaPioMode(&(LunExt->IdentifyData)),
891 (CHAR)AtaWmode(&(LunExt->IdentifyData)),
892 UDMA_MODE0+(CHAR)i );
893 }*/
894 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel,
895 (CHAR)AtaPioMode(&(LunExt->IdentifyData)),
896 (CHAR)AtaWmode(&(LunExt->IdentifyData)),
897 (CHAR)AtaUmode(&(LunExt->IdentifyData)) );
898 } else {
899 KdPrint2((PRINT_PREFIX
900 "AtapiDmaInit__: Set PIO on Device %d\n", LunExt->Lun));
901 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel,
902 (CHAR)AtaPioMode(&(LunExt->IdentifyData)), -1, -1);
903 }
904 } // end AtapiDmaInit__()
905
906 BOOLEAN
907 NTAPI
908 AtaSetTransferMode(
909 IN PHW_DEVICE_EXTENSION deviceExtension,
910 IN ULONG DeviceNumber,
911 IN ULONG lChannel, // logical channel,
912 IN PHW_LU_EXTENSION LunExt,
913 IN ULONG mode
914 )
915 {
916 KdPrint3((PRINT_PREFIX
917 "AtaSetTransferMode: Set %#x on Device %d/%d\n", mode, lChannel, DeviceNumber));
918 LONG statusByte = 0;
919 CHAR apiomode;
920 BOOLEAN disable_intr = (deviceExtension->HwFlags & UNIATA_AHCI) || (CPU_num>1);
921 /*
922 if(deviceExtension->HwFlags & UNIATA_SATA) {
923 // experimental do nothing, see ROS BUG-9119, v0.46a1
924 statusByte = IDE_STATUS_IDLE;
925 } else */
926 if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
927 statusByte = mode <= ATA_PIO2 ? IDE_STATUS_IDLE : IDE_STATUS_ERROR;
928 } else {
929 UCHAR umode;
930 if(disable_intr) {
931 AtapiDisableInterrupts(deviceExtension, lChannel);
932 }
933 if(mode > ATA_UDMA6) {
934 // for SATA, it doesn't have option to set transfer rate
935 // We need this just to switch between PIO and DMA modes
936 // Devices may support only some lower transfer rates (e.g. UDMA0-4)
937 umode = min((UCHAR)AtaUmode(&(LunExt->IdentifyData)), 6);
938 umode += ATA_UDMA0;
939 } else {
940 umode = (UCHAR)mode;
941 }
942 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
943 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
944 (UCHAR)umode, ATA_C_F_SETXFER, ATA_WAIT_BASE_READY);
945 if(disable_intr) {
946 AtapiEnableInterrupts(deviceExtension, lChannel);
947 }
948 }
949 if(statusByte & IDE_STATUS_ERROR) {
950 KdPrint3((PRINT_PREFIX " wait ready after error\n"));
951 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
952 AtapiStallExecution(10);
953 } else {
954 AtapiStallExecution(100);
955 }
956 apiomode = (CHAR)AtaPioMode(&(LunExt->IdentifyData));
957 if( (apiomode > 0) &&
958 ((CHAR)AtaWmode(&(LunExt->IdentifyData)) > 0) &&
959 ((CHAR)AtaUmode(&(LunExt->IdentifyData)) > 0)
960 ) {
961 return FALSE;
962 }
963 if(mode > ATA_PIO2) {
964 return FALSE;
965 }
966 KdPrint3((PRINT_PREFIX " assume that drive doesn't support mode swithing using PIO%d\n", apiomode));
967 mode = ATA_PIO0 + apiomode;
968 }
969 // SATA sets actual transfer rate in LunExt on init.
970 // There is no run-time SATA rate adjustment yet.
971 // On the other hand, we may turn SATA device in PIO mode
972 LunExt->TransferMode = (UCHAR)mode;
973 if(deviceExtension->HwFlags & UNIATA_SATA) {
974 if(mode < ATA_SA150) {
975 LunExt->PhyTransferMode = max(LunExt->PhyTransferMode, LunExt->TransferMode);
976 } else {
977 LunExt->PhyTransferMode = LunExt->TransferMode;
978 }
979 } else {
980 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
981 LunExt->PhyTransferMode = max(LunExt->LimitedTransferMode, LunExt->TransferMode);
982 } else {
983 LunExt->PhyTransferMode = LunExt->TransferMode;
984 }
985 }
986 return TRUE;
987 } // end AtaSetTransferMode()
988
989 VOID
990 NTAPI
991 AtapiDmaInit(
992 IN PVOID HwDeviceExtension,
993 IN ULONG DeviceNumber,
994 IN ULONG lChannel, // logical channel,
995 // is always 0 except simplex-only controllers
996 IN SCHAR apiomode,
997 IN SCHAR wdmamode,
998 IN SCHAR udmamode
999 )
1000 {
1001 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1002 ULONG Channel = deviceExtension->Channel + lChannel;
1003 PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
1004 //LONG statusByte = 0;
1005 ULONG dev = Channel*2 + DeviceNumber; // for non-SATA/AHCI only!
1006 //ULONG ldev = lChannel*2 + DeviceNumber; // for non-SATA/AHCI only!
1007 BOOLEAN isAtapi = ATAPI_DEVICE(chan, DeviceNumber);
1008 ULONG slotNumber = deviceExtension->slotNumber;
1009 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1010 LONG i;
1011 PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
1012 UCHAR ModeByte;
1013
1014 ULONG VendorID = deviceExtension->DevID & 0xffff;
1015 //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
1016 //ULONG RevID = deviceExtension->RevID;
1017 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1018 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
1019
1020 LONG statusByte = 0;
1021
1022 //UCHAR *reg_val = NULL;
1023
1024 LunExt->DeviceFlags &= ~DFLAGS_REINIT_DMA;
1025 /* set our most pessimistic default mode */
1026 LunExt->TransferMode = ATA_PIO;
1027 // if(!deviceExtension->BaseIoAddressBM[lChannel]) {
1028 if(!deviceExtension->BusMaster) {
1029 KdPrint2((PRINT_PREFIX " !deviceExtension->BusMaster: NO DMA\n"));
1030 wdmamode = udmamode = -1;
1031 }
1032
1033 // Limit transfer mode (controller limitation)
1034 if((LONG)chan->MaxTransferMode >= ATA_UDMA) {
1035 KdPrint2((PRINT_PREFIX "AtapiDmaInit: chan->MaxTransferMode >= ATA_UDMA\n"));
1036 udmamode = min( udmamode, (CHAR)(chan->MaxTransferMode - ATA_UDMA));
1037 } else
1038 if((LONG)chan->MaxTransferMode >= ATA_WDMA) {
1039 KdPrint2((PRINT_PREFIX "AtapiDmaInit: chan->MaxTransferMode >= ATA_WDMA\n"));
1040 udmamode = -1;
1041 wdmamode = min( wdmamode, (CHAR)(chan->MaxTransferMode - ATA_WDMA));
1042 } else
1043 if((LONG)chan->MaxTransferMode >= ATA_PIO0) {
1044 KdPrint2((PRINT_PREFIX "AtapiDmaInit: NO DMA\n"));
1045 wdmamode = udmamode = -1;
1046 apiomode = min( apiomode, (CHAR)(chan->MaxTransferMode - ATA_PIO0));
1047 } else {
1048 KdPrint2((PRINT_PREFIX "AtapiDmaInit: PIO0\n"));
1049 wdmamode = udmamode = -1;
1050 apiomode = 0;
1051 }
1052 // Limit transfer mode (device limitation)
1053 KdPrint2((PRINT_PREFIX "AtapiDmaInit: LunExt->LimitedTransferMode %#x\n", LunExt->LimitedTransferMode));
1054 if((LONG)LunExt->LimitedTransferMode >= ATA_UDMA) {
1055 KdPrint2((PRINT_PREFIX "AtapiDmaInit: LunExt->MaxTransferMode >= ATA_UDMA => %#x\n",
1056 min( udmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_UDMA))
1057 ));
1058 udmamode = min( udmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_UDMA));
1059 } else
1060 if((LONG)LunExt->LimitedTransferMode >= ATA_WDMA) {
1061 KdPrint2((PRINT_PREFIX "AtapiDmaInit: LunExt->MaxTransferMode >= ATA_WDMA => %#x\n",
1062 min( wdmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_WDMA))
1063 ));
1064 udmamode = -1;
1065 wdmamode = min( wdmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_WDMA));
1066 } else
1067 if((LONG)LunExt->LimitedTransferMode >= ATA_PIO0) {
1068 KdPrint2((PRINT_PREFIX "AtapiDmaInit: lun NO DMA\n"));
1069 wdmamode = udmamode = -1;
1070 apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0));
1071 } else {
1072 KdPrint2((PRINT_PREFIX "AtapiDmaInit: lun PIO0\n"));
1073 wdmamode = udmamode = -1;
1074 apiomode = 0;
1075 }
1076
1077 //if(!(ChipFlags & UNIATA_AHCI)) {
1078
1079 // this is necessary for future PM support
1080 SelectDrive(chan, DeviceNumber);
1081 GetStatus(chan, statusByte);
1082 // we can see here IDE_STATUS_ERROR status after previous operation
1083 if(statusByte & IDE_STATUS_ERROR) {
1084 KdPrint2((PRINT_PREFIX "IDE_STATUS_ERROR detected on entry, statusByte = %#x\n", statusByte));
1085 //GetBaseStatus(chan, statusByte);
1086 }
1087 if(statusByte && UniataIsIdle(deviceExtension, statusByte & ~IDE_STATUS_ERROR) != IDE_STATUS_IDLE) {
1088 KdPrint2((PRINT_PREFIX "Can't setup transfer mode: statusByte = %#x\n", statusByte));
1089 return;
1090 }
1091 //}
1092
1093 chan->last_cdev = DeviceNumber;
1094 if(UniataIsSATARangeAvailable(deviceExtension, lChannel) ||
1095 (ChipFlags & UNIATA_AHCI) || (chan->MaxTransferMode >= ATA_SA150)
1096 ) {
1097 //if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI)) {
1098 /****************/
1099 /* SATA Generic */
1100 /****************/
1101
1102 KdPrint2((PRINT_PREFIX "SATA Generic\n"));
1103
1104 if((udmamode >= 5) || (ChipFlags & UNIATA_AHCI) || ((udmamode >= 0) && (chan->MaxTransferMode >= ATA_SA150))) {
1105 /* some drives report UDMA6, some UDMA5 */
1106 /* ATAPI may not have SataCapabilities set in IDENTIFY DATA */
1107 if(ata_is_sata(&(LunExt->IdentifyData))) {
1108 //udmamode = min(udmamode, 6);
1109 KdPrint2((PRINT_PREFIX "LunExt->LimitedTransferMode %x, LunExt->OrigTransferMode %x\n",
1110 LunExt->LimitedTransferMode, LunExt->OrigTransferMode));
1111 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode))) {
1112 return;
1113 }
1114 udmamode = min(udmamode, 6);
1115
1116 } else {
1117 KdPrint2((PRINT_PREFIX "SATA -> PATA adapter ?\n"));
1118 if (udmamode > 2 && (!LunExt->IdentifyData.HwResCableId && (LunExt->IdentifyData.HwResValid == IDENTIFY_CABLE_ID_VALID) )) {
1119 KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n"));
1120 udmamode = 2;
1121 apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0));
1122 } else {
1123 udmamode = min(udmamode, 6);
1124 }
1125 }
1126 }
1127 if(udmamode >= 0) {
1128 ModeByte = ATA_UDMA0 + udmamode;
1129 } else
1130 if(wdmamode >= 0) {
1131 ModeByte = ATA_WDMA0 + wdmamode;
1132 } else
1133 if(apiomode >= 0) {
1134 ModeByte = ATA_PIO0 + apiomode;
1135 } else {
1136 ModeByte = ATA_PIO;
1137 }
1138
1139 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ModeByte);
1140 return;
1141 }
1142
1143 if(deviceExtension->UnknownDev) {
1144 KdPrint2((PRINT_PREFIX "Unknown chip, omit Vendor/Dev checks\n"));
1145 goto try_generic_dma;
1146 }
1147
1148 if(udmamode > 2 && (!LunExt->IdentifyData.HwResCableId && (LunExt->IdentifyData.HwResValid == IDENTIFY_CABLE_ID_VALID)) ) {
1149 if(ata_is_sata(&(LunExt->IdentifyData))) {
1150 KdPrint2((PRINT_PREFIX "AtapiDmaInit: SATA beyond adapter or Controller compat mode\n"));
1151 } else {
1152 KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n"));
1153 udmamode = 2;
1154 apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO));
1155 }
1156 }
1157
1158 KdPrint2((PRINT_PREFIX "Setup chip a:w:u=%d:%d:%d\n",
1159 apiomode,
1160 wdmamode,
1161 udmamode));
1162
1163 switch(VendorID) {
1164 case ATA_ACARD_ID: {
1165 /*********/
1166 /* Acard */
1167 /*********/
1168 static const USHORT reg4a = 0xa6;
1169 UCHAR reg = 0x40 + (UCHAR)dev;
1170
1171 if(ChipType == ATPOLD) {
1172 /* Old Acard 850 */
1173 static const USHORT reg4x2 = 0x0301;
1174
1175 for(i=udmamode; i>=0; i--) {
1176 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA + i)) {
1177 set_old_acard:
1178 ChangePciConfig1(0x54, a | (0x01 << dev) | ((i+1) << (dev*2)));
1179 SetPciConfig1(0x4a, reg4a);
1180 SetPciConfig2(reg, reg4x2);
1181 return;
1182 }
1183
1184 }
1185 if (wdmamode >= 2 && apiomode >= 4) {
1186 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) {
1187 goto set_old_acard;
1188 }
1189 }
1190 } else {
1191 /* New Acard 86X */
1192 static const UCHAR reg4x = 0x31;
1193
1194 for(i=udmamode; i>=0; i--) {
1195 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA + i)) {
1196 set_new_acard:
1197 ChangePciConfig2(0x44, (a & ~(0x000f << (dev * 4))) | ((i+1) << (dev*4)));
1198 SetPciConfig1(0x4a, reg4a);
1199 SetPciConfig1(reg, reg4x);
1200 return;
1201 }
1202
1203 }
1204 if (wdmamode >= 2 && apiomode >= 4) {
1205 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) {
1206 goto set_new_acard;
1207 }
1208 }
1209 }
1210 /* Use GENERIC PIO */
1211 break; }
1212 case ATA_ACER_LABS_ID: {
1213 /************************/
1214 /* Acer Labs Inc. (ALI) */
1215 /************************/
1216 static const UCHAR ali_udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f};
1217 static const ULONG ali_pio[] =
1218 { 0x006d0003, 0x00580002, 0x00440001, 0x00330001,
1219 0x00310001, 0x00440001};
1220 /* the older Aladdin doesn't support ATAPI DMA on both master & slave */
1221 if ((ChipFlags & ALIOLD) &&
1222 (udmamode >= 0 || wdmamode >= 0)) {
1223 if(ATAPI_DEVICE(chan, 0) &&
1224 ATAPI_DEVICE(chan, 1)) {
1225 // 2 devices on this channel - NO DMA
1226 chan->MaxTransferMode =
1227 min(chan->MaxTransferMode, ATA_PIO4);
1228 udmamode = wdmamode = -1;
1229 break;
1230 }
1231 }
1232 for(i=udmamode; i>=0; i--) {
1233 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1234 ULONG word54;
1235
1236 GetPciConfig4(0x54, word54);
1237 word54 &= ~(0x000f000f << (dev * 4));
1238 word54 |= (((ali_udma[i]<<16) | 5) << (dev * 4));
1239 SetPciConfig4(0x54, word54);
1240 ChangePciConfig1(0x53, a | 0x03);
1241 SetPciConfig4(0x58 + (Channel<<2), 0x00310001);
1242 return;
1243 }
1244 }
1245 /* make sure eventual UDMA mode from the BIOS is disabled */
1246 ChangePciConfig2(0x56, a & ~(0x0008 << (dev * 4)) );
1247 if (wdmamode >= 2 && apiomode >= 4) {
1248 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) {
1249 ChangePciConfig1(0x53, a | 0x03);
1250 chan->ChannelCtrlFlags |= CTRFLAGS_DMA_RO;
1251 return;
1252 }
1253 }
1254 ChangePciConfig1(0x53, (a & ~0x01) | 0x02);
1255
1256 for(i=apiomode; i>=0; i--) {
1257 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + i)) {
1258 ChangePciConfig4(0x54, a & ~(0x0008000f << (dev * 4)));
1259 SetPciConfig4(0x58 + (Channel<<2), ali_pio[i]);
1260 return;
1261 }
1262 }
1263 return;
1264 break; }
1265 case ATA_AMD_ID:
1266 case ATA_NVIDIA_ID:
1267 case ATA_VIA_ID: {
1268 /********************/
1269 /* AMD, nVidia, VIA */
1270 /********************/
1271 if(VendorID == ATA_VIA_ID) {
1272 if((ChipFlags & VIASATA) &&
1273 (Channel == 0)) {
1274 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_SA150);
1275 return;
1276 }
1277 if((ChipFlags & VIABAR) &&
1278 (Channel < 2)) {
1279 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_SA150);
1280 return;
1281 }
1282 }
1283
1284 static const UCHAR via_modes[6][7] = {
1285 { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* ATA33 and New Chips */
1286 { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* ATA66 */
1287 { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* ATA100 */
1288 { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 }, /* VIA ATA133 */
1289 { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }, /* AMD/nVIDIA */
1290 { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 }}; /* VIA new */
1291 static const UCHAR via_pio[] =
1292 { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
1293 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
1294 const UCHAR *reg_val = NULL;
1295 UCHAR reg = 0x53-(UCHAR)dev;
1296 UCHAR reg2 = reg-0x08;
1297
1298 if(ChipFlags & VIABAR) {
1299 reg = 0xb3;
1300 reg2 = 0xab;
1301 }
1302
1303 reg_val = &via_modes[ChipType][0];
1304
1305 if(VendorID == ATA_NVIDIA_ID) {
1306 reg += 0x10;
1307 reg2 += 0x10;
1308 }
1309
1310 for(i = udmamode; i>=0; i--) {
1311 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1312 SetPciConfig1(reg2, via_pio[8+i]);
1313 SetPciConfig1(reg, (UCHAR)reg_val[i]);
1314 return;
1315 }
1316 }
1317 if(!(ChipFlags & VIABAR)) {
1318 /* This chip can't do WDMA. */
1319 for(i = wdmamode; i>=0; i--) {
1320 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1321 SetPciConfig1(reg2, via_pio[5+i]);
1322 SetPciConfig1(reg, 0x8b);
1323 return;
1324 }
1325 }
1326 }
1327 /* set PIO mode timings */
1328 if((apiomode >= 0) && (ChipType != VIA133)) {
1329 SetPciConfig1(reg2, via_pio[apiomode]);
1330 }
1331 if(VendorID == ATA_VIA_ID /*&& (ChipType == VIA33 || ChipType == VIA66)*/) {
1332 via82c_timing(deviceExtension, dev, ATA_PIO0 + apiomode);
1333 }
1334 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1335 return;
1336
1337 break; }
1338 case ATA_CYRIX_ID: {
1339 /*********/
1340 /* Cyrix */
1341 /*********/
1342 dma_cs55xx:
1343 if(apiomode >= 4)
1344 apiomode = 4;
1345
1346 if(ChipType == CYRIX_3x) {
1347 ULONG cyr_piotiming[] =
1348 { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
1349 ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
1350 ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
1351 ULONG mode_reg = 0x24+(dev << 3);
1352
1353 for(i=udmamode; i>=0; i--) {
1354 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1355 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]);
1356 return;
1357 }
1358 }
1359 for(i=wdmamode; i>=0; i--) {
1360 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1361 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]);
1362 return;
1363 }
1364 }
1365 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
1366 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]);
1367 return;
1368 }
1369 } else
1370 if(ChipType == CYRIX_OLD) {
1371 UCHAR cyr_piotiming_old[] =
1372 { 11, 6, 3, 2, 1 };
1373 UCHAR timing;
1374
1375 for(i=wdmamode; i>=0; i--) {
1376 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1377 return;
1378 }
1379 }
1380 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
1381 timing = (6-apiomode) | (cyr_piotiming_old[i]);
1382 /* Channel command timing */
1383 SetPciConfig1(0x62+Channel, timing);
1384 /* Read command timing */
1385 SetPciConfig1(0x64+Channel*4+dev, timing);
1386 /* Write command timing */
1387 SetPciConfig1(0x66+Channel*4+dev, timing);
1388 return;
1389 }
1390 } else
1391 if(ChipType == CYRIX_35) {
1392 /*
1393 USHORT c35_pio_timings[5] = {
1394 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131
1395 };
1396 USHORT c35_pio_cmd_timings[5] = {
1397 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
1398 };
1399 ULONG c35_udma_timings[5] = {
1400 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061
1401 };
1402 ULONG c35_mwdma_timings[3] = {
1403 0x7F0FFFF3, 0x7F035352, 0x7F024241
1404 };
1405 ULONG mode_reg = 0x24+(dev << 3);
1406 */
1407 /* No MSR support yet, do not touch any regs */
1408 for(i=udmamode; i>=0; i--) {
1409 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1410 return;
1411 }
1412 }
1413 for(i=wdmamode; i>=0; i--) {
1414 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1415 return;
1416 }
1417 }
1418 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
1419 return;
1420 }
1421 }
1422 return;
1423
1424 break; }
1425 case ATA_NATIONAL_ID: {
1426 /************/
1427 /* National */
1428 /************/
1429 if(!ChipType) {
1430 ULONG nat_piotiming[] =
1431 { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
1432 0x00803020, 0x20102010, 0x00100010,
1433 0x00100010, 0x00100010, 0x00100010 };
1434 ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
1435 ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
1436
1437 if(apiomode >= 4)
1438 apiomode = 4;
1439 for(i=udmamode; i>=0; i--) {
1440 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1441 SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]);
1442 SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]);
1443 return;
1444 }
1445 }
1446 for(i=wdmamode; i>=0; i--) {
1447 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1448 SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]);
1449 SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]);
1450 return;
1451 }
1452 }
1453 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
1454 ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000);
1455 SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]);
1456 return;
1457 }
1458 } else {
1459 goto dma_cs55xx;
1460 }
1461 /* Use GENERIC PIO */
1462 break; }
1463 case ATA_CYPRESS_ID:
1464 /***********/
1465 /* Cypress */
1466 /***********/
1467 if (wdmamode >= 2 && apiomode >= 4) {
1468 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) {
1469 SetPciConfig2(Channel ? 0x4e:0x4c, 0x2020);
1470 return;
1471 }
1472 }
1473 /* Use GENERIC PIO */
1474 break;
1475 case ATA_MARVELL_ID:
1476 /***********/
1477 /* Marvell */
1478 /***********/
1479 for(i=udmamode; i>=0; i--) {
1480 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1481 return;
1482 }
1483 }
1484 for(i=wdmamode; i>=0; i--) {
1485 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1486 return;
1487 }
1488 }
1489 /* try generic DMA, use hpt_timing() */
1490 if (wdmamode >= 0 && apiomode >= 4) {
1491 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) {
1492 return;
1493 }
1494 }
1495 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1496 return;
1497 break;
1498 case ATA_NETCELL_ID:
1499 /***********/
1500 /* NetCell */
1501 /***********/
1502 if (wdmamode >= 2 && apiomode >= 4) {
1503 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) {
1504 return;
1505 }
1506 }
1507 /* Use GENERIC PIO */
1508 break;
1509 case ATA_HIGHPOINT_ID: {
1510 /********************/
1511 /* High Point (HPT) */
1512 /********************/
1513 for(i=udmamode; i>=0; i--) {
1514 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1515 hpt_timing(deviceExtension, dev, (UCHAR)(ATA_UDMA + i)); // ???
1516 return;
1517 }
1518 }
1519
1520 for(i=wdmamode; i>=0; i--) {
1521 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1522 hpt_timing(deviceExtension, dev, (UCHAR)(ATA_WDMA0+i));
1523 return;
1524 }
1525 }
1526 /* try generic DMA, use hpt_timing() */
1527 if (wdmamode >= 0 && apiomode >= 4) {
1528 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) {
1529 return;
1530 }
1531 }
1532 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1533 hpt_timing(deviceExtension, dev, ATA_PIO0 + apiomode);
1534 return;
1535 break; }
1536 case ATA_INTEL_ID: {
1537 /*********/
1538 /* Intel */
1539 /*********/
1540
1541 KdPrint2((PRINT_PREFIX "Intel %d\n", Channel));
1542 BOOLEAN udma_ok = FALSE;
1543 ULONG idx = 0;
1544 ULONG reg40;
1545 UCHAR reg44;
1546 USHORT reg48;
1547 USHORT reg4a;
1548 USHORT reg54;
1549 ULONG mask40 = 0;
1550 ULONG new40 = 0;
1551 UCHAR mask44 = 0;
1552 UCHAR new44 = 0;
1553 UCHAR intel_timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
1554 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
1555 UCHAR intel_utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
1556 const UCHAR needed_pio[3] = {
1557 ATA_PIO0, ATA_PIO3, ATA_PIO4
1558 };
1559
1560 if(deviceExtension->DevID == ATA_I82371FB) {
1561 KdPrint2((PRINT_PREFIX " I82371FB\n"));
1562 USHORT reg4x;
1563 USHORT control=0;
1564 for(i=wdmamode; i>=0; i--) {
1565 idx = 5+i;
1566 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1567 udma_ok = TRUE;
1568 break;
1569 }
1570 }
1571 if(!udma_ok) {
1572 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1573 idx = apiomode;
1574 } else {
1575 /* If the drive MWDMA is faster than it can do PIO then
1576 we must force PIO into PIO0 */
1577 if (apiomode < needed_pio[wdmamode]) {
1578 /* Enable DMA timing only */
1579 control |= 8; /* PIO cycles in PIO0 */
1580 }
1581 }
1582 GetPciConfig2(0x40+Channel*2, reg4x);
1583 if(apiomode > ATA_PIO0) {
1584 control |= 0x03; /* IORDY|TIME0 */
1585 } else {
1586 control |= 0x02; /* IORDY */
1587 }
1588 // if (ata_pio_need_iordy(adev))
1589 //control |= 2; /* IE */
1590 if (!isAtapi) {
1591 control |= 4; /* PPE enable */
1592 }
1593 /* Mask out the relevant control and timing bits we will load. Also
1594 clear the other drive TIME register as a precaution */
1595 reg4x &= 0xCC00 | (0x0E << (DeviceNumber*4));
1596 reg4x |= control << (DeviceNumber*4);
1597 reg4x |= intel_timings[idx] << 8;
1598 SetPciConfig2(0x40+Channel*2, reg4x);
1599 return;
1600 }
1601
1602 if(deviceExtension->DevID == ATA_ISCH) {
1603 ULONG tim;
1604 KdPrint2((PRINT_PREFIX " ISCH\n"));
1605 GetPciConfig4(0x80 + dev*4, tim);
1606
1607 for(i=udmamode; i>=0; i--) {
1608 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1609 tim |= (0x1 << 31);
1610 tim &= ~(0x7 << 16);
1611 tim |= (i << 16);
1612
1613 idx = i+8;
1614 udma_ok = TRUE;
1615 apiomode = ATA_PIO4;
1616 break;
1617 }
1618 }
1619 if(!udma_ok) {
1620 for(i=wdmamode; i>=0; i--) {
1621 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1622 tim &= ~(0x1 << 31);
1623 tim &= ~(0x3 << 8);
1624 tim |= (i << 8);
1625
1626 idx = i+5;
1627 udma_ok = TRUE;
1628 apiomode = (i == 0) ? ATA_PIO0 :
1629 (i == 1) ? ATA_PIO3 : ATA_PIO4;
1630 break;
1631 }
1632 }
1633 }
1634 if(!udma_ok) {
1635 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1636 idx = apiomode;
1637 }
1638 tim &= ~(0x7);
1639 tim |= (apiomode & 0x7);
1640 SetPciConfig4(0x80 + dev*4, tim);
1641
1642 return;
1643 }
1644
1645 GetPciConfig2(0x48, reg48);
1646 // if(!(ChipFlags & ICH4_FIX)) {
1647 GetPciConfig2(0x4a, reg4a);
1648 // }
1649 GetPciConfig2(0x54, reg54);
1650 // if(udmamode >= 0) {
1651 // enable the write buffer to be used in a split (ping/pong) manner.
1652 reg54 |= 0x400;
1653 // } else {
1654 // reg54 &= ~0x400;
1655 // }
1656
1657 // reg40 &= ~0x00ff00ff;
1658 // reg40 |= 0x40774077;
1659
1660 for(i=udmamode; i>=0; i--) {
1661 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1662
1663 /* Set UDMA reference clock (33 MHz or more). */
1664 SetPciConfig1(0x48, reg48 | (0x0001 << dev));
1665 // if(!(ChipFlags & ICH4_FIX)) {
1666 if(deviceExtension->MaxTransferMode == ATA_UDMA3) {
1667 // Special case (undocumented overclock !) for PIIX4e
1668 SetPciConfig2(0x4a, (reg4a | (0x03 << (dev<<2)) ) );
1669 } else {
1670 SetPciConfig2(0x4a, (reg4a & ~(0x03 << (dev<<2))) |
1671 (((USHORT)(intel_utimings[i])) << (dev<<2) ) );
1672 }
1673 // }
1674 /* Set UDMA reference clock (66 MHz or more). */
1675 reg54 &= ~(0x1001 << dev);
1676 if(i > 2) {
1677 reg54 |= (0x1 << dev);
1678 }
1679 /* Set UDMA reference clock (133 MHz). */
1680 if(i >= 5) {
1681 reg54 |= (0x1000 << dev);
1682 }
1683 SetPciConfig2(0x54, reg54);
1684
1685 udma_ok = TRUE;
1686 idx = i+8;
1687 if(ChipFlags & ICH4_FIX) {
1688 KdPrint2((PRINT_PREFIX " ICH4_FIX udma\n"));
1689 return;
1690 }
1691 break;
1692 }
1693 }
1694
1695 if(!udma_ok) {
1696 SetPciConfig1(0x48, reg48 & ~(0x0001 << dev));
1697 if(!(ChipFlags & ICH4_FIX)) {
1698 SetPciConfig2(0x4a, (reg4a & ~(0x3 << (dev << 2))) );
1699 }
1700 SetPciConfig2(0x54, reg54 & ~(0x1001 << dev));
1701 for(i=wdmamode; i>=0; i--) {
1702 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1703 udma_ok = TRUE;
1704 idx = i+5;
1705 if(ChipFlags & ICH4_FIX) {
1706 KdPrint2((PRINT_PREFIX " ICH4_FIX wdma\n"));
1707 return;
1708 }
1709 break;
1710 }
1711 }
1712 }
1713
1714 if(!udma_ok) {
1715 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1716 idx = apiomode;
1717 }
1718
1719 GetPciConfig4(0x40, reg40);
1720 GetPciConfig1(0x44, reg44);
1721
1722 /* Allow PIO/WDMA timing controls. */
1723 reg40 &= ~0x00ff00ff;
1724 reg40 |= 0x40774077;
1725
1726 mask40 = 0x000000ff;
1727 /* Set PIO/WDMA timings. */
1728 if(!(DeviceNumber & 1)) {
1729 mask40 = 0x00003300;
1730 new40 = ((USHORT)(intel_timings[idx]) << 8);
1731 } else {
1732 mask44 = 0x0f;
1733 new44 = ((intel_timings[idx] & 0x30) >> 2) |
1734 (intel_timings[idx] & 0x03);
1735 }
1736
1737 if (Channel) {
1738 mask40 <<= 16;
1739 new40 <<= 16;
1740 mask44 <<= 4;
1741 new44 <<= 4;
1742 }
1743
1744 KdPrint2((PRINT_PREFIX " 0x40 %x/%x, 0x44 %x/%x\n", mask40, new40, mask44, new44));
1745 SetPciConfig4(0x40, (reg40 & ~mask40) | new40);
1746 SetPciConfig1(0x44, (reg44 & ~mask44) | new44);
1747
1748 return;
1749 break; }
1750 case ATA_PROMISE_ID: {
1751 /***********/
1752 /* Promise */
1753 /***********/
1754
1755 UCHAR sel66 = Channel ? 0x08: 0x02;
1756
1757 if(ChipType < PRTX) {
1758 if (isAtapi) {
1759 udmamode =
1760 wdmamode = -1;
1761 }
1762 }
1763 for(i=udmamode; i>=0; i--) {
1764
1765 if(ChipType == PRNEW) {
1766 if(i>2) {
1767 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
1768 AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) |
1769 sel66);
1770 } else {
1771 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
1772 AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) &
1773 ~sel66);
1774 }
1775 }
1776
1777 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1778 promise_timing(deviceExtension, dev, (UCHAR)(ATA_UDMA + i)); // ???
1779 return;
1780 }
1781 }
1782 if(ChipType == PRNEW) {
1783 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
1784 AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) &
1785 ~sel66);
1786 }
1787 for(i=wdmamode; i>=0; i--) {
1788 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1789 promise_timing(deviceExtension, dev, (UCHAR)(ATA_WDMA0+i));
1790 return;
1791 }
1792 }
1793 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1794 promise_timing(deviceExtension, dev, ATA_PIO0 + apiomode);
1795 return;
1796 break; }
1797 case ATA_ATI_ID:
1798
1799 KdPrint2((PRINT_PREFIX "ATI\n"));
1800 if(ChipType == SIIMIO) {
1801 goto l_ATA_SILICON_IMAGE_ID;
1802 }
1803 //goto ATA_SERVERWORKS_ID;
1804 // FALL THROUGH
1805
1806 //break; }
1807
1808 case ATA_SERVERWORKS_ID: {
1809 /***************/
1810 /* ServerWorks */
1811 /***************/
1812 // static const ULONG udma_modes[] = { 0x70, 0x21, 0x20 };
1813 static const ULONG sw_dma_modes[] = { 0x70, 0x21, 0x20 };
1814 static const ULONG sw_pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20,
1815 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
1816 USHORT reg56;
1817 ULONG reg44;
1818 ULONG reg40;
1819 ULONG offset = dev ^ 0x01;
1820 ULONG bit_offset = offset * 8;
1821
1822 for(i=udmamode; i>=0; i--) {
1823 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1824 GetPciConfig2(0x56, reg56);
1825 reg56 &= ~(0xf << (dev * 4));
1826 reg56 |= ((USHORT)i << (dev * 4));
1827 SetPciConfig2(0x56, reg56);
1828 ChangePciConfig1(0x54, a | (0x01 << dev));
1829 // 44
1830 GetPciConfig4(0x44, reg44);
1831 reg44 = (reg44 & ~(0xff << bit_offset)) |
1832 (sw_dma_modes[2] << bit_offset);
1833 SetPciConfig4(0x44, reg44);
1834 // 40
1835 GetPciConfig4(0x40, reg40);
1836 reg40 = (reg40 & ~(0xff << bit_offset)) |
1837 (sw_pio_modes[8+i] << bit_offset);
1838 SetPciConfig4(0x40, reg40);
1839 return;
1840 }
1841 }
1842
1843 for(i=wdmamode; i>=0; i--) {
1844 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1845
1846 ChangePciConfig1(0x54, a & ~(0x01 << dev));
1847 // 44
1848 GetPciConfig4(0x44, reg44);
1849 reg44 = (reg44 & ~(0xff << bit_offset)) |
1850 (sw_dma_modes[wdmamode] << bit_offset);
1851 SetPciConfig4(0x44, reg44);
1852 // 40
1853 GetPciConfig4(0x40, reg40);
1854 reg40 = (reg40 & ~(0xff << bit_offset)) |
1855 (sw_pio_modes[5+i] << bit_offset);
1856 SetPciConfig4(0x40, reg40);
1857 return;
1858 }
1859 }
1860 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1861 // SetPciConfig4(0x44, sw_pio_modes[apiomode]);
1862 if(VendorID == ATA_ATI_ID) {
1863 // special case for ATI
1864 // Seems, that PATA ATI are just re-brended ServerWorks
1865 USHORT reg4a;
1866 // 4a
1867 GetPciConfig2(0x4a, reg4a);
1868 reg4a = (reg4a & ~(0xf << (dev*4))) |
1869 (apiomode << (dev*4));
1870 SetPciConfig2(0x4a, reg4a);
1871 }
1872
1873 // 40
1874 GetPciConfig4(0x40, reg40);
1875 reg40 = (reg40 & ~(0xff << bit_offset)) |
1876 (sw_pio_modes[apiomode] << bit_offset);
1877 SetPciConfig4(0x40, reg40);
1878 return;
1879 break; }
1880 case ATA_SILICON_IMAGE_ID: {
1881 l_ATA_SILICON_IMAGE_ID:
1882 /********************/
1883 /* SiliconImage/CMD */
1884 /********************/
1885 if(ChipType == SIIMIO) {
1886
1887 static const UCHAR sil_modes[7] =
1888 { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 };
1889 static const USHORT sil_wdma_modes[3] =
1890 { 0x2208, 0x10c2, 0x10c1 };
1891 static const USHORT sil_pio_modes[6] =
1892 { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1, 0x10c1 };
1893
1894 UCHAR ureg = 0xac + ((UCHAR)DeviceNumber * 0x02) + ((UCHAR)Channel * 0x10);
1895 UCHAR uval;
1896 UCHAR mreg = Channel ? 0x84 : 0x80;
1897 UCHAR mask = DeviceNumber ? 0x30 : 0x03;
1898 UCHAR mode;
1899
1900 GetPciConfig1(ureg, uval);
1901 GetPciConfig1(mreg, mode);
1902
1903 /* enable UDMA mode */
1904 for(i = udmamode; i>=0; i--) {
1905
1906 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1907 SetPciConfig1(mreg, mode | mask);
1908 SetPciConfig1(ureg, (uval & 0x3f) | sil_modes[i]);
1909 return;
1910 }
1911 }
1912 /* enable WDMA mode */
1913 for(i = wdmamode; i>=0; i--) {
1914
1915 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1916 SetPciConfig1(mreg, mode | (mask & 0x22));
1917 SetPciConfig2(ureg - 0x4, sil_wdma_modes[i]);
1918 return;
1919 }
1920 }
1921 /* restore PIO mode */
1922 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1923
1924 SetPciConfig1(mreg, mode | (mask & 0x11));
1925 SetPciConfig2(ureg - 0x8, sil_pio_modes[apiomode]);
1926 return;
1927
1928 } else {
1929
1930 static const UCHAR cmd_modes[2][6] = {
1931 { 0x31, 0x21, 0x011, 0x25, 0x15, 0x05 },
1932 { 0xc2, 0x82, 0x042, 0x8a, 0x4a, 0x0a } };
1933 static const UCHAR cmd_wdma_modes[] = { 0x87, 0x32, 0x3f };
1934 static const UCHAR cmd_pio_modes[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f };
1935 ULONG treg = 0x54 + ((dev < 3) ? (dev << 1) : 7);
1936
1937 udmamode = min(udmamode, 5);
1938 /* enable UDMA mode */
1939 for(i = udmamode; i>=0; i--) {
1940 UCHAR umode;
1941
1942 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
1943 GetPciConfig1(Channel ? 0x7b : 0x73, umode);
1944 umode &= ~(!(DeviceNumber & 1) ? 0x35 : 0xca);
1945 umode |= ( cmd_modes[DeviceNumber & 1][i]);
1946 SetPciConfig1(Channel ? 0x7b : 0x73, umode);
1947 return;
1948 }
1949 }
1950 /* make sure eventual UDMA mode from the BIOS is disabled */
1951 ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca));
1952
1953 for(i = wdmamode; i>=0; i--) {
1954
1955 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
1956 SetPciConfig1(treg, cmd_wdma_modes[i]);
1957 ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca));
1958 return;
1959 }
1960 }
1961 /* set PIO mode timings */
1962 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
1963
1964 SetPciConfig1(treg, cmd_pio_modes[apiomode]);
1965 ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca));
1966 return;
1967
1968 }
1969 return;
1970 break; }
1971 case ATA_SIS_ID: {
1972 /*******/
1973 /* SiS */
1974 /*******/
1975 PULONG sis_modes = NULL;
1976 static const ULONG sis_modes_new133[] =
1977 { 0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008,
1978 0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac,
1979 0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c};
1980 static const ULONG sis_modes_old133[] =
1981 { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031,
1982 0x8f31, 0x8a31, 0x8731, 0x8531, 0x8331, 0x8231, 0x8131 };
1983 static const ULONG sis_modes_old[] =
1984 { 0x0c0b, 0x0607, 0x0404, 0x0303, 0x0301, 0x0404, 0x0303, 0x0301,
1985 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301 };
1986 static const ULONG sis_modes_new100[] =
1987 { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031,
1988 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 };
1989
1990 ULONG reg = 0;
1991 UCHAR reg57;
1992 ULONG reg_size = 0;
1993 ULONG offs;
1994
1995 switch(ChipType) {
1996 case SIS133NEW:
1997 sis_modes = (PULONG)(&sis_modes_new133[0]);
1998 reg_size = 4;
1999 GetPciConfig1(0x57, reg57);
2000 reg = (reg57 & 0x40 ? 0x70 : 0x40) + (dev * 4);
2001 break;
2002 case SIS133OLD:
2003 sis_modes = (PULONG)(&sis_modes_old133[0]);
2004 reg_size = 2;
2005 reg = 0x40 + (dev * 2);
2006 break;
2007 case SIS100NEW:
2008 sis_modes = (PULONG)(&sis_modes_new100[0]);
2009 reg_size = 2;
2010 reg = 0x40 + (dev * 2);
2011 break;
2012 case SIS100OLD:
2013 case SIS66:
2014 case SIS33:
2015 sis_modes = (PULONG)(&sis_modes_old[0]);
2016 reg_size = 2;
2017 reg = 0x40 + (dev * 2);
2018 break;
2019 }
2020
2021 offs = 5+3;
2022 for(i=udmamode; i>=0; i--) {
2023 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
2024 if(reg_size == 4) {
2025 SetPciConfig4(reg, sis_modes[offs+i]);
2026 } else {
2027 SetPciConfig2(reg, (USHORT)sis_modes[offs+i]);
2028 }
2029 return;
2030 }
2031 }
2032
2033 offs = 5;
2034 for(i=wdmamode; i>=0; i--) {
2035 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
2036 if(reg_size == 4) {
2037 SetPciConfig4(reg, sis_modes[offs+i]);
2038 } else {
2039 SetPciConfig2(reg, (USHORT)sis_modes[offs+i]);
2040 }
2041 return;
2042 }
2043 }
2044 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
2045 if(reg_size == 4) {
2046 SetPciConfig4(reg, sis_modes[apiomode]);
2047 } else {
2048 SetPciConfig2(reg, (USHORT)sis_modes[apiomode]);
2049 }
2050 return;
2051 break; }
2052 case 0x16ca:
2053 /* Cenatek Rocket Drive controller */
2054 if (wdmamode >= 0 &&
2055 (AtapiReadPort1(chan, IDX_BM_Status) &
2056 (DeviceNumber ? BM_STATUS_DRIVE_1_DMA : BM_STATUS_DRIVE_0_DMA))) {
2057 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + wdmamode);
2058 } else {
2059 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
2060 }
2061 return;
2062 case ATA_ITE_ID: { /* ITE IDE controller */
2063
2064 if(ChipType == ITE_33) {
2065 int a_speed = 3 << (dev * 4);
2066 int u_flag = 1 << dev;
2067 int u_speed = 0;
2068 int pio = 1;
2069 UCHAR reg48, reg4a;
2070 USHORT drive_enables;
2071 ULONG drive_timing;
2072
2073 GetPciConfig1(0x48, reg48);
2074 GetPciConfig1(0x4a, reg4a);
2075
2076 /*
2077 * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec
2078 * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA
2079 * transfers on some drives, even though both numbers meet the minimum
2080 * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively.
2081 * So the faster times are just commented out here. The good news is
2082 * that the slower cycle time has very little affect on transfer
2083 * performance.
2084 */
2085
2086 for(i=udmamode; i>=0; i--) {
2087 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
2088 SetPciConfig1(0x48, reg48 | u_flag);
2089 reg4a &= ~a_speed;
2090 SetPciConfig1(0x4a, reg4a | u_speed);
2091 pio = 4;
2092 goto setup_drive_ite;
2093 }
2094 }
2095
2096 for(i=wdmamode; i>=0; i--) {
2097 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
2098 SetPciConfig1(0x48, reg48 & ~u_flag);
2099 SetPciConfig1(0x4a, reg4a & ~a_speed);
2100 pio = 3;
2101 return;
2102 }
2103 }
2104 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
2105 SetPciConfig1(0x48, reg48 & ~u_flag);
2106 SetPciConfig1(0x4a, reg4a & ~a_speed);
2107
2108 pio = apiomode;
2109
2110 setup_drive_ite:
2111
2112 GetPciConfig2(0x40, drive_enables);
2113 GetPciConfig4(0x44, drive_timing);
2114
2115 /*
2116 * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
2117 * are being left at the default values of 8 PCI clocks (242 nsec
2118 * for a 33 MHz clock). These can be safely shortened at higher
2119 * PIO modes. The DIOR/DIOW pulse width and recovery times only
2120 * apply to PIO modes, not to the DMA modes.
2121 */
2122
2123 /*
2124 * Enable port 0x44. The IT8172G spec is confused; it calls
2125 * this register the "Slave IDE Timing Register", but in fact,
2126 * it controls timing for both master and slave drives.
2127 */
2128 drive_enables |= 0x4000;
2129
2130 drive_enables &= (0xc000 | (0x06 << (DeviceNumber*4)));
2131 if (pio > 1) {
2132 /* enable prefetch and IORDY sample-point */
2133 drive_enables |= (0x06 << (DeviceNumber*4));
2134 }
2135
2136 SetPciConfig2(0x40, drive_enables);
2137 } else
2138 if(ChipType == ITE_133) {
2139 static const UCHAR udmatiming[] =
2140 { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 };
2141 static const UCHAR chtiming[] =
2142 { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 };
2143 ULONG offset = (Channel<<2) + DeviceNumber;
2144 UCHAR reg54;
2145
2146 for(i=udmamode; i>=0; i--) {
2147 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
2148 ChangePciConfig1(0x50, a & ~(1 << (dev + 3)) );
2149 SetPciConfig1(0x56 + offset, udmatiming[i]);
2150 return;
2151 }
2152 }
2153
2154 for(i=wdmamode; i>=0; i--) {
2155 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
2156
2157 ChangePciConfig1(0x50, a | (1 << (dev + 3)) );
2158 GetPciConfig1(0x54 + offset, reg54);
2159 if(reg54 < chtiming[i+5]) {
2160 SetPciConfig1(0x54 + offset, chtiming[i+5]);
2161 }
2162 return;
2163 }
2164 }
2165 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
2166 ChangePciConfig1(0x50, a | (1 << (dev + 3)) );
2167 GetPciConfig1(0x54 + offset, reg54);
2168 if(reg54 < chtiming[apiomode]) {
2169 SetPciConfig1(0x54 + offset, chtiming[apiomode]);
2170 }
2171 return;
2172 } else
2173 if(ChipType == ITE_133_NEW) {
2174 //static const USHORT reg54_timings[] = { 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x1001, 0x1001 };
2175 static const UCHAR udmatiming[] =
2176 { 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10 };
2177 static const UCHAR timings[] =
2178 { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
2179 0x23, 0x23, 0x23, 0x23, 0x23, 0x02, 0x02 };
2180 BOOLEAN udma_ok = FALSE;
2181 BOOLEAN ok = FALSE;
2182 UCHAR timing = 0;
2183
2184 WCHAR reg40;
2185 UCHAR reg44;
2186 USHORT reg4a;
2187 USHORT reg54;
2188 USHORT mask40=0, new40=0;
2189 UCHAR mask44=0, new44=0;
2190
2191 GetPciConfig2(0x40, reg40);
2192 GetPciConfig1(0x44, reg44);
2193 GetPciConfig2(0x4a, reg4a);
2194 GetPciConfig2(0x54, reg54);
2195
2196 if(!(reg54 & (0x10 << dev))) {
2197 // 80-pin check
2198 udmamode = min(udmamode, 2);
2199 }
2200
2201 for(i=udmamode; i>=0; i--) {
2202 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
2203 ChangePciConfig1(0x48, a | (1 << dev) );
2204 ChangePciConfig2(0x4a,
2205 (a & ~(0x3 << (dev*4))) |
2206 (udmatiming[i] << (dev*4)) );
2207 ok=TRUE;
2208 udma_ok=TRUE;
2209 timing = timings[i+8];
2210 break;
2211 }
2212 }
2213
2214 for(i=wdmamode; !ok && i>=0; i--) {
2215 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
2216
2217 ok=TRUE;
2218 timing = timings[i+5];
2219 break;
2220 }
2221 }
2222
2223 if(!ok) {
2224 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
2225 timing = timings[apiomode];
2226 }
2227
2228 if(!udma_ok) {
2229 ChangePciConfig1(0x48, a & ~(1 << dev) );
2230 ChangePciConfig2(0x4a, a & ~(0x3 << (dev << 2)) );
2231 }
2232 if (udma_ok && udmamode >= ATA_UDMA2) {
2233 reg54 |= (0x1 << dev);
2234 } else {
2235 reg54 &= ~(0x1 << dev);
2236 }
2237 if (udma_ok && udmamode >= ATA_UDMA5) {
2238 reg54 |= (0x1000 << dev);
2239 } else {
2240 reg54 &= ~(0x1000 << dev);
2241 }
2242 SetPciConfig2(0x54, reg54 );
2243
2244 reg40 &= 0xff00;
2245 reg40 |= 0x4033;
2246
2247 if(!(DeviceNumber & 1)) {
2248 reg40 |= (isAtapi ? 0x04 : 0x00);
2249 mask40 = 0x3300;
2250 new40 = timing << 8;
2251 } else {
2252 reg40 |= (isAtapi ? 0x40 : 0x00);
2253 mask44 = 0x0f;
2254 new44 = ((timing & 0x30) >> 2) |
2255 (timing & 0x03);
2256 }
2257 SetPciConfig2(0x40, (reg40 & ~mask40) | new40);
2258 SetPciConfig1(0x44, (reg44 & ~mask44) | new44);
2259 return;
2260 }
2261
2262 return;
2263 break; }
2264 case 0x3388:
2265 /* HiNT Corp. VXPro II EIDE */
2266 if (wdmamode >= 0 &&
2267 (AtapiReadPort1(chan, IDX_BM_Status) &
2268 (DeviceNumber ? BM_STATUS_DRIVE_1_DMA : BM_STATUS_DRIVE_0_DMA))) {
2269 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA);
2270 } else {
2271 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
2272 }
2273 return;
2274 case ATA_JMICRON_ID: {
2275
2276 UCHAR reg40;
2277 GetPciConfig1(0x40, reg40);
2278
2279 if(reg40 & 0x08) {
2280 // 80-pin check
2281 udmamode = min(udmamode, 2);
2282 }
2283 /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */
2284 if(apiomode >= 4)
2285 apiomode = 4;
2286 for(i=udmamode; i>=0; i--) {
2287 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
2288 return;
2289 }
2290 }
2291 for(i=wdmamode; i>=0; i--) {
2292 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
2293 return;
2294 }
2295 }
2296 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
2297 return;
2298 }
2299 return;
2300 break; }
2301 }
2302
2303 try_generic_dma:
2304
2305 /* unknown controller chip */
2306
2307 /* better not try generic DMA on ATAPI devices it almost never works */
2308 if (isAtapi) {
2309 KdPrint2((PRINT_PREFIX "ATAPI on unknown controller -> PIO\n"));
2310 udmamode =
2311 wdmamode = -1;
2312 }
2313
2314 /* if controller says its setup for DMA take the easy way out */
2315 /* the downside is we dont know what DMA mode we are in */
2316 if ((udmamode >= 0 || /*wdmamode > 1*/ wdmamode >= 0) &&
2317 /*deviceExtension->BaseIoAddressBM[lChannel]*/ (deviceExtension->BusMaster==DMA_MODE_BM) &&
2318 (GetDmaStatus(deviceExtension, lChannel) &
2319 (!(DeviceNumber & 1) ?
2320 BM_STATUS_DRIVE_0_DMA : BM_STATUS_DRIVE_1_DMA))) {
2321 // LunExt->TransferMode = ATA_DMA;
2322 // return;
2323 KdPrint2((PRINT_PREFIX "try DMA on unknown controller\n"));
2324 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) {
2325 return;
2326 }
2327 }
2328
2329 #if 0
2330 /* well, we have no support for this, but try anyways */
2331 if ((wdmamode >= 0 && apiomode >= 4) && deviceExtension->BaseIoAddressBM[lChannel]) {
2332 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA/* + wdmamode*/)) {
2333 return;
2334 }
2335 }
2336 #endif
2337
2338 KdPrint2((PRINT_PREFIX "try PIO%d on unknown controller\n", apiomode));
2339 if(!AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
2340 KdPrint2((PRINT_PREFIX "fall to PIO on unknown controller\n"));
2341 LunExt->TransferMode = ATA_PIO;
2342 }
2343 return;
2344 } // end AtapiDmaInit()
2345
2346
2347 VOID
2348 NTAPI
2349 cyrix_timing(
2350 IN PHW_DEVICE_EXTENSION deviceExtension,
2351 IN ULONG dev, // physical device number (0-3)
2352 IN CHAR mode
2353 )
2354 {
2355 // ASSERT(dev/2 >= deviceExtension->Channel);
2356 // PHW_CHANNEL chan = &(deviceExtension->chan[dev/2-deviceExtension->Channel]);
2357 ULONG reg20 = 0x0000e132;
2358 ULONG reg24 = 0x00017771;
2359
2360 if(mode == ATA_PIO5)
2361 mode = ATA_PIO4;
2362
2363 switch (mode) {
2364 case ATA_PIO0: reg20 = 0x0000e132; break;
2365 case ATA_PIO1: reg20 = 0x00018121; break;
2366 case ATA_PIO2: reg20 = 0x00024020; break;
2367 case ATA_PIO3: reg20 = 0x00032010; break;
2368 case ATA_PIO4:
2369 case ATA_PIO5: reg20 = 0x00040010; break;
2370 case ATA_WDMA2: reg24 = 0x00002020; break;
2371 case ATA_UDMA2: reg24 = 0x00911030; break;
2372 }
2373 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(dev*8) + 0x20, reg20);
2374 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(dev*8) + 0x24, reg24);
2375 } // cyrix_timing()
2376
2377 VOID
2378 NTAPI
2379 promise_timing(
2380 IN PHW_DEVICE_EXTENSION deviceExtension,
2381 IN ULONG dev, // physical device number (0-3)
2382 IN CHAR mode
2383 )
2384 {
2385 PVOID HwDeviceExtension = (PVOID)deviceExtension;
2386 ULONG slotNumber = deviceExtension->slotNumber;
2387 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
2388
2389 //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
2390
2391 ULONG port = 0x60 + (dev<<2);
2392
2393 if(mode == ATA_PIO5)
2394 mode = ATA_PIO4;
2395
2396 if(mode < ATA_PIO0)
2397 mode = ATA_PIO0;
2398
2399 #if 0
2400 // **** FreeBSD code ****
2401
2402 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
2403 ULONG timing = 0;
2404
2405 switch(ChipType) {
2406 case PROLD:
2407 switch (mode) {
2408 default:
2409 case ATA_PIO0: timing = 0x004ff329; break;
2410 case ATA_PIO1: timing = 0x004fec25; break;
2411 case ATA_PIO2: timing = 0x004fe823; break;
2412 case ATA_PIO3: timing = 0x004fe622; break;
2413 case ATA_PIO4: timing = 0x004fe421; break;
2414 case ATA_WDMA0: timing = 0x004567f3; break;
2415 case ATA_WDMA1: timing = 0x004467f3; break;
2416 case ATA_WDMA2: timing = 0x004367f3; break;
2417 case ATA_UDMA0: timing = 0x004367f3; break;
2418 case ATA_UDMA1: timing = 0x004247f3; break;
2419 case ATA_UDMA2: timing = 0x004127f3; break;
2420 }
2421 break;
2422
2423 case PRNEW:
2424 switch (mode) {
2425 default:
2426 case ATA_PIO0: timing = 0x004fff2f; break;
2427 case ATA_PIO1: timing = 0x004ff82a; break;
2428 case ATA_PIO2: timing = 0x004ff026; break;
2429 case ATA_PIO3: timing = 0x004fec24; break;
2430 case ATA_PIO4: timing = 0x004fe822; break;
2431 case ATA_WDMA0: timing = 0x004acef6; break;
2432 case ATA_WDMA1: timing = 0x0048cef6; break;
2433 case ATA_WDMA2: timing = 0x0046cef6; break;
2434 case ATA_UDMA0: timing = 0x0046cef6; break;
2435 case ATA_UDMA1: timing = 0x00448ef6; break;
2436 case ATA_UDMA2: timing = 0x00436ef6; break;
2437 case ATA_UDMA3: timing = 0x00424ef6; break;
2438 case ATA_UDMA4: timing = 0x004127f3; break;
2439 case ATA_UDMA5: timing = 0x004127f3; break;
2440 }
2441 break;
2442 default:
2443 return;
2444 }
2445 if(!timing) {
2446 return;
2447 }
2448 SetPciConfig4(port, timing);
2449
2450 #else
2451 // **** Linux code ****
2452
2453 UCHAR r_bp, r_cp, r_ap;
2454 ULONG i;
2455
2456 static UCHAR udma_timing[6][2] = {
2457 { 0x60, 0x03 }, /* 33 Mhz Clock */
2458 { 0x40, 0x02 },
2459 { 0x20, 0x01 },
2460 { 0x40, 0x02 }, /* 66 Mhz Clock */
2461 { 0x20, 0x01 },
2462 { 0x20, 0x01 }
2463 };
2464 static UCHAR mdma_timing[3][2] = {
2465 { 0xe0, 0x0f },
2466 { 0x60, 0x04 },
2467 { 0x60, 0x03 },
2468 };
2469 static USHORT pio_timing[5] = {
2470 0x0913, 0x050C , 0x0308, 0x0206, 0x0104
2471 };
2472
2473 if(mode > ATA_UDMA5) {
2474 return;
2475 }
2476
2477 if(mode > ATA_WDMA0) {
2478
2479 GetPciConfig1(port+1, r_bp);
2480 GetPciConfig1(port+2, r_cp);
2481
2482 r_bp &= ~0xE0;
2483 r_cp &= ~0x0F;
2484
2485 if(mode >= ATA_UDMA0) {
2486 i = mode - ATA_UDMA0;
2487 r_bp |= udma_timing[i][0];
2488 r_cp |= udma_timing[i][1];
2489
2490 } else {
2491 i = mode - ATA_WDMA0;
2492 r_bp |= mdma_timing[i][0];
2493 r_cp |= mdma_timing[i][1];
2494 }
2495 SetPciConfig1(port+1, r_bp);
2496 SetPciConfig1(port+2, r_cp);
2497 } else
2498 if(mode <= ATA_PIO5) {
2499 GetPciConfig1(port+0, r_ap);
2500 GetPciConfig1(port+1, r_bp);
2501
2502 i = mode - ATA_PIO0;
2503 r_ap &= ~0x3F; /* Preserve ERRDY_EN, SYNC_IN */
2504 r_bp &= ~0x1F;
2505 r_ap |= (UCHAR)(pio_timing[i] >> 8);
2506 r_bp |= (UCHAR)(pio_timing[i] & 0xFF);
2507
2508 // if (ata_pio_need_iordy(adev))
2509 r_ap |= 0x20; /* IORDY enable */
2510 // if (adev->class == ATA_DEV_ATA)
2511 // r_ap |= 0x10; /* FIFO enable */
2512
2513 SetPciConfig1(port+0, r_ap);
2514 SetPciConfig1(port+1, r_bp);
2515 }
2516
2517 #endif
2518
2519 } // end promise_timing()
2520
2521
2522 VOID
2523 NTAPI
2524 hpt_timing(
2525 IN PHW_DEVICE_EXTENSION deviceExtension,
2526 IN ULONG dev, // physical device number (0-3)
2527 IN CHAR mode
2528 )
2529 {
2530 PVOID HwDeviceExtension = (PVOID)deviceExtension;
2531 ULONG slotNumber = deviceExtension->slotNumber;
2532 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
2533
2534 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
2535 //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
2536
2537 ULONG timing = 0;
2538
2539 if(mode == ATA_PIO5)
2540 mode = ATA_PIO4;
2541
2542 switch(ChipType) {
2543 case HPT374:
2544
2545 switch (mode) { /* HPT374 */
2546 case ATA_PIO0: timing = 0x0ac1f48a; break;
2547 case ATA_PIO1: timing = 0x0ac1f465; break;
2548 case ATA_PIO2: timing = 0x0a81f454; break;
2549 case ATA_PIO3: timing = 0x0a81f443; break;
2550 case ATA_PIO4: timing = 0x0a81f442; break;
2551 case ATA_WDMA0: timing = 0x228082ea; break;
2552 case ATA_WDMA1: timing = 0x22808254; break;
2553 case ATA_WDMA2: timing = 0x22808242; break;
2554 case ATA_UDMA0: timing = 0x121882ea; break;
2555 case ATA_UDMA1: timing = 0x12148254; break;
2556 case ATA_UDMA2: timing = 0x120c8242; break;
2557 case ATA_UDMA3: timing = 0x128c8242; break;
2558 case ATA_UDMA4: timing = 0x12ac8242; break;
2559 case ATA_UDMA5: timing = 0x12848242; break;
2560 case ATA_UDMA6: timing = 0x12808242; break;
2561 default: timing = 0x0d029d5e;
2562 }
2563 break;
2564
2565 case HPT372:
2566
2567 switch (mode) { /* HPT372 */
2568 case ATA_PIO0: timing = 0x0d029d5e; break;
2569 case ATA_PIO1: timing = 0x0d029d26; break;
2570 case ATA_PIO2: timing = 0x0c829ca6; break;
2571 case ATA_PIO3: timing = 0x0c829c84; break;
2572 case ATA_PIO4: timing = 0x0c829c62; break;
2573 case ATA_WDMA0: timing = 0x2c82922e; break;
2574 case ATA_WDMA1: timing = 0x2c829266; break;
2575 case ATA_WDMA2: timing = 0x2c829262; break;
2576 case ATA_UDMA0: timing = 0x1c829c62; break;
2577 case ATA_UDMA1: timing = 0x1c9a9c62; break;
2578 case ATA_UDMA2: timing = 0x1c929c62; break;
2579 case ATA_UDMA3: timing = 0x1c8e9c62; break;
2580 case ATA_UDMA4: timing = 0x1c8a9c62; break;
2581 case ATA_UDMA5: timing = 0x1c8a9c62; break;
2582 case ATA_UDMA6: timing = 0x1c869c62; break;
2583 default: timing = 0x0d029d5e;
2584 }
2585 break;
2586
2587 case HPT370:
2588
2589 switch (mode) { /* HPT370 */
2590 case ATA_PIO0: timing = 0x06914e57; break;
2591 case ATA_PIO1: timing = 0x06914e43; break;
2592 case ATA_PIO2: timing = 0x06514e33; break;
2593 case ATA_PIO3: timing = 0x06514e22; break;
2594 case ATA_PIO4: timing = 0x06514e21; break;
2595 case ATA_WDMA0: timing = 0x26514e97; break;
2596 case ATA_WDMA1: timing = 0x26514e33; break;
2597 case ATA_WDMA2: timing = 0x26514e21; break;
2598 case ATA_UDMA0: timing = 0x16514e31; break;
2599 case ATA_UDMA1: timing = 0x164d4e31; break;
2600 case ATA_UDMA2: timing = 0x16494e31; break;
2601 case ATA_UDMA3: timing = 0x166d4e31; break;
2602 case ATA_UDMA4: timing = 0x16454e31; break;
2603 case ATA_UDMA5: timing = 0x16454e31; break;
2604 default: timing = 0x06514e57;
2605 }
2606
2607 case HPT366: {
2608 UCHAR reg41;
2609
2610 GetPciConfig1(0x41 + (dev << 2), reg41);
2611
2612 switch (reg41) {
2613 case 0x85: /* 25Mhz */
2614 switch (mode) {
2615 case ATA_PIO0: timing = 0x40d08585; break;
2616 case ATA_PIO1: timing = 0x40d08572; break;
2617 case ATA_PIO2: timing = 0x40ca8542; break;
2618 case ATA_PIO3: timing = 0x40ca8532; break;
2619 case ATA_PIO4: timing = 0x40ca8521; break;
2620 case ATA_WDMA2: timing = 0x20ca8521; break;
2621 case ATA_UDMA2: timing = 0x10cf8521; break;
2622 case ATA_UDMA4: timing = 0x10c98521; break;
2623 default: timing = 0x01208585;
2624 }
2625 break;
2626 default:
2627 case 0xa7: /* 33MHz */
2628 switch (mode) {
2629 case ATA_PIO0: timing = 0x40d0a7aa; break;
2630 case ATA_PIO1: timing = 0x40d0a7a3; break;
2631 case ATA_PIO2: timing = 0x40d0a753; break;
2632 case ATA_PIO3: timing = 0x40c8a742; break;
2633 case ATA_PIO4: timing = 0x40c8a731; break;
2634 case ATA_WDMA0: timing = 0x20c8a797; break;
2635 case ATA_WDMA1: timing = 0x20c8a732; break;
2636 case ATA_WDMA2: timing = 0x20c8a731; break;
2637 case ATA_UDMA0: timing = 0x10c8a731; break;
2638 case ATA_UDMA1: timing = 0x10cba731; break;
2639 case ATA_UDMA2: timing = 0x10caa731; break;
2640 case ATA_UDMA3: timing = 0x10cfa731; break;
2641 case ATA_UDMA4: timing = 0x10c9a731; break;
2642 default: timing = 0x0120a7a7;
2643 }
2644 break;
2645 case 0xd9: /* 40Mhz */
2646 switch (mode) {
2647 case ATA_PIO0: timing = 0x4018d9d9; break;
2648 case ATA_PIO1: timing = 0x4010d9c7; break;
2649 case ATA_PIO2: timing = 0x4010d997; break;
2650 case ATA_PIO3: timing = 0x4010d974; break;
2651 case ATA_PIO4: timing = 0x4008d963; break;
2652 case ATA_WDMA2: timing = 0x2008d943; break;
2653 case ATA_UDMA2: timing = 0x100bd943; break;
2654 case ATA_UDMA4: timing = 0x100fd943; break;
2655 default: timing = 0x0120d9d9;
2656 }
2657 }
2658 break; }
2659 }
2660
2661 SetPciConfig4(0x40 + (dev<<2), timing);
2662 } // end hpt_timing()
2663
2664
2665 #define FIT(v,min,max) (((v)>(max)?(max):(v))<(min)?(min):(v))
2666
2667 VOID
2668 NTAPI
2669 via82c_timing(
2670 IN PHW_DEVICE_EXTENSION deviceExtension,
2671 IN ULONG dev, // physical device number (0-3)
2672 IN CHAR mode
2673 )
2674 {
2675 PVOID HwDeviceExtension = (PVOID)deviceExtension;
2676 ULONG slotNumber = deviceExtension->slotNumber;
2677 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
2678
2679 // Newer chips dislike this:
2680 if(/*!(deviceExtension->HwFlags & VIAAST)*/
2681 deviceExtension->MaxTransferMode < ATA_UDMA6) {
2682 return;
2683 }
2684
2685 USHORT T = 1000 / /* PciBusClockMHz()*/ 33;
2686
2687 USHORT setup = 0;
2688 USHORT active = 0;
2689 USHORT recover = 0;
2690 USHORT cycle = 0;
2691
2692 UCHAR t;
2693
2694 switch(mode) {
2695 default:
2696 case ATA_PIO0: setup = 70; active = 165; recover = 150; cycle = 600; break;
2697 case ATA_PIO1: setup = 50; active = 125; recover = 100; cycle = 383; break;
2698 case ATA_PIO2: setup = 30; active = 100; recover = 90; cycle = 240; break;
2699 case ATA_PIO3: setup = 30; active = 80; recover = 70; cycle = 180; break;
2700 case ATA_PIO4: setup = 25; active = 70; recover = 25; cycle = 120; break;
2701 case ATA_PIO5: setup = 20; active = 50; recover = 30; cycle = 100; break;
2702 }
2703
2704 setup = (setup -1)/(T+1);
2705 active = (active -1)/(T+1);
2706 recover = (recover-1)/(T+1);
2707 cycle = (cycle -1)/(T+1);
2708
2709 if (active + recover < cycle) {
2710 active += (cycle - (active + recover)) / 2;
2711 recover = cycle - active;
2712 }
2713
2714 /* PIO address setup */
2715 GetPciConfig1(0x4c, t);
2716 t = (t & ~(3 << ((3 - dev) << 1))) | (FIT(setup - 1, 0, 3) << ((3 - dev) << 1));
2717 SetPciConfig1(0x4c, t);
2718
2719 /* PIO active & recover */
2720 SetPciConfig1(0x4b-dev, (FIT(active - 1, 0, 0xf) << 4) | FIT(recover - 1, 0, 0xf) );
2721 } // end via82c_timing()
2722