/* 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; }
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; }
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; }