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