📄 htc_send.c
字号:
#endif
HTC_DEBUG_PRINTF(ATH_LOG_ERR | ATH_LOG_SEND,
"Frame transmission failed\n");
HTC_DEBUG_PRINTF(ATH_LOG_ERR | ATH_LOG_SEND,
"EndPoint: %d, Tx credits available: %d\n",
endPointId, GET_TX_CREDITS_AVAILABLE(endPoint));
/*
* We need to check just in case the callback routine was called
* with the error status before we reach this point and in that
* context we fee up the buffer so its just a conservative design.
*/
if (!IS_ELEMENT_FREE(element)) {
mboxBuffer->buffer += HTC_HEADER_LEN;
FRAME_EVENT(eventInfo, mboxBuffer->buffer,
mboxBuffer->bufferLength,
mboxBuffer->actualLength,
A_ECANCELED, mboxBuffer->cookie);
RECYCLE_DATA_REQUEST_ELEMENT(element);
dispatchEvent(target, endPointId, HTC_BUFFER_SENT, &eventInfo);
}
HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_SEND,
"htcSendFrame - Exit\n");
return;
}
#ifdef HTC_SYNC
else if (status == A_OK) {
element->completionCB(element, status);
}
#endif
txCreditsAvailable -= 1;
txCreditsConsumed += 1;
#ifdef DEBUG
txcreditsavailable[endPointId] = txCreditsAvailable;
txcreditsconsumed[endPointId] = txCreditsConsumed;
#endif /* DEBUG */
if (!txCreditsAvailable) {
AR_DEBUG_ASSERT(txCreditsConsumed);
/*
* Instead of taking an interrupt we can just poll for more
* credits that might have been queued up by now.
*/
HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
HIF_ASYNCHRONOUS, HIF_BYTE_BASIS,
HIF_FIXED_ADDRESS);
address = getRegAddr(TX_CREDIT_COUNTER_DECREMENT_REG, endPointId);
element = allocateRegRequestElement(target);
AR_DEBUG_ASSERT(element != NULL);
#ifdef ONLY_16BIT
FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1],
txCreditsConsumed*2, TX_CREDIT_COUNTER_DECREMENT_REG,
endPointId);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&endPoint->txCreditsAvailable[1],
txCreditsConsumed*2, &request, element);
#else
FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1],
txCreditsConsumed, TX_CREDIT_COUNTER_DECREMENT_REG,
endPointId);
status = HIFReadWrite(target->device, address,
&endPoint->txCreditsAvailable[1],
txCreditsConsumed, &request, element);
#endif
#ifndef HTC_SYNC
AR_DEBUG_ASSERT(status == A_OK);
HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_SEND,
"htcSendFrame - Exit\n");
return;
#else
AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
if ( status == A_OK ) {
HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
"Critical Section (credit): LOCK at line %d in file %s \n", __LINE__, __FILE__);
A_MUTEX_LOCK(&creditCS);
regBuffer = GET_REG_BUFFER(element);
/* Calculate the number of credits available */
#ifdef ONLY_16BIT
AR_DEBUG_ASSERT((GET_TX_CREDITS_CONSUMED(endPoint) * 2) == \
regBuffer->length);
#else
AR_DEBUG_ASSERT(GET_TX_CREDITS_CONSUMED(endPoint) == \
regBuffer->length);
#endif
SET_TX_CREDITS_AVAILABLE(endPoint, regBuffer->buffer[0] -
GET_TX_CREDITS_CONSUMED(endPoint));
SET_TX_CREDITS_CONSUMED(endPoint, 0);
txCreditsAvailable = GET_TX_CREDITS_AVAILABLE(endPoint);
txCreditsConsumed = GET_TX_CREDITS_CONSUMED(endPoint);
SET_TX_CREDITS_AVAILABLE(endPoint, 0);
SET_TX_CREDITS_CONSUMED(endPoint, txCreditsConsumed + txCreditsAvailable);
HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
"Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
A_MUTEX_UNLOCK(&creditCS);
HTC_DEBUG_PRINTF(ATH_LOG_INF | ATH_LOG_SEND,
"Pulling %d tx credits from the target\n",
txCreditsAvailable);
#ifdef DEBUG
txcreditsavailable[endPointId] = txCreditsAvailable;
txcreditsconsumed[endPointId] = txCreditsConsumed;
#endif /* DEBUG */
freeRegRequestElement(element);
if (!txCreditsAvailable) {
/* Enable the Tx credit counter interrupt so that we can get
* the credits posted by the target */
htcEnableCreditCounterInterrupt(target, endPointId);
/* Counter Interrupts have been enabled if
* txCreditsAvailable is still 0 after polling. We need to
* return here as there is nothing we can send till we get
* a Counter Interrupt.
*/
return;
}
}
#endif
}
}
HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
"Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__);
A_MUTEX_LOCK(&creditCS);
SET_TX_CREDITS_AVAILABLE(endPoint, txCreditsAvailable);
SET_TX_CREDITS_CONSUMED(endPoint, txCreditsConsumed);
HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
"Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
A_MUTEX_UNLOCK(&creditCS);
HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_SEND, "htcSendFrame - Exit\n");
}
void
htcSendBlkSize(HTC_ENDPOINT *endPoint)
{
A_STATUS status;
A_UINT32 address;
HTC_TARGET *target;
HIF_REQUEST request;
HTC_ENDPOINT_ID endPointId;
HTC_QUEUE_ELEMENT *element;
HTC_MBOX_BUFFER *mboxBuffer;
HTC_DATA_REQUEST_QUEUE *sendQueue;
HTC_REG_REQUEST_LIST *regList;
/* Get the context */
AR_DEBUG_ASSERT(endPoint != NULL);
target = endPoint->target;
AR_DEBUG_ASSERT(target != NULL);
regList = &target->regList;
AR_DEBUG_ASSERT(regList != NULL);
sendQueue = &endPoint->sendQueue;
AR_DEBUG_ASSERT(sendQueue != NULL);
endPointId = GET_ENDPOINT_ID(endPoint);
/* Decrement the tx credit count */
AR_DEBUG_ASSERT(endPoint->txCreditsConsumed == 0);
endPoint->txCreditsConsumed = 1;
HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS,
HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
address = getRegAddr(TX_CREDIT_COUNTER_DECREMENT_REG, endPointId);
element = allocateRegRequestElement(target);
AR_DEBUG_ASSERT(element != NULL);
#ifdef ONLY_16BIT
FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1],
endPoint->txCreditsConsumed*2,
TX_CREDIT_COUNTER_DECREMENT_REG, endPointId);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&endPoint->txCreditsAvailable[1],
endPoint->txCreditsConsumed*2, &request, element);
#else
FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1],
endPoint->txCreditsConsumed,
TX_CREDIT_COUNTER_DECREMENT_REG, endPointId);
status = HIFReadWrite(target->device, address,
&endPoint->txCreditsAvailable[1],
endPoint->txCreditsConsumed, &request, element);
#endif
#ifndef HTC_SYNC
AR_DEBUG_ASSERT(status == A_OK);
#else
AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
if (status == A_OK) {
element->completionCB(element, status);
}
#endif
/* Negotiate the maximum block size for the endpoint */
addToMboxQueue(sendQueue, (A_UCHAR *)&endPoint->blockSize,
sizeof(endPoint->blockSize), sizeof(endPoint->blockSize),
NULL);
element = removeFromMboxQueue(sendQueue);
element->completionCB = htcBlkSzNegCompletionCB;
mboxBuffer = GET_MBOX_BUFFER(element);
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS,
HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
address = HIF_MBOX_START_ADDR(endPointId);
status = HIFReadWrite(target->device, address, mboxBuffer->buffer,
mboxBuffer->bufferLength, &request, element);
#ifndef HTC_SYNC
AR_DEBUG_ASSERT(status == A_OK);
#else
AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
if (status == A_OK) {
element->completionCB(element, status);
}
#endif
HTC_DEBUG_PRINTF(ATH_LOG_INF | ATH_LOG_SEND ,
"Mailbox(%d), Block size: %d\n",
endPointId, endPoint->blockSize);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -