示例#1
0
/* read write an internal SPI register- ALWAYS synchronous */
static A_STATUS SPIReadWriteInternal(HIF_DEVICE *device, 
                                     UINT16      address,
                                     UINT16      *pValue,
                                     BOOL        Read)
{
    SDIO_STATUS status;
    SDREQUEST   *sdrequest;
    BUS_REQUEST *busrequest = NULL;
    A_STATUS    a_status = A_OK;
    
    do {
            /* Allocate a new bus request */ 
        busrequest = hifAllocateBusRequest(device);
        if (busrequest == NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate bus request\n"));
            a_status = A_ERROR;
            break;
        }
    
        sdrequest = busrequest->request;
        
        if (Read) {
            ATH_SET_PIO_INTERNAL_READ_OPERATION(sdrequest,address); 
        } else {
            ATH_SET_PIO_INTERNAL_WRITE_OPERATION(sdrequest,address,*pValue);     
        }
        
            /* always synchronous */
        sdrequest->Flags = SDREQ_FLAGS_RAW;
        sdrequest->pCompleteContext = NULL;
        sdrequest->pCompletion = NULL;
        
            /* issue the request */
        status = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest);
        if (!SDIO_SUCCESS(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Spi Internal Read/Write failure: %d\n", status));
            a_status = A_ERROR;
        } else {
            if (Read) {
                    /* get the read result */
                *pValue = ATH_GET_PIO_INTERNAL_READ_RESULT(sdrequest);
            }   
        }
       
    } while (FALSE);
    
    if (busrequest != NULL) {
        hifFreeBusRequest(device, busrequest);
    }   
    
    return a_status;
}
示例#2
0
文件: hif.c 项目: AvalueAES/rev-sa01
/* queue a read/write request */
A_STATUS
HIFReadWrite(HIF_DEVICE *device,
             A_UINT32 address,
             A_UCHAR *buffer,
             A_UINT32 length,
             A_UINT32 request,
             void *context)
{
    A_STATUS    status = A_OK;
    BUS_REQUEST *busrequest;


    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->func != NULL);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address));

    do {            
        if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
            /* serialize all requests through the async thread */
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n", 
                        (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
            busrequest = hifAllocateBusRequest(device);
            if (busrequest == NULL) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                    ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n", 
                        request & HIF_READ ? "READ":"WRITE", address, length));
                return A_ERROR;
            }
            busrequest->address = address;
            busrequest->buffer = buffer;
            busrequest->length = length;
            busrequest->request = request;
            busrequest->context = context;
            
            AddToAsyncList(device, busrequest);
            
            if (request & HIF_SYNCHRONOUS) {
                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%X\n", (unsigned int)busrequest));

                /* wait for completion */
                up(&device->sem_async);
                if (down_interruptible(&busrequest->sem_req) != 0) {
                    /* interrupted, exit */
                    return A_ERROR;
                } else {
                    A_STATUS status = busrequest->status;
                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%X: 0x%X\n", 
						      (unsigned int)busrequest, busrequest->status));
                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
                    hifFreeBusRequest(device, busrequest);
                    return status;
                }
            } else {
                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%X\n", (unsigned int)busrequest));
                up(&device->sem_async);
                return A_PENDING;
            }
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
            status = A_EINVAL;
            break;
        }
    } while(0);

    return status;
}
示例#3
0
    /* setup of HIF scatter resources */
