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