Lines Matching refs:pCtl

535     PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
538 if (!pCtl->fReset)
548 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
551 if (!pCtl->fReset)
561 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
564 if (!pCtl->fReset)
704 static void ataAsyncIOClearRequests(PATACONTROLLER pCtl)
708 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
710 pCtl->AsyncIOReqHead = 0;
711 pCtl->AsyncIOReqTail = 0;
712 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
717 static void ataAsyncIOPutRequest(PATACONTROLLER pCtl, const ATARequest *pReq)
721 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
723 Assert((pCtl->AsyncIOReqHead + 1) % RT_ELEMENTS(pCtl->aAsyncIORequests) != pCtl->AsyncIOReqTail);
724 memcpy(&pCtl->aAsyncIORequests[pCtl->AsyncIOReqHead], pReq, sizeof(*pReq));
725 pCtl->AsyncIOReqHead++;
726 pCtl->AsyncIOReqHead %= RT_ELEMENTS(pCtl->aAsyncIORequests);
727 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
729 rc = PDMR3CritSectScheduleExitEvent(&pCtl->lock, pCtl->AsyncIOSem);
732 rc = RTSemEventSignal(pCtl->AsyncIOSem);
738 static const ATARequest *ataAsyncIOGetCurrentRequest(PATACONTROLLER pCtl)
743 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
745 if (pCtl->AsyncIOReqHead != pCtl->AsyncIOReqTail)
746 pReq = &pCtl->aAsyncIORequests[pCtl->AsyncIOReqTail];
749 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
760 * @param pCtl Controller for which to remove the request.
763 static void ataAsyncIORemoveCurrentRequest(PATACONTROLLER pCtl, ATAAIO ReqType)
767 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
769 if (pCtl->AsyncIOReqHead != pCtl->AsyncIOReqTail && pCtl->aAsyncIORequests[pCtl->AsyncIOReqTail].ReqType == ReqType)
771 pCtl->AsyncIOReqTail++;
772 pCtl->AsyncIOReqTail %= RT_ELEMENTS(pCtl->aAsyncIORequests);
774 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
784 * @param pCtl Controller for which to dump the queue.
786 static void ataAsyncIODumpRequests(PATACONTROLLER pCtl)
791 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
793 LogRel(("PIIX3 ATA: Ctl#%d: request queue dump (topmost is current):\n", ATACONTROLLER_IDX(pCtl)));
794 curr = pCtl->AsyncIOReqTail;
797 if (curr == pCtl->AsyncIOReqHead)
798 LogRel(("PIIX3 ATA: Ctl#%d: processed requests (topmost is oldest):\n", ATACONTROLLER_IDX(pCtl)));
799 switch (pCtl->aAsyncIORequests[curr].ReqType)
802 LogRel(("new transfer request, iIf=%d iBeginTransfer=%d iSourceSink=%d cbTotalTransfer=%d uTxDir=%d\n", pCtl->aAsyncIORequests[curr].u.t.iIf, pCtl->aAsyncIORequests[curr].u.t.iBeginTransfer, pCtl->aAsyncIORequests[curr].u.t.iSourceSink, pCtl->aAsyncIORequests[curr].u.t.cbTotalTransfer, pCtl->aAsyncIORequests[curr].u.t.uTxDir));
817 LogRel(("abort request, iIf=%d fResetDrive=%d\n", pCtl->aAsyncIORequests[curr].u.a.iIf, pCtl->aAsyncIORequests[curr].u.a.fResetDrive));
820 LogRel(("unknown request %d\n", pCtl->aAsyncIORequests[curr].ReqType));
822 curr = (curr + 1) % RT_ELEMENTS(pCtl->aAsyncIORequests);
823 } while (curr != pCtl->AsyncIOReqTail);
824 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
833 * @param pCtl Controller for which to check the queue.
836 static bool ataAsyncIOIsIdle(PATACONTROLLER pCtl, bool fStrict)
841 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
843 fIdle = pCtl->fRedoIdle;
845 fIdle = (pCtl->AsyncIOReqHead == pCtl->AsyncIOReqTail);
847 fIdle &= (pCtl->uAsyncIOState == ATA_AIO_NEW);
848 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
866 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
869 Assert(PDMCritSectIsOwner(&pCtl->lock));
872 if (pCtl->fReset)
874 Log2(("%s: Ctl#%d: suppressed new request as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
881 if (!fChainedTransfer && !ataAsyncIOIsIdle(pCtl, true /*fStrict*/))
883 Log(("%s: Ctl#%d: ignored command %#04x, controller state %d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegCommand, pCtl->uAsyncIOState));
890 Req.u.t.iIf = pCtl->iAIOIf;
892 Req.u.t.iIf = pCtl->iSelectedIf;
898 pCtl->fChainedTransfer = fChainedTransfer;
903 Log2(("%s: Ctl#%d: message to async I/O thread, new request\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
904 ataAsyncIOPutRequest(pCtl, &Req);
916 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
919 Assert(PDMCritSectIsOwner(&pCtl->lock));
922 if (pCtl->fReset)
924 Log2(("%s: Ctl#%d: suppressed aborting command as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
929 Req.u.a.iIf = pCtl->iSelectedIf;
932 Log2(("%s: Ctl#%d: message to async I/O thread, abort command on LUN#%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->iLUN));
933 ataAsyncIOPutRequest(pCtl, &Req);
939 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
948 pCtl->BmDma.u8Status |= BM_STATUS_INT;
950 if (s == &pCtl->aIfs[pCtl->iSelectedIf])
954 if (pCtl->irq == 16)
957 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 1);
967 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
974 if (s == &pCtl->aIfs[pCtl->iSelectedIf])
976 if (pCtl->irq == 16)
979 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 0);
1319 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1325 PDMCritSectLeave(&pCtl->lock);
1332 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1333 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1334 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1525 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1526 Assert(!PDMCritSectIsOwner(&pCtl->lock));
1529 pCtl->fRedoIdle = true;
1535 pCtl->fRedoIdle = true;
1541 pCtl->fRedoIdle = true;
1550 pCtl->fRedoIdle = true;
1561 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1564 PDMCritSectLeave(&pCtl->lock);
1581 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1582 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1583 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1591 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1594 PDMCritSectLeave(&pCtl->lock);
1619 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1620 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1621 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1857 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1867 PDMCritSectLeave(&pCtl->lock);
1913 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1914 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1915 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1955 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1982 PDMCritSectLeave(&pCtl->lock);
2056 STAM_PROFILE_START(&pCtl->StatLockWait, a);
2057 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
2058 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
2138 STAM_PROFILE_START(&pCtl->StatLockWait, a);
2139 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
2140 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3280 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
3284 PDMCritSectLeave(&pCtl->lock);
3297 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3298 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3299 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3901 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
3904 PDMCritSectLeave(&pCtl->lock);
3918 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3919 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3920 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4270 static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4272 Log2(("%s: LUN#%d write addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN, addr, val));
4280 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4281 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4282 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
4283 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
4284 pCtl->aIfs[0].uATARegFeature = val;
4285 pCtl->aIfs[1].uATARegFeature = val;
4288 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4289 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4290 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
4291 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
4292 pCtl->aIfs[0].uATARegNSector = val;
4293 pCtl->aIfs[1].uATARegNSector = val;
4296 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4297 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4298 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
4299 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
4300 pCtl->aIfs[0].uATARegSector = val;
4301 pCtl->aIfs[1].uATARegSector = val;
4304 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4305 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4306 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
4307 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
4308 pCtl->aIfs[0].uATARegLCyl = val;
4309 pCtl->aIfs[1].uATARegLCyl = val;
4312 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4313 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4314 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
4315 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
4316 pCtl->aIfs[0].uATARegHCyl = val;
4317 pCtl->aIfs[1].uATARegHCyl = val;
4320 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
4321 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
4322 if (((val >> 4) & 1) != pCtl->iSelectedIf)
4324 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
4327 pCtl->iSelectedIf = (val >> 4) & 1;
4332 if ( !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ)
4333 && ( pCtl->aIfs[pCtl->iSelectedIf].fIrqPending
4334 != pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending))
4336 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
4338 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4342 pCtl->BmDma.u8Status |= BM_STATUS_INT;
4343 if (pCtl->irq == 16)
4346 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 1);
4350 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4351 if (pCtl->irq == 16)
4354 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 0);
4362 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
4368 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
4375 static int ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
4377 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4384 if (pCtl->iSelectedIf) /* Device 1 selected, Device 0 responding for it. */
4386 if (!pCtl->aIfs[0].pDrvBlock) /* @todo: this case should never get here! */
4391 if (((addr & 7) != 1) && pCtl->aIfs[0].fATAPI) {
4393 s->iLUN, pCtl->aIfs[0].iLUN));
4450 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
4478 PDMCritSectLeave(&pCtl->lock);
4493 if (pCtl->fReset)
4497 if ((u64ResetTimeStop - pCtl->u64ResetTime) >= 10)
4500 pCtl->u64ResetTime = u64ResetTimeStop;
4501 RTThreadPoke(pCtl->AsyncIOThread);
4509 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4510 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4511 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4539 static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr)
4541 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4546 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
4548 else if (pCtl->iSelectedIf == 1 && !s->pDrvBlock)
4556 static int ataControlWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4559 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
4565 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
4572 if (pCtl->aIfs[0].u64CmdTS)
4573 uCmdWait0 = (uNow - pCtl->aIfs[0].u64CmdTS) / 1000;
4574 if (pCtl->aIfs[1].u64CmdTS)
4575 uCmdWait1 = (uNow - pCtl->aIfs[1].u64CmdTS) / 1000;
4577 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
4578 pCtl->aIfs[0].uATARegCommand, uCmdWait0,
4579 pCtl->aIfs[1].uATARegCommand, uCmdWait1));
4580 pCtl->fReset = true;
4584 pCtl->fChainedTransfer = false;
4585 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4587 ataResetDevice(&pCtl->aIfs[i]);
4590 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
4591 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
4592 pCtl->aIfs[i].uATARegError = 0x01;
4594 ataAsyncIOClearRequests(pCtl);
4595 Log2(("%s: Ctl#%d: message to async I/O thread, resetA\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4603 pCtl->u64ResetTime = RTTimeMilliTS();
4606 ataAsyncIOPutRequest(pCtl, &g_ataResetARequest);
4611 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
4617 Log2(("%s: Ctl#%d: message to async I/O thread, resetC\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4623 ataAsyncIOPutRequest(pCtl, &g_ataResetCRequest);
4631 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ
4632 && pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
4636 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4640 pCtl->BmDma.u8Status |= BM_STATUS_INT;
4641 if (pCtl->irq == 16)
4642 PDMDevHlpPCISetIrq(CONTROLLER_2_DEVINS(pCtl), 0, 1);
4644 PDMDevHlpISASetIrq(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
4648 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4649 if (pCtl->irq == 16)
4650 PDMDevHlpPCISetIrq(CONTROLLER_2_DEVINS(pCtl), 0, 0);
4652 PDMDevHlpISASetIrq(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
4659 pCtl->aIfs[0].uATARegDevCtl = val;
4660 pCtl->aIfs[1].uATARegDevCtl = val;
4667 static void ataPIOTransfer(PATACONTROLLER pCtl)
4671 s = &pCtl->aIfs[pCtl->iAIOIf];
4688 pCtl->fRedo = fRedo;
4720 DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
4724 if (pCtl->fReset)
4726 Log2(("%s: Ctl#%d: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4740 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4741 ataAsyncIOPutRequest(pCtl, &g_ataPIORequest);
4756 ataPIOTransfer(pCtl);
4761 Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4763 ataPIOTransfer(pCtl);
4764 Assert(!pCtl->fRedo);
4771 static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
4773 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4794 ataPIOTransferFinish(pCtl, s);
4803 static int ataDataRead(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
4805 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4826 ataPIOTransferFinish(pCtl, s);
4854 * @param pCtl Controller for which to perform the transfer.
4856 static void ataDMATransfer(PATACONTROLLER pCtl)
4858 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
4859 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
4870 fRedo = pCtl->fRedo;
4882 PDMCritSectLeave(&pCtl->lock);
4888 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
4896 pBuffer = pCtl->pRedoDMABuffer;
4897 cbBuffer = pCtl->cbRedoDMABuffer;
4898 fLastDesc = pCtl->fRedoDMALastDesc;
4940 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4941 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4942 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4959 pCtl->pFirstDMADesc = pDesc;
4960 pCtl->pRedoDMABuffer = pBuffer;
4961 pCtl->cbRedoDMABuffer = cbBuffer;
4962 pCtl->fRedoDMALastDesc = fLastDesc;
4974 pCtl->fRedo = fRedo;
4979 pDesc = pCtl->pLastDMADesc + 1;
4982 PDMCritSectLeave(&pCtl->lock);
4996 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4997 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4998 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
5001 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
5003 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
5004 if (!pCtl->fReset)
5007 pDesc = pCtl->pLastDMADesc + 1;
5010 PDMCritSectLeave(&pCtl->lock);
5014 STAM_PROFILE_START(&pCtl->StatLockWait, a);
5015 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5016 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
5023 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
5033 * @param pCtl The controller.
5035 static void ataR3AsyncSignalIdle(PATACONTROLLER pCtl)
5041 int rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT); AssertRC(rc);
5043 if ( pCtl->fSignalIdle
5044 && ataAsyncIOIsIdle(pCtl, false /*fStrict*/))
5046 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3);
5047 RTThreadUserSignal(pCtl->AsyncIOThread); /* for ataR3Construct/ataR3ResetCommon. */
5050 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex); AssertRC(rc);
5063 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
5067 pCtl->fChainedTransfer = false;
5068 while (!pCtl->fShutdown)
5071 while (pCtl->fRedoIdle)
5073 if (pCtl->fSignalIdle)
5074 ataR3AsyncSignalIdle(pCtl);
5075 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
5081 if (RT_FAILURE(rc) || pCtl->fShutdown)
5084 pCtl->fRedoIdle = false;
5090 if (pCtl->fSignalIdle)
5091 ataR3AsyncSignalIdle(pCtl);
5092 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
5098 if (RT_FAILURE(rc) || RT_UNLIKELY(pCtl->fShutdown))
5101 pReq = ataAsyncIOGetCurrentRequest(pCtl);
5104 if (RT_FAILURE(rc) || pCtl->fShutdown)
5112 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
5113 if (pCtl->uAsyncIOState != ReqType)
5118 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
5122 ataAsyncIODumpRequests(pCtl);
5124 AssertReleaseMsg(ReqType == ATA_AIO_RESET_ASSERTED || ReqType == ATA_AIO_RESET_CLEARED || ReqType == ATA_AIO_ABORT || pCtl->uAsyncIOState == ReqType, ("I/O state inconsistent: state=%d request=%d\n", pCtl->uAsyncIOState, ReqType));
5129 STAM_PROFILE_START(&pCtl->StatLockWait, a);
5130 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5131 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
5134 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
5138 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
5146 pCtl->iAIOIf = pReq->u.t.iIf;
5147 s = &pCtl->aIfs[pCtl->iAIOIf];
5157 if (pCtl->fChainedTransfer)
5175 pCtl->fChainedTransfer = false;
5179 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5197 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5199 pCtl->fRedo = fRedo;
5200 if (RT_UNLIKELY(fRedo && !pCtl->fReset))
5205 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5206 ataAsyncIOPutRequest(pCtl, pReq);
5220 if (pCtl->fReset)
5229 pCtl->uAsyncIOState = ATA_AIO_DMA;
5231 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
5233 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5234 ataAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5243 pCtl->uAsyncIOState = ATA_AIO_NEW;
5250 ataPIOTransfer(pCtl);
5251 Assert(!pCtl->fRedo);
5259 pCtl->uAsyncIOState = ATA_AIO_PIO;
5271 pCtl->uAsyncIOState = ATA_AIO_NEW;
5278 ataPIOTransfer(pCtl);
5279 Assert(!pCtl->fRedo);
5282 pCtl->uAsyncIOState = ATA_AIO_NEW;
5289 BMDMAState *bm = &pCtl->BmDma;
5290 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
5298 if (RT_LIKELY(!pCtl->fRedo))
5302 pCtl->pFirstDMADesc = bm->pvAddr;
5303 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
5305 ataDMATransfer(pCtl);
5307 if (RT_UNLIKELY(pCtl->fRedo && !pCtl->fReset))
5309 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
5310 ataAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5317 && pCtl->DelayIRQMillies)
5324 PDMCritSectLeave(&pCtl->lock);
5325 RTThreadSleep(pCtl->DelayIRQMillies);
5326 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5330 Assert(!pCtl->fChainedTransfer);
5335 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
5339 pCtl->uAsyncIOState = ATA_AIO_NEW;
5344 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
5349 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5351 pCtl->fRedo = fRedo;
5352 if (RT_UNLIKELY(fRedo && !pCtl->fReset))
5354 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
5355 ataAsyncIOPutRequest(pCtl, &g_ataPIORequest);
5373 if (pCtl->fReset)
5378 ataPIOTransfer(pCtl);
5385 pCtl->uAsyncIOState = ATA_AIO_PIO;
5397 pCtl->uAsyncIOState = ATA_AIO_NEW;
5403 ataPIOTransfer(pCtl);
5404 if ( !pCtl->fChainedTransfer
5410 pCtl->uAsyncIOState = ATA_AIO_NEW;
5415 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
5416 ataPIOTransferStop(&pCtl->aIfs[0]);
5417 ataPIOTransferStop(&pCtl->aIfs[1]);
5424 pCtl->uAsyncIOState = ATA_AIO_NEW;
5425 pCtl->fReset = false;
5428 pCtl->fRedo = false;
5429 pCtl->fRedoDMALastDesc = false;
5431 ATACONTROLLER_IDX(pCtl)));
5432 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
5434 if (pCtl->aIfs[i].fATAPI)
5435 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
5437 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
5438 ataSetSignature(&pCtl->aIfs[i]);
5446 s = &pCtl->aIfs[pReq->u.a.iIf];
5448 pCtl->uAsyncIOState = ATA_AIO_NEW;
5469 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
5472 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
5473 pReq = ataAsyncIOGetCurrentRequest(pCtl);
5475 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
5478 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
5483 Log(("%s: Ctl#%d: LUN#%d finished I/O transaction in %d microseconds\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->aIfs[pCtl->iAIOIf].iLUN, (uint32_t)(uWait)));
5485 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
5492 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
5502 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
5515 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
5520 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
5521 pCtl->StatAsyncMinWait = uWait;
5522 if (uWait > pCtl->StatAsyncMaxWait)
5523 pCtl->StatAsyncMaxWait = uWait;
5525 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
5526 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
5530 PDMCritSectLeave(&pCtl->lock);
5534 RTThreadUserSignal(pCtl->AsyncIOThread);
5535 if (pCtl->fSignalIdle)
5536 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3);
5540 pCtl->fShutdown = false;
5542 Log2(("%s: Ctl#%d: return %Rrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
5548 static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
5550 uint32_t val = pCtl->BmDma.u8Cmd;
5556 static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5561 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
5562 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5569 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
5570 uint8_t uOldBmDmaStatus = pCtl->BmDma.u8Status;
5571 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
5572 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5575 if (pCtl->fReset)
5577 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5583 if ( !pCtl->aIfs[pCtl->iSelectedIf].fDMA
5587 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
5589 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5590 ataAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5598 static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
5600 uint32_t val = pCtl->BmDma.u8Status;
5605 static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5608 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
5609 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
5610 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
5613 static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
5615 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
5620 static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5623 pCtl->BmDma.pvAddr = val & ~3;
5626 static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5629 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
5633 static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5636 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
5649 PATACONTROLLER pCtl = &pThis->aCts[i];
5651 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
5656 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5657 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5658 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5659 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5660 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
5663 *pu32 = ataBMDMACmdReadB(pCtl, Port) | (ataBMDMAStatusReadB(pCtl, Port) << 16);
5667 PDMCritSectLeave(&pCtl->lock);
5670 PDMCritSectLeave(&pCtl->lock);
5682 PATACONTROLLER pCtl = &pThis->aCts[i];
5684 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
5697 ataBMDMACmdWriteB(pCtl, Port, u32);
5699 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
5700 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
5701 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
5702 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
5705 PDMCritSectLeave(&pCtl->lock);
5854 PATACONTROLLER pCtl = &pThis->aCts[i];
5859 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
5862 if (Port == pCtl->IOPortBase1)
5866 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
5877 rc = ataIOPortWriteU8(pCtl, Port, u32);
5879 PDMCritSectLeave(&pCtl->lock);
5892 PATACONTROLLER pCtl = &pThis->aCts[i];
5897 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
5900 if (Port == pCtl->IOPortBase1)
5904 rc = ataDataRead(pCtl, Port, cb == 1 ? 2 : cb, (uint8_t *)pu32);
5914 rc = ataIOPortReadU8(pCtl, Port, pu32);
5927 PDMCritSectLeave(&pCtl->lock);
5940 PATACONTROLLER pCtl = &pThis->aCts[i];
5945 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
5948 if (Port == pCtl->IOPortBase1)
5952 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5960 PDMCritSectLeave(&pCtl->lock);
5977 PDMCritSectLeave(&pCtl->lock);
5992 ataPIOTransferFinish(pCtl, s);
5995 PDMCritSectLeave(&pCtl->lock);
6008 PATACONTROLLER pCtl = &pThis->aCts[i];
6013 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
6016 if (Port == pCtl->IOPortBase1)
6020 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
6028 PDMCritSectLeave(&pCtl->lock);
6045 PDMCritSectLeave(&pCtl->lock);
6060 ataPIOTransferFinish(pCtl, s);
6063 PDMCritSectLeave(&pCtl->lock);
6076 PATACONTROLLER pCtl = &pThis->aCts[i];
6083 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
6086 rc = ataControlWrite(pCtl, Port, u32);
6087 PDMCritSectLeave(&pCtl->lock);
6100 PATACONTROLLER pCtl = &pThis->aCts[i];
6108 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
6111 *pu32 = ataStatusRead(pCtl, Port);
6112 PDMCritSectLeave(&pCtl->lock);
6138 PATACONTROLLER pCtl;
6151 pCtl = &pThis->aCts[iController];
6154 pIf = &pCtl->aIfs[iInterface];
6323 PATACONTROLLER pCtl;
6338 pCtl = &pThis->aCts[iController];
6341 pIf = &pCtl->aIfs[iInterface];
6346 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
7404 PATACONTROLLER pCtl = &pThis->aCts[i];
7409 pCtl->uAsyncIOState = ATA_AIO_NEW;
7410 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
7412 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
7414 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
7416 ataAsyncIOClearRequests(pCtl);
7417 rc = RTThreadCreateF(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024 /*cbStack*/,
7420 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
7421 Log(("%s: controller %d AIO thread id %#x; sem %p susp_sem %p mutex %p\n", __FUNCTION__, i, pCtl->AsyncIOThread, pCtl->AsyncIOSem, pCtl->SuspendIOSem, pCtl->AsyncIORequestMutex));
7423 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
7425 static const char *s_apszDescs[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
7435 ATADevState *pIf = &pCtl->aIfs[j];
7446 static const char *s_apszCFGMKeys[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =