| Index: chromeos/drivers/ath6kl/htc2/AR6000/ar6k_events.c
|
| diff --git a/chromeos/drivers/ath6kl/htc2/AR6000/ar6k_events.c b/chromeos/drivers/ath6kl/htc2/AR6000/ar6k_events.c
|
| index 90d464758cd4852e6fe75c165f4e8e639dc50494..920123b9ba1adcf556647775f263a3f85b62f6f6 100644
|
| --- a/chromeos/drivers/ath6kl/htc2/AR6000/ar6k_events.c
|
| +++ b/chromeos/drivers/ath6kl/htc2/AR6000/ar6k_events.c
|
| @@ -1,15 +1,19 @@
|
| //------------------------------------------------------------------------------
|
| // <copyright file="ar6k_events.c" company="Atheros">
|
| -// Copyright (c) 2007-2008 Atheros Corporation. All rights reserved.
|
| +// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
|
| //
|
| -// This program is free software; you can redistribute it and/or modify
|
| -// it under the terms of the GNU General Public License version 2 as
|
| -// published by the Free Software Foundation;
|
| //
|
| -// Software distributed under the License is distributed on an "AS
|
| -// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
| -// implied. See the License for the specific language governing
|
| -// rights and limitations under the License.
|
| +// Permission to use, copy, modify, and/or distribute this software for any
|
| +// purpose with or without fee is hereby granted, provided that the above
|
| +// copyright notice and this permission notice appear in all copies.
|
| +//
|
| +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
| +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
| +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
| +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
| +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
| +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
| +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
| //
|
| //
|
| //------------------------------------------------------------------------------
|
| @@ -42,15 +46,15 @@ A_STATUS DevRWCompletionHandler(void *context, A_STATUS status)
|
| HTC_PACKET *pPacket = (HTC_PACKET *)context;
|
|
|
| AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
|
| - ("+DevRWCompletionHandler (Pkt:0x%X) , Status: %d \n",
|
| - (A_UINT32)pPacket,
|
| + ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n",
|
| + (unsigned long)pPacket,
|
| status));
|
| -
|
| +
|
| COMPLETE_HTC_PACKET(pPacket,status);
|
|
|
| AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
|
| ("-DevRWCompletionHandler\n"));
|
| -
|
| +
|
| return A_OK;
|
| }
|
|
|
| @@ -72,6 +76,10 @@ A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
|
|
|
| HIF_PENDING_EVENTS_INFO events;
|
|
|
| +#ifdef THREAD_X
|
| + events.Polling =1;
|
| +#endif
|
| +
|
| /* the HIF layer uses a special mechanism to get events, do this
|
| * synchronously */
|
| status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
|
| @@ -248,7 +256,7 @@ static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev)
|
| if (pDev->TargetFailureCallback != NULL) {
|
| pDev->TargetFailureCallback(pDev->HTCContext);
|
| }
|
| -
|
| +
|
| if (pDev->GMboxEnabled) {
|
| DevNotifyGMboxTargetFailure(pDev);
|
| }
|
| @@ -282,7 +290,7 @@ static A_STATUS DevServiceCounterInterrupt(AR6K_DEVICE *pDev)
|
|
|
| /* Check if the debug interrupt is pending
|
| * NOTE: other modules like GMBOX may use the counter interrupt for
|
| - * credit flow control on other counters, we only need to check for the debug assertion
|
| + * credit flow control on other counters, we only need to check for the debug assertion
|
| * counter interrupt */
|
| if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
|
| return DevServiceDebugInterrupt(pDev);
|
| @@ -298,7 +306,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket)
|
| A_UINT32 lookAhead = 0;
|
| A_BOOL otherInts = FALSE;
|
|
|
| - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%X)\n", (A_UINT32)pDev));
|
| + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
|
|
|
| do {
|
|
|
| @@ -356,18 +364,18 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket)
|
| } else {
|
| int fetched = 0;
|
| A_STATUS status;
|
| -
|
| +
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
|
| (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n",
|
| lookAhead));
|
| /* lookahead is non-zero and there are no other interrupts to service,
|
| * go get the next message */
|
| status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched);
|
| -
|
| +
|
| if (A_SUCCESS(status) && !fetched) {
|
| - /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */
|
| + /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n"));
|
| - DevAsyncIrqProcessComplete(pDev);
|
| + DevAsyncIrqProcessComplete(pDev);
|
| }
|
| }
|
|
|
| @@ -389,7 +397,7 @@ A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
|
| /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can
|
| * cause us to switch contexts */
|
|
|
| - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%X)\n", (A_UINT32)pDev));
|
| + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%lX)\n", (unsigned long)pDev));
|
|
|
| do {
|
|
|
| @@ -399,7 +407,7 @@ A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
|
| * synchronously */
|
| break;
|
| }
|
| -
|
| +
|
| /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
|
| * the target, if upper layers determine that we are in a low-throughput mode, we can
|
| * rely on taking another interrupt rather than re-checking the status registers which can
|
| @@ -408,9 +416,9 @@ A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-acking HIF interrupts\n"));
|
| /* ack interrupt */
|
| HIFAckInterrupt(pDev->HIFDevice);
|
| - break;
|
| + break;
|
| }
|
| -
|
| +
|
| /* first allocate one of our HTC packets we created for async I/O
|
| * we reuse HTC packet definitions so that we can use the completion mechanism
|
| * in DevRWCompletionHandler() */
|
| @@ -453,7 +461,7 @@ A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
|
| }
|
|
|
| void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev)
|
| -{
|
| +{
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n"));
|
| HIFAckInterrupt(pDev->HIFDevice);
|
| }
|
| @@ -465,7 +473,7 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
| A_UINT8 host_int_status = 0;
|
| A_UINT32 lookAhead = 0;
|
|
|
| - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%X)\n", (A_UINT32)pDev));
|
| + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev));
|
|
|
| /*** NOTE: the HIF implementation guarantees that the context of this call allows
|
| * us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that
|
| @@ -474,16 +482,19 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
| * */
|
| do {
|
|
|
| - if (pDev->IrqEnableRegisters.int_status_enable == 0) {
|
| - /* interrupt enables have been cleared, do not try to process any pending interrupts that
|
| - * may result in more bus transactions. The target may be unresponsive at this
|
| - * point. */
|
| - break;
|
| - }
|
| -
|
| - if (pDev->GetPendingEventsFunc != NULL) {
|
| - HIF_PENDING_EVENTS_INFO events;
|
| + if (pDev->IrqEnableRegisters.int_status_enable == 0) {
|
| + /* interrupt enables have been cleared, do not try to process any pending interrupts that
|
| + * may result in more bus transactions. The target may be unresponsive at this
|
| + * point. */
|
| + break;
|
| + }
|
|
|
| + if (pDev->GetPendingEventsFunc != NULL) {
|
| + HIF_PENDING_EVENTS_INFO events;
|
| +
|
| +#ifdef THREAD_X
|
| + events.Polling= 0;
|
| +#endif
|
| /* the HIF layer uses a special mechanism to get events
|
| * get this synchronously */
|
| status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
|
| @@ -543,11 +554,13 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
| break;
|
| }
|
|
|
| +#ifdef ATH_DEBUG_MODULE
|
| if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
|
| DevDumpRegisters(pDev,
|
| &pDev->IrqProcRegisters,
|
| &pDev->IrqEnableRegisters);
|
| }
|
| +#endif
|
|
|
| /* Update only those registers that are enabled */
|
| host_int_status = pDev->IrqProcRegisters.host_int_status &
|
| @@ -575,8 +588,8 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
|
|
| if (pDev->GMboxEnabled) {
|
| /*call GMBOX layer to process any interrupts of interest */
|
| - status = DevCheckGMboxInterrupts(pDev);
|
| - }
|
| + status = DevCheckGMboxInterrupts(pDev);
|
| + }
|
|
|
| } while (FALSE);
|
|
|
| @@ -596,7 +609,7 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
|
|
| if (lookAhead != 0) {
|
| int fetched = 0;
|
| -
|
| +
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead: 0x%X\n",lookAhead));
|
| /* Mailbox Interrupt, the HTC layer may issue async requests to empty the
|
| * mailbox...
|
| @@ -607,12 +620,12 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
| if (A_FAILED(status)) {
|
| break;
|
| }
|
| -
|
| +
|
| if (!fetched) {
|
| /* HTC could not pull any messages out due to lack of resources */
|
| /* force DSR handler to ack the interrupt */
|
| - *pASyncProcessing = FALSE;
|
| - pDev->RecheckIRQStatusCnt = 0;
|
| + *pASyncProcessing = FALSE;
|
| + pDev->RecheckIRQStatusCnt = 0;
|
| }
|
| }
|
|
|
| @@ -651,7 +664,7 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
| * the target, if upper layers determine that we are in a low-throughput mode, we can
|
| * rely on taking another interrupt rather than re-checking the status registers which can
|
| * re-wake the target.
|
| - *
|
| + *
|
| * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot
|
| * be used due to possible side-effects. For example, SPI requires the host to drain all
|
| * messages from the mailbox before exiting the ISR routine. */
|
| @@ -659,7 +672,7 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing done \n"));
|
| *pDone = TRUE;
|
| }
|
| -
|
| +
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n",
|
| *pDone, *pASyncProcessing, status));
|
|
|
| @@ -675,13 +688,13 @@ A_STATUS DevDsrHandler(void *context)
|
| A_BOOL done = FALSE;
|
| A_BOOL asyncProc = FALSE;
|
|
|
| - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%X)\n", (A_UINT32)pDev));
|
| + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
|
|
|
| /* reset the recv counter that tracks when we need to yield from the DSR */
|
| pDev->CurrentDSRRecvCount = 0;
|
| /* reset counter used to flag a re-scan of IRQ status registers on the target */
|
| pDev->RecheckIRQStatusCnt = 0;
|
| -
|
| +
|
| while (!done) {
|
| status = ProcessPendingIRQs(pDev, &done, &asyncProc);
|
| if (A_FAILED(status)) {
|
| @@ -695,11 +708,11 @@ A_STATUS DevDsrHandler(void *context)
|
| * this has a nice side effect of blocking us until all async read requests are completed.
|
| * This behavior is required on some HIF implementations that do not allow ASYNC
|
| * processing in interrupt handlers (like Windows CE) */
|
| -
|
| +
|
| if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) {
|
| /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop
|
| * checking for more messages and return */
|
| - break;
|
| + break;
|
| }
|
| }
|
|
|
| @@ -716,13 +729,13 @@ A_STATUS DevDsrHandler(void *context)
|
| /* Ack the interrupt only if :
|
| * 1. we did not get any errors in processing interrupts
|
| * 2. there are no outstanding async processing requests */
|
| - if (pDev->DSRCanYield) {
|
| + if (pDev->DSRCanYield) {
|
| /* if the DSR can yield do not ACK the interrupt, there could be more pending messages.
|
| - * The HIF layer must ACK the interrupt on behalf of HTC */
|
| + * The HIF layer must ACK the interrupt on behalf of HTC */
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount));
|
| } else {
|
| AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler \n"));
|
| - HIFAckInterrupt(pDev->HIFDevice);
|
| + HIFAckInterrupt(pDev->HIFDevice);
|
| }
|
| }
|
|
|
| @@ -730,6 +743,7 @@ A_STATUS DevDsrHandler(void *context)
|
| return status;
|
| }
|
|
|
| +#ifdef ATH_DEBUG_MODULE
|
| void DumpAR6KDevState(AR6K_DEVICE *pDev)
|
| {
|
| A_STATUS status;
|
| @@ -740,7 +754,7 @@ void DumpAR6KDevState(AR6K_DEVICE *pDev)
|
| /* copy into our temp area */
|
| A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
|
| UNLOCK_AR6K(pDev);
|
| -
|
| +
|
| /* load the register table from the device */
|
| status = HIFReadWrite(pDev->HIFDevice,
|
| HOST_INT_STATUS_ADDRESS,
|
| @@ -754,16 +768,17 @@ void DumpAR6KDevState(AR6K_DEVICE *pDev)
|
| ("DumpAR6KDevState : Failed to read register table (%d) \n",status));
|
| return;
|
| }
|
| -
|
| +
|
| DevDumpRegisters(pDev,&procRegs,®s);
|
| -
|
| +
|
| if (pDev->GMboxInfo.pStateDumpCallback != NULL) {
|
| - pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
|
| + pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
|
| }
|
| -
|
| +
|
| /* dump any bus state at the HIF layer */
|
| HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0);
|
| -
|
| +
|
| }
|
| +#endif
|
|
|
|
|
|
|