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