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