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