A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo)
{
    A_STATUS              status = A_ERROR;   
    int                   i;
    HIF_SCATTER_REQ_PRIV *pReqPriv;
    BUS_REQUEST          *busrequest;
        
    do {
        
            /* check if host supports scatter requests and it meets our requirements */
        if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
                    device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ));
            status = A_ENOTSUP;
            break;    
        }
                    
        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n",
                MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ)); 
        
        for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {    
                /* allocate the private request blob */
            pReqPriv = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV));
            if (NULL == pReqPriv) {
                break;    
            }
            A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV));
                /* save the device instance*/
            pReqPriv->device = device;      
                /* allocate the scatter request */
            pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) + 
                                         (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM))); 
           
            if (NULL == pReqPriv->pHifScatterReq) {
                A_FREE(pReqPriv);
                break;      
            }           
                /* just zero the main part of the scatter request */
            A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(HIF_SCATTER_REQ));
                /* back pointer to the private struct */
            pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv;
                /* allocate a bus request for this scatter request */
            busrequest = hifAllocateBusRequest(device);
            if (NULL == busrequest) {
                A_FREE(pReqPriv->pHifScatterReq);
                A_FREE(pReqPriv);
                break;    
            }
                /* assign the scatter request to this bus request */
            busrequest->pScatterReq = pReqPriv;
                /* point back to the request */
            pReqPriv->busrequest = busrequest;                           
                /* add it to the scatter pool */
            FreeScatterReq(device,pReqPriv->pHifScatterReq);
        }
        
        if (i != MAX_SCATTER_REQUESTS) {
            status = A_NO_MEMORY;
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n"));
            break;    
        }
        
            /* set scatter function pointers */
        pInfo->pAllocateReqFunc = AllocScatterReq;
        pInfo->pFreeReqFunc = FreeScatterReq;
        pInfo->pReadWriteScatterFunc = HifReadWriteScatter;   
        pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ;
        pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE;
     
        status = A_OK;
        
    } while (FALSE);
    
    if (A_FAILED(status)) {
        CleanupHIFScatterResources(device);   
    }
    
    return status;
}
示例#4
0
文件: hif.c 项目: NemProjects/WLAN
A_STATUS 
HIFReadWrite(HIF_DEVICE		*device, 
             A_UINT32		address, 
             A_UCHAR		*buffer, 
             A_UINT32		length, 
             A_UINT32		request, 
             void			*context) 
{

    A_STATUS            status = A_OK;
	//unsigned long 		flags;
	BUS_REQUEST 		*busrequest;
	BUS_REQUEST 		*async;
	BUS_REQUEST 		*active;


	AR_DEBUG_ASSERT(device != NULL);
	
	
	
	do 
	{
		
		
		if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS))
		{
		
			/* serialize all requests through the async thread */
			NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: Execution mode: %s\n", (request & HIF_ASYNCHRONOUS) ?"Async":"Synch");

			busrequest = hifAllocateBusRequest(device);
			if (busrequest == NULL) {
				NDIS_DEBUG_PRINTF(DBG_ERR, "AR6000: no async bus requests available\n");
				return A_ERROR;
			}

			Hif_Lock();
			
			busrequest->address = address;
			busrequest->buffer = buffer;
			busrequest->length = length;
			busrequest->request = request;
			busrequest->context = context;

			//NDIS_DEBUG_PRINTF(1, " add = %x, length = %x, request = %d \r\n", address, length, request);
					
			/* add to async list */
			active = device->asyncreq;
			if (active == NULL) 
			{
				device->asyncreq = busrequest;
				device->asyncreq->inusenext = NULL;
			} 
			else 	
			{
				for (async = device->asyncreq; async != NULL; async = async->inusenext) {
					 active =  async;
				}
				active->inusenext = busrequest;
				busrequest->inusenext = NULL;
			}
			
			Hif_Unlock();
			
		    if (request & HIF_SYNCHRONOUS) 
			{

				NdisSetEvent(&device->sem_async);

				/* Wait Read/Write Complete from the async_task */
				if( ! NdisWaitEvent(&busrequest->sem_req, HIF_SYNCHRONOUS_WAIT_TIME)) {
					NDIS_DEBUG_PRINTF(DBG_ERR, " HIF Synchronous Read/Write Time Out !! \r\n");
					NdisResetEvent(&busrequest->sem_req);
					
					return A_ERROR;
				} 

				NdisResetEvent(&busrequest->sem_req);
				hifFreeBusRequest(device, busrequest);	
				
				if(busrequest->status != A_OK)
					NDIS_DEBUG_PRINTF(DBG_ERR, "%s() Read/Write Err \r\n", __FUNCTION__);
				
				
				return busrequest->status;
			} 
			else 
			{
				NdisSetEvent(&device->sem_async);	
				
				return  A_PENDING;
		  	}
			
		}
		else
		{
			NDIS_DEBUG_PRINTF(DBG_ERR, "AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request);
            status = A_EINVAL;
            break;			
		}
		
	}while(0);
    NDIS_DEBUG_PRINTF(0, "%s() :  - Exit \r\n",__FUNCTION__);
    return status;
}
示例#5
0
/* queue a read/write request */
A_STATUS
HIFReadWrite(HIF_DEVICE *device,
             A_UINT32 address,
             A_UCHAR *buffer,
             A_UINT32 length,
             A_UINT32 request,
             void *context)
{
    A_STATUS    status = A_OK;
    unsigned long flags;
    BUS_REQUEST *busrequest;
    BUS_REQUEST *async;
    BUS_REQUEST *active;

    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->func != NULL);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p\n", device));

    do {
        if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
            /* serialize all requests through the async thread */
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n", (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
            busrequest = hifAllocateBusRequest(device);
            if (busrequest == NULL) {
               AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: no async bus requests available\n"));
                return A_ERROR;
            }
            spin_lock_irqsave(&device->asynclock, flags);
            busrequest->address = address;
            busrequest->buffer = buffer;
            busrequest->length = length;
            busrequest->request = request;
            busrequest->context = context;
            /* add to async list */
            active = device->asyncreq;
            if (active == NULL) {
                device->asyncreq = busrequest;
                device->asyncreq->inusenext = NULL;
            } else {
                for (async = device->asyncreq;
                     async != NULL;
                     async = async->inusenext) {
                     active =  async;
                }
                active->inusenext = busrequest;
                busrequest->inusenext = NULL;
            }
            spin_unlock_irqrestore(&device->asynclock, flags);
            if (request & HIF_SYNCHRONOUS) {
                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%X\n", (unsigned int)busrequest));

                /* wait for completion */
                up(&device->sem_async);
                if (down_interruptible(&busrequest->sem_req) != 0) {
                    /* interrupted, exit */
                    return A_ERROR;
                } else {
                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%X: 0x%X\n",
						      (unsigned int)busrequest, busrequest->status));
                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
                    hifFreeBusRequest(device, busrequest);
                    return busrequest->status;
                }
            } else {
                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%X\n", (unsigned int)busrequest));
                up(&device->sem_async);
                return A_PENDING;
            }
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
            status = A_EINVAL;
            break;
        }
    } while(0);

    return status;
}
示例#6
0
A_STATUS HIFReadWrite(HIF_DEVICE *device, 
                      A_UINT32 address, 
                      A_UCHAR *buffer, 
                      A_UINT32 length, 
                      A_UINT32 request, 
                      void *context) 
{
    SDIO_STATUS status;
    SDREQUEST   *sdrequest;
    BUS_REQUEST *busrequest = NULL;
    A_STATUS    a_status = A_OK;
    
    /* Return any new requests if the shutdown is already in progress */
    if (device->shutdownInProgress) {
        if (request & HIF_ASYNCHRONOUS) {
            device->htcCallbacks.rwCompletionHandler(context, A_ERROR);
            return A_PENDING;
        }
        return A_ERROR;
    }

    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->handle != NULL);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Device: %p\n", device));

    if (length > device->curBlockSize) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Invalid data length: %d\n", length));
        return A_ERROR;
    }

    /* 
     * We do not differentiate between the extended and the basic I/O so 
     * we do not process the request type.
     */

    /*
     * We do not differentiate between the byte and block data mode so
     * we do not process the request dmode.
     */

    do {
        /* Addressing mode */
        if (request & HIF_FIXED_ADDRESS) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Address mode: Fixed\n"));
        } else if (request & HIF_INCREMENTAL_ADDRESS) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Address mode: Incremental\n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Invalid address mode: 0x%08x\n", request));
            a_status = A_ERROR;
            break;
        }

        /* 
         * Mailbox write. Adjust the address so that the last byte 
         * falls on the EOM address.
         */
        if (request & HIF_WRITE) { 
            if ((address >= HIF_MBOX_START_ADDR(0)) && 
                (address <= HIF_MBOX_END_ADDR(3)))
            {
                DBG_ASSERT(length <= HIF_MBOX_WIDTH);
                address += (HIF_MBOX_WIDTH - length);
            }
        }

        /* Allocate a new bus request */ 
        busrequest = hifAllocateBusRequest(device);
        if (busrequest == NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate bus request\n"));
            a_status = A_ERROR;
            break;
        }
    
        sdrequest = busrequest->request;
        sdrequest->pDataBuffer = buffer;
    
        if (request & HIF_SYNCHRONOUS) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Execution mode: Synchronous\n"));
            sdrequest->Flags = SDREQ_FLAGS_RAW;
            sdrequest->pCompleteContext = NULL;
            sdrequest->pCompletion = NULL;
        } else if (request & HIF_ASYNCHRONOUS) {
                /* Populate the bus request to be passed in as context */
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Execution mode: Asynchronous\n"));
                /* setup async context */
            busrequest->device = device;
            busrequest->context = context;
            sdrequest->pCompleteContext = busrequest;
            sdrequest->Flags = SDREQ_FLAGS_RAW | SDREQ_FLAGS_TRANS_ASYNC;
            sdrequest->pCompletion = hifRWCompletionHandler;
        }
        
            /* Indicate to the bus driver if its a read or a write */
        if (request & HIF_WRITE) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Direction: Write\n"));
            if (((address >= HIF_MBOX_START_ADDR(0)) &&
                 (address <= HIF_MBOX_END_ADDR(3)))) {  
                
                /* trapping HTC WRITE to mailbox, these will use the special DMA operation */                               
                AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
                            ("--- MAILBOX WRITE ACCESS!!!!\n"));
                            
                ATH_SET_DMA_OPERATION(sdrequest,ATH_TRANS_WRITE,address,length);

            } else {
                ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(sdrequest,
                                                     address,
                                                     (request & HIF_INCREMENTAL_ADDRESS) ? TRUE : FALSE,
                                                     length);
                
            }       
        } else if (request & HIF_READ) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Direction: Read\n"));
            if (((address >= HIF_MBOX_START_ADDR(0)) &&
                 (address <= HIF_MBOX_END_ADDR(3)))) {   
                                     
                 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
                            (" --- MAILBOX READ ACCESS!!!!\n"));
                /*  trapping on HTC READ mailbox , these will use the special DMA operation */
               ATH_SET_DMA_OPERATION(sdrequest,ATH_TRANS_READ,address,length);
            } else { 
                ATH_SET_PIO_EXTERNAL_READ_OPERATION(sdrequest,
                                                    address,
                                                    request & HIF_INCREMENTAL_ADDRESS ? TRUE : FALSE,
                                                    length);
            }
            
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Invalid direction: 0x%08x\n", request));
            a_status = A_ERROR;
            break;
        }

            /* issue the request */
        status = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest);
        if (!SDIO_SUCCESS(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("HIF Read/Write failure: %d\n", status));
            a_status = A_ERROR;
        }
       
    } while (FALSE);
    
    if ((busrequest != NULL) && (request & HIF_SYNCHRONOUS)) {
        hifFreeBusRequest(device,busrequest);
    }   

    return a_status;
}