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