📄 hif.c
字号:
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 + -