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