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