Esempio n. 1
0
void XHCIAsyncEndpoint::Complete(IOReturn passthruReturnCode)
{
	XHCIAsyncTD* pTd;
	IOUSBCommand* command;
	IOUSBCompletion comp;

	while (doneHead) {
		pTd = GetTD(&doneHead, &doneTail, &numTDsDone);
		if (!pTd)
			continue;
		command = pTd->command;
		if (pTd->absoluteShortfall)
			command->SetUIMScratch(9U, pTd->shortfall);
		else
			command->SetUIMScratch(9U, command->GetUIMScratch(9U) + pTd->shortfall);
		if (pTd->interruptThisTD &&
			pTd->finalTDInTransaction) {
			comp = command->GetUSLCompletion();
			if (comp.action) {
				/*
				 * Note: Mavericks updates a couple
				 *   of diagnostic counters here.
				 */
				provider->_completer.AddItem(&comp,
											 passthruReturnCode,
											 command->GetUIMScratch(9U),
											 true);
				pTd->shortfall = 0U;
				pTd->absoluteShortfall = false;
			}
			pTd->interruptThisTD = false;
		}
		PutTD(&freeHead, &freeTail, pTd, &numTDsFree);
	}
}
Esempio n. 2
0
void XHCIAsyncEndpoint::MoveAllTDsFromReadyQToDoneQ(void)
{
	XHCIAsyncTD* pTd;
	while (queuedHead) {
		pTd = GetTD(&queuedHead, &queuedTail, &numTDsQueued);
		if (pTd)
			PutTDonDoneQueue(pTd);
	}
}
Esempio n. 3
0
void XHCIAsyncEndpoint::MoveTDsFromReadyQToDoneQ(IOUSBCommand* command)
{
	XHCIAsyncTD* pTd;
	while (queuedHead) {
		if (command && command != queuedHead->command)
			break;
		pTd = GetTD(&queuedHead, &queuedTail, &numTDsQueued);
		if (pTd)
			PutTDonDoneQueue(pTd);
	}
}
Esempio n. 4
0
XHCIAsyncTD* XHCIAsyncEndpoint::GetTDFromFreeQueue(bool newOneOk)
{
	XHCIAsyncTD* pTd;

	if (!freeHead)
		return newOneOk ? XHCIAsyncTD::ForEndpoint(this) : 0;
	pTd = GetTD(&freeHead, &freeTail, &numTDsFree);
	if (pTd)
		pTd->reinit();
	return pTd;
}
Esempio n. 5
0
File: cdr.c Progetto: bsv798/pcsxr
// return Track Time
// buffer:
//  byte 0 - frame
//  byte 1 - second
//  byte 2 - minute
long CDRgetTD(unsigned char track, unsigned char *buffer) {
	long ret;

	if (!IsCdHandleOpen()) {
		memset(buffer + 1, 0, 3);
		return 0;
	}

	if (ReadMode == THREADED) pthread_mutex_lock(&mut);
	ret = GetTD(track, buffer);
	if (ReadMode == THREADED) pthread_mutex_unlock(&mut);

	return ret;
}
Esempio n. 6
0
struct XHCIAsyncTD* XHCIAsyncEndpoint::GetTDFromActiveQueueWithIndex(uint16_t indexInQueue)
{
	XHCIAsyncTD *pPrevTd, *pTd;
	uint32_t orphanCount = 0U;
	pTd = pPrevTd = scheduledHead;
	while (pTd) {
		if (pTd->lastTrbIndex == indexInQueue)
			break;
		if (pTd == scheduledTail)
			return 0;
		++orphanCount;
		pPrevTd = pTd;
		pTd = pTd->next;
	}
	if (!pTd)
		return 0;
#if 0
	if (pTd == scheduledTail) {
		if (pTd == scheduledHead) {
			scheduledTail = 0;
			scheduledHead = 0;
		} else
			scheduledTail = pPrevTd;
	} else if (pTd == scheduledHead)
		scheduledHead = pTd->next;
	else
		pPrevTd->next = pTd->next;
	--numTDsScheduled;
#else
	if (orphanCount) {
		/*
		 * Flush all scheduled TDs prior to pTd
		 */
		if (doneHead)
			doneTail->next = scheduledHead;
		else
			doneHead = scheduledHead;
		doneTail = pPrevTd;
		numTDsDone += orphanCount;
		scheduledHead = pTd;
		numTDsScheduled -= orphanCount;
		Complete(kIOReturnSuccess);
		if (provider)
			provider->_diagCounters[DIAGCTR_ORPHANEDTDS] += orphanCount;
	}
	GetTD(&scheduledHead, &scheduledTail, &numTDsScheduled);
#endif
	return pTd;
}
Esempio n. 7
0
void XHCIAsyncEndpoint::FlushTDs(IOUSBCommand* command, int32_t updateDequeueOption)
{
	XHCIAsyncTD* pTd;
	uint32_t streamId;
	int32_t indexInQueue;

	pTd = scheduledHead;
	if (!command || !pTd)
		return;
	indexInQueue = -1;
	streamId = 0U;
	while (pTd && pTd->command == command) {
		GetTD(&scheduledHead, &scheduledTail, &numTDsScheduled);
		if (updateDequeueOption) {
			streamId = pTd->streamId;
#if 1
			indexInQueue = pTd->lastTrbIndex + 1;
			if (indexInQueue >= static_cast<int32_t>(pRing->numTRBs) - 1)
				indexInQueue = 0;
#else
			indexInQueue = GenericUSBXHCI::NextTransferDQ(pRing, pTd->lastTrbIndex);
#endif
		}
		PutTDonDoneQueue(pTd);
		pTd = scheduledHead;
	}
	switch (updateDequeueOption) {
		case 0:
			return;
		case 1:
			if (scheduledHead)
				return;
			break;
	}
	if (indexInQueue < 0)
		return;
#if 0
	/*
	 * Note: Added Mavericks
	 */
	if (!provider->_controllerAvailable) {
		pRing->dequeueIndex = static_cast<uint16_t>(indexInQueue);
		pRing->needsSetTRDQPtr = true;
		return;
	}
#endif
	provider->SetTRDQPtr(pRing->slot, pRing->endpoint, streamId, indexInQueue);
}
Esempio n. 8
0
void XHCIAsyncEndpoint::ScheduleTDs(void)
{
	XHCIAsyncTD* pTd;
	IOReturn rc;

	if (!queuedHead)
		return;
	if (aborting) {
		if (pRing->returnInProgress)
			pRing->needsDoorbell = true;
		return;
	}
	do {
		if (!(provider->CanTDFragmentFit(pRing, maxTDBytes))) {
			if (gux_log_level >= 2 && provider)
				++provider->_diagCounters[DIAGCTR_XFERKEEPAWAY];
			break;
		}
		pTd = GetTD(&queuedHead, &queuedTail, &numTDsQueued);
		if (!pTd)
			continue;
		rc = provider->_createTransfer(pTd,
									   false,
									   pTd->bytesThisTD,
									   pTd->mystery,
									   pTd->bytesPreceedingThisTD,
									   pTd->interruptThisTD,
									   pTd->multiTDTransaction,
									   &pTd->firstTrbIndex,
									   &pTd->TrbCount,
									   &pTd->lastTrbIndex);
		if (rc != kIOReturnSuccess) {
			if (provider)
				++provider->_diagCounters[DIAGCTR_XFERLAYOUT];
			PutTDAtHead(&queuedHead, &queuedTail, pTd, &numTDsQueued);
			break;
		}
		PutTD(&scheduledHead, &scheduledTail, pTd, &numTDsScheduled);
		if (pRing->returnInProgress)
			pRing->needsDoorbell = true;
		else
			provider->StartEndpoint(pRing->slot, pRing->endpoint, pTd->streamId);
	} while(queuedHead);
}
Esempio n. 9
0
void XHCIAsyncEndpoint::UpdateTimeouts(bool abortAll, uint32_t frameNumber, bool stopped)
{
	uint64_t addr;
	int64_t trbIndex64;
	XHCIAsyncTD* pTd;
	IOUSBCommand* command;
	IOReturn passthruReturnCode;
	uint32_t shortfall, ndto, cto, bytesShortfell, firstSeen, TRTime;
	int32_t next;
	bool returnATransfer = false, absoluteShortfall = false, oldAS;

	pTd = scheduledHead;
	if (!pTd)
		return;
	addr = GenericUSBXHCI::GetTRBAddr64(&pRing->stopTrb);
	trbIndex64 = GenericUSBXHCI::DiffTRBIndex(addr, pRing->physAddr);
	if (trbIndex64 < 0 || trbIndex64 >= pRing->numTRBs - 1U) {
		trbIndex64 = pRing->dequeueIndex;
		shortfall = pTd->bytesThisTD;
	} else {
		if ((pRing->stopTrb.d & XHCI_TRB_3_ED_BIT) != 0U) {
			shortfall = pTd->bytesThisTD - XHCI_TRB_2_REM_GET(pRing->stopTrb.c);
			if (provider->_errataBits & kErrataAbsoluteEDTLA) {
				absoluteShortfall = true;
				shortfall += pTd->bytesPreceedingThisTD;
			}
		} else {
			if (XHCI_TRB_2_ERROR_GET(pRing->stopTrb.c) == XHCI_TRB_ERROR_LENGTH)
				/*
				 * Note: If stopped on a link TRB, this field is zero
				 */
				shortfall = XHCI_TRB_2_BYTES_GET(pRing->ptr[trbIndex64].c);
			else
				shortfall = XHCI_TRB_2_REM_GET(pRing->stopTrb.c);
			GenericUSBXHCI::CountRingToED(pRing, static_cast<int32_t>(trbIndex64), &shortfall);
		}
	}
	if (!abortAll) {
		command = pTd->command;
		if (!command)
			return;
		ndto = command->GetNoDataTimeout();
		cto = command->GetCompletionTimeout();
		firstSeen = command->GetUIMScratch(5U);
		if (!firstSeen) {
			command->SetUIMScratch(5U, frameNumber);
			firstSeen = frameNumber;
		}
		if (cto && frameNumber && frameNumber - firstSeen > cto) {
			pTd->shortfall = shortfall;
			pTd->absoluteShortfall = absoluteShortfall;
			returnATransfer = true;
		}
		if (ndto) {
			bytesShortfell = command->GetUIMScratch(4U);
			oldAS = ((bytesShortfell & OLDAS_MASK) != 0U);
			bytesShortfell &= ~OLDAS_MASK;
			TRTime = command->GetUIMScratch(6U);
			if (!TRTime ||
				command->GetUIMScratch(3U) != static_cast<uint32_t>(trbIndex64) ||
				bytesShortfell != shortfall ||
				oldAS != absoluteShortfall) {
				command->SetUIMScratch(3U, static_cast<uint32_t>(trbIndex64));
				command->SetUIMScratch(4U, absoluteShortfall ? (shortfall | OLDAS_MASK) : shortfall);
				command->SetUIMScratch(6U, frameNumber);
			} else if (frameNumber && frameNumber - TRTime > ndto) {
				pTd->shortfall = bytesShortfell;
				pTd->absoluteShortfall = oldAS;
				returnATransfer = true;
			}
		}
		if (!returnATransfer)
			return;
		passthruReturnCode = kIOUSBTransactionTimeout;
	} else {
		pTd->shortfall = shortfall;
		pTd->absoluteShortfall = absoluteShortfall;
		passthruReturnCode = kIOReturnNotResponding;
	}
	GetTD(&scheduledHead, &scheduledTail, &numTDsScheduled);
	if (provider->GetNeedsReset(pRing->slot))
		passthruReturnCode = kIOReturnNotResponding;
	/*
	 * Note: Mavericks updates a couple
	 *   of diagnostic counters here.
	 */
#if 1
	next = pTd->lastTrbIndex + 1;
	if (next >= static_cast<int32_t>(pRing->numTRBs) - 1)
		next = 0;
#else
	next = GenericUSBXHCI::NextTransferDQ(pRing, pTd->lastTrbIndex);
#endif
	if (!stopped)
		provider->QuiesceEndpoint(pRing->slot, pRing->endpoint);
	provider->SetTRDQPtr(pRing->slot, pRing->endpoint, pTd->streamId, next);
	RetireTDs(pTd, passthruReturnCode, true, true);
}