Beispiel #1
0
/* called by the HTC layer when it wants us to check if the device has any more pending
 * recv messages, this starts off a series of async requests to read interrupt registers  */
A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
{
    AR6K_DEVICE  *pDev = (AR6K_DEVICE *)context;
    A_STATUS      status = A_OK;
    HTC_PACKET   *pIOPacket;

    /* 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));

   do {

        if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
                /* break the async processing chain right here, no need to continue.
                 * The DevDsrHandler() will handle things in a loop when things are driven
                 * synchronously  */
            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() */
        pIOPacket = AR6KAllocIOPacket(pDev);

        if (NULL == pIOPacket) {
                /* there should be only 1 asynchronous request out at a time to read these registers
                 * so this should actually never happen */
            status = A_NO_MEMORY;
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

            /* stick in our completion routine when the I/O operation completes */
        pIOPacket->Completion = DevGetEventAsyncHandler;
        pIOPacket->pContext = pDev;

        if (pDev->GetPendingEventsFunc) {
                /* HIF layer has it's own mechanism, pass the IO to it.. */
            status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
                                                (HIF_PENDING_EVENTS_INFO *)pIOPacket->pBuffer,
                                                pIOPacket);

        } else {
                /* standard way, read the interrupt register table asynchronously again */
            status = HIFReadWrite(pDev->HIFDevice,
                                  HOST_INT_STATUS_ADDRESS,
                                  pIOPacket->pBuffer,
                                  AR6K_IRQ_PROC_REGS_SIZE,
                                  HIF_RD_ASYNC_BYTE_INC,
                                  pIOPacket);
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n"));
   } while (FALSE);

   AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n"));

   return status;
}
Beispiel #2
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "override" method when the HIF reports another methods to
 * disable recv events */
static A_STATUS DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode)
{
    A_STATUS                  status = A_OK;
    HTC_PACKET                *pIOPacket = NULL;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
            EnableRecv,AsyncMode));

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(FALSE);
                break;
            }

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* call the HIF layer override and do this asynchronously */
            status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                                 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                                 pIOPacket);
            break;
        }

            /* if we get here we are doing it synchronously */
        status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                             EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                             NULL);

    } while (FALSE);

    if (A_FAILED(status) && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Beispiel #3
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "override" method when the HIF reports another methods to
 * disable recv events */
static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
{
    int                  status = 0;
    struct htc_packet                *pIOPacket = NULL;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
            EnableRecv,AsyncMode));

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* call the HIF layer override and do this asynchronously */
            status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                                 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                                 pIOPacket);
            break;
        }

            /* if we get here we are doing it synchronously */
        status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                             EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                             NULL);

    } while (false);

    if (status && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Beispiel #4
0
static A_STATUS DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq)
{
    AR6K_DEVICE     *pDev = (AR6K_DEVICE *)Context;
    A_STATUS        status = A_OK;
    HTC_PACKET      *pIOPacket = NULL;
    A_UINT32        request = pReq->Request;

    do {

        if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                            ("Invalid length: %d \n", pReq->TotalLength));
            break;
        }

        if (pReq->TotalLength == 0) {
            A_ASSERT(FALSE);
            break;
        }

        if (request & HIF_ASYNCHRONOUS) {
                /* use an I/O packet to carry this request */
            pIOPacket = AR6KAllocIOPacket(pDev);
            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                break;
            }

                /* save the request */
            pIOPacket->pPktContext = pReq;
                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevReadWriteScatterAsyncHandler;
            pIOPacket->pContext = pDev;
        }

        if (request & HIF_WRITE) {
            /* in virtual DMA, we are issuing the requests through the legacy HIFReadWrite API
             * this API will adjust the address automatically for the last byte to fall on the mailbox
             * EOM. */

            /* if the address is an extended address, we can adjust the address here since the extended
             * address will bypass the normal checks in legacy HIF layers */
            if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress) {
                pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize - pReq->TotalLength;
            }
        }

            /* use legacy readwrite */
        status = HIFReadWrite(pDev->HIFDevice,
                              pReq->Address,
                              DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer,
                              pReq->TotalLength,
                              request,
                              (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL);

    } while (FALSE);

    if ((status != A_PENDING) && A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
        if (pIOPacket != NULL) {
            AR6KFreeIOPacket(pDev,pIOPacket);
        }
        pReq->CompletionStatus = status;
        pReq->CompletionRoutine(pReq);
        status = A_OK;
    }

    return status;
}
Beispiel #5
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "normal" method using the interrupt enable registers through
 * the host I/F */
