static void hifDeviceRemoved(struct sdio_func *func) { A_STATUS status = A_OK; HIF_DEVICE *device; int ret; AR_DEBUG_ASSERT(func != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); device = getHifDevice(func); if (device->claimedContext != NULL) { status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device); } do { if (device->is_suspend) { device->is_suspend = FALSE; break; } if (!IS_ERR(device->async_task)) { init_completion(&device->async_completion); device->async_shutdown = 1; up(&device->sem_async); wait_for_completion(&device->async_completion); device->async_task = NULL; } /* Disable the card */ sdio_claim_host(device->func); ret = sdio_disable_func(device->func); sdio_release_host(device->func); } while (0); delHifDevice(device); AR_DEBUG_ASSERT(status == A_OK); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); }
static void hifDeviceRemoved(struct sdio_func *func) { A_STATUS status = A_OK; HIF_DEVICE *device; AR_DEBUG_ASSERT(func != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); device = getHifDevice(func); if (device->claimedContext != NULL) { status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device); } if (device->is_suspend) { device->is_suspend = FALSE; } else { if (hifDisableFunc(device, func)!=0) { status = A_ERROR; } } CleanupHIFScatterResources(device); delHifDevice(device); AR_DEBUG_ASSERT(status == A_OK); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); }
SD_API_STATUS hifIRQHandler(SD_DEVICE_HANDLE hDevice, PVOID notUsed) { #ifndef CEPC A_STATUS status; HIF_DEVICE *device; A_BOOL callDSR; #endif HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIRQHandler : Enter\n"); #ifndef CEPC /* Disable device interrupts */ device = getHifDevice(hDevice); status = htcCallbacks.deviceInterruptDisabler(device, &callDSR); AR_DEBUG_ASSERT(status == A_OK); /* Call the DSR Handler if it is not a Spurious Interrupt */ if (callDSR) { status = htcCallbacks.dsrHandler(device); AR_DEBUG_ASSERT(status == A_OK); } #else NdisSetEvent(&hifIRQEvent); #endif HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIRQHandler : Exit\n"); return SD_API_STATUS_SUCCESS; }
static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) { int ret = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); device = getHifDevice(func); if (!IS_ERR(device->async_task)) { init_completion(&device->async_completion); device->async_shutdown = 1; up(&device->sem_async); wait_for_completion(&device->async_completion); device->async_task = NULL; } /* Disable the card */ sdio_claim_host(device->func); ret = sdio_disable_func(device->func); if (reset_sdio_on_unload) { /* reset the SDIO interface. This is useful in automated testing where the card * does not need to be removed at the end of the test. It is expected that the user will * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n")); /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access * to undefined registers in the range of: 0xF0-0xFF */ ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3)); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret)); } } sdio_release_host(device->func); return ret; }
static int hifDeviceResume(struct device *dev) { HIF_DEVICE *device; A_STATUS status = A_OK; struct sdio_func *func = dev_to_sdio_func(dev); device = getHifDevice(func); status = HIFDoDeviceResume(device); return A_SUCCESS(status) ? 0 : status; }
void hifDeviceRemoved(SD_DEVICE_HANDLE *handle) { A_STATUS status; HIF_DEVICE *device; device = getHifDevice(handle); status = htcCallbacks.deviceRemovedHandler(device); delHifDevice(handle); AR_DEBUG_ASSERT(status == A_OK); return; }
static void hifIRQHandler(struct sdio_func *func) { A_STATUS status; HIF_DEVICE *device; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n")); device = getHifDevice(func); /* release the host during ints so we can pick it back up when we process cmds */ sdio_release_host(device->func); status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context); sdio_claim_host(device->func); AR_DEBUG_ASSERT(status == A_OK || status == A_ECANCELED); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n")); }
static void hifISRHandler(CF_DEVICE_HANDLE cfHandle,A_BOOL *callDsr) { A_STATUS status; HIF_DEVICE *device; device = getHifDevice(cfHandle); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIsrHandler: Enter\n"); status = htcCallbacks.deviceInterruptDisabler(device, callDsr); AR_DEBUG_ASSERT(status == A_OK); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIsrHandler: Exit\n"); return; }
static int hifDeviceSuspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); A_STATUS status = A_OK; HIF_DEVICE *device; device = getHifDevice(func); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); } if (status == A_OK) { int oldresetvalue = reset_sdio_on_unload; reset_sdio_on_unload = 1; hifDisableFunc(device, func); reset_sdio_on_unload = oldresetvalue; device->is_suspend = TRUE; } else if (status == A_EBUSY) { A_INT32 cnt = 10; A_UINT8 host_int_status; do { while (atomic_read(&device->irqHandling)) { /* wait until irq handler finished all the jobs */ schedule_timeout(HZ/10); } /* check if there is any pending irq due to force done */ host_int_status = 0; status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, (A_UINT8 *)&host_int_status, sizeof(host_int_status), HIF_RD_SYNC_BYTE_INC, NULL); host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) : 0; if (host_int_status) { schedule(); /* schedule for next dsrHandler */ } } while (host_int_status && --cnt > 0); if (host_int_status && cnt == 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__)); } #if 1 status = A_OK; /* assume that sdio host controller will take care the power of wifi chip */ #else return -EBUSY; /* Return -EBUSY if customer use all android patch of mmc stack provided by us */ #endif } return A_SUCCESS(status) ? 0 : status; }
static int hifDeviceSuspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); A_STATUS status = A_OK; HIF_DEVICE *device; device = getHifDevice(func); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); } if (status == A_OK) { hifDisableFunc(device, func); device->is_suspend = TRUE; } else if (status == A_EBUSY) { status = A_OK; /* assume that sdio host controller will take care the power of wifi chip */ } return A_SUCCESS(status) ? 0 : status; }
static void hifDSRHandler(CF_DEVICE_HANDLE cfHandle) { A_STATUS status; HIF_DEVICE *device; device = getHifDevice(cfHandle); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDsrHandler: Enter\n"); status = htcCallbacks.dsrHandler(device); AR_DEBUG_ASSERT(status == A_OK); htcCallbacks.deviceInterruptEnabler(device); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDsrHandler: Exit\n"); }
void hifDeviceRemoved(SD_DEVICE_HANDLE *handle) { A_STATUS status; HIF_DEVICE *device; NDIS_DEBUG_PRINTF(1, "%s() : + Enter \r\n", __FUNCTION__); device = getHifDevice(handle); if (device->claimedContext != NULL) { status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device); } delHifDevice(handle); AR_DEBUG_ASSERT(status == A_OK); return; }
DWORD hifIRQThread(LPVOID Context) { SD_DEVICE_HANDLE hDevice = Context; A_STATUS status; HIF_DEVICE *device; if (hDevice == NULL) { return SD_API_STATUS_UNSUCCESSFUL; } while (1) { NdisWaitEvent(&hifIRQEvent, 0); NdisResetEvent(&hifIRQEvent); device = getHifDevice(hDevice); status = htcCallbacks.dsrHandler(device); AR_DEBUG_ASSERT(status == A_OK); } // while return SD_API_STATUS_SUCCESS; }
static void hifDeviceRemoved(CF_DEVICE_HANDLE cfHandle) { A_STATUS status; HIF_DEVICE *device; device = getHifDevice(cfHandle); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceRemoved: Enter\n"); HIF_DEBUG_PRINTF(ATH_LOG_INF, "hifDeviceRemoved: Device = %p\n",device); /* Inform HTC */ status = htcCallbacks.deviceRemovedHandler(device); delHifDevice(cfHandle); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceRemoved: Exit\n"); AR_DEBUG_ASSERT(status == A_OK); }
SD_API_STATUS hifIRQHandler(SD_DEVICE_HANDLE hDevice, PVOID notUsed) { #ifndef CEPC A_STATUS status = A_OK; HIF_DEVICE *device = NULL; // A_BOOL callDSR; #endif NDIS_DEBUG_PRINTF(DBG_TRACE, "hifIRQHandler : Enter\r\n"); device = getHifDevice(hDevice); #if USE_IRQ_THREAD SDIODisconnectInterrupt(device->handle); NdisSetEvent(&hifIRQEvent); #else /* Disable device interrupts */ SDIODisconnectInterrupt(device->handle); #if 0 /* Call the DSR Handler if it is not a Spurious Interrupt */ if (callDSR) #endif { status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context); AR_DEBUG_ASSERT(status == A_OK); } SDIOConnectInterrupt(device->handle,hifIRQHandler); #endif NDIS_DEBUG_PRINTF(0, "hifIRQHandler : Exit\r\n"); return SD_API_STATUS_SUCCESS; }
static int hifDeviceResume(struct device *dev) { struct task_struct* pTask; const char *taskName; int (*taskFunc)(void *); struct sdio_func *func = dev_to_sdio_func(dev); A_STATUS ret = A_OK; HIF_DEVICE *device; device = getHifDevice(func); if (device->is_suspend) { /* enable the SDIO function */ sdio_claim_host(func); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) /* give us some time to enable, in ms */ func->enable_timeout = 100; #endif ret = sdio_enable_func(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", __FUNCTION__, ret)); sdio_release_host(func); return ret; } ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); sdio_release_host(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); return ret; } device->is_suspend = FALSE; /* create async I/O thread */ if (!device->async_task) { device->async_shutdown = 0; device->async_task = kthread_create(async_task, (void *)device, "AR6K Async"); if (IS_ERR(device->async_task)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); wake_up_process(device->async_task ); } } if (!device->claimedContext) { printk("WARNING!!! No claimedContext during resume wlan\n"); taskFunc = startup_task; taskName = "AR6K startup"; } else { taskFunc = resume_task; taskName = "AR6K resume"; } /* create resume thread */ pTask = kthread_create(taskFunc, (void *)device, taskName); if (IS_ERR(pTask)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create resume task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start resume task\n")); wake_up_process(pTask); return A_SUCCESS(ret) ? 0 : ret; }
static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id) { int ret; HIF_DEVICE * device; int count; struct task_struct* startup_task_struct; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n", func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize)); addHifDevice(func); device = getHifDevice(func); spin_lock_init(&device->lock); spin_lock_init(&device->asynclock); /* enable the SDIO function */ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: claim\n")); sdio_claim_host(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: enable\n")); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) /* give us some time to enable, in ms */ func->enable_timeout = 100; #endif ret = sdio_enable_func(func); if (ret) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X, timeout: %d\n", __FUNCTION__, ret, func->enable_timeout)); #else AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", __FUNCTION__, ret)); #endif sdio_release_host(func); return ret; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: set block size 0x%X\n", HIF_MBOX_BLOCK_SIZE)); ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); sdio_release_host(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); return ret; } /* Initialize the bus requests to be used later */ A_MEMZERO(device->busRequest, sizeof(device->busRequest)); for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { sema_init(&device->busRequest[count].sem_req, 0); hifFreeBusRequest(device, &device->busRequest[count]); } /* create async I/O thread */ device->async_shutdown = 0; device->async_task = kthread_create(async_task, (void *)device, "AR6K Async"); if (IS_ERR(device->async_task)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); sema_init(&device->sem_async, 0); wake_up_process(device->async_task ); /* create startup thread */ startup_task_struct = kthread_create(startup_task, (void *)device, "AR6K startup"); if (IS_ERR(startup_task_struct)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create startup task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start startup task\n")); wake_up_process(startup_task_struct); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: return %d\n", ret)); return ret; }
static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id) { int ret; HIF_DEVICE * device; int count; struct task_struct* startup_task_struct; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n", func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize)); addHifDevice(func); device = getHifDevice(func); spin_lock_init(&device->lock); spin_lock_init(&device->asynclock); DL_LIST_INIT(&device->ScatterReqHead); if (!nohifscattersupport) { /* try to allow scatter operation on all instances, * unless globally overridden */ device->scatter_enabled = TRUE; } /* enable the SDIO function */ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: claim\n")); sdio_claim_host(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: enable\n")); if ((id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) { /* enable 4-bit ASYNC interrupt on AR6003 or later devices */ ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret)); sdio_release_host(func); return ret; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n")); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) /* give us some time to enable, in ms */ func->enable_timeout = 100; #endif ret = sdio_enable_func(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", __FUNCTION__, ret)); sdio_release_host(func); return ret; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: set block size 0x%X\n", HIF_MBOX_BLOCK_SIZE)); ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); sdio_release_host(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); return ret; } /* Initialize the bus requests to be used later */ A_MEMZERO(device->busRequest, sizeof(device->busRequest)); for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { sema_init(&device->busRequest[count].sem_req, 0); hifFreeBusRequest(device, &device->busRequest[count]); } /* create async I/O thread */ device->async_shutdown = 0; device->async_task = kthread_create(async_task, (void *)device, "AR6K Async"); if (IS_ERR(device->async_task)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); sema_init(&device->sem_async, 0); wake_up_process(device->async_task ); /* create startup thread */ startup_task_struct = kthread_create(startup_task, (void *)device, "AR6K startup"); if (IS_ERR(startup_task_struct)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create startup task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start startup task\n")); wake_up_process(startup_task_struct); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: return %d\n", ret)); return ret; }