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