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

📄 hif.c

📁 linux下的SDIO 驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    A_STATUS status;    void *context;    if (SDIO_SUCCESS(request->Status)) {        status = A_OK;    } else {        status = A_ERROR;    }    context = (void *)request->pCompleteContext;    htcCallbacks.rwCompletionHandler(context, status);    DBG_ASSERT(status == A_OK);    hifFreeDeviceRequest(request);}voidhifIRQHandler(void *context){    A_STATUS status;    HIF_DEVICE *device;    device = (HIF_DEVICE *)context;    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device));    status = htcCallbacks.dsrHandler(device);    DBG_ASSERT(status == A_OK);}BOOLhifDeviceInserted(SDFUNCTION *function, SDDEVICE *handle){    BOOL enabled;    A_UINT8 data;    A_UINT32 count;    HIF_DEVICE *device;    SDIO_STATUS status;    A_UINT16 maxBlocks;    A_UINT16 maxBlockSize;    SDCONFIG_BUS_MODE_DATA busSettings;    SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData;    TARGET_FUNCTION_CONTEXT *functionContext;    SDCONFIG_FUNC_SLOT_CURRENT_DATA slotCurrent;    DBG_ASSERT(function != NULL);    DBG_ASSERT(handle != NULL);    device = addHifDevice(handle);    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device));    functionContext =  (TARGET_FUNCTION_CONTEXT *)function->pContext;    /*     * Issue commands to get the manufacturer ID and stuff and compare it     * against the rev Id derived from the ID registered during the     * initialization process. Report the device only in the case there     * is a match. In the case od SDIO, the bus driver has already queried     * these details so we just need to use their data structures to get the     * relevant values. Infact, the driver has already matched it against     * the Ids that we registered with it so we dont need to the step here.     */    /* Configure the SDIO Bus Width */    if (onebitmode) {        data = SDIO_BUS_WIDTH_1_BIT;        status = SDLIB_IssueCMD52(handle, 0, SDIO_BUS_IF_REG, &data, 1, 1);        if (!SDIO_SUCCESS(status)) {            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,                            ("Unable to set the bus width to 1 bit\n"));            return FALSE;        }    }    /* Get current bus flags */    ZERO_OBJECT(busSettings);    busSettings.BusModeFlags = handle->pHcd->CardProperties.BusMode;    if (onebitmode) {        SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags,                               SDCONFIG_BUS_WIDTH_1_BIT);    }    busSettings.ClockRate = (busspeedlow ? SDIO_CLOCK_FREQUENCY_REDUCED :                                           SDIO_CLOCK_FREQUENCY_DEFAULT);    /* Issue config request to override clock rate */    status = SDLIB_IssueConfig(handle, SDCONFIG_BUS_MODE_CTRL, &busSettings,                               sizeof(SDCONFIG_BUS_MODE_DATA));    if (!SDIO_SUCCESS(status)) {        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,                        ("Unable to configure the host clock\n"));        return FALSE;    } else {        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,                        ("Configured clock: %d, Maximum clock: %d\n",                        busSettings.ActualClockRate,                        SDDEVICE_GET_MAX_CLOCK(handle)));    }    /*     * Check if the target supports block mode. This result of this check     * can be used to implement the HIFReadWrite API.     */    if (SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle)) {        /* Limit block size to operational block limit or card function           capability */        maxBlockSize = min(SDDEVICE_GET_OPER_BLOCK_LEN(handle),                           SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle));        /* check if the card support multi-block transfers */        if (!(SDDEVICE_GET_SDIOCARD_CAPS(handle) & SDIO_CAPS_MULTI_BLOCK)) {            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Byte basis only\n"));            /* Limit block size to max byte basis */            maxBlockSize =  min(maxBlockSize,                                (A_UINT16)SDIO_MAX_LENGTH_BYTE_BASIS);            maxBlocks = 1;        } else {            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Multi-block capable\n"));            maxBlocks = SDDEVICE_GET_OPER_BLOCKS(handle);            status = SDLIB_SetFunctionBlockSize(handle, HIF_MBOX_BLOCK_SIZE);            if (!SDIO_SUCCESS(status)) {                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,                                ("Failed to set block size. Err:%d\n", status));                return FALSE;            }        }        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,                        ("Bytes Per Block: %d bytes, Block Count:%d \n",                        maxBlockSize, maxBlocks));    } else {        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,                        ("Function does not support Block Mode!\n"));        return FALSE;    }    /* Allocate the slot current */    status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent);    if (SDIO_SUCCESS(status)) {        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n",                                slotCurrent.SlotCurrent));        status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT,                                   &slotCurrent, sizeof(slotCurrent));        if (!SDIO_SUCCESS(status)) {            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,                            ("Failed to allocate slot current %d\n", status));            return FALSE;        }    }    /* Enable the dragon function */    count = 0;    enabled = FALSE;    fData.TimeOut = 1;    fData.EnableFlags = SDCONFIG_ENABLE_FUNC;    while ((count++ < SDWLAN_ENABLE_DISABLE_TIMEOUT) && !enabled)    {        /* Enable dragon */        status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ENABLE_DISABLE,                                   &fData, sizeof(fData));        if (!SDIO_SUCCESS(status)) {            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,                            ("Attempting to enable the card again\n"));            continue;        }        /* Mark the status as enabled */        enabled = TRUE;    }    /* Check if we were succesful in enabling the target */    if (!enabled) {        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,                        ("Failed to communicate with the target\n"));        return FALSE;    }    /* Allocate the bus requests to be used later */    for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {        if ((busRequest[count].request = SDDeviceAllocRequest(handle)) == NULL){            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate memory\n"));            /* TODO: Free the memory that has already been allocated */            return FALSE;        }        busRequest[count].free = TRUE;        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,                        ("busRequest[%d].request = 0x%p, busRequest[%d].free = %d\n", count, busRequest[count].request, count, busRequest[count].free));    }    /*     * Adding a wait of around a second before we issue the very first     * command to dragon. During the process of loading/unloading the     * driver repeatedly it was observed that we get a data timeout     * while accessing function 1 registers in the chip. The theory at     * this point is that some initialization delay in dragon is     * causing the SDIO state in dragon core to be not ready even after     * the ready bit indicates that function 1 is ready. Accomodating     * for this behavior by adding some delay in the driver before it     * issues the first command after switching on dragon. Need to     * investigate this a bit more - TODO     */    A_MDELAY(1000);    /* Inform HTC */    if ((htcCallbacks.deviceInsertedHandler(device)) != A_OK) {        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device rejected\n"));        return FALSE;    }    return TRUE;}voidHIFAckInterrupt(HIF_DEVICE *device){    SDIO_STATUS status;    DBG_ASSERT(device != NULL);    DBG_ASSERT(device->handle != NULL);    /* Acknowledge our function IRQ */    status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_ACK_IRQ,                               NULL, 0);    DBG_ASSERT(SDIO_SUCCESS(status));}voidHIFUnMaskInterrupt(HIF_DEVICE *device){    SDIO_STATUS status;    DBG_ASSERT(device != NULL);    DBG_ASSERT(device->handle != NULL);    /* Register the IRQ Handler */    SDDEVICE_SET_IRQ_HANDLER(device->handle, hifIRQHandler, device);    /* Unmask our function IRQ */    status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_UNMASK_IRQ,                               NULL, 0);    DBG_ASSERT(SDIO_SUCCESS(status));}void HIFMaskInterrupt(HIF_DEVICE *device){    SDIO_STATUS status;    DBG_ASSERT(device != NULL);    DBG_ASSERT(device->handle != NULL);    /* Mask our function IRQ */    status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_MASK_IRQ,                               NULL, 0);    DBG_ASSERT(SDIO_SUCCESS(status));    /* Unregister the IRQ Handler */    SDDEVICE_SET_IRQ_HANDLER(device->handle, NULL, NULL);}SDREQUEST *hifAllocateDeviceRequest(SDDEVICE *device){    SDREQUEST *request;    A_UINT32 count;    DBG_ASSERT(device != NULL);    /* Acquire lock */    CriticalSectionAcquire(&lock);    request = NULL;    for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) {        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,                        ("busRequest[%d].request = 0x%p, busRequest[%d].free = %d\n", count, busRequest[count].request, count, busRequest[count].free));        if (busRequest[count].free) {            request = busRequest[count].request;            busRequest[count].free = FALSE;            break;        }    }    /* Release lock */    CriticalSectionRelease(&lock);    return request;}voidhifFreeDeviceRequest(SDREQUEST *request){    A_UINT32 count;    DBG_ASSERT(request != NULL);    /* Acquire lock */    CriticalSectionAcquire(&lock);    for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {        if (busRequest[count].request == request) {            busRequest[count].free = TRUE;            break;        }    }    /* Release lock */    CriticalSectionRelease(&lock);}voidhifDeviceRemoved(SDFUNCTION *function, SDDEVICE *handle){    A_STATUS status;    HIF_DEVICE *device;    DBG_ASSERT(function != NULL);    DBG_ASSERT(handle != NULL);    device = getHifDevice(handle);    status = htcCallbacks.deviceRemovedHandler(device);    delHifDevice(handle);    DBG_ASSERT(status == A_OK);}HIF_DEVICE *addHifDevice(SDDEVICE *handle){    DBG_ASSERT(handle != NULL);    hifDevice[0].handle = handle;    return &hifDevice[0];}HIF_DEVICE *getHifDevice(SDDEVICE *handle){    DBG_ASSERT(handle != NULL);    return &hifDevice[0];}voiddelHifDevice(SDDEVICE *handle){    DBG_ASSERT(handle != NULL);    hifDevice[0].handle = NULL;}

⌨️ 快捷键说明

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