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