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