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

📄 htc_utils.c

📁 Linux下SDIO设备的驱动程序
💻 C
字号:
/* * Copyright (c) 2004-2006 Atheros Communications Inc. * *  Wireless Network driver for Atheros AR6001 * *  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. * * * This file contains the utility routines used across the entire HTC module. */#include "htc_internal.h"/* ------ Global Variable Declarations ------- */extern HTC_TARGET *AtherosTargetList[HIF_MAX_DEVICES];extern HTC_GLOBAL_EVENT_TABLE AtherosEventTable;extern A_MUTEX_T instanceCS;#ifdef DEBUGextern A_UINT32 debughtc;#endif/* ------ Static Variables ------ *//* ------ Functions ------ */voiddispatchEvent(HTC_TARGET     *target,              HTC_ENDPOINT_ID endPointId,              HTC_EVENT_ID    eventId,              HTC_EVENT_INFO *eventInfo){    EVENT_TABLE_ELEMENT *eventElement;    if (eventId == HTC_TARGET_AVAILABLE) {        eventElement = &AtherosEventTable.element[0];    } else if (eventId == HTC_TARGET_UNAVAILABLE) {        eventElement = &AtherosEventTable.element[1];    } else {        eventElement =            &target->endPoint[endPointId].eventTable.element[eventId];    }    AR_DEBUG_ASSERT(eventElement != NULL);    AR_DEBUG_PRINTF(ATH_DEBUG_INF,                    ("dispatchEvent(endpoint: %d, eventId: 0x%d, handler: 0x%p)\n", endPointId, eventElement->id, eventElement->handler));    if (eventElement->handler) {        eventElement->handler(target, endPointId, eventId, eventInfo,                              eventElement->param);    }}A_STATUSaddToEventTable(HTC_TARGET       *target,                HTC_ENDPOINT_ID   endPointId,                HTC_EVENT_ID      eventId,                HTC_EVENT_HANDLER handler,                void             *param){    EVENT_TABLE_ELEMENT *new;    if (eventId == HTC_TARGET_AVAILABLE) {        new = &AtherosEventTable.element[0];    } else if (eventId == HTC_TARGET_UNAVAILABLE) {        new = &AtherosEventTable.element[1];    } else {        new = &target->endPoint[endPointId].eventTable.element[eventId];    }    /* Store the event id, the corresponding handler and the param passed */    new->id = eventId;    new->handler = handler;    new->param = param;    AR_DEBUG_PRINTF(ATH_DEBUG_INF,                    ("addToEventTable(endpoint: %d, eventId: 0x%d, handler: 0x%p)\n", endPointId, new->id, new->handler));    return A_OK;}A_STATUSremoveFromEventTable(HTC_TARGET *target,                     HTC_ENDPOINT_ID endPointId,                     HTC_EVENT_ID  eventId){    EVENT_TABLE_ELEMENT *remove;    if (eventId == HTC_TARGET_AVAILABLE) {        remove = &AtherosEventTable.element[0];    } else if (eventId == HTC_TARGET_UNAVAILABLE) {        remove = &AtherosEventTable.element[1];    } else {        remove = &target->endPoint[endPointId].eventTable.element[eventId];    }    /* Remove the event handler */    A_MEMZERO(remove, sizeof(EVENT_TABLE_ELEMENT));    return A_OK;}A_STATUSaddToMboxQueue(HTC_DATA_REQUEST_QUEUE *queue,               A_UCHAR        *buffer,               A_UINT32        bufferLength,               A_UINT32        actualLength,               void           *cookie){    A_STATUS status;    HTC_DATA_REQUEST_ELEMENT *element;    AR_DEBUG_ASSERT(queue != NULL);    AR_DEBUG_ASSERT(bufferLength);    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,                    ("Critical Section (queue): LOCK at line %d in file %s\n", __LINE__, __FILE__));    A_MUTEX_LOCK(&instanceCS);    element = GET_QUEUE_TAIL(queue);    if (!(IS_DATA_QUEUE_FULL(queue)) && IS_ELEMENT_FREE(element)) {        element->buffer.free = FALSE;        FILL_MBOX_BUFFER(element, buffer, bufferLength, actualLength, cookie);        queue->size += 1;        AR_DEBUG_PRINTF(ATH_DEBUG_INF,                        ("addToMboxQueue (index: %d, size: %d, bufferElement: 0x%p, bufferElement->buffer: 0x%p, bufferElement->cookie: 0x%p)\n", (queue->head + queue->size - 1) % HTC_DATA_REQUEST_RING_BUFFER_SIZE, queue->size, element, (GET_MBOX_BUFFER(element))->buffer, (GET_MBOX_BUFFER(element))->cookie));        status = A_OK;    } else {        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Queue size: %d\n", queue->size));        status = A_ERROR;    }    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,                    ("Critical Section (queue): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));    A_MUTEX_UNLOCK(&instanceCS);    return status;}HTC_DATA_REQUEST_ELEMENT *removeFromMboxQueue(HTC_DATA_REQUEST_QUEUE *queue) {    HTC_DATA_REQUEST_ELEMENT *element;    AR_DEBUG_ASSERT(queue != NULL);    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,                    ("Critical Section (queue): LOCK at line %d in file %s\n", __LINE__, __FILE__));    A_MUTEX_LOCK(&instanceCS);    if (!(IS_DATA_QUEUE_EMPTY(queue))) {        element = GET_QUEUE_HEAD(queue);        queue->head = (queue->head + 1) % HTC_DATA_REQUEST_RING_BUFFER_SIZE;        queue->size -= 1;        AR_DEBUG_PRINTF(ATH_DEBUG_INF,                        ("removeFromMboxQueue (index: %d, size: %d, bufferElement: 0x%p, bufferElement->buffer: 0x%p, bufferElement->cookie: 0x%p)\n", queue->head, queue->size, element, (GET_MBOX_BUFFER(element))->buffer, (GET_MBOX_BUFFER(element))->cookie));    } else {        element = NULL;    }    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,                    ("Critical Section (queue): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));    A_MUTEX_UNLOCK(&instanceCS);    return element;}voidflushMboxQueue(HTC_ENDPOINT *endPoint,               HTC_DATA_REQUEST_QUEUE *queue,               HTC_EVENT_ID eventId){    HTC_DATA_REQUEST_ELEMENT *curr;    HTC_EVENT_INFO eventInfo;    HTC_ENDPOINT_EVENT_TABLE *eventTable;    HTC_ENDPOINT_ID endPointId;    EVENT_TABLE_ELEMENT *eventElement;    HTC_MBOX_BUFFER *mboxBuffer;    eventTable = &endPoint->eventTable;    endPointId = GET_ENDPOINT_ID(endPoint);    /*     * Release the buffer to WMI using the registered event handler. If WMI     * has not registered any callbacks for a particular endpoint then it     * means that its queues will not have any buffers so we skip that     * endpoint.     */    if ((eventElement = &eventTable->element[eventId]) != NULL) {        while ((curr = removeFromMboxQueue(queue)) != NULL) {            /* Frame the event and dispatch it */            mboxBuffer = GET_MBOX_BUFFER(curr);            FRAME_EVENT(eventInfo, mboxBuffer->buffer,                        mboxBuffer->bufferLength, mboxBuffer->actualLength,                        A_ECANCELED, mboxBuffer->cookie);            if (eventElement->handler) {                eventElement->handler(endPoint->target, endPointId, eventId,                                      &eventInfo, eventElement->param);            }            RECYCLE_DATA_REQUEST_ELEMENT(curr);        }    }    /* Initialize the head and tail pointer */    queue->head = 0;    queue->size = 0;}HTC_REG_REQUEST_ELEMENT *allocateRegRequestElement(HTC_TARGET *target) {    A_UINT32 count;    HTC_REG_REQUEST_ELEMENT *element;    A_MUTEX_LOCK(&instanceCS);    element = NULL;    for (count = 0; count < HTC_REG_REQUEST_LIST_SIZE; count ++) {        element = &target->regList.element[count];        if (IS_ELEMENT_FREE(element)) {            element->buffer.free = FALSE;            break;        }    }    A_MUTEX_UNLOCK(&instanceCS);    return element;}voidfreeRegRequestElement(HTC_REG_REQUEST_ELEMENT *element) {    A_MUTEX_LOCK(&instanceCS);    FILL_REG_BUFFER(element, NULL, 0, 0, 0);    element->buffer.free = TRUE;    A_MUTEX_UNLOCK(&instanceCS);}HTC_TARGET *getTargetInstance(void *device){    return AtherosTargetList[0];}voidaddTargetInstance(HTC_TARGET *target){    AtherosTargetList[0] = target;}voiddelTargetInstance(HTC_TARGET *target){    AtherosTargetList[0] = NULL;}A_UINT32getRegAddr(TARGET_REGISTERS base,           HTC_ENDPOINT_ID endPointId){    A_UINT32 address;    switch(base) {    case TX_CREDIT_COUNTER_RESET_REG:        address = COUNT_DEC_ADDRESS + endPointId * 4;        break;    case TX_CREDIT_COUNTER_DECREMENT_REG:        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + endPointId) * 4;        break;    case TX_CREDIT_COUNTER_REG:        address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + endPointId) * 4;        break;    case INT_STATUS_ENABLE_REG:        address = INT_STATUS_ENABLE_ADDRESS;        break;    case COUNTER_INT_STATUS_ENABLE_REG:    case COUNTER_INT_STATUS_DISABLE_REG:        address = COUNTER_INT_STATUS_ENABLE_ADDRESS;        break;    case INT_STATUS_REG:        address = HOST_INT_STATUS_ADDRESS;        break;    case CPU_INT_STATUS_REG:        address = CPU_INT_STATUS_ADDRESS;        break;    case ERROR_INT_STATUS_REG:        address = ERROR_INT_STATUS_ADDRESS;        break;    case INT_WLAN_REG:        address = INT_WLAN_ADDRESS;        break;    case WINDOW_DATA_REG:        address = WINDOW_DATA_ADDRESS;        break;    case WINDOW_WRITE_ADDR_REG:        address = WINDOW_WRITE_ADDR_ADDRESS;        break;    case WINDOW_READ_ADDR_REG:        address = WINDOW_READ_ADDR_ADDRESS;        break;    default:        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid register: %d\n", base));        AR_DEBUG_ASSERT(0);        address = 0;        break;    }    return address;}voiddumpBytes(A_UCHAR *buffer, A_UINT16 length){    A_CHAR stream[60];    A_UINT32 i;    A_UINT16 offset, count;    AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("Dumping %d Bytes : ------>\n", length));    count = 0;    offset = 0;    for(i = 0; i < length; i++) {        sprintf(stream + offset, "%2x ", buffer[i]);	count ++;	offset += 3;	if(count == 16) {	    count = 0;	    offset = 0;	    AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("[H]: %s\n", stream));	    A_MEMZERO(stream, 60);	}    }    if(offset != 0) {	AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("[H]: %s\n", stream));    }}voiddumpRegisters(HTC_TARGET *target){    HTC_REGISTER_TABLE *reg;    reg = &target->table;    AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("\n<------- Register Table -------->\nInt Status:                0x%x\nCPU Int Status:            0x%x\nError Int Status:          0x%x\nCounter Int Status:        0x%x\nMbox Frame:                0x%x\nRx Lookahead Valid:        0x%x\nRx Lookahead 0:            0x%x\nRx Lookahead 1:            0x%x\nRx Lookahead 2:            0x%x\nRx Lookahead 3:            0x%x\nInt Status Enable:         0x%x\nCounter Int Status Enable: 0x%x\n<------------------------------->\n", reg->host_int_status, reg->cpu_int_status, reg->error_int_status, reg->counter_int_status, reg->mbox_frame, reg->rx_lookahead_valid, reg->rx_lookahead[ENDPOINT1], reg->rx_lookahead[ENDPOINT2], reg->rx_lookahead[ENDPOINT3], reg->rx_lookahead[ENDPOINT4], reg->int_status_enable, reg->counter_int_status_enable));}A_UINT8htcGetBitNumSet(A_UINT32 data){    A_UINT8 count;    count = 0;    while(!(data & 0x1)) {        count += 1;        data >>= 1;    }    return count;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -