Changeset 45646 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Apr 19, 2013 1:48:09 PM (12 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r45025 r45646 43 43 #include <VBox/vmm/pdmthread.h> 44 44 #include <VBox/vmm/pdmcritsect.h> 45 #include <VBox/sup.h> 45 46 #include <VBox/scsi.h> 46 47 #include <iprt/assert.h> … … 450 451 /** Flag whether the port is in redo task mode. */ 451 452 volatile bool fRedo; 453 /** Flag whether the worker thread is sleeping. */ 454 volatile bool fWrkThreadSleeping; 452 455 453 456 /** Number of total sectors. */ … … 516 519 /** Async IO Thread. */ 517 520 R3PTRTYPE(PPDMTHREAD) pAsyncIOThread; 518 /** Request semaphore. */519 RTSEMEVENT AsyncIORequestSem;520 521 /** 521 522 * Array of cached tasks. The tag number is the index value. … … 527 528 /** The current tracklist of the loaded medium if passthrough is used. */ 528 529 R3PTRTYPE(PTRACKLIST) pTrackList; 530 531 /** The event semaphore the processing thread waits on. */ 532 SUPSEMEVENT hEvtProcess; 529 533 530 534 /** Release statistics: number of DMA commands. */ … … 694 698 volatile bool f8ByteMMIO4BytesWrittenSuccessfully; 695 699 700 /** The support driver session handle. */ 701 R3R0PTRTYPE(PSUPDRVSESSION) pSupDrvSession; 696 702 } AHCI; 697 703 /** Pointer to the state of an AHCI device. */ … … 1064 1070 1065 1071 ASMAtomicOrU32(&pAhciPort->u32TasksNew, u32Value); 1066 u32Tasks = ASMAtomicReadU32(&pAhciPort->u32TasksNew);1067 1072 1068 1073 /* Send a notification to R3 if u32TasksNew was before our write. */ 1069 if (!(u32Tasks ^ u32Value)) 1070 { 1074 if (ASMAtomicReadBool(&pAhciPort->fWrkThreadSleeping)) 1075 { 1076 #ifdef IN_RC 1071 1077 PDEVPORTNOTIFIERQUEUEITEM pItem = (PDEVPORTNOTIFIERQUEUEITEM)PDMQueueAlloc(ahci->CTX_SUFF(pNotifierQueue)); 1072 1078 AssertMsg(VALID_PTR(pItem), ("Allocating item for queue failed\n")); … … 1074 1080 pItem->iPort = pAhciPort->iLUN; 1075 1081 PDMQueueInsert(ahci->CTX_SUFF(pNotifierQueue), (PPDMQUEUEITEMCORE)pItem); 1082 #else 1083 LogFlowFunc(("Singal event semaphore\n")); 1084 int rc = SUPSemEventSignal(ahci->pSupDrvSession, pAhciPort->hEvtProcess); 1085 AssertRC(rc); 1086 #endif 1076 1087 } 1077 1088 } … … 2403 2414 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 2404 2415 /** @todo change this to IOMMMIO_FLAGS_WRITE_ONLY_DWORD once EM/IOM starts 2405 * handling 2nd DWORD failures on split accesses correctly. */ 2416 * handling 2nd DWORD failures on split accesses correctly. */ 2406 2417 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 2407 2418 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD, … … 5608 5619 AHCITXSTATE enmTxState = AHCITXSTATE_INVALID; 5609 5620 5621 LogFlowFunc(("pAhciPort=%p pAhciReq=%p rcReq=%d fFreeReq=%RTbool\n", 5622 pAhciPort, pAhciReq, rcReq, fFreeReq)); 5623 5610 5624 ASMAtomicReadSize(&pAhciReq->enmTxState, &enmTxState); 5611 5625 VBOXDD_AHCI_REQ_COMPLETED(pAhciReq, rcReq, enmTxState, pAhciReq->uOffset, pAhciReq->cbTransfer); … … 6207 6221 { 6208 6222 PDEVPORTNOTIFIERQUEUEITEM pNotifierItem = (PDEVPORTNOTIFIERQUEUEITEM)pItem; 6209 PAHCI p Ahci= PDMINS_2_DATA(pDevIns, PAHCI);6210 PAHCIPort pAhciPort = &p Ahci->ahciPort[pNotifierItem->iPort];6223 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 6224 PAHCIPort pAhciPort = &pThis->ahciPort[pNotifierItem->iPort]; 6211 6225 int rc = VINF_SUCCESS; 6212 6226 6213 if (!pAhciPort->fAsyncInterface) 6214 { 6215 ahciLog(("%s: Got notification from GC\n", __FUNCTION__)); 6216 /* Notify the async IO thread. */ 6217 rc = RTSemEventSignal(pAhciPort->AsyncIORequestSem); 6218 AssertRC(rc); 6219 } 6220 else 6227 ahciLog(("%s: Got notification from GC\n", __FUNCTION__)); 6228 /* Notify the async IO thread. */ 6229 rc = SUPSemEventSignal(pThis->pSupDrvSession, pAhciPort->hEvtProcess); 6230 AssertRC(rc); 6231 6232 return true; 6233 } 6234 6235 /* The async IO thread for one port. */ 6236 static DECLCALLBACK(int) ahciAsyncIOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 6237 { 6238 PAHCIPort pAhciPort = (PAHCIPort)pThread->pvUser; 6239 PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci); 6240 int rc = VINF_SUCCESS; 6241 uint64_t u64StartTime = 0; 6242 uint64_t u64StopTime = 0; 6243 uint32_t uIORequestsProcessed = 0; 6244 uint32_t uIOsPerSec = 0; 6245 uint32_t fTasksToProcess = 0; 6246 6247 ahciLog(("%s: Port %d entering async IO loop.\n", __FUNCTION__, pAhciPort->iLUN)); 6248 6249 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 6250 return VINF_SUCCESS; 6251 6252 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 6221 6253 { 6222 6254 unsigned idx = 0; 6223 uint32_t u32Tasks = ASMAtomicXchgU32(&pAhciPort->u32TasksNew, 0); 6224 6255 uint32_t u32Tasks = 0; 6256 6257 ASMAtomicWriteBool(&pAhciPort->fWrkThreadSleeping, true); 6258 u32Tasks = ASMAtomicXchgU32(&pAhciPort->u32TasksNew, 0); 6259 if (!u32Tasks) 6260 { 6261 Assert(ASMAtomicReadBool(&pAhciPort->fWrkThreadSleeping)); 6262 rc = SUPSemEventWaitNoResume(pAhci->pSupDrvSession, pAhciPort->hEvtProcess, RT_INDEFINITE_WAIT); 6263 AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), rc); 6264 if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING)) 6265 break; 6266 LogFlowFunc(("Woken up with rc=%Rrc\n", rc)); 6267 u32Tasks = ASMAtomicXchgU32(&pAhciPort->u32TasksNew, 0); 6268 } 6269 6270 ASMAtomicWriteBool(&pAhciPort->fWrkThreadSleeping, false); 6225 6271 idx = ASMBitFirstSetU32(u32Tasks); 6226 6272 while (idx) … … 6280 6326 ASMAtomicCmpXchgSize(&pAhciReq->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 6281 6327 AssertMsg(fXchg, ("Task is not active\n")); 6282 return true;6328 break; 6283 6329 } 6284 6285 if (pAhciPort->fResetDevice) /* The bit is not set and we are in a reset state. */ 6330 else if (pAhciPort->fResetDevice) /* The bit is not set and we are in a reset state. */ 6286 6331 { 6287 6332 ahciFinishStorageDeviceReset(pAhciPort, pAhciReq); … … 6289 6334 ASMAtomicCmpXchgSize(&pAhciReq->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 6290 6335 AssertMsg(fXchg, ("Task is not active\n")); 6291 return true;6336 break; 6292 6337 } 6293 6294 /* We are not in a reset state update the control registers. */ 6295 AssertMsgFailed(("%s: Update the control register\n", __FUNCTION__)); 6338 else /* We are not in a reset state update the control registers. */ 6339 AssertMsgFailed(("%s: Update the control register\n", __FUNCTION__)); 6296 6340 } 6297 6341 else … … 6318 6362 if (!(pAhciReq->fFlags & AHCI_REQ_OVERFLOW)) 6319 6363 { 6320 VBOXDD_AHCI_REQ_SUBMIT(pAhciReq, enmTxDir, pAhciReq->uOffset, pAhciReq->cbTransfer); 6321 VBOXDD_AHCI_REQ_SUBMIT_TIMESTAMP(pAhciReq, pAhciReq->tsStart); 6322 if (enmTxDir == AHCITXDIR_FLUSH) 6323 rc = pAhciPort->pDrvBlockAsync->pfnStartFlush(pAhciPort->pDrvBlockAsync, pAhciReq); 6324 else if (enmTxDir == AHCITXDIR_TRIM) 6364 if (pAhciPort->fAsyncInterface) 6325 6365 { 6326 rc = ahciTrimRangesCreate(pAhciPort, pAhciReq); 6327 if (RT_SUCCESS(rc)) 6366 VBOXDD_AHCI_REQ_SUBMIT(pAhciReq, enmTxDir, pAhciReq->uOffset, pAhciReq->cbTransfer); 6367 VBOXDD_AHCI_REQ_SUBMIT_TIMESTAMP(pAhciReq, pAhciReq->tsStart); 6368 if (enmTxDir == AHCITXDIR_FLUSH) 6369 { 6370 rc = pAhciPort->pDrvBlockAsync->pfnStartFlush(pAhciPort->pDrvBlockAsync, 6371 pAhciReq); 6372 } 6373 else if (enmTxDir == AHCITXDIR_TRIM) 6374 { 6375 rc = ahciTrimRangesCreate(pAhciPort, pAhciReq); 6376 if (RT_SUCCESS(rc)) 6377 { 6378 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6379 rc = pAhciPort->pDrvBlockAsync->pfnStartDiscard(pAhciPort->pDrvBlockAsync, pAhciReq->u.Trim.paRanges, 6380 pAhciReq->u.Trim.cRanges, pAhciReq); 6381 } 6382 } 6383 else if (enmTxDir == AHCITXDIR_READ) 6384 { 6385 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 6386 rc = pAhciPort->pDrvBlockAsync->pfnStartRead(pAhciPort->pDrvBlockAsync, pAhciReq->uOffset, 6387 &pAhciReq->u.Io.DataSeg, 1, 6388 pAhciReq->cbTransfer, 6389 pAhciReq); 6390 } 6391 else 6328 6392 { 6329 6393 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6330 rc = pAhciPort->pDrvBlockAsync->pfnStartDiscard(pAhciPort->pDrvBlockAsync, pAhciReq->u.Trim.paRanges, 6331 pAhciReq->u.Trim.cRanges, pAhciReq); 6394 rc = pAhciPort->pDrvBlockAsync->pfnStartWrite(pAhciPort->pDrvBlockAsync, pAhciReq->uOffset, 6395 &pAhciReq->u.Io.DataSeg, 1, 6396 pAhciReq->cbTransfer, 6397 pAhciReq); 6332 6398 } 6333 } 6334 else if (enmTxDir == AHCITXDIR_READ) 6335 { 6336 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 6337 rc = pAhciPort->pDrvBlockAsync->pfnStartRead(pAhciPort->pDrvBlockAsync, pAhciReq->uOffset, 6338 &pAhciReq->u.Io.DataSeg, 1, 6339 pAhciReq->cbTransfer, 6340 pAhciReq); 6399 if (rc == VINF_VD_ASYNC_IO_FINISHED) 6400 rc = ahciTransferComplete(pAhciPort, pAhciReq, VINF_SUCCESS, true); 6401 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS) 6402 rc = ahciTransferComplete(pAhciPort, pAhciReq, rc, true); 6341 6403 } 6342 6404 else 6343 6405 { 6344 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6345 rc = pAhciPort->pDrvBlockAsync->pfnStartWrite(pAhciPort->pDrvBlockAsync, pAhciReq->uOffset, 6346 &pAhciReq->u.Io.DataSeg, 1, 6347 pAhciReq->cbTransfer, 6348 pAhciReq); 6406 if (enmTxDir == AHCITXDIR_FLUSH) 6407 rc = pAhciPort->pDrvBlock->pfnFlush(pAhciPort->pDrvBlock); 6408 else if (enmTxDir == AHCITXDIR_TRIM) 6409 { 6410 rc = ahciTrimRangesCreate(pAhciPort, pAhciReq); 6411 if (RT_SUCCESS(rc)) 6412 { 6413 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6414 rc = pAhciPort->pDrvBlock->pfnDiscard(pAhciPort->pDrvBlock, pAhciReq->u.Trim.paRanges, 6415 pAhciReq->u.Trim.cRanges); 6416 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 0; 6417 } 6418 } 6419 else if (enmTxDir == AHCITXDIR_READ) 6420 { 6421 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 6422 rc = pAhciPort->pDrvBlock->pfnRead(pAhciPort->pDrvBlock, pAhciReq->uOffset, 6423 pAhciReq->u.Io.DataSeg.pvSeg, 6424 pAhciReq->cbTransfer); 6425 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 0; 6426 } 6427 else 6428 { 6429 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6430 rc = pAhciPort->pDrvBlock->pfnWrite(pAhciPort->pDrvBlock, pAhciReq->uOffset, 6431 pAhciReq->u.Io.DataSeg.pvSeg, 6432 pAhciReq->cbTransfer); 6433 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 0; 6434 } 6435 rc = ahciTransferComplete(pAhciPort, pAhciReq, rc, true); 6349 6436 } 6350 if (rc == VINF_VD_ASYNC_IO_FINISHED)6351 rc = ahciTransferComplete(pAhciPort, pAhciReq, VINF_SUCCESS, true);6352 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)6353 rc = ahciTransferComplete(pAhciPort, pAhciReq, rc, true);6354 6437 } 6355 6438 } … … 6361 6444 idx = ASMBitFirstSetU32(u32Tasks); 6362 6445 } /* while tasks available */ 6363 } /* fUseAsyncInterface */6364 6365 return true;6366 }6367 6368 /* The async IO thread for one port. */6369 static DECLCALLBACK(int) ahciAsyncIOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)6370 {6371 PAHCIPort pAhciPort = (PAHCIPort)pThread->pvUser;6372 PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci);6373 PAHCIREQ pAhciReq;6374 int rc = VINF_SUCCESS;6375 uint64_t u64StartTime = 0;6376 uint64_t u64StopTime = 0;6377 uint32_t uIORequestsProcessed = 0;6378 uint32_t uIOsPerSec = 0;6379 uint32_t fTasksToProcess = 0;6380 unsigned idx = 0;6381 6382 ahciLog(("%s: Port %d entering async IO loop.\n", __FUNCTION__, pAhciPort->iLUN));6383 6384 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)6385 return VINF_SUCCESS;6386 6387 /* We use only one task structure. */6388 pAhciReq = (PAHCIREQ)RTMemAllocZ(sizeof(AHCIREQ));6389 if (!pAhciReq)6390 {6391 AssertMsgFailed(("Failed to allocate task state memory\n"));6392 return VERR_NO_MEMORY;6393 }6394 6395 pAhciReq->enmTxState = AHCITXSTATE_FREE;6396 6397 while (pThread->enmState == PDMTHREADSTATE_RUNNING)6398 {6399 /* New run to get number of I/O requests per second?. */6400 if (!u64StartTime)6401 u64StartTime = RTTimeMilliTS();6402 6403 ASMAtomicXchgBool(&pAhciPort->fAsyncIOThreadIdle, true);6404 if (pAhci->fSignalIdle)6405 PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3);6406 6407 rc = RTSemEventWait(pAhciPort->AsyncIORequestSem, 1000);6408 if (rc == VERR_TIMEOUT)6409 {6410 /* No I/O requests in-between. Reset statistics and wait again. */6411 pAhciPort->StatIORequestsPerSecond.c = 0;6412 rc = RTSemEventWait(pAhciPort->AsyncIORequestSem, RT_INDEFINITE_WAIT);6413 }6414 6415 if (RT_FAILURE(rc) || (pThread->enmState != PDMTHREADSTATE_RUNNING))6416 break;6417 6418 /* Go to sleep again if we are in redo mode. */6419 if (RT_UNLIKELY(pAhciPort->fRedo))6420 continue;6421 6422 AssertMsg(pAhciPort->pDrvBase, ("I/O thread without attached device?!\n"));6423 6424 ASMAtomicXchgBool(&pAhciPort->fAsyncIOThreadIdle, false);6425 fTasksToProcess = ASMAtomicXchgU32(&pAhciPort->u32TasksNew, 0);6426 6427 idx = ASMBitFirstSetU32(fTasksToProcess);6428 6429 /* Process commands. */6430 while ( idx6431 && RT_LIKELY(!pAhciPort->fPortReset))6432 {6433 bool fReqCanceled = false;6434 AHCITXDIR enmTxDir;6435 6436 idx--;6437 STAM_PROFILE_START(&pAhciPort->StatProfileProcessTime, a);6438 6439 pAhciReq->tsStart = RTTimeMilliTS();6440 pAhciReq->uATARegStatus = 0;6441 pAhciReq->uATARegError = 0;6442 pAhciReq->fFlags = 0;6443 pAhciReq->uTag = idx;6444 AssertMsg(pAhciReq->uTag < AHCI_NR_COMMAND_SLOTS, ("%s: Invalid Tag number %u!!\n", __FUNCTION__, pAhciReq->uTag));6445 6446 bool fXchg;6447 ASMAtomicCmpXchgSize(&pAhciReq->enmTxState, AHCITXSTATE_ACTIVE, AHCITXSTATE_FREE, fXchg);6448 AssertMsg(fXchg, ("Task is already active\n"));6449 6450 /* Set current command slot */6451 ASMAtomicWriteU32(&pAhciPort->u32CurrentCommandSlot, pAhciReq->uTag);6452 pAhciPort->aCachedTasks[0] = pAhciReq; /* Make cancelling the request possible. */6453 6454 /* Mark the task as processed by the HBA if this is a queued task so that it doesn't occur in the CI register anymore. */6455 if (pAhciPort->regSACT & (1 << idx))6456 {6457 pAhciReq->fFlags |= AHCI_REQ_CLEAR_SACT;6458 ASMAtomicOrU32(&pAhciPort->u32TasksFinished, (1 << pAhciReq->uTag));6459 }6460 6461 ahciPortTaskGetCommandFis(pAhciPort, pAhciReq);6462 6463 ahciLog(("%s: Got command at slot %d\n", __FUNCTION__, pAhciReq->uTag));6464 6465 if (!(pAhciReq->cmdFis[AHCI_CMDFIS_BITS] & AHCI_CMDFIS_C))6466 {6467 /* If the reset bit is set put the device into reset state. */6468 if (pAhciReq->cmdFis[AHCI_CMDFIS_CTL] & AHCI_CMDFIS_CTL_SRST)6469 {6470 ahciLog(("%s: Setting device into reset state\n", __FUNCTION__));6471 pAhciPort->fResetDevice = true;6472 ahciSendD2HFis(pAhciPort, pAhciReq, &pAhciReq->cmdFis[0], true);6473 }6474 else if (pAhciPort->fResetDevice) /* The bit is not set and we are in a reset state. */6475 {6476 ahciFinishStorageDeviceReset(pAhciPort, pAhciReq);6477 }6478 /* TODO: We are not in a reset state update the control registers. */6479 6480 ASMAtomicCmpXchgSize(&pAhciReq->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg);6481 AssertMsg(fXchg, ("Task is already free\n"));6482 }6483 else6484 {6485 AssertReleaseMsg(ASMAtomicReadU32(&pAhciPort->cTasksActive) < AHCI_NR_COMMAND_SLOTS,6486 ("There are more than 32 requests active"));6487 ASMAtomicIncU32(&pAhciPort->cTasksActive);6488 enmTxDir = ahciProcessCmd(pAhciPort, pAhciReq, &pAhciReq->cmdFis[0]);6489 pAhciReq->enmTxDir = enmTxDir;6490 6491 if (enmTxDir == AHCITXDIR_FLUSH)6492 rc = pAhciPort->pDrvBlock->pfnFlush(pAhciPort->pDrvBlock);6493 else if (enmTxDir == AHCITXDIR_TRIM)6494 {6495 rc = ahciTrimRangesCreate(pAhciPort, pAhciReq);6496 if (RT_SUCCESS(rc))6497 {6498 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1;6499 rc = pAhciPort->pDrvBlock->pfnDiscard(pAhciPort->pDrvBlock,6500 pAhciReq->u.Trim.paRanges,6501 pAhciReq->u.Trim.cRanges);6502 pAhciPort->Led.Actual.s.fWriting = 0;6503 }6504 }6505 else if (enmTxDir != AHCITXDIR_NONE)6506 {6507 uint64_t uOffset = 0;6508 size_t cbTransfer = 0;6509 6510 rc = ahciIoBufAllocate(pAhciPort->pDevInsR3, pAhciReq, pAhciReq->cbTransfer);6511 if (RT_FAILURE(rc))6512 AssertMsgFailed(("%s: Failed to get number of list elments %Rrc\n", __FUNCTION__, rc));6513 6514 if (!(pAhciReq->fFlags & AHCI_REQ_OVERFLOW))6515 {6516 STAM_REL_COUNTER_INC(&pAhciPort->StatDMA);6517 6518 /* Initialize all values. */6519 uOffset = pAhciReq->uOffset;6520 cbTransfer = pAhciReq->cbTransfer;6521 6522 STAM_PROFILE_START(&pAhciPort->StatProfileReadWrite, b);6523 6524 AssertMsg(!(uOffset % 512), ("Offset is not sector aligned %llu\n", uOffset));6525 AssertMsg(!(cbTransfer % 512), ("Number of bytes to process is not sector aligned %lu\n", cbTransfer));6526 6527 if (enmTxDir == AHCITXDIR_READ)6528 {6529 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1;6530 rc = pAhciPort->pDrvBlock->pfnRead(pAhciPort->pDrvBlock, uOffset,6531 pAhciReq->u.Io.DataSeg.pvSeg,6532 cbTransfer);6533 pAhciPort->Led.Actual.s.fReading = 0;6534 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, cbTransfer);6535 }6536 else6537 {6538 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1;6539 rc = pAhciPort->pDrvBlock->pfnWrite(pAhciPort->pDrvBlock, uOffset,6540 pAhciReq->u.Io.DataSeg.pvSeg,6541 cbTransfer);6542 pAhciPort->Led.Actual.s.fWriting = 0;6543 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, cbTransfer);6544 }6545 6546 STAM_PROFILE_STOP(&pAhciPort->StatProfileReadWrite, b);6547 }6548 }6549 6550 fReqCanceled = ahciTransferComplete(pAhciPort, pAhciReq, rc, false /* fFreeReq */);6551 uIORequestsProcessed++;6552 STAM_PROFILE_STOP(&pAhciPort->StatProfileProcessTime, a);6553 }6554 6555 if (!pAhciPort->fRedo)6556 {6557 #ifdef DEBUG6558 /* Be paranoid. */6559 memset(&pAhciReq->cmdHdr, 0, sizeof(CmdHdr));6560 memset(&pAhciReq->cmdFis, 0, AHCI_CMDFIS_TYPE_H2D_SIZE);6561 pAhciReq->GCPhysCmdHdrAddr = 0;6562 pAhciReq->uOffset = 0;6563 pAhciReq->cbTransfer = 0;6564 #endif6565 }6566 6567 /*6568 * Don't process other requests if the last one was canceled,6569 * the others are not valid anymore.6570 */6571 if (fReqCanceled)6572 break;6573 fTasksToProcess &= ~(1 << idx);6574 idx = ASMBitFirstSetU32(fTasksToProcess);6575 } /* while tasks to process */6576 6577 u64StopTime = RTTimeMilliTS();6578 /* Check if one second has passed. */6579 if (u64StopTime - u64StartTime >= 1000)6580 {6581 /* Calculate number of I/O requests per second. */6582 uIOsPerSec = uIORequestsProcessed / ((u64StopTime - u64StartTime) / 1000);6583 ahciLog(("%s: Processed %u requests in %llu ms -> %u requests/s\n", __FUNCTION__, uIORequestsProcessed, u64StopTime - u64StartTime, uIOsPerSec));6584 u64StartTime = 0;6585 uIORequestsProcessed = 0;6586 /* For the release statistics. There is no macro to set the counter to a specific value. */6587 pAhciPort->StatIORequestsPerSecond.c = uIOsPerSec;6588 }6589 6446 } /* While running */ 6590 6591 if (pAhci->fSignalIdle)6592 PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3);6593 6594 RTMemFree(pAhciReq);6595 memset(pAhciPort->aCachedTasks, 0, sizeof(pAhciPort->aCachedTasks));6596 6447 6597 6448 ahciLog(("%s: Port %d async IO thread exiting\n", __FUNCTION__, pAhciPort->iLUN)); … … 6608 6459 static DECLCALLBACK(int) ahciAsyncIOLoopWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 6609 6460 { 6461 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 6610 6462 PAHCIPort pAhciPort = (PAHCIPort)pThread->pvUser; 6611 return RTSemEventSignal(pAhciPort->AsyncIORequestSem);6463 return SUPSemEventSignal(pThis->pSupDrvSession, pAhciPort->hEvtProcess); 6612 6464 } 6613 6465 … … 7537 7389 AssertMsg(iLUN < pAhci->cPortsImpl, ("iLUN=%u", iLUN)); 7538 7390 7539 if ( !pAhciPort->fAsyncInterface)7391 if (pAhciPort->pAsyncIOThread) 7540 7392 { 7541 7393 int rcThread; … … 7546 7398 7547 7399 pAhciPort->pAsyncIOThread = NULL; 7548 7549 rc = RTSemEventDestroy(pAhciPort->AsyncIORequestSem);7550 if (RT_FAILURE(rc))7551 AssertMsgFailed(("%s: Failed to destroy the event semaphore rc=%Rrc.\n", __FUNCTION__, rc));7552 7400 } 7553 7401 … … 7633 7481 pAhciPort->fAsyncInterface = true; 7634 7482 else 7635 {7636 7483 pAhciPort->fAsyncInterface = false; 7637 7484 7638 /* Create event semaphore. */ 7639 rc = RTSemEventCreate(&pAhciPort->AsyncIORequestSem); 7640 if (RT_FAILURE(rc)) 7641 { 7642 Log(("%s: Failed to create event semaphore for %s.\n", __FUNCTION__, szName)); 7643 return rc; 7644 } 7645 7646 /* Create the async IO thread. */ 7647 rc = PDMDevHlpThreadCreate(pDevIns, &pAhciPort->pAsyncIOThread, pAhciPort, ahciAsyncIOLoop, ahciAsyncIOLoopWakeUp, 0, 7648 RTTHREADTYPE_IO, szName); 7649 if (RT_FAILURE(rc)) 7650 { 7651 AssertMsgFailed(("%s: Async IO Thread creation for %s failed rc=%d\n", __FUNCTION__, szName, rc)); 7652 return rc; 7653 } 7654 } 7485 /* Create the async IO thread. */ 7486 rc = PDMDevHlpThreadCreate(pDevIns, &pAhciPort->pAsyncIOThread, pAhciPort, ahciAsyncIOLoop, ahciAsyncIOLoopWakeUp, 0, 7487 RTTHREADTYPE_IO, szName); 7488 if (RT_FAILURE(rc)) 7489 return rc; 7655 7490 7656 7491 /* … … 7765 7600 static DECLCALLBACK(int) ahciR3Destruct(PPDMDEVINS pDevIns) 7766 7601 { 7767 PAHCI p Ahci= PDMINS_2_DATA(pDevIns, PAHCI);7602 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 7768 7603 int rc = VINF_SUCCESS; 7769 7604 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); … … 7774 7609 * will take care of terminating and cleaning up the thread. 7775 7610 */ 7776 if (PDMCritSectIsInitialized(&p Ahci->lock))7777 { 7778 TMR3TimerDestroy(p Ahci->CTX_SUFF(pHbaCccTimer));7779 p Ahci->CTX_SUFF(pHbaCccTimer) = NULL;7611 if (PDMCritSectIsInitialized(&pThis->lock)) 7612 { 7613 TMR3TimerDestroy(pThis->CTX_SUFF(pHbaCccTimer)); 7614 pThis->CTX_SUFF(pHbaCccTimer) = NULL; 7780 7615 7781 7616 Log(("%s: Destruct every port\n", __FUNCTION__)); 7782 for (unsigned iActPort = 0; iActPort < p Ahci->cPortsImpl; iActPort++)7783 { 7784 PAHCIPort pAhciPort = &p Ahci->ahciPort[iActPort];7785 7786 if (pAhciPort-> pAsyncIOThread)7617 for (unsigned iActPort = 0; iActPort < pThis->cPortsImpl; iActPort++) 7618 { 7619 PAHCIPort pAhciPort = &pThis->ahciPort[iActPort]; 7620 7621 if (pAhciPort->hEvtProcess != NIL_SUPSEMEVENT) 7787 7622 { 7788 /* Destroy the event semaphore. */ 7789 rc = RTSemEventDestroy(pAhciPort->AsyncIORequestSem); 7790 if (RT_FAILURE(rc)) 7791 Log(("%s: Destroying event semaphore for port %d failed rc=%Rrc\n", __FUNCTION__, iActPort, rc)); 7792 pAhciPort->AsyncIORequestSem = NIL_RTSEMEVENT; 7623 SUPSemEventClose(pThis->pSupDrvSession, pAhciPort->hEvtProcess); 7624 pAhciPort->hEvtProcess = NIL_SUPSEMEVENT; 7793 7625 } 7794 7626 … … 7802 7634 } 7803 7635 7804 PDMR3CritSectDelete(&p Ahci->lock);7636 PDMR3CritSectDelete(&pThis->lock); 7805 7637 } 7806 7638 … … 7899 7731 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 7900 7732 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 7733 pThis->pSupDrvSession = PDMDevHlpGetSupDrvSession(pDevIns); 7901 7734 7902 7735 PCIDevSetVendorId (&pThis->dev, 0x8086); /* Intel */ … … 7946 7779 pAhciPort->Led.u32Magic = PDMLED_MAGIC; 7947 7780 pAhciPort->pDrvBase = NULL; 7948 pAhciPort->AsyncIORequestSem = NIL_RTSEMEVENT;7949 7781 pAhciPort->pAsyncIOThread = NULL; 7782 pAhciPort->hEvtProcess = NIL_SUPSEMEVENT; 7950 7783 } 7951 7784 … … 8056 7889 { 8057 7890 PAHCIPort pAhciPort = &pThis->ahciPort[i]; 7891 8058 7892 PDMDevHlpSTAMRegisterF(pDevIns, &pAhciPort->StatDMA, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 8059 7893 "Number of DMA transfers.", "/Devices/SATA%d/Port%d/DMA", iInstance, i); … … 8129 7963 LogRel(("AHCI: LUN#%d: using normal I/O\n", pAhciPort->iLUN)); 8130 7964 pAhciPort->fAsyncInterface = false; 8131 8132 rc = RTSemEventCreate(&pAhciPort->AsyncIORequestSem);8133 AssertMsgRC(rc, ("Failed to create event semaphore for %s rc=%Rrc.\n", szName, rc));8134 8135 8136 rc = PDMDevHlpThreadCreate(pDevIns, &pAhciPort->pAsyncIOThread, pAhciPort, ahciAsyncIOLoop,8137 ahciAsyncIOLoopWakeUp, 0, RTTHREADTYPE_IO, szName);8138 AssertMsgRC(rc, ("%s: Async IO Thread creation for %s failed rc=%Rrc\n", szName, rc));8139 7965 } 7966 7967 rc = PDMDevHlpThreadCreate(pDevIns, &pAhciPort->pAsyncIOThread, pAhciPort, ahciAsyncIOLoop, 7968 ahciAsyncIOLoopWakeUp, 0, RTTHREADTYPE_IO, szName); 7969 if (RT_FAILURE(rc)) 7970 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 7971 N_("AHCI: Failed to create worker thread %s"), szName); 7972 7973 rc = SUPSemEventCreate(pThis->pSupDrvSession, &pAhciPort->hEvtProcess); 7974 if (RT_FAILURE(rc)) 7975 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 7976 N_("AHCI: Failed to create SUP event semaphore")); 8140 7977 } 8141 7978 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r44892 r45646 1152 1152 GEN_CHECK_OFF(AHCIPort, fAsyncIOThreadIdle); 1153 1153 GEN_CHECK_OFF(AHCIPort, fRedo); 1154 GEN_CHECK_OFF(AHCIPort, fWrkThreadSleeping); 1154 1155 GEN_CHECK_OFF(AHCIPort, cTotalSectors); 1155 1156 GEN_CHECK_OFF(AHCIPort, cMultSectors); … … 1177 1178 GEN_CHECK_OFF(AHCIPort, Led); 1178 1179 GEN_CHECK_OFF(AHCIPort, pAsyncIOThread); 1179 GEN_CHECK_OFF(AHCIPort, AsyncIORequestSem);1180 1180 1181 1181 GEN_CHECK_OFF(AHCIPort, aCachedTasks); 1182 1182 GEN_CHECK_OFF(AHCIPort, pTaskErr); 1183 1183 GEN_CHECK_OFF(AHCIPort, pTrackList); 1184 GEN_CHECK_OFF(AHCIPort, hEvtProcess); 1184 1185 GEN_CHECK_OFF(AHCIPort, StatDMA); 1185 1186 GEN_CHECK_OFF(AHCIPort, StatBytesWritten); … … 1245 1246 GEN_CHECK_OFF(AHCI, cCmdSlotsAvail); 1246 1247 GEN_CHECK_OFF(AHCI, f8ByteMMIO4BytesWrittenSuccessfully); 1248 GEN_CHECK_OFF(AHCI, pSupDrvSession); 1247 1249 #endif /* VBOX_WITH_AHCI */ 1248 1250
Note:
See TracChangeset
for help on using the changeset viewer.