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