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