static A_STATUS DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode)
{
    A_STATUS                  status = A_OK;
    HTC_PACKET                *pIOPacket = NULL;
    AR6K_IRQ_ENABLE_REGISTERS regs;

        /* take the lock to protect interrupt enable shadows */
    LOCK_AR6K(pDev);

    if (EnableRecv) {
        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    } else {
        pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    }

        /* copy into our temp area */
    A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(FALSE);
                break;
            }

                /* copy values to write to our async I/O buffer */
            A_MEMCPY(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         INT_STATUS_ENABLE_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_IRQ_ENABLE_REGS_SIZE,
                         HIF_WR_ASYNC_BYTE_INC,
                         pIOPacket);
            break;
        }

        /* if we get here we are doing it synchronously */

        status = HIFReadWrite(pDev->HIFDevice,
                              INT_STATUS_ENABLE_ADDRESS,
                              &regs.int_status_enable,
                              AR6K_IRQ_ENABLE_REGS_SIZE,
                              HIF_WR_SYNC_BYTE_INC,
                              NULL);

    } while (FALSE);

    if (A_FAILED(status) && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Beispiel #6
0
static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
{
    int                  status = 0;
    struct ar6k_irq_enable_registers regs;
    struct htc_packet                *pIOPacket = NULL;  
    
    LOCK_AR6K(pDev);
    
    if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
        pDev->GMboxInfo.CreditCountIRQEnabled = true;
        pDev->IrqEnableRegisters.counter_int_status_enable |=
            COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER);
        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01);
    } else {
        pDev->GMboxInfo.CreditCountIRQEnabled = false;
        pDev->IrqEnableRegisters.counter_int_status_enable &=
            ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER));    
    }
        /* copy into our temp area */
    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);

    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* copy values to write to our async I/O buffer */
            memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
            pIOPacket->pContext = pDev;
            pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         INT_STATUS_ENABLE_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_IRQ_ENABLE_REGS_SIZE,
                         HIF_WR_ASYNC_BYTE_INC,
                         pIOPacket);
                         
            pIOPacket = NULL; 
            break;
        } 

            /* if we get here we are doing it synchronously */
        status = HIFReadWrite(pDev->HIFDevice,
                              INT_STATUS_ENABLE_ADDRESS,
                              &regs.int_status_enable,
                              AR6K_IRQ_ENABLE_REGS_SIZE,
                              HIF_WR_SYNC_BYTE_INC,
                              NULL);    
    } while (false);
    
    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));    
    } else {
        if (!AsyncMode) {
            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                    (" IRQAction Operation (%d) success \n", IrqAction)); 
        }       
    }
    
    if (pIOPacket != NULL) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }
        
    return status;
}
Beispiel #7
0
int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits)
{
    int    status = 0;
    struct htc_packet  *pIOPacket = NULL;  
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC"));
                                            
    do {
        
        pIOPacket = AR6KAllocIOPacket(pDev);

        if (NULL == pIOPacket) {
            status = A_NO_MEMORY;
            A_ASSERT(false);
            break;
        }
        
        A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
      
        if (AsyncMode) {   
                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
            pIOPacket->pContext = pDev;
                /* read registers asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         AR6K_GMBOX_CREDIT_DEC_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_REG_IO_BUFFER_SIZE,  /* hit the register multiple times */
                         HIF_RD_ASYNC_BYTE_FIX,
                         pIOPacket);
            pIOPacket = NULL;
            break;
        } 

        pIOPacket->Completion = NULL;
            /* if we get here we are doing it synchronously */
        status = HIFReadWrite(pDev->HIFDevice,
                              AR6K_GMBOX_CREDIT_DEC_ADDRESS,
                              pIOPacket->pBuffer,
                              AR6K_REG_IO_BUFFER_SIZE,
                              HIF_RD_SYNC_BYTE_FIX,
                              NULL);    
    } while (false);
    
    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" DevGMboxReadCreditCounter failed! status:%d \n", status));          
    }
    
    if (pIOPacket != NULL) {
        if (!status) {
                /* sync mode processing */
            *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);     
        }
        AR6KFreeIOPacket(pDev,pIOPacket);
    }
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n", 
            AsyncMode ? "ASYNC" : "SYNC", status));
    
    return status;
}
Beispiel #8
0
int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
{
    int      status = 0;
    struct htc_packet    *pIOPacket = NULL;   
    u8 GMboxIntControl[4];

    if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
        return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode);
    } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) {
        return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
    }
    
    if (GMBOX_DISABLE_ALL == IrqAction) {
            /* disable credit IRQ, those are on a different set of registers */
        DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);    
    }
            
        /* take the lock to protect interrupt enable shadows */
    LOCK_AR6K(pDev);

    switch (IrqAction) {
        
        case GMBOX_DISABLE_ALL:
            pDev->GMboxControlRegisters.int_status_enable = 0;
            break;
        case GMBOX_ERRORS_IRQ_ENABLE:
            pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW |
                                                             GMBOX_INT_STATUS_RX_OVERFLOW;
            break;
        case GMBOX_RECV_IRQ_ENABLE:
            pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA;
            break;
        case GMBOX_RECV_IRQ_DISABLE:
            pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA;
            break;
        case GMBOX_ACTION_NONE:
        default:
            A_ASSERT(false);
            break;
    }
    
    GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable;
    GMboxIntControl[1] = GMboxIntControl[0];
    GMboxIntControl[2] = GMboxIntControl[0];
    GMboxIntControl[3] = GMboxIntControl[0];
    
    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* copy values to write to our async I/O buffer */
            memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl));

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
            pIOPacket->pContext = pDev;
            pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         GMBOX_INT_STATUS_ENABLE_REG,
                         pIOPacket->pBuffer,
                         sizeof(GMboxIntControl),
                         HIF_WR_ASYNC_BYTE_FIX,
                         pIOPacket);
            pIOPacket = NULL;
            break;
        }

        /* if we get here we are doing it synchronously */

        status = HIFReadWrite(pDev->HIFDevice,
                              GMBOX_INT_STATUS_ENABLE_REG,
                              GMboxIntControl,
                              sizeof(GMboxIntControl),
                              HIF_WR_SYNC_BYTE_FIX,
                              NULL);

    } while (false);

    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));    
    } else {
        if (!AsyncMode) {
            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                    (" IRQAction Operation (%d) success \n", IrqAction)); 
        }      
    }
    
    if (pIOPacket != NULL) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Beispiel #9
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "normal" method using the interrupt enable registers through
 * the host I/F */
static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
{
    int                  status = 0;
    struct htc_packet                *pIOPacket = NULL;
    struct ar6k_irq_enable_registers regs;

        /* take the lock to protect interrupt enable shadows */
    LOCK_AR6K(pDev);

    if (EnableRecv) {
        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    } else {
        pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    }

        /* copy into our temp area */
    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* copy values to write to our async I/O buffer */
            memcpy(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         INT_STATUS_ENABLE_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_IRQ_ENABLE_REGS_SIZE,
                         HIF_WR_ASYNC_BYTE_INC,
                         pIOPacket);
            break;
        }

        /* if we get here we are doing it synchronously */

        status = HIFReadWrite(pDev->HIFDevice,
                              INT_STATUS_ENABLE_ADDRESS,
                              &regs.int_status_enable,
                              AR6K_IRQ_ENABLE_REGS_SIZE,
                              HIF_WR_SYNC_BYTE_INC,
                              NULL);

    } while (false);

    if (status && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Beispiel #10
0
/* called by the HTC layer when it wants us to check if the device has any more pending
 * recv messages, this starts off a series of async requests to read interrupt registers  */
int DevCheckPendingRecvMsgsAsync(void *context)
{
    struct ar6k_device  *pDev = (struct ar6k_device *)context;
    int      status = 0;
    struct htc_packet   *pIOPacket;

    /* 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%lX)\n", (unsigned long)pDev));

   do {

        if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
                /* break the async processing chain right here, no need to continue.
                 * The DevDsrHandler() will handle things in a loop when things are driven
                 * 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
             * re-wake the target */
        if (pDev->RecheckIRQStatusCnt == 0) {
            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-acking HIF interrupts\n"));
                /* ack interrupt */
            HIFAckInterrupt(pDev->HIFDevice);
            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() */
        pIOPacket = AR6KAllocIOPacket(pDev);

        if (NULL == pIOPacket) {
                /* there should be only 1 asynchronous request out at a time to read these registers
                 * so this should actually never happen */
            status = A_NO_MEMORY;
            A_ASSERT(false);
            break;
        }

            /* stick in our completion routine when the I/O operation completes */
        pIOPacket->Completion = DevGetEventAsyncHandler;
        pIOPacket->pContext = pDev;

        if (pDev->GetPendingEventsFunc) {
                /* HIF layer has it's own mechanism, pass the IO to it.. */
            status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
                                                (struct hif_pending_events_info *)pIOPacket->pBuffer,
                                                pIOPacket);

        } else {
                /* standard way, read the interrupt register table asynchronously again */
            status = HIFReadWrite(pDev->HIFDevice,
                                  HOST_INT_STATUS_ADDRESS,
                                  pIOPacket->pBuffer,
                                  AR6K_IRQ_PROC_REGS_SIZE,
                                  HIF_RD_ASYNC_BYTE_INC,
                                  pIOPacket);
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n"));
   } while (false);

   AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n"));

   return status;
}