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

📄 htc.c

📁 Linux下SDIO设备的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 HTC APIs that are exposed to higher layers. */#include "htc_internal.h"/* ------ Global Variable Declarations ------- */HTC_TARGET *AtherosTargetList[HIF_MAX_DEVICES];HTC_GLOBAL_EVENT_TABLE AtherosEventTable;A_MUTEX_T creditCS, counterCS, instanceCS;A_WAITQUEUE_HEAD htcEvent;#ifdef DEBUGextern A_UINT32 debughtc;extern A_UINT32 txcreditsavailable[HTC_MAILBOX_NUM_MAX];extern A_UINT32 txcreditsconsumed[HTC_MAILBOX_NUM_MAX];extern A_UINT32 txcreditintrenable[HTC_MAILBOX_NUM_MAX];extern A_UINT32 txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX];#endifextern int tx_attempt[HTC_MAILBOX_NUM_MAX];    /* Num of attempts to add */extern int tx_post[HTC_MAILBOX_NUM_MAX];       /* Num of attemps succeded */extern int tx_complete[HTC_MAILBOX_NUM_MAX];   /* Num of tx complete *//* Initializes the HTC module */A_STATUSHTCInit(void){    HTC_CALLBACKS htcCallbacks;    static A_BOOL HTCInitialized = FALSE;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Enter\n"));    if (HTCInitialized) {        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n"));        return A_OK;    }    A_MEMZERO(&AtherosEventTable, sizeof(HTC_GLOBAL_EVENT_TABLE));    A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));    A_INIT_WAITQUEUE_HEAD(&htcEvent);    htcCallbacks.deviceInsertedHandler = htcTargetInsertedHandler;    htcCallbacks.deviceRemovedHandler = htcTargetRemovedHandler;    htcCallbacks.rwCompletionHandler = htcRWCompletionHandler;#ifdef CF        htcCallbacks.deviceInterruptEnabler = htcInterruptEnabler;        htcCallbacks.deviceInterruptDisabler = htcInterruptDisabler;#endif /* CF */    htcCallbacks.dsrHandler = htcDSRHandler;    HIFRegisterCallbacks(&htcCallbacks);    HTCInitialized = TRUE;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n"));    return A_OK;}/* Enables Dragon interrupts */A_STATUSHTCStart(HTC_TARGET *target){    A_STATUS status;    A_UINT32 address;    HIF_REQUEST request;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));    /* Unmask the host controller interrupts */    HIFUnMaskInterrupt(target->device);    /* Enable all the interrupts except for the dragon interrupt */    target->table.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |                                      INT_STATUS_ENABLE_CPU_SET(0x01) |                                      INT_STATUS_ENABLE_COUNTER_SET(0x01) |                                      INT_STATUS_ENABLE_MBOX_DATA_SET(0x0F);    /* Set up the CPU Interrupt Status Register */    target->table.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);    /* Set up the Error Interrupt Status Register */    target->table.error_status_enable =                                  ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |                                  ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);    /* Set up the Counter Interrupt Status Register */    target->table.counter_int_status_enable =        COUNTER_INT_STATUS_ENABLE_BIT_SET(0xFF);    /* Write to the register */    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);    if (status != A_OK) {        /* Can't write it for some reason */        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,                        ("Failed to enable INT_STATUS_ENABLE | CPU_INT_STATUS_ENABLE | ERROR_STATUS_ENABLE | COUNTER_INT_STATUS_ENABLE, err: %d\n", status));        HTCStop(target);        return status;    }#ifdef DEBUG    txcreditintrenable[ENDPOINT1] += 1;    txcreditintrenable[ENDPOINT2] += 1;    txcreditintrenable[ENDPOINT3] += 1;    txcreditintrenable[ENDPOINT4] += 1;    txcreditintrenableaggregate[ENDPOINT1] += 1;    txcreditintrenableaggregate[ENDPOINT2] += 1;    txcreditintrenableaggregate[ENDPOINT3] += 1;    txcreditintrenableaggregate[ENDPOINT4] += 1;#endif /* DEBUG */    /* Wait on a timed semaphore that will get signalled once the block       size negotiation with the target has completed. Furthermore, we have       to do it only once during the lifetime of the target detection */    if (!target->ready) {        AR_DEBUG_PRINTF(ATH_DEBUG_INF,                        ("Waiting for the block size negotiation to finish\n"));        A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(htcEvent, (target->ready == TRUE),                                           HTC_TARGET_RESPONSE_TIMEOUT);        if (target->ready) {            status = A_OK;        } else {            status = A_ERROR;            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,                                ("Failed to negotiate the block sizes\n"));            HTCStop(target);        }    }    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));    return status;}/* * Provides an interface for the higher layer module to register for * different events supported by the HTC module */A_STATUSHTCEventReg(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId,            HTC_EVENT_ID eventId, HTC_EVENT_HANDLER eventHandler,            void *param){    /*     * Add the event handler against the specified event and store it in     * the event table     */    A_STATUS status;    HTC_ENDPOINT *endPoint;    HTC_EVENT_INFO eventInfo;    HTC_DATA_REQUEST_QUEUE *sendQueue, *recvQueue;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,                    ("HTCEventReg: Enter (eventId: 0x%x, endPointId: %d)\n",                    eventId, endPointId));    if (eventHandler) {        if ((status = addToEventTable(target, endPointId, eventId,                                      eventHandler, param)) != A_OK)        {            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,                            ("Could not add the event 0x%x to the event table\n", eventId));            return status;        }    }    switch(eventId) {        case HTC_TARGET_AVAILABLE:            if (eventHandler != NULL) {                /*                 * Dispatch a Target Available event for all the targets                 * present. Iterate through the global list of targets but                 * currently we shall simply look for the first instance                 */                target = AtherosTargetList[0];                if (target != NULL) {                    FRAME_EVENT(eventInfo, (A_UCHAR *)target->device,                                sizeof(HIF_DEVICE *), sizeof(HIF_DEVICE *),                                A_OK, NULL);                    dispatchEvent(target, ENDPOINT_UNUSED, eventId, &eventInfo);                }            } else {                /* Initiate a shut down procedure */            }            break;        case HTC_TARGET_UNAVAILABLE:            break;        case HTC_BUFFER_RECEIVED:            if (eventHandler == NULL) {                /* Flush the queue before unregistering the event handler */                endPoint = &target->endPoint[endPointId];                recvQueue = &endPoint->recvQueue;                flushMboxQueue(endPoint, recvQueue, HTC_BUFFER_RECEIVED);            }            break;        case HTC_SKB_RECEIVED:            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("skb not handled currently\n"));            break;

⌨️ 快捷键说明

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