/* thread to serialize all requests, both sync and async */ static int async_task(void *param) { HIF_DEVICE *device; BUS_REQUEST *request; A_STATUS status; unsigned long flags; device = (HIF_DEVICE *)param; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n")); set_current_state(TASK_INTERRUPTIBLE); while(!device->async_shutdown) { /* wait for work */ if (down_interruptible(&device->sem_async) != 0) { /* interrupted, exit */ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n")); break; } if (device->async_shutdown) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n")); break; } /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */ sdio_claim_host(device->func); spin_lock_irqsave(&device->asynclock, flags); /* pull the request to work on */ while (device->asyncreq != NULL) { request = device->asyncreq; if (request->inusenext != NULL) { device->asyncreq = request->inusenext; } else { device->asyncreq = NULL; } spin_unlock_irqrestore(&device->asynclock, flags); /* call HIFReadWrite in sync mode to do the work */ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%X\n", (unsigned int)request)); status = __HIFReadWrite(device, request->address, request->buffer, request->length, request->request & ~HIF_SYNCHRONOUS, NULL); if (request->request & HIF_ASYNCHRONOUS) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%X\n", (unsigned int)request)); device->htcCallbacks.rwCompletionHandler(request->context, status); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%X\n", (unsigned int)request)); hifFreeBusRequest(device, request); } else { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%X\n", (unsigned int)request)); request->status = status; up(&request->sem_req); } spin_lock_irqsave(&device->asynclock, flags); } spin_unlock_irqrestore(&device->asynclock, flags); sdio_release_host(device->func); } complete_and_exit(&device->async_completion, 0); return 0; }
/* thread to serialize all requests, both sync and async */ static int async_task(void *param) { struct hif_device *device; BUS_REQUEST *request; int status; unsigned long flags; device = (struct hif_device *)param; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n")); set_current_state(TASK_INTERRUPTIBLE); while(!device->async_shutdown) { /* wait for work */ if (down_interruptible(&device->sem_async) != 0) { /* interrupted, exit */ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n")); break; } if (device->async_shutdown) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n")); break; } /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */ sdio_claim_host(device->func); spin_lock_irqsave(&device->asynclock, flags); /* pull the request to work on */ while (device->asyncreq != NULL) { request = device->asyncreq; if (request->inusenext != NULL) { device->asyncreq = request->inusenext; } else { device->asyncreq = NULL; } spin_unlock_irqrestore(&device->asynclock, flags); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request)); if (request->pScatterReq != NULL) { A_ASSERT(device->scatter_enabled); /* this is a queued scatter request, pass the request to scatter routine which * executes it synchronously, note, no need to free the request since scatter requests * are maintained on a separate list */ status = DoHifReadWriteScatter(device,request); } else { /* call HIFReadWrite in sync mode to do the work */ status = __HIFReadWrite(device, request->address, request->buffer, request->length, request->request & ~HIF_SYNCHRONOUS, NULL); if (request->request & HIF_ASYNCHRONOUS) { void *context = request->context; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request)); hifFreeBusRequest(device, request); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request)); device->htcCallbacks.rwCompletionHandler(context, status); } else { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request)); request->status = status; up(&request->sem_req); } } spin_lock_irqsave(&device->asynclock, flags); } spin_unlock_irqrestore(&device->asynclock, flags); sdio_release_host(device->func); } complete_and_exit(&device->async_completion, 0); return 0; }
static int async_task(void *param) { HIF_DEVICE *device; BUS_REQUEST *request; A_STATUS status; static int rw_cnt = 0; device = (HIF_DEVICE *)param; while(!device->async_shutdown) { /* wait for work */ NdisWaitEvent(&device->sem_async, 0); NdisResetEvent(&device->sem_async); if (device->async_shutdown) { NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async task stopping\n"); break; } /* pull the request to work on */ while (device->asyncreq != NULL) { request = device->asyncreq; if (request->inusenext != NULL) device->asyncreq = request->inusenext; else device->asyncreq = NULL; /* call HIFReadWrite in sync mode to do the work */ NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task processing req: 0x%X \r\n", (unsigned int)request); rw_cnt++; if(rw_cnt > 1) NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : two time call !!!!! \r\n", __FUNCTION__); status = __HIFReadWrite(device, request->address, request->buffer, request->length, request->request & ~HIF_SYNCHRONOUS, NULL); rw_cnt --; if (request->request & HIF_ASYNCHRONOUS) { NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task completion routine req: 0x%X\n", (unsigned int)request); device->htcCallbacks.rwCompletionHandler(request->context, status); NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task freeing req: 0x%X\n", (unsigned int)request); hifFreeBusRequest(device, request); } else { NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task upping req: 0x%X\n", (unsigned int)request); request->status = status; NdisSetEvent(&request->sem_req); } } } return 0; }