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