📄 htc.c
字号:
sendQueue = &endPoint->sendQueue;
flushMboxQueue(endPoint, sendQueue, HTC_BUFFER_SENT);
}
break;
case HTC_SKB_SENT:
HTC_DEBUG_PRINTF(ATH_LOG_ERR, "skb not handled currently\n");
break;
case HTC_DATA_AVAILABLE:
/*
* Dispatch a data available event with the length. We are
* not handling this specific case currently because registering
* for HTC_DATA_AVAILABLE event is a part of the discipline
* that is imposed before one starts using HTC
*/
break;
default:
HTC_DEBUG_PRINTF(ATH_LOG_ERR,
"Unknown Event ID: 0x%x\n", eventId);
return A_EINVAL;
}
/* Check if its a call for registering the event or unregistering it */
if (eventHandler == NULL) {
if ((status = removeFromEventTable(target, endPointId,
eventId)) != A_OK)
{
HTC_DEBUG_PRINTF(ATH_LOG_ERR,
"Could not remove the event 0x%x from the event table\n", eventId);
return status;
}
}
HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCEventReg: Exit\n");
return A_OK;
}
/*
* Commit an address to either WINDOW_WRITE_ADDR_REG or to
* WINDOW_READ_ADDR_REG. We write the least significan byte (LSB)
* last, since it triggers the read/write.
*/
static void
_WRITE_WINDOW_ADDR(HTC_TARGET *target, A_UINT32 whichreg, A_UINT32 value)
{
A_UINT32 window_addr;
HIF_REQUEST request;
A_STATUS status;
A_UINT32 address;
window_addr = value;
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
address = getRegAddr(whichreg, ENDPOINT_UNUSED);
#ifdef ONLY_16BIT
status = HIFReadWrite(target->device, address+2,
(A_UCHAR *)&window_addr+2, 2, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&window_addr, 2, &request, NULL);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&window_addr, 2, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
#else
status = HIFReadWrite(target->device, address+1,
(A_UCHAR *)&window_addr+1, 3, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
status = HIFReadWrite(target->device, address,
(A_UCHAR *)&window_addr, 1, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
#endif
}
void
HTCStop(HTC_TARGET *target)
{
A_UINT32 count;
A_STATUS status;
A_UINT32 address;
HIF_REQUEST request;
A_UINT32 window_data;
HTC_ENDPOINT *endPoint;
HTC_REG_REQUEST_LIST *regList;
HTC_REG_REQUEST_ELEMENT *element;
HTC_DATA_REQUEST_QUEUE *sendQueue;
HTC_DATA_REQUEST_QUEUE *recvQueue;
HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStop: Enter");
/* Disable all the dragon interrupts */
target->table.int_status_enable = 0;
target->table.cpu_int_status_enable = 0;
target->table.error_status_enable = 0;
target->table.counter_int_status_enable = 0;
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address,
&target->table.int_status_enable, 4, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
/* Disable the host controller interrupts */
HIFMaskInterrupt(target->device);
/* Flush all the queues and return the buffers to their owner */
for (count = ENDPOINT1; count <= ENDPOINT4; count ++) {
endPoint = &target->endPoint[count];
/* Decrement the number of credits consumed */
if (endPoint->txCreditsConsumed) {
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,
HIF_SYNCHRONOUS, HIF_BYTE_BASIS,
HIF_FIXED_ADDRESS);
address = getRegAddr(TX_CREDIT_COUNTER_DECREMENT_REG, count);
#ifdef ONLY_16BIT
status = HIFReadWrite(target->device, address,
(A_UCHAR *)endPoint->txCreditsAvailable,
endPoint->txCreditsConsumed * 2, &request, NULL);
#else
status = HIFReadWrite(target->device, address,
endPoint->txCreditsAvailable,
endPoint->txCreditsConsumed, &request, NULL);
#endif
AR_DEBUG_ASSERT(status == A_OK);
}
SET_TX_CREDITS_AVAILABLE(endPoint, 0);
SET_TX_CREDITS_CONSUMED(endPoint, 0);
#ifdef DEBUG
txcreditsavailable[count] = GET_TX_CREDITS_AVAILABLE(endPoint);
txcreditsconsumed[count] = GET_TX_CREDITS_CONSUMED(endPoint);
#endif
endPoint->txCreditsIntrEnable = FALSE;
endPoint->rxLengthPending = 0;
endPoint->enabled = FALSE;
/* Flush the Pending Receive Queue */
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"Flushing the recv queue & returning the buffers\n");
recvQueue = &endPoint->recvQueue;
flushMboxQueue(endPoint, recvQueue, HTC_BUFFER_RECEIVED);
/* Flush the Pending Send Queue */
HTC_DEBUG_PRINTF(ATH_LOG_INF,
"Flushing the send queue & returning the buffers\n");
sendQueue = &endPoint->sendQueue;
flushMboxQueue(endPoint, sendQueue, HTC_BUFFER_SENT);
}
/* Clear the tx counters */
memset(tx_attempt, 0, sizeof(tx_attempt));
memset(tx_post, 0, sizeof(tx_post));
memset(tx_complete, 0, sizeof(tx_complete));
/* Attempting a force reset of the target */
window_data = RESET_CONTROL_COLD_RST_MASK;
HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
address = getRegAddr(WINDOW_DATA_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address, (A_UCHAR *)&window_data,
4, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
_WRITE_WINDOW_ADDR(target, WINDOW_WRITE_ADDR_REG, RESET_CONTROL_ADDRESS);
/*
* Read back the RESET CAUSE register to ensure that the cold reset
* went through.
*/
A_MDELAY(2000); /* 2 Second delay to allow dragon to settle down */
_WRITE_WINDOW_ADDR(target, WINDOW_READ_ADDR_REG, RESET_CAUSE_ADDRESS);
window_data = 0;
HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
address = getRegAddr(WINDOW_DATA_REG, ENDPOINT_UNUSED);
status = HIFReadWrite(target->device, address, (A_UCHAR *)&window_data,
4, &request, NULL);
AR_DEBUG_ASSERT(status == A_OK);
HTC_DEBUG_PRINTF(ATH_LOG_INF, "window data: %d\n", window_data);
window_data &= RESET_CAUSE_LAST_MASK;
if (window_data != 2) {
HTC_DEBUG_PRINTF(ATH_LOG_ERR, "Unable to cold reset the target\n");
}
/*
* Ensure that all the pending asynchronous register read/writes have
* been finished.
*/
regList = &target->regList;
for (count = 0; count < HTC_REG_REQUEST_LIST_SIZE; count ++) {
element = ®List->element[count];
AR_DEBUG_ASSERT(IS_ELEMENT_FREE(element));
}
/* Initialize the shadow copy of the target register table */
A_MEMZERO(&target->table, sizeof(HTC_REGISTER_TABLE));
target->ready = FALSE;
HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStop: Exit");
}
void
HTCShutDown(HTC_TARGET *target)
{
HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCShutDown: Enter\n");
if (target != NULL) {
HIFShutDownDevice(target->device);
delTargetInstance(target);
A_MEMZERO(target, sizeof(HTC_TARGET));
A_FREE(target);
} else {
HIFShutDownDevice(NULL);
}
A_DELETE_WAITQUEUE_HEAD(&htcEvent);
HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCShutDown: Exit\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -