⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htc_events.c

📁 Linux下SDIO设备的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (HOST_INT_STATUS_MBOX_DATA_GET(host_int_status)) {        /* Mailbox Interrupt */        htcServiceMailboxInterrupt(target);    }    if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {        /* Counter Interrupt */        htcServiceCounterInterrupt(target);    } else {        /* Ack the interrupt */        HIFAckInterrupt(target->device);        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcDSRHandler - ACK\n"));    }    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcDSRHandler: Exit\n"));    return A_OK;}voidhtcServiceCPUInterrupt(HTC_TARGET *target){    A_STATUS status;    A_UINT32 address;    HIF_REQUEST request;    A_UINT8 cpu_int_status;    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("CPU Interrupt\n"));    cpu_int_status = target->table.cpu_int_status &                     target->table.cpu_int_status_enable;    AR_DEBUG_ASSERT(cpu_int_status);    AR_DEBUG_PRINTF(ATH_DEBUG_INF,                    ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",                    cpu_int_status));    /* Figure out the interrupt number */    AR_DEBUG_PRINTF(ATH_DEBUG_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);}voidhtcServiceErrorInterrupt(HTC_TARGET *target){    A_STATUS status;    A_UINT32 address;    HIF_REQUEST request;    A_UINT8 error_int_status;    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Error Interrupt\n"));    error_int_status = target->table.error_int_status &                       target->table.error_status_enable;    AR_DEBUG_ASSERT(error_int_status);    AR_DEBUG_PRINTF(ATH_DEBUG_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 */        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Wakeup\n"));    }    if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {        /* Rx Underflow */        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Rx Underflow\n"));    }    if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {        /* Tx Overflow */        AR_DEBUG_PRINTF(ATH_DEBUG_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);}voidhtcServiceCounterInterrupt(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;    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Counter Interrupt\n"));    counter_int_status = target->table.counter_int_status &                         target->table.counter_int_status_enable;    AR_DEBUG_ASSERT(counter_int_status);    AR_DEBUG_PRINTF(ATH_DEBUG_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);        AR_DEBUG_PRINTF(ATH_DEBUG_INF,                        ("endPoint(%d): %p\n", endPointId, endPoint));        /* Initialize the number of credits available to zero */        SET_TX_CREDITS_AVAILABLE(endPoint, 0);        /* 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], 1,                        TX_CREDIT_COUNTER_RESET_REG, endPointId);        status = HIFReadWrite(target->device, address,                              &endPoint->txCreditsAvailable[1],                              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);        SET_TX_CREDITS_AVAILABLE(endPoint, 1);#ifdef DEBUG        txcreditsavailable[endPointId] = GET_TX_CREDITS_AVAILABLE(endPoint);        txcreditintrenable[endPointId] -= 1;#endif /* DEBUG */        AR_DEBUG_PRINTF(ATH_DEBUG_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));    }}voidhtcEnableCreditCounterInterrupt(HTC_TARGET *target,                                HTC_ENDPOINT_ID endPointId){    A_STATUS status;    A_UINT32 address;    HIF_REQUEST request;    HTC_ENDPOINT *endPoint;    HTC_REG_REQUEST_ELEMENT *element;    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);    address = getRegAddr(COUNTER_INT_STATUS_ENABLE_REG,                         ENDPOINT_UNUSED);    element = allocateRegRequestElement(target);    AR_DEBUG_ASSERT(element != NULL);    FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_ENABLE_REG,                    (target->endPoint[0].txCreditsIntrEnable << (4)) |                    (target->endPoint[1].txCreditsIntrEnable << (5)) |                    (target->endPoint[2].txCreditsIntrEnable << (6)) |                    (target->endPoint[3].txCreditsIntrEnable << (7)) | 0x0F);    status = HIFReadWrite(target->device, address,                     (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),                     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) {				element->completionCB(element, status);			}#endif    A_MUTEX_UNLOCK(&counterCS);}voidhtcDisableCreditCounterInterrupt(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 counter_int_status;    A_UINT8 update_credit_int_status;    HTC_REG_REQUEST_ELEMENT *element;    A_MUTEX_LOCK(&counterCS);    /* The Tx credit counter update bits are reflected in the upper nibble */    counter_int_status = target->table.counter_int_status &                         target->table.counter_int_status_enable;    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);        AR_DEBUG_PRINTF(ATH_DEBUG_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);    address = getRegAddr(COUNTER_INT_STATUS_DISABLE_REG, ENDPOINT_UNUSED);    element = allocateRegRequestElement(target);    AR_DEBUG_ASSERT(element != NULL);    FILL_REG_BUFFER(element, NULL, 1,                    COUNTER_INT_STATUS_DISABLE_REG,                    (target->endPoint[0].txCreditsIntrEnable << (4)) |                    (target->endPoint[1].txCreditsIntrEnable << (5)) |                    (target->endPoint[2].txCreditsIntrEnable << (6)) |                    (target->endPoint[3].txCreditsIntrEnable << (7)) | 0x0F);    status = HIFReadWrite(target->device, address,                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),                          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 ) {		element->completionCB(element, status);	}#endif    A_MUTEX_UNLOCK(&counterCS);}voidhtcServiceMailboxInterrupt(HTC_TARGET *target){    A_STATUS status;    A_UINT32 address;    HIF_REQUEST request;    HTC_ENDPOINT *endPoint;    HTC_ENDPOINT_ID endPointId;    A_UINT8 mailbox_int_status;    AR_DEBUG_PRINTF(ATH_DEBUG_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;    AR_DEBUG_PRINTF(ATH_DEBUG_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);            AR_DEBUG_PRINTF(ATH_DEBUG_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);        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 + -