- Timestamp:
- Sep 27, 2016 10:40:37 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r64030 r64036 5208 5208 * @returns nothing. 5209 5209 * @param pAhciPort The port of the SATA controller. 5210 * @param pAhciReq The state of the task.5210 * @param cbTransfer Transfer size of the request. 5211 5211 * @param pCmdFis Pointer to the command FIS from the guest. 5212 * @param fRead Flag whether this is a read request. 5212 5213 * @param fInterrupt If an interrupt should be send to the guest. 5213 5214 */ 5214 static void ahciSendPioSetupFis(PAHCIPort pAhciPort, PAHCIREQ pAhciReq, uint8_t *pCmdFis,5215 bool f Interrupt)5215 static void ahciSendPioSetupFis(PAHCIPort pAhciPort, size_t cbTransfer, uint8_t *pCmdFis, 5216 bool fRead, bool fInterrupt) 5216 5217 { 5217 5218 uint8_t abPioSetupFis[20]; … … 5221 5222 ahciLog(("%s: building PIO setup Fis\n", __FUNCTION__)); 5222 5223 5223 AssertMsg( pAhciReq->cbTransfer > 05224 && pAhciReq->cbTransfer <= 65534,5224 AssertMsg( cbTransfer > 0 5225 && cbTransfer <= 65534, 5225 5226 ("Can't send PIO setup FIS for requests with 0 bytes to transfer or greater than 65534\n")); 5226 5227 … … 5230 5231 abPioSetupFis[AHCI_CMDFIS_TYPE] = AHCI_CMDFIS_TYPE_PIOSETUP; 5231 5232 abPioSetupFis[AHCI_CMDFIS_BITS] = (fInterrupt ? AHCI_CMDFIS_I : 0); 5232 if ( pAhciReq->enmType == PDMMEDIAEXIOREQTYPE_READ)5233 if (fRead) 5233 5234 abPioSetupFis[AHCI_CMDFIS_BITS] |= AHCI_CMDFIS_D; 5234 5235 abPioSetupFis[AHCI_CMDFIS_STS] = pCmdFis[AHCI_CMDFIS_STS]; … … 5245 5246 5246 5247 /* Set transfer count. */ 5247 abPioSetupFis[16] = ( pAhciReq->cbTransfer >> 8) & 0xff;5248 abPioSetupFis[17] = pAhciReq->cbTransfer & 0xff;5248 abPioSetupFis[16] = (cbTransfer >> 8) & 0xff; 5249 abPioSetupFis[17] = cbTransfer & 0xff; 5249 5250 5250 5251 /* Update registers. */ … … 5274 5275 * @returns Nothing 5275 5276 * @param pAhciPort The port of the SATA controller. 5276 * @param pAhciReq The state of the task.5277 * @param uTag The tag of the request. 5277 5278 * @param pCmdFis Pointer to the command FIS from the guest. 5278 5279 * @param fInterrupt If an interrupt should be send to the guest. 5279 5280 */ 5280 static void ahciSendD2HFis(PAHCIPort pAhciPort, PAHCIREQ pAhciReq, uint8_t *pCmdFis, bool fInterrupt)5281 static void ahciSendD2HFis(PAHCIPort pAhciPort, uint32_t uTag, uint8_t *pCmdFis, bool fInterrupt) 5281 5282 { 5282 5283 uint8_t d2hFis[20]; … … 5327 5328 5328 5329 /* Mark command as completed. */ 5329 ASMAtomicOrU32(&pAhciPort->u32TasksFinished, (1 << pAhciReq->uTag));5330 ASMAtomicOrU32(&pAhciPort->u32TasksFinished, RT_BIT_32(uTag)); 5330 5331 } 5331 5332 … … 5857 5858 static void ahciR3ReqFree(PAHCIPort pAhciPort, PAHCIREQ pAhciReq) 5858 5859 { 5859 int rc = pAhciPort->pDrvMediaEx->pfnIoReqFree(pAhciPort->pDrvMediaEx, pAhciReq->hIoReq); 5860 AssertRC(rc); 5860 if ( pAhciReq 5861 && !(pAhciReq->fFlags & AHCI_REQ_IS_ON_STACK)) 5862 { 5863 int rc = pAhciPort->pDrvMediaEx->pfnIoReqFree(pAhciPort->pDrvMediaEx, pAhciReq->hIoReq); 5864 AssertRC(rc); 5865 } 5861 5866 } 5862 5867 … … 5957 5962 } 5958 5963 5964 /* 5965 * Make a copy of the required data now and free the request. Otherwise the guest 5966 * might issue a new request with the same tag and we run into a conflict when allocating 5967 * a new request with the same tag later on. 5968 */ 5969 uint32_t fFlags = pAhciReq->fFlags; 5970 uint32_t uTag = pAhciReq->uTag; 5971 size_t cbTransfer = pAhciReq->cbTransfer; 5972 bool fRead = pAhciReq->enmType == PDMMEDIAEXIOREQTYPE_READ; 5973 uint8_t cmdFis[AHCI_CMDFIS_TYPE_H2D_SIZE]; 5974 memcpy(&cmdFis[0], &pAhciReq->cmdFis[0], sizeof(cmdFis)); 5975 5976 ahciR3ReqFree(pAhciPort, pAhciReq); 5959 5977 if (!fRedo) 5960 5978 { 5961 5979 5962 5980 /* Post a PIO setup FIS first if this is a PIO command which transfers data. */ 5963 if ( pAhciReq->fFlags & AHCI_REQ_PIO_DATA)5964 ahciSendPioSetupFis(pAhciPort, pAhciReq, pAhciReq->cmdFis, false /* fInterrupt */);5965 5966 if ( pAhciReq->fFlags & AHCI_REQ_CLEAR_SACT)5981 if (fFlags & AHCI_REQ_PIO_DATA) 5982 ahciSendPioSetupFis(pAhciPort, cbTransfer, &cmdFis[0], fRead, false /* fInterrupt */); 5983 5984 if (fFlags & AHCI_REQ_CLEAR_SACT) 5967 5985 { 5968 5986 if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtrT(&pAhciPort->pTaskErr, PAHCIREQ)) 5969 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, RT_BIT_32( pAhciReq->uTag));5987 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, RT_BIT_32(uTag)); 5970 5988 } 5971 5989 5972 if ( pAhciReq->fFlags & AHCI_REQ_IS_QUEUED)5990 if (fFlags & AHCI_REQ_IS_QUEUED) 5973 5991 { 5974 5992 /* … … 5980 5998 } 5981 5999 else 5982 ahciSendD2HFis(pAhciPort, pAhciReq, pAhciReq->cmdFis, true);6000 ahciSendD2HFis(pAhciPort, uTag, &cmdFis[0], true); 5983 6001 } 5984 6002 } … … 6009 6027 pAhciReq->cbTransfer, rcReq)); 6010 6028 } 6029 6030 ahciR3ReqFree(pAhciPort, pAhciReq); 6011 6031 } 6012 6032 … … 6024 6044 PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3); 6025 6045 6026 /* Don't free the request if it is on the stack. */6027 if ( pAhciReq6028 && !(pAhciReq->fFlags & AHCI_REQ_IS_ON_STACK))6029 ahciR3ReqFree(pAhciPort, pAhciReq);6030 6046 return fCanceled; 6031 6047 } … … 6456 6472 * but this FIS does not assert an interrupt 6457 6473 */ 6458 ahciSendD2HFis(pAhciPort, pAhciReq , pAhciReq->cmdFis, false);6474 ahciSendD2HFis(pAhciPort, pAhciReq->uTag, pAhciReq->cmdFis, false); 6459 6475 pAhciPort->regTFD &= ~AHCI_PORT_TFD_BSY; 6460 6476 } … … 6586 6602 ahciLog(("%s: Setting device into reset state\n", __FUNCTION__)); 6587 6603 pAhciPort->fResetDevice = true; 6588 ahciSendD2HFis(pAhciPort, pAhciReq , pAhciReq->cmdFis, true);6604 ahciSendD2HFis(pAhciPort, pAhciReq->uTag, pAhciReq->cmdFis, true); 6589 6605 } 6590 6606 else if (pAhciPort->fResetDevice) /* The bit is not set and we are in a reset state. */
Note:
See TracChangeset
for help on using the changeset viewer.