📄 htc_events.c
字号:
} else {
/* Ack the interrupt */
HIFAckInterrupt(target->device);
}
HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcDSRHandler: Exit\n");
return A_OK;
}
void
htcServiceCPUInterrupt(HTC_TARGET *target)
{
A_STATUS status;
A_UINT32 address;
HIF_REQUEST request;
A_UINT8 cpu_int_status;
HTC_DEBUG_PRINTF(ATH_LOG_INF, "CPU Interrupt\n");
cpu_int_status = target->table.cpu_int_status &
target->table.cpu_int_status_enable;
AR_DEBUG_ASSERT(cpu_int_status);
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
cpu_int_status);
/* Figure out the interrupt number */
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Interrupt Number: 0x%x\n",
htcGetBitNumSet(cpu_int_status));
/* Clear the interrupt */
target->table.cpu_int_status = cpu_int_status; /* W1C */
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
address = getRegAddr(CPU_INT_STATUS_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
&target->table.cpu_int_status, 1, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
}
void
htcServiceErrorInterrupt(HTC_TARGET *target)
{
A_STATUS status;
A_UINT32 address;
HIF_REQUEST request;
A_UINT8 error_int_status;
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Error Interrupt\n");
error_int_status = target->table.error_int_status &
target->table.error_status_enable;
AR_DEBUG_ASSERT(error_int_status);
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
error_int_status);
if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
/* Wakeup */
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Wakeup\n");
}
if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
/* Rx Underflow */
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Rx Underflow\n");
}
if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
/* Tx Overflow */
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Tx Overflow\n");
}
/* Clear the interrupt */
target->table.error_int_status = error_int_status; /* W1C */
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
address = getRegAddr(ERROR_INT_STATUS_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
&target->table.error_int_status, 1,
&request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
}
void
htcServiceCounterInterrupt(HTC_TARGET *target)
{
A_STATUS status;
A_UINT32 address;
HIF_REQUEST request;
HTC_ENDPOINT *endPoint;
HTC_ENDPOINT_ID endPointId;
A_UINT8 counter_int_status;
A_UINT8 reset_credit_int_status;
A_UINT8 update_credit_int_status;
HTC_REG_REQUEST_ELEMENT *element;
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Counter Interrupt\n");
counter_int_status = target->table.counter_int_status &
target->table.counter_int_status_enable;
AR_DEBUG_ASSERT(counter_int_status);
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
counter_int_status);
/* Service the reset credit counter interrupt */
reset_credit_int_status = (counter_int_status & 0x0F);
while(reset_credit_int_status) {
endPointId = htcGetBitNumSet(reset_credit_int_status);
endPoint = &target->endPoint[endPointId];
AR_DEBUG_ASSERT(endPoint != NULL);
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"endPoint(%d): %p\n", endPointId, endPoint);
/* Initialize the number of credits available to zero */
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, 0);
HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
"Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
A_MUTEX_UNLOCK(&creditCS);
/* Clear the interrupt */
HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
HIF_ASYNCHRONOUS, HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
address = getRegAddr(TX_CREDIT_COUNTER_RESET_REG, endPointId);
element = allocateRegRequestElement(target);
AR_DEBUG_ASSERT(element != NULL);
FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1], sizeof(endPoint->txCreditsAvailable[1]),
TX_CREDIT_COUNTER_RESET_REG, endPointId);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&endPoint->txCreditsAvailable[1],
sizeof(endPoint->txCreditsAvailable[1]), &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) {
/* Enable the Tx credit counter interrupt so that we can get the
* credits posted by the target */
htcEnableCreditCounterInterrupt(target, endPointId);
}
#endif
reset_credit_int_status &=
~(1 << htcGetBitNumSet(reset_credit_int_status));
}
/* Disable the credit counter interrupt */
htcDisableCreditCounterInterrupt(target, ENDPOINT_UNUSED);
/* Service the credit counter interrupt */
update_credit_int_status = counter_int_status & 0xF0;
while(update_credit_int_status) {
endPointId = htcGetBitNumSet(update_credit_int_status) -
HTC_MAILBOX_NUM_MAX;
endPoint = &target->endPoint[endPointId];
AR_DEBUG_ASSERT(endPoint != NULL);
/* This is the minimum number of credits that we would have got */
AR_DEBUG_ASSERT(GET_TX_CREDITS_AVAILABLE(endPoint) == 0);
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, 1);
HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
"Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
A_MUTEX_UNLOCK(&creditCS);
#ifdef DEBUG
txcreditsavailable[endPointId] = GET_TX_CREDITS_AVAILABLE(endPoint);
txcreditintrenable[endPointId] -= 1;
#endif /* DEBUG */
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Tx Credits Available: %d\n",
GET_TX_CREDITS_AVAILABLE(endPoint));
if (!target->ready) {
htcSendBlkSize(endPoint);
} else {
htcSendFrame(endPoint);
}
update_credit_int_status &=
~(1 << htcGetBitNumSet(update_credit_int_status));
}
}
void
htcEnableCreditCounterInterrupt(HTC_TARGET *target,
HTC_ENDPOINT_ID endPointId)
{
A_STATUS status;
A_UINT32 address;
HIF_REQUEST request;
HTC_ENDPOINT *endPoint;
HTC_REG_REQUEST_ELEMENT *element;
#ifdef ONLY_16BIT
A_UINT16 counter_int_enable16;
#endif
A_UCHAR counter_int_enable;
endPoint = &target->endPoint[endPointId];
AR_DEBUG_ASSERT(endPoint != NULL);
A_MUTEX_LOCK(&counterCS);
endPoint->txCreditsIntrEnable = TRUE;
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,
HIF_ASYNCHRONOUS, HIF_BYTE_BASIS,
HIF_FIXED_ADDRESS);
element = allocateRegRequestElement(target);
AR_DEBUG_ASSERT(element != NULL);
counter_int_enable = ((target->endPoint[0].txCreditsIntrEnable << (4)) |
(target->endPoint[1].txCreditsIntrEnable << (5)) |
(target->endPoint[2].txCreditsIntrEnable << (6)) |
(target->endPoint[3].txCreditsIntrEnable << (7)) |
0x0F);
#ifdef ONLY_16BIT
counter_int_enable16 = (counter_int_enable << 8) | target->table.error_status_enable;
FILL_REG_BUFFER(element, NULL, 2, COUNTER_INT_STATUS_ENABLE_REG, counter_int_enable16);
address = getRegAddr(ERROR_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
2, &request, element);
#else
FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_ENABLE_REG, counter_int_enable);
address = getRegAddr(COUNTER_INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
1, &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
A_MUTEX_UNLOCK(&counterCS);
}
void
htcDisableCreditCounterInterrupt(HTC_TARGET *target,
HTC_ENDPOINT_ID unused)
{
A_STATUS status;
A_UINT32 address;
HIF_REQUEST request;
HTC_ENDPOINT *endPoint;
HTC_ENDPOINT_ID endPointId;
A_UINT8 update_credit_int_status;
HTC_REG_REQUEST_ELEMENT *element;
#ifdef ONLY_16BIT
A_UINT16 counter_int_enable16;
#endif
A_UCHAR counter_int_enable;
A_MUTEX_LOCK(&counterCS);
/* The Tx credit counter update bits are reflected in the upper nibble */
update_credit_int_status = target->table.counter_int_status & 0xF0;
while(update_credit_int_status) {
endPointId = htcGetBitNumSet(update_credit_int_status) -
HTC_MAILBOX_NUM_MAX;
endPoint = &target->endPoint[endPointId];
AR_DEBUG_ASSERT(endPoint != NULL);
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"endPoint(%d): %p\n", endPointId, endPoint);
/* Disable the tx credit interrupt */
endPoint->txCreditsIntrEnable = FALSE;
update_credit_int_status &=
~(1 << htcGetBitNumSet(update_credit_int_status));
}
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS,
HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
element = allocateRegRequestElement(target);
AR_DEBUG_ASSERT(element != NULL);
counter_int_enable = ((target->endPoint[0].txCreditsIntrEnable << (4)) |
(target->endPoint[1].txCreditsIntrEnable << (5)) |
(target->endPoint[2].txCreditsIntrEnable << (6)) |
(target->endPoint[3].txCreditsIntrEnable << (7)) | 0x0F);
#ifdef ONLY_16BIT
counter_int_enable16 = (counter_int_enable << 8) | target->table.error_status_enable;
FILL_REG_BUFFER(element, NULL, 2, COUNTER_INT_STATUS_DISABLE_REG,
counter_int_enable16);
address = getRegAddr(ERROR_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
2, &request, element);
#else
FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_DISABLE_REG,
counter_int_enable);
address = getRegAddr(COUNTER_INT_STATUS_DISABLE_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
1, &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
A_MUTEX_UNLOCK(&counterCS);
}
void
htcServiceMailboxInterrupt(HTC_TARGET *target)
{
A_STATUS status;
A_UINT32 address;
HIF_REQUEST request;
HTC_ENDPOINT *endPoint;
HTC_ENDPOINT_ID endPointId;
A_UINT8 mailbox_int_status;
HTC_DEBUG_PRINTF(ATH_LOG_INF, "Mailbox Interrupt\n");
/* The Rx interrupt bits are reflected in the lower nibble */
mailbox_int_status = target->table.host_int_status &
HOST_INT_STATUS_MBOX_DATA_MASK;
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"Valid mailbox interrupt source(s) in INT_STATUS: 0x%x\n",
mailbox_int_status);
/* Disable the receive interrupt for all four mailboxes */
target->table.int_status_enable &= ~(HOST_INT_STATUS_MBOX_DATA_MASK);
do {
while(mailbox_int_status) {
endPointId = htcGetBitNumSet(mailbox_int_status);
endPoint = &target->endPoint[endPointId];
AR_DEBUG_ASSERT(endPoint != NULL);
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"endPoint(%d): %p\n", endPointId, endPoint);
/* Service the Rx interrupt */
htcReceiveFrame(endPoint);
mailbox_int_status &= ~(1 << htcGetBitNumSet(mailbox_int_status));
}
/*
* Read the register table again. Repeat the process until there are
* no more valid packets queued up on receive. It is assumed that
* the following request will be serialized along with the request
* above and will be completed in the order in which it is received
* by the bus driver.
*/
HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
HIF_SYNCHRONOUS, HIF_BYTE_BASIS,
HIF_INCREMENTAL_ADDRESS);
address = getRegAddr(INT_STATUS_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
&target->table.host_int_status,
24, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
// Hack for CF card surprise removal crash.
if(target->table.host_int_status == 0xff) {
target->table.host_int_status = 0;
return;
}
mailbox_int_status = target->table.host_int_status &
HOST_INT_STATUS_MBOX_DATA_MASK;
} while (mailbox_int_status);
target->table.int_status_enable |= HOST_INT_STATUS_MBOX_DATA_MASK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -