Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenid_dma.cpp
Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 2002-2011 Alexander A. Telyatnikov (Alter) 00004 00005 Module Name: 00006 id_dma.cpp 00007 00008 Abstract: 00009 This is the miniport driver for ATAPI IDE controllers 00010 With Busmaster DMA support 00011 00012 Author: 00013 Alexander A. Telyatnikov (Alter) 00014 00015 Environment: 00016 kernel mode only 00017 00018 Notes: 00019 00020 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00021 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00022 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00023 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00024 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00025 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00029 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 00031 Revision History: 00032 00033 This module is a port from FreeBSD 4.3-6.1 ATA driver (ata-dma.c, ata-chipset.c) by 00034 Søren Schmidt, Copyright (c) 1998-2008 00035 00036 Changed defaulting-to-generic-PIO/DMA policy 00037 Added PIO settings for VIA 00038 Optimized VIA/AMD/nVidia init part 00039 Optimized Promise TX2 init part 00040 Optimized Intel init part 00041 by Alex A. Telyatnikov (Alter) (c) 2002-2007 00042 00043 00044 --*/ 00045 00046 #include "stdafx.h" 00047 00048 static const ULONG valid_udma[7] = {0,0,2,0,4,5,6}; 00049 00050 static const CHAR retry_Wdma[MAX_RETRIES+1] = {2, 2, 2,-1,-1,-1}; 00051 static const CHAR retry_Udma[MAX_RETRIES+1] = {6, 2,-1,-1,-1,-1}; 00052 00053 PHYSICAL_ADDRESS ph4gb = {{0xFFFFFFFF, 0}}; 00054 00055 VOID 00056 NTAPI 00057 cyrix_timing ( 00058 IN PHW_DEVICE_EXTENSION deviceExtension, 00059 IN ULONG dev, // physical device number (0-3) 00060 IN CHAR mode 00061 ); 00062 00063 VOID 00064 NTAPI 00065 promise_timing ( 00066 IN PHW_DEVICE_EXTENSION deviceExtension, 00067 IN ULONG dev, // physical device number (0-3) 00068 IN CHAR mode 00069 ); 00070 00071 VOID 00072 NTAPI 00073 hpt_timing ( 00074 IN PHW_DEVICE_EXTENSION deviceExtension, 00075 IN ULONG dev, // physical device number (0-3) 00076 IN CHAR mode 00077 ); 00078 00079 VOID 00080 NTAPI 00081 via82c_timing ( 00082 IN PHW_DEVICE_EXTENSION deviceExtension, 00083 IN ULONG dev, // physical device number (0-3) 00084 IN CHAR mode 00085 ); 00086 00087 ULONG 00088 NTAPI 00089 hpt_cable80( 00090 IN PHW_DEVICE_EXTENSION deviceExtension, 00091 IN ULONG channel // physical channel number (0-1) 00092 ); 00093 00094 #define ATAPI_DEVICE(de, ldev) (de->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE) 00095 00096 ULONG 00097 NTAPI 00098 AtapiVirtToPhysAddr_( 00099 IN PVOID HwDeviceExtension, 00100 IN PSCSI_REQUEST_BLOCK Srb, 00101 IN PUCHAR data, 00102 IN PULONG count, 00103 OUT PULONG ph_addru 00104 ) 00105 { 00106 PHYSICAL_ADDRESS ph_addr; 00107 ULONG addr; 00108 00109 ph_addr = MmGetPhysicalAddress(data); 00110 if(!ph_addru && ph_addr.HighPart) { 00111 // do so until we add 64bit address support 00112 // or some workaround 00113 *count = 0; 00114 return -1; 00115 } 00116 00117 (*ph_addru) = ph_addr.HighPart; 00118 //addr = ScsiPortConvertPhysicalAddressToUlong(ph_addr); 00119 addr = ph_addr.LowPart; 00120 if(!addr && !ph_addr.HighPart) { 00121 *count = 0; 00122 return 0; 00123 } 00124 if(!Srb) { 00125 *count = sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES; 00126 } else { 00127 *count = PAGE_SIZE - (addr & (PAGE_SIZE-1)); 00128 } 00129 return addr; 00130 } // end AtapiVirtToPhysAddr_() 00131 00132 VOID 00133 NTAPI 00134 AtapiDmaAlloc( 00135 IN PVOID HwDeviceExtension, 00136 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, 00137 IN ULONG lChannel // logical channel, 00138 ) 00139 { 00140 #ifdef USE_OWN_DMA 00141 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00142 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); 00143 ULONG c = lChannel; 00144 ULONG i; 00145 ULONG ph_addru; 00146 00147 deviceExtension->chan[c].CopyDmaBuffer = FALSE; 00148 00149 if(!deviceExtension->Host64 && (WinVer_Id() > WinVer_NT)) { 00150 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: allocate tmp buffers below 4Gb\n")); 00151 chan->DB_PRD = MmAllocateContiguousMemory(sizeof(((PATA_REQ)NULL)->dma_tab), ph4gb); 00152 if(chan->DB_PRD) { 00153 chan->DB_PRD_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->DB_PRD), &i, &ph_addru); 00154 if(!chan->DB_PRD_PhAddr || !i || ((LONG)(chan->DB_PRD_PhAddr) == -1)) { 00155 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD BASE\n" )); 00156 chan->DB_PRD = NULL; 00157 chan->DB_PRD_PhAddr = 0; 00158 return; 00159 } 00160 if(ph_addru) { 00161 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD below 4Gb\n" )); 00162 goto err_1; 00163 } 00164 } 00165 chan->DB_IO = MmAllocateContiguousMemory(deviceExtension->MaximumDmaTransferLength, ph4gb); 00166 if(chan->DB_IO) { 00167 chan->DB_IO_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->DB_IO), &i, &ph_addru); 00168 if(!chan->DB_IO_PhAddr || !i || ((LONG)(chan->DB_IO_PhAddr) == -1)) { 00169 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB IO BASE\n" )); 00170 err_1: 00171 MmFreeContiguousMemory(chan->DB_PRD); 00172 chan->DB_PRD = NULL; 00173 chan->DB_PRD_PhAddr = 0; 00174 chan->DB_IO = NULL; 00175 chan->DB_IO_PhAddr = 0; 00176 return; 00177 } 00178 if(ph_addru) { 00179 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB IO below 4Gb\n" )); 00180 MmFreeContiguousMemory(chan->DB_IO); 00181 goto err_1; 00182 } 00183 } 00184 } 00185 00186 00187 if(deviceExtension->HwFlags & UNIATA_AHCI) { 00188 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: AHCI\n" )); 00189 if(chan->AhciCtlBlock) { 00190 KdPrint2((PRINT_PREFIX " already initialized %x\n", chan->AhciCtlBlock)); 00191 return; 00192 } 00193 // Need 1K-byte alignment 00194 chan->AhciCtlBlock0 = (PIDE_AHCI_CHANNEL_CTL_BLOCK)MmAllocateContiguousMemory( 00195 sizeof(IDE_AHCI_CHANNEL_CTL_BLOCK)+AHCI_CLB_ALIGNEMENT_MASK, 00196 ph4gb); 00197 if(chan->AhciCtlBlock0) { 00198 union { 00199 PUCHAR AhciCtlBlock; 00200 ULONGLONG AhciCtlBlock64; 00201 }; 00202 AhciCtlBlock64 = 0; 00203 AhciCtlBlock = (PUCHAR)chan->AhciCtlBlock0; 00204 00205 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: CLP BASE %I64x\n", AhciCtlBlock64)); 00206 00207 AhciCtlBlock64 += AHCI_CLB_ALIGNEMENT_MASK; 00208 AhciCtlBlock64 &= ~AHCI_CLB_ALIGNEMENT_MASK; 00209 00210 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: CLP BASE 1k-aligned %I64x\n", AhciCtlBlock64)); 00211 00212 chan->AhciCtlBlock = (PIDE_AHCI_CHANNEL_CTL_BLOCK)AhciCtlBlock; 00213 00214 chan->AHCI_CTL_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->AhciCtlBlock), &i, &ph_addru); 00215 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: CLP Phys BASE %I64x\n", chan->AHCI_CTL_PhAddr)); 00216 if(!chan->AHCI_CTL_PhAddr || !i || ((LONG)(chan->AHCI_CTL_PhAddr) == -1)) { 00217 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No AHCI CLP BASE\n" )); 00218 chan->AhciCtlBlock = NULL; 00219 chan->AHCI_CTL_PhAddr = 0; 00220 return; 00221 } 00222 if(ph_addru) { 00223 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No AHCI CLP below 4Gb\n" )); 00224 MmFreeContiguousMemory(chan->AhciCtlBlock0); 00225 chan->AhciCtlBlock = NULL; 00226 chan->AHCI_CTL_PhAddr = 0; 00227 return; 00228 } 00229 } else { 00230 KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: Can't alloc AHCI CLP\n")); 00231 } 00232 } 00233 #endif //USE_OWN_DMA 00234 return; 00235 } // end AtapiDmaAlloc() 00236 00237 BOOLEAN 00238 NTAPI 00239 AtapiDmaSetup( 00240 IN PVOID HwDeviceExtension, 00241 IN ULONG DeviceNumber, 00242 IN ULONG lChannel, // logical channel, 00243 IN PSCSI_REQUEST_BLOCK Srb, 00244 IN PUCHAR data, 00245 IN ULONG count 00246 ) 00247 { 00248 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00249 ULONG dma_count, dma_base, dma_baseu; 00250 ULONG i; 00251 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); 00252 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension); 00253 BOOLEAN use_DB_IO = FALSE; 00254 BOOLEAN use_AHCI = (deviceExtension->HwFlags & UNIATA_AHCI) ? TRUE : FALSE; 00255 ULONG orig_count = count; 00256 ULONG max_entries = use_AHCI ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES; 00257 00258 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION; 00259 00260 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: mode %#x, data %x, count %x, lCh %x, dev %x\n", 00261 chan->lun[DeviceNumber]->TransferMode, 00262 data, count, lChannel, DeviceNumber )); 00263 if(chan->lun[DeviceNumber]->TransferMode < ATA_DMA) { 00264 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: Not DMA mode, assume this is just preparation\n" )); 00265 //return FALSE; 00266 } 00267 //KdPrint2((PRINT_PREFIX " checkpoint 1\n" )); 00268 if(!count) { 00269 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: count=0\n" )); 00270 return FALSE; 00271 } 00272 //KdPrint2((PRINT_PREFIX " checkpoint 2\n" )); 00273 if(count > deviceExtension->MaximumDmaTransferLength) { 00274 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: deviceExtension->MaximumDmaTransferLength > count\n" )); 00275 return FALSE; 00276 } 00277 //KdPrint2((PRINT_PREFIX " checkpoint 3\n" )); 00278 if((ULONG)data & deviceExtension->AlignmentMask) { 00279 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: unaligned data: %#x (%#x)\n", data, deviceExtension->AlignmentMask)); 00280 return FALSE; 00281 } 00282 00283 //KdPrint2((PRINT_PREFIX " checkpoint 4\n" )); 00284 if(use_AHCI) { 00285 KdPrint2((PRINT_PREFIX " get Phys(AHCI_CMD=%x)\n", &(AtaReq->ahci.ahci_cmd_ptr->prd_tab) )); 00286 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab), &i, &dma_baseu); 00287 AtaReq->ahci.ahci_base64 = NULL; // clear before setup 00288 } else { 00289 KdPrint2((PRINT_PREFIX " get Phys(PRD=%x)\n", &(AtaReq->dma_tab) )); 00290 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)&(AtaReq->dma_tab) /*chan->dma_tab*/, &i, &dma_baseu); 00291 } 00292 if(dma_baseu) { 00293 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: SRB built-in PRD above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); 00294 if(!deviceExtension->Host64) { 00295 dma_base = chan->DB_PRD_PhAddr; 00296 AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD; 00297 i = 1; 00298 } 00299 } else 00300 if(!dma_base || !i || ((LONG)(dma_base) == -1)) { 00301 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No BASE\n" )); 00302 return FALSE; 00303 } 00304 AtaReq->ata.dma_base = dma_base; // aliased to ahci_base64 00305 00306 KdPrint2((PRINT_PREFIX " get Phys(data=%x)\n", data )); 00307 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu); 00308 if(dma_baseu) { 00309 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: 1st block of buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); 00310 if(!deviceExtension->Host64) { 00311 retry_DB_IO: 00312 use_DB_IO = TRUE; 00313 dma_base = chan->DB_IO_PhAddr; 00314 data = (PUCHAR)(chan->DB_IO); 00315 } else { 00316 AtaReq->ahci.ahci_base64 = (ULONGLONG)dma_base | ((ULONGLONG)dma_baseu << 32); 00317 } 00318 } else 00319 if(!dma_count || ((LONG)(dma_base) == -1)) { 00320 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No 1st block\n" )); 00321 //AtaReq->dma_base = NULL; 00322 AtaReq->ahci.ahci_base64 = NULL; 00323 return FALSE; 00324 } 00325 00326 dma_count = min(count, (PAGE_SIZE - ((ULONG)data & PAGE_MASK))); 00327 data += dma_count; 00328 count -= dma_count; 00329 i = 0; 00330 00331 while (count) { 00332 if(use_AHCI) { 00333 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].base = dma_base; 00334 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].baseu = dma_baseu; 00335 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC = ((dma_count-1) & 0x3fffff); 00336 } else { 00337 AtaReq->dma_tab[i].base = dma_base; 00338 AtaReq->dma_tab[i].count = (dma_count & 0xffff); 00339 } 00340 i++; 00341 if (i >= max_entries) { 00342 KdPrint2((PRINT_PREFIX "too many segments in DMA table\n" )); 00343 //AtaReq->dma_base = NULL; 00344 AtaReq->ahci.ahci_base64 = NULL; 00345 return FALSE; 00346 } 00347 KdPrint2((PRINT_PREFIX " get Phys(data[n]=%x)\n", data )); 00348 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu); 00349 if(dma_baseu) { 00350 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: block of buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); 00351 if(!deviceExtension->Host64) { 00352 if(use_DB_IO) { 00353 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: *ERROR* special buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); 00354 return FALSE; 00355 } 00356 count = orig_count; 00357 goto retry_DB_IO; 00358 } 00359 } else 00360 if(!dma_count || !dma_base || ((LONG)(dma_base) == -1)) { 00361 //AtaReq->dma_base = NULL; 00362 AtaReq->ahci.ahci_base64 = 0; 00363 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No NEXT block\n" )); 00364 return FALSE; 00365 } 00366 00367 dma_count = min(count, PAGE_SIZE); 00368 data += min(count, PAGE_SIZE); 00369 count -= min(count, PAGE_SIZE); 00370 } 00371 KdPrint2((PRINT_PREFIX " set TERM\n" )); 00372 if(use_AHCI) { 00373 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].base = dma_base; 00374 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].baseu = dma_baseu; 00375 AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC = ((dma_count-1) & 0x3fffff); 00376 } else { 00377 AtaReq->dma_tab[i].base = dma_base; 00378 AtaReq->dma_tab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; 00379 } 00380 AtaReq->dma_entries = i; 00381 00382 if(use_DB_IO) { 00383 AtaReq->Flags |= REQ_FLAG_DMA_DBUF; 00384 } 00385 AtaReq->Flags |= REQ_FLAG_DMA_OPERATION; 00386 00387 KdPrint2((PRINT_PREFIX "AtapiDmaSetup: OK\n" )); 00388 return TRUE; 00389 00390 } // end AtapiDmaSetup() 00391 00392 BOOLEAN 00393 NTAPI 00394 AtapiDmaPioSync( 00395 PVOID HwDeviceExtension, 00396 PSCSI_REQUEST_BLOCK Srb, 00397 PUCHAR data, 00398 ULONG count 00399 ) 00400 { 00401 #ifndef USE_OWN_DMA 00402 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00403 ULONG dma_base; 00404 PUCHAR DmaBuffer; 00405 ULONG dma_count; 00406 ULONG len; 00407 PATA_REQ AtaReq; 00408 00409 // This must never be called after DMA operation !!! 00410 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: data %#x, len %#x\n", data, count)); 00411 00412 if(!Srb) { 00413 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !Srb\n" )); 00414 return FALSE; 00415 } 00416 00417 AtaReq = (PATA_REQ)(Srb->SrbExtension); 00418 00419 // do nothing on PCI (This can be changed. We cannot guarantee, 00420 // that CommonBuffer will always point to User's buffer, 00421 // however, this usually happens on PCI-32) 00422 if(deviceExtension->OrigAdapterInterfaceType == PCIBus) { 00423 return TRUE; 00424 } 00425 // do nothing for DMA 00426 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) { 00427 return TRUE; 00428 } 00429 00430 if(!data) { 00431 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !data\n" )); 00432 return FALSE; 00433 } 00434 00435 while(count) { 00436 dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count); 00437 if(!dma_base) { 00438 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !dma_base for data %#x\n", data)); 00439 return FALSE; 00440 } 00441 DmaBuffer = (PUCHAR)ScsiPortGetVirtualAddress(HwDeviceExtension, 00442 ScsiPortConvertUlongToPhysicalAddress(dma_base)); 00443 if(!DmaBuffer) { 00444 KdPrint2((PRINT_PREFIX "AtapiDmaPioSync: !DmaBuffer for dma_base %#x\n", dma_base)); 00445 return FALSE; 00446 } 00447 len = min(dma_count, count); 00448 memcpy(DmaBuffer, data, len); 00449 count -= len; 00450 data += len; 00451 } 00452 #endif //USE_OWN_DMA 00453 00454 return TRUE; 00455 } // end AtapiDmaPioSync() 00456 00457 BOOLEAN 00458 NTAPI 00459 AtapiDmaDBSync( 00460 PHW_CHANNEL chan, 00461 PSCSI_REQUEST_BLOCK Srb 00462 ) 00463 { 00464 PATA_REQ AtaReq; 00465 00466 AtaReq = (PATA_REQ)(Srb->SrbExtension); 00467 if((Srb->SrbFlags & SRB_FLAGS_DATA_IN) && 00468 (AtaReq->Flags & REQ_FLAG_DMA_DBUF)) { 00469 KdPrint2((PRINT_PREFIX " AtapiDmaDBSync is issued.\n")); 00470 ASSERT(FALSE); 00471 KdPrint2((PRINT_PREFIX " DBUF (Read)\n")); 00472 RtlCopyMemory(AtaReq->DataBuffer, chan->DB_IO, 00473 Srb->DataTransferLength); 00474 } 00475 return TRUE; 00476 } // end AtapiDmaDBSync() 00477 00478 VOID 00479 NTAPI 00480 AtapiDmaStart( 00481 IN PVOID HwDeviceExtension, 00482 IN ULONG DeviceNumber, 00483 IN ULONG lChannel, // logical channel, 00484 IN PSCSI_REQUEST_BLOCK Srb 00485 ) 00486 { 00487 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00488 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM = deviceExtension->BaseIoAddressBM[lChannel]; 00489 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension); 00490 PHW_CHANNEL chan = &deviceExtension->chan[lChannel]; 00491 00492 ULONG VendorID = deviceExtension->DevID & 0xffff; 00493 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; 00494 00495 KdPrint2((PRINT_PREFIX "AtapiDmaStart: %s on %#x:%#x\n", 00496 (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "read" : "write", 00497 lChannel, DeviceNumber )); 00498 00499 if(!AtaReq->ata.dma_base) { 00500 KdPrint2((PRINT_PREFIX "AtapiDmaStart: *** !AtaReq->ata.dma_base\n")); 00501 return; 00502 } 00503 if(AtaReq->Flags & REQ_FLAG_DMA_DBUF_PRD) { 00504 KdPrint2((PRINT_PREFIX " DBUF_PRD\n")); 00505 ASSERT(FALSE); 00506 if(deviceExtension->HwFlags & UNIATA_AHCI) { 00507 RtlCopyMemory(chan->DB_PRD, AtaReq->ahci.ahci_cmd_ptr, sizeof(AtaReq->ahci_cmd0)); 00508 } else { 00509 RtlCopyMemory(chan->DB_PRD, &(AtaReq->dma_tab), sizeof(AtaReq->dma_tab)); 00510 } 00511 } 00512 if(!(Srb->SrbFlags & SRB_FLAGS_DATA_IN) && 00513 (AtaReq->Flags & REQ_FLAG_DMA_DBUF)) { 00514 KdPrint2((PRINT_PREFIX " DBUF (Write)\n")); 00515 ASSERT(FALSE); 00516 RtlCopyMemory(chan->DB_IO, AtaReq->DataBuffer, 00517 Srb->DataTransferLength); 00518 } 00519 00520 // set flag 00521 chan->ChannelCtrlFlags |= CTRFLAGS_DMA_ACTIVE; 00522 00523 switch(VendorID) { 00524 case ATA_PROMISE_ID: 00525 if(ChipType == PRNEW) { 00526 ULONG Channel = deviceExtension->Channel + lChannel; 00527 if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) { 00528 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11, 00529 AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) | 00530 (Channel ? 0x08 : 0x02)); 00531 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(Channel ? 0x24 : 0x20), 00532 ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x05000000 : 0x06000000) | (Srb->DataTransferLength >> 1) 00533 ); 00534 } 00535 /* 00536 } else 00537 if(deviceExtension->MemIo) { 00538 // begin transaction 00539 AtapiWritePort4(chan, 00540 IDX_BM_Command, 00541 (AtapiReadPort4(chan, 00542 IDX_BM_Command) & ~0x000000c0) | 00543 ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x00000080 : 0x000000c0) ); 00544 return; 00545 */ 00546 } 00547 break; 00548 } 00549 00550 // set pointer to Pointer Table 00551 AtapiWritePort4(chan, IDX_BM_PRD_Table, 00552 AtaReq->ata.dma_base 00553 ); 00554 // set transfer direction 00555 AtapiWritePort1(chan, IDX_BM_Command, 00556 (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? BM_COMMAND_READ : BM_COMMAND_WRITE); 00557 // clear Error & Intr bits (writeing 1 clears bits) 00558 // set DMA capability bit 00559 AtapiWritePort1(chan, IDX_BM_Status, 00560 AtapiReadPort1(chan, IDX_BM_Status) | 00561 (BM_STATUS_INTR | BM_STATUS_ERR) /*| 00562 (DeviceNumber ? BM_STATUS_DRIVE_1_DMA : BM_STATUS_DRIVE_0_DMA)*/); 00563 // begin transaction 00564 AtapiWritePort1(chan, IDX_BM_Command, 00565 AtapiReadPort1(chan, IDX_BM_Command) | 00566 BM_COMMAND_START_STOP); 00567 return; 00568 00569 } // end AtapiDmaStart() 00570 00571 UCHAR 00572 NTAPI 00573 AtapiDmaDone( 00574 IN PVOID HwDeviceExtension, 00575 IN ULONG DeviceNumber, 00576 IN ULONG lChannel, // logical channel, 00577 IN PSCSI_REQUEST_BLOCK Srb 00578 ) 00579 { 00580 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00581 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM = deviceExtension->BaseIoAddressBM[lChannel]; 00582 PHW_CHANNEL chan = &deviceExtension->chan[lChannel]; 00583 UCHAR dma_status; 00584 00585 ULONG VendorID = deviceExtension->DevID & 0xffff; 00586 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; 00587 00588 KdPrint2((PRINT_PREFIX "AtapiDmaDone: dev %d\n", DeviceNumber)); 00589 00590 if(deviceExtension->HwFlags & UNIATA_AHCI) { 00591 KdPrint2((PRINT_PREFIX " ACHTUNG! should not be called for AHCI!\n")); 00592 return 0xff; 00593 } 00594 00595 switch(VendorID) { 00596 case ATA_PROMISE_ID: 00597 if(ChipType == PRNEW) { 00598 ULONG Channel = deviceExtension->Channel + lChannel; 00599 if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) { 00600 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11, 00601 AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) & 00602 ~(Channel ? 0x08 : 0x02)); 00603 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(Channel ? 0x24 : 0x20), 00604 0 00605 ); 00606 } 00607 /* 00608 } else 00609 if(deviceExtension->MemIo) { 00610 // end transaction 00611 AtapiWritePort4(chan, 00612 IDX_BM_Command, 00613 (AtapiReadPort4(chan, 00614 IDX_BM_Command) & ~0x00000080) ); 00615 // clear flag 00616 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_ACTIVE; 00617 return 0; 00618 */ 00619 } 00620 break; 00621 } 00622 00623 // get status 00624 dma_status = AtapiReadPort1(chan, IDX_BM_Status) & BM_STATUS_MASK; 00625 // end transaction 00626 AtapiWritePort1(chan, IDX_BM_Command, 00627 AtapiReadPort1(chan, IDX_BM_Command) & 00628 ~BM_COMMAND_START_STOP); 00629 // clear interrupt and error status 00630 AtapiWritePort1(chan, IDX_BM_Status, BM_STATUS_ERR | BM_STATUS_INTR); 00631 // clear flag 00632 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_ACTIVE; 00633 00634 return dma_status; 00635 00636 } // end AtapiDmaDone() 00637 00638 VOID 00639 NTAPI 00640 AtapiDmaReinit( 00641 IN PHW_DEVICE_EXTENSION deviceExtension, 00642 IN PHW_LU_EXTENSION LunExt, 00643 IN PATA_REQ AtaReq 00644 ) 00645 { 00646 SCHAR apiomode; 00647 00648 apiomode = (CHAR)AtaPioMode(&(LunExt->IdentifyData)); 00649 00650 if(!(AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) { 00651 KdPrint2((PRINT_PREFIX 00652 "AtapiDmaReinit: !(AtaReq->Flags & REQ_FLAG_DMA_OPERATION), fall to PIO on Device %d\n", LunExt->Lun)); 00653 goto limit_pio; 00654 } 00655 if(deviceExtension->HwFlags & UNIATA_AHCI) { 00656 if(!AtaReq->ahci.ahci_base64) { 00657 KdPrint2((PRINT_PREFIX 00658 "AtapiDmaReinit: no AHCI PRD, fall to PIO on Device %d\n", LunExt->Lun)); 00659 goto limit_pio; 00660 } 00661 } else 00662 if(!AtaReq->ata.dma_base) { 00663 KdPrint2((PRINT_PREFIX 00664 "AtapiDmaReinit: no PRD, fall to PIO on Device %d\n", LunExt->Lun)); 00665 goto limit_pio; 00666 } 00667 00668 if((deviceExtension->HbaCtrlFlags & HBAFLAGS_DMA_DISABLED_LBA48) && 00669 (AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) && 00670 (LunExt->TransferMode > ATA_PIO5) ) { 00671 KdPrint2((PRINT_PREFIX 00672 "AtapiDmaReinit: FORCE_DOWNRATE on Device %d for LBA48\n", LunExt->Lun)); 00673 goto limit_lba48; 00674 } 00675 00676 00677 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) { 00678 KdPrint2((PRINT_PREFIX 00679 "AtapiDmaReinit: FORCE_DOWNRATE on Device %d\n", LunExt->Lun)); 00680 if(AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) { 00681 limit_lba48: 00682 LunExt->DeviceFlags |= REQ_FLAG_FORCE_DOWNRATE_LBA48; 00683 limit_pio: 00684 // do not make extra work if we already use PIO 00685 if(/*LunExt->TransferMode >= ATA_DMA*/ 00686 (LunExt->TransferMode > ATA_PIO5) && (LunExt->TransferMode != ATA_PIO0+apiomode) 00687 ) { 00688 KdPrint2((PRINT_PREFIX 00689 "AtapiDmaReinit: set PIO mode on Device %d (%x -> %x)\n", LunExt->Lun, LunExt->TransferMode, ATA_PIO0+apiomode)); 00690 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel, 00691 apiomode, 00692 -1, 00693 -1 ); 00694 } else 00695 if(LunExt->LimitedTransferMode < LunExt->TransferMode) { 00696 KdPrint2((PRINT_PREFIX 00697 "AtapiDmaReinit: set PIO mode on Device %d (%x -> %x) (2)\n", LunExt->Lun, LunExt->TransferMode, LunExt->LimitedTransferMode)); 00698 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel, 00699 LunExt->LimitedTransferMode-ATA_PIO0, 00700 -1, 00701 -1 ); 00702 } 00703 00704 } else { 00705 KdPrint2((PRINT_PREFIX 00706 "AtapiDmaReinit: set MAX mode on Device %d\n", LunExt->Lun)); 00707 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel, 00708 apiomode, 00709 min( retry_Wdma[AtaReq->retry], 00710 (CHAR)AtaWmode(&(LunExt->IdentifyData)) ), 00711 min( retry_Udma[AtaReq->retry], 00712 (CHAR)AtaUmode(&(LunExt->IdentifyData)) ) ); 00713 } 00714 // LunExt->DeviceFlags &= ~DFLAGS_FORCE_DOWNRATE; 00715 } else 00716 if( 00717 (LunExt->LimitedTransferMode > 00718 LunExt->TransferMode) || 00719 (LunExt->DeviceFlags & DFLAGS_REINIT_DMA)) { 00720 // restore IO mode 00721 KdPrint2((PRINT_PREFIX 00722 "AtapiDmaReinit: restore IO mode on Device %d\n", LunExt->Lun)); 00723 AtapiDmaInit__(deviceExtension, LunExt); 00724 } 00725 } // end AtapiDmaReinit() 00726 00727 VOID 00728 NTAPI 00729 AtapiDmaInit__( 00730 IN PHW_DEVICE_EXTENSION deviceExtension, 00731 IN PHW_LU_EXTENSION LunExt 00732 ) 00733 { 00734 if(LunExt->IdentifyData.SupportDma) { 00735 KdPrint2((PRINT_PREFIX 00736 "AtapiDmaInit__: Set (U)DMA on Device %d\n", LunExt->Lun)); 00737 /* for(i=AtaUmode(&(LunExt->IdentifyData)); i>=0; i--) { 00738 AtapiDmaInit(deviceExtension, ldev & 1, ldev >> 1, 00739 (CHAR)AtaPioMode(&(LunExt->IdentifyData)), 00740 (CHAR)AtaWmode(&(LunExt->IdentifyData)), 00741 UDMA_MODE0+(CHAR)i ); 00742 } 00743 for(i=AtaWmode(&(LunExt->IdentifyData)); i>=0; i--) { 00744 AtapiDmaInit(deviceExtension, ldev & 1, ldev >> 1, 00745 (CHAR)AtaPioMode(&(LunExt->IdentifyData)), 00746 (CHAR)AtaWmode(&(LunExt->IdentifyData)), 00747 UDMA_MODE0+(CHAR)i ); 00748 }*/ 00749 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel, 00750 (CHAR)AtaPioMode(&(LunExt->IdentifyData)), 00751 (CHAR)AtaWmode(&(LunExt->IdentifyData)), 00752 (CHAR)AtaUmode(&(LunExt->IdentifyData)) ); 00753 } else { 00754 KdPrint2((PRINT_PREFIX 00755 "AtapiDmaInit__: Set PIO on Device %d\n", LunExt->Lun)); 00756 AtapiDmaInit(deviceExtension, LunExt->Lun, LunExt->chan->lChannel, 00757 (CHAR)AtaPioMode(&(LunExt->IdentifyData)), -1, -1); 00758 } 00759 } // end AtapiDmaInit__() 00760 00761 BOOLEAN 00762 NTAPI 00763 AtaSetTransferMode( 00764 IN PHW_DEVICE_EXTENSION deviceExtension, 00765 IN ULONG DeviceNumber, 00766 IN ULONG lChannel, // logical channel, 00767 IN PHW_LU_EXTENSION LunExt, 00768 IN ULONG mode 00769 ) 00770 { 00771 KdPrint3((PRINT_PREFIX 00772 "AtaSetTransferMode: Set %#x on Device %d/%d\n", mode, lChannel, DeviceNumber)); 00773 LONG statusByte = 0; 00774 CHAR apiomode; 00775 00776 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, 00777 IDE_COMMAND_SET_FEATURES, 0, 0, 0, 00778 (UCHAR)((mode > ATA_UDMA6) ? ATA_UDMA6 : mode), ATA_C_F_SETXFER, ATA_WAIT_BASE_READY); 00779 if(statusByte & IDE_STATUS_ERROR) { 00780 KdPrint3((PRINT_PREFIX " wait ready after error\n")); 00781 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) { 00782 AtapiStallExecution(10); 00783 } else { 00784 AtapiStallExecution(100); 00785 } 00786 apiomode = (CHAR)AtaPioMode(&(LunExt->IdentifyData)); 00787 if( (apiomode > 0) && 00788 ((CHAR)AtaWmode(&(LunExt->IdentifyData)) > 0) && 00789 ((CHAR)AtaUmode(&(LunExt->IdentifyData)) > 0) 00790 ) { 00791 return FALSE; 00792 } 00793 if(mode > ATA_PIO2) { 00794 return FALSE; 00795 } 00796 KdPrint3((PRINT_PREFIX " assume that drive doesn't support mode swithing using PIO%d\n", apiomode)); 00797 mode = ATA_PIO0 + apiomode; 00798 } 00799 //if(mode <= ATA_UDMA6) { 00800 LunExt->TransferMode = (UCHAR)mode; 00801 //} 00802 return TRUE; 00803 } // end AtaSetTransferMode() 00804 00805 VOID 00806 NTAPI 00807 AtapiDmaInit( 00808 IN PVOID HwDeviceExtension, 00809 IN ULONG DeviceNumber, 00810 IN ULONG lChannel, // logical channel, 00811 // is always 0 except simplex-only controllers 00812 IN SCHAR apiomode, 00813 IN SCHAR wdmamode, 00814 IN SCHAR udmamode 00815 ) 00816 { 00817 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; 00818 ULONG Channel = deviceExtension->Channel + lChannel; 00819 PHW_CHANNEL chan = &deviceExtension->chan[lChannel]; 00820 //LONG statusByte = 0; 00821 ULONG dev = Channel*2 + DeviceNumber; // for non-SATA/AHCI only! 00822 ULONG ldev = lChannel*2 + DeviceNumber; // for non-SATA/AHCI only! 00823 ULONG slotNumber = deviceExtension->slotNumber; 00824 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber; 00825 LONG i; 00826 PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber]; 00827 00828 ULONG VendorID = deviceExtension->DevID & 0xffff; 00829 //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff; 00830 //ULONG RevID = deviceExtension->RevID; 00831 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; 00832 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK; 00833 00834 LONG statusByte = 0; 00835 00836 //UCHAR *reg_val = NULL; 00837 00838 LunExt->DeviceFlags &= ~DFLAGS_REINIT_DMA; 00839 /* set our most pessimistic default mode */ 00840 LunExt->TransferMode = ATA_PIO; 00841 // if(!deviceExtension->BaseIoAddressBM[lChannel]) { 00842 if(!deviceExtension->BusMaster) { 00843 KdPrint2((PRINT_PREFIX " !deviceExtension->BusMaster: NO DMA\n")); 00844 wdmamode = udmamode = -1; 00845 } 00846 00847 // Limit transfer mode (controller limitation) 00848 if((LONG)deviceExtension->MaxTransferMode >= ATA_UDMA) { 00849 KdPrint2((PRINT_PREFIX "AtapiDmaInit: deviceExtension->MaxTransferMode >= ATA_UDMA\n")); 00850 udmamode = min( udmamode, (CHAR)(deviceExtension->MaxTransferMode - ATA_UDMA)); 00851 } else 00852 if((LONG)deviceExtension->MaxTransferMode >= ATA_WDMA) { 00853 KdPrint2((PRINT_PREFIX "AtapiDmaInit: deviceExtension->MaxTransferMode >= ATA_WDMA\n")); 00854 udmamode = -1; 00855 wdmamode = min( wdmamode, (CHAR)(deviceExtension->MaxTransferMode - ATA_WDMA)); 00856 } else 00857 if((LONG)deviceExtension->MaxTransferMode >= ATA_PIO0) { 00858 KdPrint2((PRINT_PREFIX "AtapiDmaInit: NO DMA\n")); 00859 wdmamode = udmamode = -1; 00860 apiomode = min( apiomode, (CHAR)(deviceExtension->MaxTransferMode - ATA_PIO0)); 00861 } else { 00862 KdPrint2((PRINT_PREFIX "AtapiDmaInit: PIO0\n")); 00863 wdmamode = udmamode = -1; 00864 apiomode = 0; 00865 } 00866 // Limit transfer mode (device limitation) 00867 KdPrint2((PRINT_PREFIX "AtapiDmaInit: LunExt->LimitedTransferMode %#x\n", LunExt->LimitedTransferMode)); 00868 if((LONG)LunExt->LimitedTransferMode >= ATA_UDMA) { 00869 KdPrint2((PRINT_PREFIX "AtapiDmaInit: LunExt->MaxTransferMode >= ATA_UDMA => %#x\n", 00870 min( udmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_UDMA)) 00871 )); 00872 udmamode = min( udmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_UDMA)); 00873 } else 00874 if((LONG)LunExt->LimitedTransferMode >= ATA_WDMA) { 00875 KdPrint2((PRINT_PREFIX "AtapiDmaInit: LunExt->MaxTransferMode >= ATA_WDMA => %#x\n", 00876 min( wdmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_WDMA)) 00877 )); 00878 udmamode = -1; 00879 wdmamode = min( wdmamode, (CHAR)(LunExt->LimitedTransferMode - ATA_WDMA)); 00880 } else 00881 if((LONG)LunExt->LimitedTransferMode >= ATA_PIO0) { 00882 KdPrint2((PRINT_PREFIX "AtapiDmaInit: lun NO DMA\n")); 00883 wdmamode = udmamode = -1; 00884 apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0)); 00885 } else { 00886 KdPrint2((PRINT_PREFIX "AtapiDmaInit: lun PIO0\n")); 00887 wdmamode = udmamode = -1; 00888 apiomode = 0; 00889 } 00890 00891 SelectDrive(chan, DeviceNumber); 00892 GetStatus(chan, statusByte); 00893 // we can see here IDE_STATUS_ERROR status after previous operation 00894 if(statusByte & IDE_STATUS_ERROR) { 00895 KdPrint2((PRINT_PREFIX "IDE_STATUS_ERROR detected on entry, statusByte = %#x\n", statusByte)); 00896 //GetBaseStatus(chan, statusByte); 00897 } 00898 if(statusByte && UniataIsIdle(deviceExtension, statusByte & ~IDE_STATUS_ERROR) != IDE_STATUS_IDLE) { 00899 KdPrint2((PRINT_PREFIX "Can't setup transfer mode: statusByte = %#x\n", statusByte)); 00900 return; 00901 } 00902 00903 if(deviceExtension->UnknownDev) { 00904 KdPrint2((PRINT_PREFIX "Unknown chip, omit Vendor/Dev checks\n")); 00905 goto try_generic_dma; 00906 } 00907 00908 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { 00909 //if(ChipFlags & UNIATA_SATA) { 00910 /****************/ 00911 /* SATA Generic */ 00912 /****************/ 00913 UCHAR ModeByte; 00914 00915 KdPrint2((PRINT_PREFIX "SATA Generic\n")); 00916 if(udmamode > 5) { 00917 if(LunExt->IdentifyData.SataCapabilities != 0x0000 && 00918 LunExt->IdentifyData.SataCapabilities != 0xffff) { 00919 //udmamode = min(udmamode, 6); 00920 KdPrint2((PRINT_PREFIX "LunExt->LimitedTransferMode %x, LunExt->OrigTransferMode %x\n", 00921 LunExt->LimitedTransferMode, LunExt->OrigTransferMode)); 00922 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode))) { 00923 return; 00924 } 00925 udmamode = min(udmamode, 5); 00926 00927 } else { 00928 KdPrint2((PRINT_PREFIX "SATA -> PATA adapter ?\n")); 00929 if (udmamode > 2 && !LunExt->IdentifyData.HwResCableId) { 00930 KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n")); 00931 udmamode = 2; 00932 apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0)); 00933 } else { 00934 udmamode = min(udmamode, 5); 00935 } 00936 } 00937 } 00938 if(udmamode >= 0) { 00939 ModeByte = ATA_UDMA0 + udmamode; 00940 } else 00941 if(wdmamode >= 0) { 00942 ModeByte = ATA_WDMA0 + wdmamode; 00943 } else 00944 if(apiomode >= 0) { 00945 ModeByte = ATA_PIO0 + apiomode; 00946 } else { 00947 ModeByte = ATA_PIO; 00948 } 00949 00950 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ModeByte); 00951 return; 00952 } 00953 if(udmamode > 2 && !LunExt->IdentifyData.HwResCableId) { 00954 KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n")); 00955 udmamode = 2; 00956 apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO)); 00957 } 00958 00959 KdPrint2((PRINT_PREFIX "Setup chip a:w:u=%d:%d:%d\n", 00960 apiomode, 00961 wdmamode, 00962 udmamode)); 00963 00964 switch(VendorID) { 00965 case ATA_ACARD_ID: { 00966 /*********/ 00967 /* Acard */ 00968 /*********/ 00969 static const USHORT reg4a = 0xa6; 00970 UCHAR reg = 0x40 + (UCHAR)dev; 00971 00972 if(ChipType == ATPOLD) { 00973 /* Old Acard 850 */ 00974 static const USHORT reg4x = 0x0301; 00975 00976 for(i=udmamode; i>=0; i--) { 00977 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA + i)) { 00978 set_old_acard: 00979 ChangePciConfig1(0x54, a | (0x01 << dev) | ((i+1) << (dev*2))); 00980 SetPciConfig1(0x4a, reg4a); 00981 SetPciConfig2(reg, reg4x); 00982 return; 00983 } 00984 00985 } 00986 if (wdmamode >= 2 && apiomode >= 4) { 00987 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { 00988 goto set_old_acard; 00989 } 00990 } 00991 } else { 00992 /* New Acard 86X */ 00993 static const UCHAR reg4x = 0x31; 00994 00995 for(i=udmamode; i>=0; i--) { 00996 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA + i)) { 00997 set_new_acard: 00998 ChangePciConfig2(0x44, (a & ~(0x000f << (dev * 4))) | ((i+1) << (dev*4))); 00999 SetPciConfig1(0x4a, reg4a); 01000 SetPciConfig1(reg, reg4x); 01001 return; 01002 } 01003 01004 } 01005 if (wdmamode >= 2 && apiomode >= 4) { 01006 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { 01007 goto set_new_acard; 01008 } 01009 } 01010 } 01011 /* Use GENERIC PIO */ 01012 break; } 01013 case ATA_ACER_LABS_ID: { 01014 /************************/ 01015 /* Acer Labs Inc. (ALI) */ 01016 /************************/ 01017 static const UCHAR ali_udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f}; 01018 static const ULONG ali_pio[] = 01019 { 0x006d0003, 0x00580002, 0x00440001, 0x00330001, 01020 0x00310001, 0x00440001}; 01021 /* the older Aladdin doesn't support ATAPI DMA on both master & slave */ 01022 if ((ChipFlags & ALIOLD) && 01023 (udmamode >= 0 || wdmamode >= 0)) { 01024 if(ATAPI_DEVICE(deviceExtension, lChannel*2) && 01025 ATAPI_DEVICE(deviceExtension, lChannel*2 + 1)) { 01026 // 2 devices on this channel - NO DMA 01027 chan->MaxTransferMode = 01028 min(chan->MaxTransferMode, ATA_PIO4); 01029 udmamode = wdmamode = -1; 01030 break; 01031 } 01032 } 01033 for(i=udmamode; i>=0; i--) { 01034 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01035 ULONG word54; 01036 01037 GetPciConfig4(0x54, word54); 01038 word54 &= ~(0x000f000f << (dev * 4)); 01039 word54 |= (((ali_udma[i]<<16) | 5) << (dev * 4)); 01040 SetPciConfig4(0x54, word54); 01041 ChangePciConfig1(0x53, a | 0x03); 01042 SetPciConfig4(0x58 + (Channel<<2), 0x00310001); 01043 return; 01044 } 01045 } 01046 /* make sure eventual UDMA mode from the BIOS is disabled */ 01047 ChangePciConfig2(0x56, a & ~(0x0008 << (dev * 4)) ); 01048 if (wdmamode >= 2 && apiomode >= 4) { 01049 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { 01050 ChangePciConfig1(0x53, a | 0x03); 01051 chan->ChannelCtrlFlags |= CTRFLAGS_DMA_RO; 01052 return; 01053 } 01054 } 01055 ChangePciConfig1(0x53, (a & ~0x01) | 0x02); 01056 01057 for(i=apiomode; i>=0; i--) { 01058 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + i)) { 01059 ChangePciConfig4(0x54, a & ~(0x0008000f << (dev * 4))); 01060 SetPciConfig4(0x58 + (Channel<<2), ali_pio[i]); 01061 return; 01062 } 01063 } 01064 return; 01065 break; } 01066 case ATA_AMD_ID: 01067 case ATA_NVIDIA_ID: 01068 case ATA_VIA_ID: { 01069 /********************/ 01070 /* AMD, nVidia, VIA */ 01071 /********************/ 01072 if((VendorID == ATA_VIA_ID) && 01073 (ChipFlags & VIASATA) && 01074 (Channel == 0)) { 01075 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_SA150); 01076 return; 01077 } 01078 01079 static const UCHAR via_modes[5][7] = { 01080 { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* ATA33 and New Chips */ 01081 { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* ATA66 */ 01082 { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* ATA100 */ 01083 { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 }, /* VIA ATA133 */ 01084 { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }}; /* AMD/nVIDIA */ 01085 static const UCHAR via_pio[] = 01086 { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20, 01087 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; 01088 const UCHAR *reg_val = NULL; 01089 UCHAR reg = 0x53-(UCHAR)dev; 01090 01091 reg_val = &via_modes[ChipType][0]; 01092 01093 if(VendorID == ATA_NVIDIA_ID) 01094 reg += 0x10; 01095 01096 for(i = udmamode; i>=0; i--) { 01097 SetPciConfig1(reg-0x08, via_pio[8+i]); 01098 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01099 SetPciConfig1(reg, (UCHAR)reg_val[i]); 01100 return; 01101 } 01102 } 01103 if(!(ChipFlags & VIABAR)) { 01104 /* This chip can't do WDMA. */ 01105 for(i = wdmamode; i>=0; i--) { 01106 SetPciConfig1(reg-0x08, via_pio[5+i]); 01107 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01108 SetPciConfig1(reg, 0x8b); 01109 return; 01110 } 01111 } 01112 } 01113 /* set PIO mode timings */ 01114 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01115 if((apiomode >= 0) && (ChipType != VIA133)) { 01116 SetPciConfig1(reg-0x08, via_pio[apiomode]); 01117 } 01118 via82c_timing(deviceExtension, dev, ATA_PIO0 + apiomode); 01119 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01120 return; 01121 01122 break; } 01123 case ATA_CYRIX_ID: { 01124 /*********/ 01125 /* Cyrix */ 01126 /*********/ 01127 ULONG cyr_piotiming[] = 01128 { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 }; 01129 ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 }; 01130 ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 }; 01131 ULONG mode_reg = 0x24+(dev << 3); 01132 01133 if(apiomode >= 4) 01134 apiomode = 4; 01135 for(i=udmamode; i>=0; i--) { 01136 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01137 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]); 01138 return; 01139 } 01140 } 01141 for(i=wdmamode; i>=0; i--) { 01142 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01143 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]); 01144 return; 01145 } 01146 } 01147 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { 01148 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]); 01149 return; 01150 } 01151 return; 01152 01153 break; } 01154 case ATA_NATIONAL_ID: { 01155 /************/ 01156 /* National */ 01157 /************/ 01158 ULONG nat_piotiming[] = 01159 { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010, 01160 0x00803020, 0x20102010, 0x00100010, 01161 0x00100010, 0x00100010, 0x00100010 }; 01162 ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 }; 01163 ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 }; 01164 01165 if(apiomode >= 4) 01166 apiomode = 4; 01167 for(i=udmamode; i>=0; i--) { 01168 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01169 SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]); 01170 SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]); 01171 return; 01172 } 01173 } 01174 for(i=wdmamode; i>=0; i--) { 01175 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01176 SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]); 01177 SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]); 01178 return; 01179 } 01180 } 01181 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { 01182 ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000); 01183 SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]); 01184 return; 01185 } 01186 /* Use GENERIC PIO */ 01187 break; } 01188 case ATA_CYPRESS_ID: 01189 /***********/ 01190 /* Cypress */ 01191 /***********/ 01192 if (wdmamode >= 2 && apiomode >= 4) { 01193 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { 01194 SetPciConfig2(Channel ? 0x4e:0x4c, 0x2020); 01195 return; 01196 } 01197 } 01198 /* Use GENERIC PIO */ 01199 break; 01200 case ATA_MARVELL_ID: 01201 /***********/ 01202 /* Marvell */ 01203 /***********/ 01204 for(i=udmamode; i>=0; i--) { 01205 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01206 return; 01207 } 01208 } 01209 for(i=wdmamode; i>=0; i--) { 01210 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01211 return; 01212 } 01213 } 01214 /* try generic DMA, use hpt_timing() */ 01215 if (wdmamode >= 0 && apiomode >= 4) { 01216 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) { 01217 return; 01218 } 01219 } 01220 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01221 return; 01222 break; 01223 case ATA_NETCELL_ID: 01224 /***********/ 01225 /* NetCell */ 01226 /***********/ 01227 if (wdmamode >= 2 && apiomode >= 4) { 01228 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { 01229 return; 01230 } 01231 } 01232 /* Use GENERIC PIO */ 01233 break; 01234 case ATA_HIGHPOINT_ID: { 01235 /********************/ 01236 /* High Point (HPT) */ 01237 /********************/ 01238 for(i=udmamode; i>=0; i--) { 01239 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01240 hpt_timing(deviceExtension, dev, (UCHAR)(ATA_UDMA + i)); // ??? 01241 return; 01242 } 01243 } 01244 01245 for(i=wdmamode; i>=0; i--) { 01246 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01247 hpt_timing(deviceExtension, dev, (UCHAR)(ATA_WDMA0+i)); 01248 return; 01249 } 01250 } 01251 /* try generic DMA, use hpt_timing() */ 01252 if (wdmamode >= 0 && apiomode >= 4) { 01253 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) { 01254 return; 01255 } 01256 } 01257 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01258 hpt_timing(deviceExtension, dev, ATA_PIO0 + apiomode); 01259 return; 01260 break; } 01261 case ATA_INTEL_ID: { 01262 /*********/ 01263 /* Intel */ 01264 /*********/ 01265 01266 BOOLEAN udma_ok = FALSE; 01267 ULONG idx = 0; 01268 ULONG reg40; 01269 UCHAR reg44; 01270 USHORT reg48; 01271 USHORT reg4a; 01272 USHORT reg54; 01273 ULONG mask40 = 0; 01274 ULONG new40 = 0; 01275 UCHAR mask44 = 0; 01276 UCHAR new44 = 0; 01277 UCHAR intel_timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23, 01278 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 }; 01279 01280 if(deviceExtension->DevID == ATA_I82371FB) { 01281 if (wdmamode >= 2 && apiomode >= 4) { 01282 ULONG word40; 01283 01284 GetPciConfig4(0x40, word40); 01285 word40 >>= Channel * 16; 01286 01287 /* Check for timing config usable for DMA on controller */ 01288 if (!((word40 & 0x3300) == 0x2300 && 01289 ((word40 >> ((!(DeviceNumber & 1)) ? 0 : 4)) & 1) == 1)) { 01290 udmamode = wdmamode = -1; 01291 break; 01292 } 01293 01294 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { 01295 return; 01296 } 01297 } 01298 break; 01299 } 01300 01301 if(deviceExtension->DevID == ATA_ISCH) { 01302 ULONG tim; 01303 GetPciConfig4(0x80 + dev*4, tim); 01304 01305 for(i=udmamode; i>=0; i--) { 01306 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01307 tim |= (0x1 << 31); 01308 tim &= ~(0x7 << 16); 01309 tim |= (i << 16); 01310 01311 idx = i+8; 01312 udma_ok = TRUE; 01313 apiomode = ATA_PIO4; 01314 break; 01315 } 01316 } 01317 if(!udma_ok) { 01318 for(i=wdmamode; i>=0; i--) { 01319 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01320 tim &= ~(0x1 << 31); 01321 tim &= ~(0x3 << 8); 01322 tim |= (i << 8); 01323 01324 idx = i+5; 01325 udma_ok = TRUE; 01326 apiomode = (i == 0) ? ATA_PIO0 : 01327 (i == 1) ? ATA_PIO3 : ATA_PIO4; 01328 break; 01329 } 01330 } 01331 } 01332 if(!udma_ok) { 01333 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01334 idx = apiomode; 01335 } 01336 tim &= ~(0x7); 01337 tim |= (apiomode & 0x7); 01338 SetPciConfig4(0x80 + dev*4, tim); 01339 01340 break; 01341 } 01342 01343 GetPciConfig2(0x48, reg48); 01344 if(!(ChipFlags & ICH4_FIX)) { 01345 GetPciConfig2(0x4a, reg4a); 01346 } 01347 GetPciConfig2(0x54, reg54); 01348 // if(udmamode >= 0) { 01349 // enable the write buffer to be used in a split (ping/pong) manner. 01350 reg54 |= 0x400; 01351 // } else { 01352 // reg54 &= ~0x400; 01353 // } 01354 01355 // reg40 &= ~0x00ff00ff; 01356 // reg40 |= 0x40774077; 01357 01358 for(i=udmamode; i>=0; i--) { 01359 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01360 01361 /* Set UDMA reference clock (33/66/133MHz). */ 01362 SetPciConfig1(0x48, reg48 | (0x0001 << dev)); 01363 if(!(ChipFlags & ICH4_FIX)) { 01364 SetPciConfig2(0x4a, (reg4a & ~(0x3 << (dev<<2))) | 01365 (0x01 + !(i & 0x01)) ); 01366 } 01367 if(i >= 3) { 01368 reg54 |= (0x1 << dev); 01369 } else { 01370 reg54 &= ~(0x1 << dev); 01371 } 01372 if(i >= 5) { 01373 reg54 |= (0x1000 << dev); 01374 } else { 01375 reg54 &= ~(0x1000 << dev); 01376 } 01377 SetPciConfig2(0x54, reg54); 01378 01379 udma_ok = TRUE; 01380 idx = i+8; 01381 if(ChipFlags & ICH4_FIX) { 01382 return; 01383 } 01384 break; 01385 } 01386 } 01387 01388 if(!udma_ok) { 01389 SetPciConfig1(0x48, reg48 & ~(0x0001 << dev)); 01390 if(!(ChipFlags & ICH4_FIX)) { 01391 SetPciConfig2(0x4a, (reg4a & ~(0x3 << (dev << 2))) ); 01392 } 01393 SetPciConfig2(0x54, reg54 & ~(0x1001 << dev)); 01394 for(i=wdmamode; i>=0; i--) { 01395 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01396 udma_ok = TRUE; 01397 idx = i+5; 01398 if(ChipFlags & ICH4_FIX) { 01399 return; 01400 } 01401 break; 01402 } 01403 } 01404 } 01405 01406 if(!udma_ok) { 01407 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01408 idx = apiomode; 01409 } 01410 01411 GetPciConfig4(0x40, reg40); 01412 GetPciConfig1(0x44, reg44); 01413 01414 /* Allow PIO/WDMA timing controls. */ 01415 reg40 &= ~0x00ff00ff; 01416 reg40 |= ~0x40774077; 01417 /* Set PIO/WDMA timings. */ 01418 if(!(DeviceNumber & 1)) { 01419 mask40 |= 0x00003300; 01420 new40 = ((USHORT)(intel_timings[idx]) << 8); 01421 } else { 01422 mask44 = 0x0f; 01423 new44 = ((intel_timings[idx] & 0x30) >> 2) | 01424 (intel_timings[idx] & 0x03); 01425 } 01426 01427 if (Channel) { 01428 mask40 <<= 16; 01429 new40 <<= 16; 01430 mask44 <<= 4; 01431 new44 <<= 4; 01432 } 01433 01434 SetPciConfig4(0x40, (reg40 & ~mask40) | new40); 01435 SetPciConfig1(0x44, (reg44 & ~mask44) | new44); 01436 01437 return; 01438 break; } 01439 case ATA_PROMISE_ID: 01440 /***********/ 01441 /* Promise */ 01442 /***********/ 01443 if(ChipType < PRTX) { 01444 if (ATAPI_DEVICE(deviceExtension, ldev)) { 01445 udmamode = 01446 wdmamode = -1; 01447 } 01448 } 01449 for(i=udmamode; i>=0; i--) { 01450 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01451 promise_timing(deviceExtension, dev, (UCHAR)(ATA_UDMA + i)); // ??? 01452 return; 01453 } 01454 } 01455 01456 for(i=wdmamode; i>=0; i--) { 01457 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01458 promise_timing(deviceExtension, dev, (UCHAR)(ATA_WDMA0+i)); 01459 return; 01460 } 01461 } 01462 /* try generic DMA, use hpt_timing() */ 01463 if (wdmamode >= 0 && apiomode >= 4) { 01464 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) { 01465 return; 01466 } 01467 } 01468 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01469 promise_timing(deviceExtension, dev, ATA_PIO0 + apiomode); 01470 return; 01471 break; 01472 case ATA_ATI_ID: 01473 01474 KdPrint2((PRINT_PREFIX "ATI\n")); 01475 if(ChipType == SIIMIO) { 01476 goto l_ATA_SILICON_IMAGE_ID; 01477 } 01478 //goto ATA_SERVERWORKS_ID; 01479 // FALL THROUGH 01480 01481 //break; } 01482 01483 case ATA_SERVERWORKS_ID: { 01484 /***************/ 01485 /* ServerWorks */ 01486 /***************/ 01487 // static const ULONG udma_modes[] = { 0x70, 0x21, 0x20 }; 01488 static const ULONG sw_dma_modes[] = { 0x70, 0x21, 0x20 }; 01489 static const ULONG sw_pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20, 01490 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; 01491 USHORT reg56; 01492 ULONG reg44; 01493 ULONG reg40; 01494 ULONG offset = dev ^ 0x01; 01495 ULONG bit_offset = offset * 8; 01496 01497 for(i=udmamode; i>=0; i--) { 01498 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01499 GetPciConfig2(0x56, reg56); 01500 reg56 &= ~(0xf << (dev * 4)); 01501 reg56 |= ((USHORT)i << (dev * 4)); 01502 SetPciConfig2(0x56, reg56); 01503 ChangePciConfig1(0x54, a | (0x01 << dev)); 01504 // 44 01505 GetPciConfig4(0x44, reg44); 01506 reg44 = (reg44 & ~(0xff << bit_offset)) | 01507 (sw_dma_modes[2] << bit_offset); 01508 SetPciConfig4(0x44, reg44); 01509 // 40 01510 GetPciConfig4(0x40, reg40); 01511 reg40 = (reg40 & ~(0xff << bit_offset)) | 01512 (sw_pio_modes[8+i] << bit_offset); 01513 SetPciConfig4(0x40, reg40); 01514 return; 01515 } 01516 } 01517 01518 for(i=wdmamode; i>=0; i--) { 01519 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01520 01521 ChangePciConfig1(0x54, a & ~(0x01 << dev)); 01522 // 44 01523 GetPciConfig4(0x44, reg44); 01524 reg44 = (reg44 & ~(0xff << bit_offset)) | 01525 (sw_dma_modes[wdmamode] << bit_offset); 01526 SetPciConfig4(0x44, reg44); 01527 // 40 01528 GetPciConfig4(0x40, reg40); 01529 reg40 = (reg40 & ~(0xff << bit_offset)) | 01530 (sw_pio_modes[5+i] << bit_offset); 01531 SetPciConfig4(0x40, reg40); 01532 return; 01533 } 01534 } 01535 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01536 // SetPciConfig4(0x44, sw_pio_modes[apiomode]); 01537 if(VendorID == ATA_ATI_ID) { 01538 // special case for ATI 01539 // Seems, that PATA ATI are just re-brended ServerWorks 01540 USHORT reg4a; 01541 // 4a 01542 GetPciConfig2(0x4a, reg4a); 01543 reg4a = (reg4a & ~(0xf << (dev*4))) | 01544 (apiomode << (dev*4)); 01545 SetPciConfig2(0x4a, reg4a); 01546 } 01547 01548 // 40 01549 GetPciConfig4(0x40, reg40); 01550 reg40 = (reg40 & ~(0xff << bit_offset)) | 01551 (sw_pio_modes[apiomode] << bit_offset); 01552 SetPciConfig4(0x40, reg40); 01553 return; 01554 break; } 01555 case ATA_SILICON_IMAGE_ID: { 01556 l_ATA_SILICON_IMAGE_ID: 01557 /********************/ 01558 /* SiliconImage/CMD */ 01559 /********************/ 01560 if(ChipType == SIIMIO) { 01561 01562 static const UCHAR sil_modes[7] = 01563 { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 }; 01564 static const USHORT sil_wdma_modes[3] = 01565 { 0x2208, 0x10c2, 0x10c1 }; 01566 static const USHORT sil_pio_modes[6] = 01567 { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1, 0x10c1 }; 01568 01569 UCHAR ureg = 0xac + ((UCHAR)DeviceNumber * 0x02) + ((UCHAR)Channel * 0x10); 01570 UCHAR uval; 01571 UCHAR mreg = Channel ? 0x84 : 0x80; 01572 UCHAR mask = DeviceNumber ? 0x30 : 0x03; 01573 UCHAR mode; 01574 01575 GetPciConfig1(ureg, uval); 01576 GetPciConfig1(mreg, mode); 01577 01578 /* enable UDMA mode */ 01579 for(i = udmamode; i>=0; i--) { 01580 01581 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01582 SetPciConfig1(mreg, mode | mask); 01583 SetPciConfig1(ureg, (uval & 0x3f) | sil_modes[i]); 01584 return; 01585 } 01586 } 01587 /* enable WDMA mode */ 01588 for(i = wdmamode; i>=0; i--) { 01589 01590 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01591 SetPciConfig1(mreg, mode | (mask & 0x22)); 01592 SetPciConfig2(ureg - 0x4, sil_wdma_modes[i]); 01593 return; 01594 } 01595 } 01596 /* restore PIO mode */ 01597 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01598 01599 SetPciConfig1(mreg, mode | (mask & 0x11)); 01600 SetPciConfig2(ureg - 0x8, sil_pio_modes[apiomode]); 01601 return; 01602 01603 } else { 01604 01605 static const UCHAR cmd_modes[2][6] = { 01606 { 0x31, 0x21, 0x011, 0x25, 0x15, 0x05 }, 01607 { 0xc2, 0x82, 0x042, 0x8a, 0x4a, 0x0a } }; 01608 static const UCHAR cmd_wdma_modes[] = { 0x87, 0x32, 0x3f }; 01609 static const UCHAR cmd_pio_modes[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f }; 01610 ULONG treg = 0x54 + ((dev < 3) ? (dev << 1) : 7); 01611 01612 udmamode = min(udmamode, 5); 01613 /* enable UDMA mode */ 01614 for(i = udmamode; i>=0; i--) { 01615 UCHAR umode; 01616 01617 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01618 GetPciConfig1(Channel ? 0x7b : 0x73, umode); 01619 umode &= ~(!(DeviceNumber & 1) ? 0x35 : 0xca); 01620 umode |= ( cmd_modes[DeviceNumber & 1][i]); 01621 SetPciConfig1(Channel ? 0x7b : 0x73, umode); 01622 return; 01623 } 01624 } 01625 /* make sure eventual UDMA mode from the BIOS is disabled */ 01626 ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca)); 01627 01628 for(i = wdmamode; i>=0; i--) { 01629 01630 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01631 SetPciConfig1(treg, cmd_wdma_modes[i]); 01632 ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca)); 01633 return; 01634 } 01635 } 01636 /* set PIO mode timings */ 01637 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01638 01639 SetPciConfig1(treg, cmd_pio_modes[apiomode]); 01640 ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca)); 01641 return; 01642 01643 } 01644 return; 01645 break; } 01646 case ATA_SIS_ID: { 01647 /*******/ 01648 /* SiS */ 01649 /*******/ 01650 PULONG sis_modes = NULL; 01651 static const ULONG sis_modes_new133[] = 01652 { 0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008, 01653 0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac, 01654 0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c}; 01655 static const ULONG sis_modes_old133[] = 01656 { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031, 01657 0x8f31, 0x8a31, 0x8731, 0x8531, 0x8331, 0x8231, 0x8131 }; 01658 static const ULONG sis_modes_old[] = 01659 { 0x0c0b, 0x0607, 0x0404, 0x0303, 0x0301, 0x0404, 0x0303, 0x0301, 01660 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301 }; 01661 static const ULONG sis_modes_new100[] = 01662 { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031, 01663 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 }; 01664 01665 ULONG reg = 0; 01666 UCHAR reg57; 01667 ULONG reg_size = 0; 01668 ULONG offs; 01669 01670 switch(ChipType) { 01671 case SIS133NEW: 01672 sis_modes = (PULONG)(&sis_modes_new133[0]); 01673 reg_size = 4; 01674 GetPciConfig1(0x57, reg57); 01675 reg = (reg57 & 0x40 ? 0x70 : 0x40) + (dev * 4); 01676 break; 01677 case SIS133OLD: 01678 sis_modes = (PULONG)(&sis_modes_old133[0]); 01679 reg_size = 2; 01680 reg = 0x40 + (dev * 2); 01681 break; 01682 case SIS100NEW: 01683 sis_modes = (PULONG)(&sis_modes_new100[0]); 01684 reg_size = 2; 01685 reg = 0x40 + (dev * 2); 01686 break; 01687 case SIS100OLD: 01688 case SIS66: 01689 case SIS33: 01690 sis_modes = (PULONG)(&sis_modes_old[0]); 01691 reg_size = 2; 01692 reg = 0x40 + (dev * 2); 01693 break; 01694 } 01695 01696 offs = 5+3; 01697 for(i=udmamode; i>=0; i--) { 01698 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01699 if(reg_size == 4) { 01700 SetPciConfig4(reg, sis_modes[offs+i]); 01701 } else { 01702 SetPciConfig2(reg, (USHORT)sis_modes[offs+i]); 01703 } 01704 return; 01705 } 01706 } 01707 01708 offs = 5; 01709 for(i=wdmamode; i>=0; i--) { 01710 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01711 if(reg_size == 4) { 01712 SetPciConfig4(reg, sis_modes[offs+i]); 01713 } else { 01714 SetPciConfig2(reg, (USHORT)sis_modes[offs+i]); 01715 } 01716 return; 01717 } 01718 } 01719 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01720 if(reg_size == 4) { 01721 SetPciConfig4(reg, sis_modes[apiomode]); 01722 } else { 01723 SetPciConfig2(reg, (USHORT)sis_modes[apiomode]); 01724 } 01725 return; 01726 break; } 01727 case 0x16ca: 01728 /* Cenatek Rocket Drive controller */ 01729 if (wdmamode >= 0 && 01730 (AtapiReadPort1(chan, IDX_BM_Status) & 01731 (DeviceNumber ? BM_STATUS_DRIVE_1_DMA : BM_STATUS_DRIVE_0_DMA))) { 01732 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + wdmamode); 01733 } else { 01734 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01735 } 01736 return; 01737 case ATA_ITE_ID: { /* ITE IDE controller */ 01738 01739 if(ChipType == ITE_33) { 01740 int a_speed = 3 << (dev * 4); 01741 int u_flag = 1 << dev; 01742 int u_speed = 0; 01743 int pio = 1; 01744 UCHAR reg48, reg4a; 01745 USHORT drive_enables; 01746 ULONG drive_timing; 01747 01748 GetPciConfig1(0x48, reg48); 01749 GetPciConfig1(0x4a, reg4a); 01750 01751 /* 01752 * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec 01753 * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA 01754 * transfers on some drives, even though both numbers meet the minimum 01755 * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively. 01756 * So the faster times are just commented out here. The good news is 01757 * that the slower cycle time has very little affect on transfer 01758 * performance. 01759 */ 01760 01761 for(i=udmamode; i>=0; i--) { 01762 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01763 SetPciConfig1(0x48, reg48 | u_flag); 01764 reg4a &= ~a_speed; 01765 SetPciConfig1(0x4a, reg4a | u_speed); 01766 pio = 4; 01767 goto setup_drive_ite; 01768 } 01769 } 01770 01771 for(i=wdmamode; i>=0; i--) { 01772 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01773 SetPciConfig1(0x48, reg48 & ~u_flag); 01774 SetPciConfig1(0x4a, reg4a & ~a_speed); 01775 pio = 3; 01776 return; 01777 } 01778 } 01779 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01780 SetPciConfig1(0x48, reg48 & ~u_flag); 01781 SetPciConfig1(0x4a, reg4a & ~a_speed); 01782 01783 pio = apiomode; 01784 01785 setup_drive_ite: 01786 01787 GetPciConfig2(0x40, drive_enables); 01788 GetPciConfig4(0x44, drive_timing); 01789 01790 /* 01791 * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 01792 * are being left at the default values of 8 PCI clocks (242 nsec 01793 * for a 33 MHz clock). These can be safely shortened at higher 01794 * PIO modes. The DIOR/DIOW pulse width and recovery times only 01795 * apply to PIO modes, not to the DMA modes. 01796 */ 01797 01798 /* 01799 * Enable port 0x44. The IT8172G spec is confused; it calls 01800 * this register the "Slave IDE Timing Register", but in fact, 01801 * it controls timing for both master and slave drives. 01802 */ 01803 drive_enables |= 0x4000; 01804 01805 drive_enables &= (0xc000 | (0x06 << (DeviceNumber*4))); 01806 if (pio > 1) { 01807 /* enable prefetch and IORDY sample-point */ 01808 drive_enables |= (0x06 << (DeviceNumber*4)); 01809 } 01810 01811 SetPciConfig2(0x40, drive_enables); 01812 } else 01813 if(ChipType == ITE_133) { 01814 static const UCHAR udmatiming[] = 01815 { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 }; 01816 static const UCHAR chtiming[] = 01817 { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 }; 01818 ULONG offset = (Channel<<2) + DeviceNumber; 01819 UCHAR reg54; 01820 01821 for(i=udmamode; i>=0; i--) { 01822 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01823 ChangePciConfig1(0x50, a & ~(1 << (dev + 3)) ); 01824 SetPciConfig1(0x56 + offset, udmatiming[i]); 01825 return; 01826 } 01827 } 01828 01829 for(i=wdmamode; i>=0; i--) { 01830 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01831 01832 ChangePciConfig1(0x50, a | (1 << (dev + 3)) ); 01833 GetPciConfig1(0x54 + offset, reg54); 01834 if(reg54 < chtiming[i+5]) { 01835 SetPciConfig1(0x54 + offset, chtiming[i+5]); 01836 } 01837 return; 01838 } 01839 } 01840 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01841 ChangePciConfig1(0x50, a | (1 << (dev + 3)) ); 01842 GetPciConfig1(0x54 + offset, reg54); 01843 if(reg54 < chtiming[apiomode]) { 01844 SetPciConfig1(0x54 + offset, chtiming[apiomode]); 01845 } 01846 return; 01847 } else 01848 if(ChipType == ITE_133_NEW) { 01849 //static const USHORT reg54_timings[] = { 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x1001, 0x1001 }; 01850 static const UCHAR udmatiming[] = 01851 { 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10 }; 01852 static const UCHAR timings[] = 01853 { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23, 01854 0x23, 0x23, 0x23, 0x23, 0x23, 0x02, 0x02 }; 01855 BOOLEAN udma_ok = FALSE; 01856 BOOLEAN ok = FALSE; 01857 UCHAR timing = 0; 01858 01859 WCHAR reg40; 01860 UCHAR reg44; 01861 USHORT reg4a; 01862 USHORT reg54; 01863 USHORT mask40=0, new40=0; 01864 UCHAR mask44=0, new44=0; 01865 01866 GetPciConfig2(0x40, reg40); 01867 GetPciConfig1(0x44, reg44); 01868 GetPciConfig2(0x4a, reg4a); 01869 GetPciConfig2(0x54, reg54); 01870 01871 if(!(reg54 & (0x10 << dev))) { 01872 // 80-pin check 01873 udmamode = min(udmamode, 2); 01874 } 01875 01876 for(i=udmamode; i>=0; i--) { 01877 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01878 ChangePciConfig1(0x48, a | (1 << dev) ); 01879 ChangePciConfig2(0x4a, 01880 (a & ~(0x3 << (dev*4))) | 01881 (udmatiming[i] << (dev*4)) ); 01882 ok=TRUE; 01883 udma_ok=TRUE; 01884 timing = timings[i+8]; 01885 break; 01886 } 01887 } 01888 01889 for(i=wdmamode; !ok && i>=0; i--) { 01890 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01891 01892 ok=TRUE; 01893 timing = timings[i+5]; 01894 break; 01895 } 01896 } 01897 01898 if(!ok) { 01899 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01900 timing = timings[apiomode]; 01901 } 01902 01903 if(!udma_ok) { 01904 ChangePciConfig1(0x48, a & ~(1 << dev) ); 01905 ChangePciConfig2(0x4a, a & ~(0x3 << (dev << 2)) ); 01906 } 01907 if (udma_ok && udmamode >= ATA_UDMA2) { 01908 reg54 |= (0x1 << dev); 01909 } else { 01910 reg54 &= ~(0x1 << dev); 01911 } 01912 if (udma_ok && udmamode >= ATA_UDMA5) { 01913 reg54 |= (0x1000 << dev); 01914 } else { 01915 reg54 &= ~(0x1000 << dev); 01916 } 01917 SetPciConfig2(0x54, reg54 ); 01918 01919 reg40 &= 0xff00; 01920 reg40 |= 0x4033; 01921 01922 if(!(ldev & 1)) { 01923 reg40 |= (ATAPI_DEVICE(deviceExtension, ldev) ? 0x04 : 0x00); 01924 mask40 = 0x3300; 01925 new40 = timing << 8; 01926 } else { 01927 reg40 |= (ATAPI_DEVICE(deviceExtension, ldev) ? 0x40 : 0x00); 01928 mask44 = 0x0f; 01929 new44 = ((timing & 0x30) >> 2) | 01930 (timing & 0x03); 01931 } 01932 SetPciConfig2(0x40, (reg40 & ~mask40) | new40); 01933 SetPciConfig1(0x44, (reg44 & ~mask44) | new44); 01934 return; 01935 } 01936 01937 return; 01938 break; } 01939 case 0x3388: 01940 /* HiNT Corp. VXPro II EIDE */ 01941 if (wdmamode >= 0 && 01942 (AtapiReadPort1(chan, IDX_BM_Status) & 01943 (DeviceNumber ? BM_STATUS_DRIVE_1_DMA : BM_STATUS_DRIVE_0_DMA))) { 01944 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA); 01945 } else { 01946 AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); 01947 } 01948 return; 01949 case ATA_JMICRON_ID: { 01950 01951 UCHAR reg40; 01952 GetPciConfig1(0x40, reg40); 01953 01954 if(reg40 & 0x08) { 01955 // 80-pin check 01956 udmamode = min(udmamode, 2); 01957 } 01958 /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */ 01959 if(apiomode >= 4) 01960 apiomode = 4; 01961 for(i=udmamode; i>=0; i--) { 01962 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { 01963 return; 01964 } 01965 } 01966 for(i=wdmamode; i>=0; i--) { 01967 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { 01968 return; 01969 } 01970 } 01971 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { 01972 return; 01973 } 01974 return; 01975 break; } 01976 } 01977 01978 try_generic_dma: 01979 01980 /* unknown controller chip */ 01981 01982 /* better not try generic DMA on ATAPI devices it almost never works */ 01983 if (ATAPI_DEVICE(deviceExtension, ldev)) { 01984 KdPrint2((PRINT_PREFIX "ATAPI on unknown controller -> PIO\n")); 01985 udmamode = 01986 wdmamode = -1; 01987 } 01988 01989 /* if controller says its setup for DMA take the easy way out */ 01990 /* the downside is we dont know what DMA mode we are in */ 01991 if ((udmamode >= 0 || /*wdmamode > 1*/ wdmamode >= 0) && 01992 /*deviceExtension->BaseIoAddressBM[lChannel]*/ deviceExtension->BusMaster && 01993 (GetDmaStatus(deviceExtension, lChannel) & 01994 (!(ldev & 1) ? 01995 BM_STATUS_DRIVE_0_DMA : BM_STATUS_DRIVE_1_DMA))) { 01996 // LunExt->TransferMode = ATA_DMA; 01997 // return; 01998 KdPrint2((PRINT_PREFIX "try DMA on unknown controller\n")); 01999 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) { 02000 return; 02001 } 02002 } 02003 02004 #if 0 02005 /* well, we have no support for this, but try anyways */ 02006 if ((wdmamode >= 0 && apiomode >= 4) && deviceExtension->BaseIoAddressBM[lChannel]) { 02007 if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA/* + wdmamode*/)) { 02008 return; 02009 } 02010 } 02011 #endif 02012 02013 KdPrint2((PRINT_PREFIX "try PIO%d on unknown controller\n", apiomode)); 02014 if(!AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { 02015 KdPrint2((PRINT_PREFIX "fall to PIO on unknown controller\n")); 02016 LunExt->TransferMode = ATA_PIO; 02017 } 02018 return; 02019 } // end AtapiDmaInit() 02020 02021 02022 VOID 02023 NTAPI 02024 cyrix_timing( 02025 IN PHW_DEVICE_EXTENSION deviceExtension, 02026 IN ULONG dev, // physical device number (0-3) 02027 IN CHAR mode 02028 ) 02029 { 02030 // ASSERT(dev/2 >= deviceExtension->Channel); 02031 // PHW_CHANNEL chan = &(deviceExtension->chan[dev/2-deviceExtension->Channel]); 02032 ULONG reg20 = 0x0000e132; 02033 ULONG reg24 = 0x00017771; 02034 02035 if(mode == ATA_PIO5) 02036 mode = ATA_PIO4; 02037 02038 switch (mode) { 02039 case ATA_PIO0: reg20 = 0x0000e132; break; 02040 case ATA_PIO1: reg20 = 0x00018121; break; 02041 case ATA_PIO2: reg20 = 0x00024020; break; 02042 case ATA_PIO3: reg20 = 0x00032010; break; 02043 case ATA_PIO4: 02044 case ATA_PIO5: reg20 = 0x00040010; break; 02045 case ATA_WDMA2: reg24 = 0x00002020; break; 02046 case ATA_UDMA2: reg24 = 0x00911030; break; 02047 } 02048 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(dev*8) + 0x20, reg20); 02049 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(dev*8) + 0x24, reg24); 02050 } // cyrix_timing() 02051 02052 VOID 02053 NTAPI 02054 promise_timing( 02055 IN PHW_DEVICE_EXTENSION deviceExtension, 02056 IN ULONG dev, // physical device number (0-3) 02057 IN CHAR mode 02058 ) 02059 { 02060 PVOID HwDeviceExtension = (PVOID)deviceExtension; 02061 ULONG slotNumber = deviceExtension->slotNumber; 02062 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber; 02063 02064 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; 02065 //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK; 02066 02067 ULONG timing = 0; 02068 02069 if(mode == ATA_PIO5) 02070 mode = ATA_PIO4; 02071 02072 switch(ChipType) { 02073 case PROLD: 02074 switch (mode) { 02075 default: 02076 case ATA_PIO0: timing = 0x004ff329; break; 02077 case ATA_PIO1: timing = 0x004fec25; break; 02078 case ATA_PIO2: timing = 0x004fe823; break; 02079 case ATA_PIO3: timing = 0x004fe622; break; 02080 case ATA_PIO4: timing = 0x004fe421; break; 02081 case ATA_WDMA0: timing = 0x004567f3; break; 02082 case ATA_WDMA1: timing = 0x004467f3; break; 02083 case ATA_WDMA2: timing = 0x004367f3; break; 02084 case ATA_UDMA0: timing = 0x004367f3; break; 02085 case ATA_UDMA1: timing = 0x004247f3; break; 02086 case ATA_UDMA2: timing = 0x004127f3; break; 02087 } 02088 break; 02089 02090 case PRNEW: 02091 switch (mode) { 02092 default: 02093 case ATA_PIO0: timing = 0x004fff2f; break; 02094 case ATA_PIO1: timing = 0x004ff82a; break; 02095 case ATA_PIO2: timing = 0x004ff026; break; 02096 case ATA_PIO3: timing = 0x004fec24; break; 02097 case ATA_PIO4: timing = 0x004fe822; break; 02098 case ATA_WDMA0: timing = 0x004acef6; break; 02099 case ATA_WDMA1: timing = 0x0048cef6; break; 02100 case ATA_WDMA2: timing = 0x0046cef6; break; 02101 case ATA_UDMA0: timing = 0x0046cef6; break; 02102 case ATA_UDMA1: timing = 0x00448ef6; break; 02103 case ATA_UDMA2: timing = 0x00436ef6; break; 02104 case ATA_UDMA3: timing = 0x00424ef6; break; 02105 case ATA_UDMA4: timing = 0x004127f3; break; 02106 case ATA_UDMA5: timing = 0x004127f3; break; 02107 } 02108 break; 02109 default: 02110 return; 02111 } 02112 SetPciConfig4(0x60 + (dev<<2), timing); 02113 } // end promise_timing() 02114 02115 02116 VOID 02117 NTAPI 02118 hpt_timing( 02119 IN PHW_DEVICE_EXTENSION deviceExtension, 02120 IN ULONG dev, // physical device number (0-3) 02121 IN CHAR mode 02122 ) 02123 { 02124 PVOID HwDeviceExtension = (PVOID)deviceExtension; 02125 ULONG slotNumber = deviceExtension->slotNumber; 02126 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber; 02127 02128 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; 02129 //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK; 02130 02131 ULONG timing = 0; 02132 02133 if(mode == ATA_PIO5) 02134 mode = ATA_PIO4; 02135 02136 switch(ChipType) { 02137 case HPT374: 02138 02139 switch (mode) { /* HPT374 */ 02140 case ATA_PIO0: timing = 0x0ac1f48a; break; 02141 case ATA_PIO1: timing = 0x0ac1f465; break; 02142 case ATA_PIO2: timing = 0x0a81f454; break; 02143 case ATA_PIO3: timing = 0x0a81f443; break; 02144 case ATA_PIO4: timing = 0x0a81f442; break; 02145 case ATA_WDMA0: timing = 0x228082ea; break; 02146 case ATA_WDMA1: timing = 0x22808254; break; 02147 case ATA_WDMA2: timing = 0x22808242; break; 02148 case ATA_UDMA0: timing = 0x121882ea; break; 02149 case ATA_UDMA1: timing = 0x12148254; break; 02150 case ATA_UDMA2: timing = 0x120c8242; break; 02151 case ATA_UDMA3: timing = 0x128c8242; break; 02152 case ATA_UDMA4: timing = 0x12ac8242; break; 02153 case ATA_UDMA5: timing = 0x12848242; break; 02154 case ATA_UDMA6: timing = 0x12808242; break; 02155 default: timing = 0x0d029d5e; 02156 } 02157 break; 02158 02159 case HPT372: 02160 02161 switch (mode) { /* HPT372 */ 02162 case ATA_PIO0: timing = 0x0d029d5e; break; 02163 case ATA_PIO1: timing = 0x0d029d26; break; 02164 case ATA_PIO2: timing = 0x0c829ca6; break; 02165 case ATA_PIO3: timing = 0x0c829c84; break; 02166 case ATA_PIO4: timing = 0x0c829c62; break; 02167 case ATA_WDMA0: timing = 0x2c82922e; break; 02168 case ATA_WDMA1: timing = 0x2c829266; break; 02169 case ATA_WDMA2: timing = 0x2c829262; break; 02170 case ATA_UDMA0: timing = 0x1c829c62; break; 02171 case ATA_UDMA1: timing = 0x1c9a9c62; break; 02172 case ATA_UDMA2: timing = 0x1c929c62; break; 02173 case ATA_UDMA3: timing = 0x1c8e9c62; break; 02174 case ATA_UDMA4: timing = 0x1c8a9c62; break; 02175 case ATA_UDMA5: timing = 0x1c8a9c62; break; 02176 case ATA_UDMA6: timing = 0x1c869c62; break; 02177 default: timing = 0x0d029d5e; 02178 } 02179 break; 02180 02181 case HPT370: 02182 02183 switch (mode) { /* HPT370 */ 02184 case ATA_PIO0: timing = 0x06914e57; break; 02185 case ATA_PIO1: timing = 0x06914e43; break; 02186 case ATA_PIO2: timing = 0x06514e33; break; 02187 case ATA_PIO3: timing = 0x06514e22; break; 02188 case ATA_PIO4: timing = 0x06514e21; break; 02189 case ATA_WDMA0: timing = 0x26514e97; break; 02190 case ATA_WDMA1: timing = 0x26514e33; break; 02191 case ATA_WDMA2: timing = 0x26514e21; break; 02192 case ATA_UDMA0: timing = 0x16514e31; break; 02193 case ATA_UDMA1: timing = 0x164d4e31; break; 02194 case ATA_UDMA2: timing = 0x16494e31; break; 02195 case ATA_UDMA3: timing = 0x166d4e31; break; 02196 case ATA_UDMA4: timing = 0x16454e31; break; 02197 case ATA_UDMA5: timing = 0x16454e31; break; 02198 default: timing = 0x06514e57; 02199 } 02200 02201 case HPT366: { 02202 UCHAR reg41; 02203 02204 GetPciConfig1(0x41 + (dev << 2), reg41); 02205 02206 switch (reg41) { 02207 case 0x85: /* 25Mhz */ 02208 switch (mode) { 02209 case ATA_PIO0: timing = 0x40d08585; break; 02210 case ATA_PIO1: timing = 0x40d08572; break; 02211 case ATA_PIO2: timing = 0x40ca8542; break; 02212 case ATA_PIO3: timing = 0x40ca8532; break; 02213 case ATA_PIO4: timing = 0x40ca8521; break; 02214 case ATA_WDMA2: timing = 0x20ca8521; break; 02215 case ATA_UDMA2: timing = 0x10cf8521; break; 02216 case ATA_UDMA4: timing = 0x10c98521; break; 02217 default: timing = 0x01208585; 02218 } 02219 break; 02220 default: 02221 case 0xa7: /* 33MHz */ 02222 switch (mode) { 02223 case ATA_PIO0: timing = 0x40d0a7aa; break; 02224 case ATA_PIO1: timing = 0x40d0a7a3; break; 02225 case ATA_PIO2: timing = 0x40d0a753; break; 02226 case ATA_PIO3: timing = 0x40c8a742; break; 02227 case ATA_PIO4: timing = 0x40c8a731; break; 02228 case ATA_WDMA0: timing = 0x20c8a797; break; 02229 case ATA_WDMA1: timing = 0x20c8a732; break; 02230 case ATA_WDMA2: timing = 0x20c8a731; break; 02231 case ATA_UDMA0: timing = 0x10c8a731; break; 02232 case ATA_UDMA1: timing = 0x10cba731; break; 02233 case ATA_UDMA2: timing = 0x10caa731; break; 02234 case ATA_UDMA3: timing = 0x10cfa731; break; 02235 case ATA_UDMA4: timing = 0x10c9a731; break; 02236 default: timing = 0x0120a7a7; 02237 } 02238 break; 02239 case 0xd9: /* 40Mhz */ 02240 switch (mode) { 02241 case ATA_PIO0: timing = 0x4018d9d9; break; 02242 case ATA_PIO1: timing = 0x4010d9c7; break; 02243 case ATA_PIO2: timing = 0x4010d997; break; 02244 case ATA_PIO3: timing = 0x4010d974; break; 02245 case ATA_PIO4: timing = 0x4008d963; break; 02246 case ATA_WDMA2: timing = 0x2008d943; break; 02247 case ATA_UDMA2: timing = 0x100bd943; break; 02248 case ATA_UDMA4: timing = 0x100fd943; break; 02249 default: timing = 0x0120d9d9; 02250 } 02251 } 02252 break; } 02253 } 02254 02255 SetPciConfig4(0x40 + (dev<<2), timing); 02256 } // end hpt_timing() 02257 02258 02259 #define FIT(v,min,max) (((v)>(max)?(max):(v))<(min)?(min):(v)) 02260 02261 VOID 02262 NTAPI 02263 via82c_timing( 02264 IN PHW_DEVICE_EXTENSION deviceExtension, 02265 IN ULONG dev, // physical device number (0-3) 02266 IN CHAR mode 02267 ) 02268 { 02269 PVOID HwDeviceExtension = (PVOID)deviceExtension; 02270 ULONG slotNumber = deviceExtension->slotNumber; 02271 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber; 02272 02273 USHORT T = 1000 / /* PciBusClockMHz()*/ 33; 02274 02275 USHORT setup = 0; 02276 USHORT active = 0; 02277 USHORT recover = 0; 02278 USHORT cycle = 0; 02279 02280 UCHAR t; 02281 02282 switch(mode) { 02283 default: 02284 case ATA_PIO0: setup = 70; active = 165; recover = 150; cycle = 600; break; 02285 case ATA_PIO1: setup = 50; active = 125; recover = 100; cycle = 383; break; 02286 case ATA_PIO2: setup = 30; active = 100; recover = 90; cycle = 240; break; 02287 case ATA_PIO3: setup = 30; active = 80; recover = 70; cycle = 180; break; 02288 case ATA_PIO4: setup = 25; active = 70; recover = 25; cycle = 120; break; 02289 case ATA_PIO5: setup = 20; active = 50; recover = 30; cycle = 100; break; 02290 } 02291 02292 setup = (setup -1)/(T+1); 02293 active = (active -1)/(T+1); 02294 recover = (recover-1)/(T+1); 02295 cycle = (cycle -1)/(T+1); 02296 02297 if (active + recover < cycle) { 02298 active += (cycle - (active + recover)) / 2; 02299 recover = cycle - active; 02300 } 02301 02302 // Newer chips dislike this: 02303 if( 02304 deviceExtension->MaxTransferMode < ATA_UDMA6) { 02305 /* PIO address setup */ 02306 GetPciConfig1(0x4c, t); 02307 t = (t & ~(3 << ((3 - dev) << 1))) | (FIT(setup - 1, 0, 3) << ((3 - dev) << 1)); 02308 SetPciConfig1(0x4c, t); 02309 } 02310 02311 /* PIO active & recover */ 02312 SetPciConfig1(0x4b-dev, (FIT(active - 1, 0, 0xf) << 4) | FIT(recover - 1, 0, 0xf) ); 02313 } // end via82c_timing() 02314 Generated on Sun May 27 2012 04:28:24 for ReactOS by
1.7.6.1
|