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