Exemplo n.º 1
0
/* 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;
 }
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
}