Esempio n. 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;
}
Esempio n. 2
0
static A_STATUS HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq)
{
   
    A_STATUS        status = A_EINVAL;   
    SDREQUEST       *sdrequest;
    A_UINT8         rw;
    A_UINT8         mode;
    A_UINT8         funcNo;
    A_UINT8         opcode;
    A_UINT16        count;
    SDIO_STATUS     sdiostatus;
    A_UINT32        request = pReq->Request;
    
    do {
        
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("HIF Scatter : %d Scatter Entries: %d\n", 
                            pReq->TotalLength, pReq->ValidScatterEntries));
        
        if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid length: %d \n", pReq->TotalLength));
            break;          
        }
        
        if (pReq->TotalLength == 0) {
            A_ASSERT(FALSE);
            break;    
        }
        
            /* get the sd bus request associated with this scatter request */         
        sdrequest = GET_SDREQUEST_SR(pReq);
        
        if (request & HIF_SYNCHRONOUS) {
            sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS;
            sdrequest->pCompleteContext = NULL;
            sdrequest->pCompletion = NULL;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,("  Synchronous \n"));
        } else if (request & HIF_ASYNCHRONOUS) {
            sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS |
                               SDREQ_FLAGS_TRANS_ASYNC;  
            sdrequest->pCompleteContext = pReq;
            sdrequest->pCompletion = HifReadWriteScatterCompletion;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,("  Asynchronous \n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid execution mode: 0x%08x\n", request));
            break;
        }

        if (!(request & HIF_EXTENDED_IO)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid command type: 0x%08x\n", request));
            break;
        }

        sdrequest->Command = CMD53;
            
        if (!(request & HIF_BLOCK_BASIS)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid data mode: 0x%08x\n", request));
            break;   
        }
            /* only block-mode commands */
        mode = CMD53_BLOCK_BASIS;
        sdrequest->BlockLen = HIF_MBOX_BLOCK_SIZE;
        sdrequest->BlockCount = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE;
        count = sdrequest->BlockCount;
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
                        ("  Block mode (BlockLen: %d, BlockCount: %d)\n",
                        sdrequest->BlockLen, sdrequest->BlockCount));
             
        if (request & HIF_WRITE) {
            rw = CMD53_WRITE;
            sdrequest->Flags |= SDREQ_FLAGS_DATA_WRITE;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Direction: Write\n"));
        } else if (request & HIF_READ) {
            rw = CMD53_READ;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Direction: Read\n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid direction: 0x%08x\n", request));
            break;
        }

        if (request & HIF_FIXED_ADDRESS) {
            opcode = CMD53_FIXED_ADDRESS;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Address mode: Fixed\n"));
        } else if (request & HIF_INCREMENTAL_ADDRESS) {
            opcode = CMD53_INCR_ADDRESS;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Address mode: Incremental\n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid address mode: 0x%08x\n", request));
            break;
        }
        
        
        funcNo = SDDEVICE_GET_SDIO_FUNCNO(device->handle);
       
        SDIO_SET_CMD53_ARG(sdrequest->Argument, rw, funcNo,
                           mode, opcode, pReq->Address, count);
        
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("HIF Scatter : SDIO CMD53 card address: 0x%X blocks: %d\n", 
                            pReq->Address, count));
                            
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("HIF Scatter : SDIO CMD53 , request flags:0x%X arg:0x%X\n", 
                            sdrequest->Flags, sdrequest->Argument));
                            
        status = SetupBusRequestForDMA(device, sdrequest, pReq);
        
        if (A_FAILED(status)){
            break;    
        }

        if (sdrequest->pDataBuffer == NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            (" sdrequest->pDataBuffer is NULL!!!\n"));
            status = A_ERROR;
            // A_ASSERT(FALSE);
            break;    
        }
                    
            /* Send the command out */
        sdiostatus = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest);
        
        if (!SDIO_SUCCESS(sdiostatus)) {
            status = A_ERROR;
            break;
        }
            
        status = A_OK;
       
    } while (FALSE);

    if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
        pReq->CompletionStatus = status;
        pReq->CompletionRoutine(pReq);
        status = A_OK;
    }
        
    return status;  
}
Esempio n. 3
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;
}