A_STATUS bmiBufferReceive(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) { A_STATUS status; A_UINT32 address; A_UINT32 timeout; #ifdef ONLY_16BIT A_UINT16 cmdCredits; #else A_UCHAR cmdCredits; #endif HIF_REQUEST request; HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, HIF_BYTE_BASIS, HIF_FIXED_ADDRESS); address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1; status = HIFReadWrite(device, address, (A_UCHAR *)&cmdCredits, sizeof(cmdCredits), &request, NULL); if (status != A_OK) { BMI_DEBUG_PRINTF(ATH_LOG_ERR,"Unable to decrement the command credit count register\n"); return A_ERROR; } timeout = BMI_COMMUNICATION_TIMEOUT; while(timeout--) { if (cmdCredits == 1) { HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, HIF_BYTE_BASIS, HIF_FIXED_ADDRESS); address = HIF_MBOX_END_ADDR(ENDPOINT1); status = HIFReadWrite(device, address, buffer, length, &request, NULL); if (status != A_OK) { BMI_DEBUG_PRINTF(ATH_LOG_ERR,"Unable to read the BMI data from the device\n"); return A_ERROR; } break; } HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, HIF_BYTE_BASIS, HIF_FIXED_ADDRESS); address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1; status = HIFReadWrite(device, address, (A_UCHAR *)&cmdCredits, sizeof(cmdCredits), &request, NULL); if (status != A_OK) { BMI_DEBUG_PRINTF(ATH_LOG_ERR,"Unable to decrement the command credit count register\n"); return A_ERROR; } status = A_ERROR; A_MDELAY(1); } if (status != A_OK) { BMI_DEBUG_PRINTF(ATH_LOG_ERR,"BMI Communication timeout\n"); } return status; }
A_STATUS HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, HIF_REQUEST *request, void *context) { A_UINT8 rw; A_UINT8 mode; A_UINT8 opcode; A_UINT32 blockLen, blockCount, count; PSD_BUS_REQUEST busRequest; A_STATUS status = A_OK; SD_TRANSFER_CLASS transferClass; DWORD dwArg; A_UCHAR command; SD_API_STATUS sdStatus; SD_COMMAND_RESPONSE response; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "HIFReadWrite:Enter\n"); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Address 0x%x\n", address); if (request->dmode == HIF_BLOCK_BASIS && request->type != HIF_EXTENDED_IO) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Block mode not allowed for this type of command\n"); return A_ERROR; } if (request->dmode == HIF_BLOCK_BASIS) { mode = SD_IO_BLOCK_MODE; blockLen = HIF_MBOX_BLOCK_SIZE; blockCount = length / HIF_MBOX_BLOCK_SIZE; count = blockCount; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Block mode (BlockLen: %d, BlockCount: %d)\n", blockLen, blockCount); } else if (request->dmode == HIF_BYTE_BASIS) { mode = SD_IO_BYTE_MODE; blockLen = length; blockCount = 1; count = blockLen; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Byte mode (BlockLen: %d, BlockCount: %d)\n", blockLen, blockCount); } else { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid data mode: %d\n", request->dmode); return A_ERROR; } if (request->amode == HIF_FIXED_ADDRESS) { opcode = SD_IO_FIXED_ADDRESS; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Fixed "); } else if (request->amode == HIF_INCREMENTAL_ADDRESS) { opcode = SD_IO_INCREMENT_ADDRESS; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Incremental "); } else { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid address mode: %d\n", request->amode); return A_ERROR; } if (request->direction == HIF_WRITE) { transferClass = SD_WRITE; rw = SD_IO_OP_WRITE; if ((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3))) { /* Mailbox write. Adjust the address so that the last byte falls on the EOM address */ address = address + HIF_MBOX_WIDTH - length; } HIF_DEBUG_PRINTF(ATH_LOG_TRC, "[Write]"); } else { transferClass = SD_READ; rw = SD_IO_OP_READ; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "[Read ]"); } if (request->type == HIF_EXTENDED_IO) { dwArg = BUILD_IO_RW_EXTENDED_ARG(rw, mode, funcNo, address, opcode, count); command = SD_IO_RW_EXTENDED; } else if (request->type == HIF_BASIC_IO) { dwArg = BUILD_IO_RW_DIRECT_ARG(rw, SD_IO_RW_NORMAL, funcNo, address, 0); command = SD_IO_RW_NORMAL; } else { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid command type: %d\n", request->type); return A_ERROR; } if (request->emode == HIF_SYNCHRONOUS) { HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Synchronous\n"); sdStatus = SDSynchronousBusRequest(device->handle, command, dwArg, transferClass, ResponseR5, &response, blockCount, blockLen, buffer, 0); if (!SD_API_SUCCESS(sdStatus)) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "SDBusRequest failed 0x%x\n", sdStatus); status = A_ERROR; } } else { HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Asynchronous\n"); sdStatus = SDBusRequest(device->handle, command, dwArg, transferClass, ResponseR5, blockCount, blockLen, buffer, hifRWCompletionHandler, (DWORD) context, &busRequest, 0); if (!SD_API_SUCCESS(sdStatus)) { status = A_ERROR; } } return status; }
static A_STATUS __HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, A_UINT32 request, void *context) { A_UINT8 opcode; A_STATUS status = A_OK; int ret; A_UINT8 *tbuffer; A_BOOL bounced = FALSE; AR_DEBUG_ASSERT(device != NULL); AR_DEBUG_ASSERT(device->func != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n", device, buffer, address)); do { if (request & HIF_EXTENDED_IO) { //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n")); } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: Invalid command type: 0x%08x\n", request)); status = A_EINVAL; break; } if (request & HIF_BLOCK_BASIS) { /* round to whole block length size */ length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Block mode (BlockLen: %d)\n", length)); } else if (request & HIF_BYTE_BASIS) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Byte mode (BlockLen: %d)\n", length)); } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: Invalid data mode: 0x%08x\n", request)); status = A_EINVAL; break; } #if 0 /* useful for checking register accesses */ if (length & 0x3) { A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n", request & HIF_WRITE ? "write":"read", address, length); } #endif if (request & HIF_WRITE) { if ((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3))) { AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH); /* * Mailbox write. Adjust the address so that the last byte * falls on the EOM address. */ address += (HIF_MBOX_WIDTH - length); } } if (request & HIF_FIXED_ADDRESS) { opcode = CMD53_FIXED_ADDRESS; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address)); } else if (request & HIF_INCREMENTAL_ADDRESS) { opcode = CMD53_INCR_ADDRESS; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address)); } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: Invalid address mode: 0x%08x\n", request)); status = A_EINVAL; break; } if (request & HIF_WRITE) { #if HIF_USE_DMA_BOUNCE_BUFFER if (BUFFER_NEEDS_BOUNCE(buffer)) { AR_DEBUG_ASSERT(device->dma_buffer != NULL); tbuffer = device->dma_buffer; /* copy the write data to the dma buffer */ AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); memcpy(tbuffer, buffer, length); bounced = TRUE; } else { tbuffer = buffer; } #else tbuffer = buffer; #endif if (opcode == CMD53_FIXED_ADDRESS) { ret = sdio_writesb(device->func, address, tbuffer, length); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n", ret, address, length, *(int *)tbuffer)); } else { ret = sdio_memcpy_toio(device->func, address, tbuffer, length); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n", ret, address, length, *(int *)tbuffer)); } } else if (request & HIF_READ) { #if HIF_USE_DMA_BOUNCE_BUFFER if (BUFFER_NEEDS_BOUNCE(buffer)) { AR_DEBUG_ASSERT(device->dma_buffer != NULL); AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); tbuffer = device->dma_buffer; bounced = TRUE; } else { tbuffer = buffer; } #else tbuffer = buffer; #endif if (opcode == CMD53_FIXED_ADDRESS) { ret = sdio_readsb(device->func, tbuffer, address, length); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n", ret, address, length, *(int *)tbuffer)); } else { ret = sdio_memcpy_fromio(device->func, tbuffer, address, length); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n", ret, address, length, *(int *)tbuffer)); } #if HIF_USE_DMA_BOUNCE_BUFFER if (bounced) { /* copy the read data from the dma buffer */ memcpy(buffer, tbuffer, length); } #endif } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: Invalid direction: 0x%08x\n", request)); status = A_EINVAL; break; } if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret)); status = A_ERROR; } } while (FALSE); return status; }
static A_STATUS __HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, A_UINT32 request, void *context) { A_UINT8 rw; A_UINT8 mode; A_UINT8 opcode; A_UINT32 blockLen, blockCount, count; PSD_BUS_REQUEST busRequest=NULL; A_STATUS status = A_OK; SD_TRANSFER_CLASS transferClass; DWORD dwArg; A_UCHAR command; SD_API_STATUS sdStatus; SD_COMMAND_RESPONSE response; NDIS_DEBUG_PRINTF(0, "%s() : Enter \r\n",__FUNCTION__); if(context != NULL) NDIS_DEBUG_PRINTF(0, "%s() : context = 0x%08x \r\n", __FUNCTION__,context); if ((request & HIF_BLOCK_BASIS) && (!(request & HIF_EXTENDED_IO))) { NDIS_DEBUG_PRINTF(DBG_ERR, "Block mode not allowed for this type of command\r\n"); return A_ERROR; } if (request & HIF_BLOCK_BASIS) { mode = SD_IO_BLOCK_MODE; blockLen = HIF_MBOX_BLOCK_SIZE; blockCount = length / HIF_MBOX_BLOCK_SIZE; count = blockCount; } else if (request & HIF_BYTE_BASIS) { mode = SD_IO_BYTE_MODE; blockLen = length; blockCount = 1; count = blockLen; } else { NDIS_DEBUG_PRINTF(DBG_ERR, "Invalid data mode: %08x\r\n", request); return A_ERROR; } if (request & HIF_FIXED_ADDRESS) { opcode = SD_IO_FIXED_ADDRESS; NDIS_DEBUG_PRINTF(DBG_TRACE, "Fixed "); } else if (request & HIF_INCREMENTAL_ADDRESS) { opcode = SD_IO_INCREMENT_ADDRESS; NDIS_DEBUG_PRINTF(0, "Incremental "); } else { NDIS_DEBUG_PRINTF(DBG_ERR, "Invalid address mode: %08x\r\n", request); return A_ERROR; } if (request & HIF_WRITE) { transferClass = SD_WRITE; rw = SD_IO_OP_WRITE; if ((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3))) { /* Mailbox write. Adjust the address so that the last byte falls on the EOM address */ address = address + HIF_MBOX_WIDTH - length; } NDIS_DEBUG_PRINTF(0, "[Write]"); } else { transferClass = SD_READ; rw = SD_IO_OP_READ; NDIS_DEBUG_PRINTF(0, "[Read ] \r\n"); } if (request & HIF_EXTENDED_IO) { dwArg = BUILD_IO_RW_EXTENDED_ARG(rw, mode, funcNo, address, opcode, count); command = SD_IO_RW_EXTENDED; } else if (request & HIF_BASIC_IO) { dwArg = BUILD_IO_RW_DIRECT_ARG(rw, SD_IO_RW_NORMAL, funcNo, address, 0); command = SD_IO_RW_NORMAL; } else { NDIS_DEBUG_PRINTF(DBG_ERR, "Invalid command type: %08x\r\n", request); return A_ERROR; } if((request & HIF_READ) && (dwArg > 0x14000000)) { NDIS_DEBUG_PRINTF(DBG_TRACE, "Synchronous, command = %d, dwArg = 0x%08x, funcNo=%d \r\n", command, dwArg,funcNo); NDIS_DEBUG_PRINTF(0, "blockCount=%d,blockLen=%d \r\n", blockCount, blockLen); } sdStatus = SDSynchronousBusRequest(device->handle, command, dwArg, transferClass, ResponseR5, &response, blockCount, blockLen, buffer, 0); if (!SD_API_SUCCESS(sdStatus)) { NDIS_DEBUG_PRINTF(DBG_ERR, "SDBusRequest failed 0x%x, device->handle = 0x%x, buffer = 0x%x\r\n", sdStatus, device->handle, buffer); NDIS_DEBUG_PRINTF(DBG_ERR, "1[%d]2[%d]3[%d]4[%d]5[%d]6[%d] \r\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5]); status = A_ERROR; } if(status != A_OK) NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : Status = %d - Exit \r\n",__FUNCTION__, status); return status; }
void htcReceiveFrame(HTC_ENDPOINT *endPoint) { A_STATUS status; A_UINT32 address; A_UINT32 paddedLength; A_UINT32 frameLength; HIF_REQUEST request; HTC_ENDPOINT_ID endPointId; HTC_QUEUE_ELEMENT *element; HTC_MBOX_BUFFER *mboxBuffer; HTC_DATA_REQUEST_QUEUE *recvQueue; HTC_TARGET *target; HTC_EVENT_INFO eventInfo; HIF_DATAMODE dmode; HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "htcReceiveFrame - Enter\n"); /* Get the context */ AR_DEBUG_ASSERT(endPoint != NULL); endPointId = GET_ENDPOINT_ID(endPoint); target = endPoint->target; AR_DEBUG_ASSERT(target != NULL); recvQueue = &endPoint->recvQueue; AR_DEBUG_ASSERT(recvQueue != NULL); /* * Receive the frame if we have any pending frames and a buffer to * receive it into. */ if (IS_DATA_QUEUE_EMPTY(recvQueue)) { HTC_DEBUG_PRINTF(ATH_LOG_WARN | ATH_LOG_RECV, "Mailbox (%d) recv queue empty. Unable to remove buffer\n", endPointId); /* * Communicate this situation to the host via the HTC_DATA_AVAILABLE * event to request some buffers in the queue. */ endPoint->rxLengthPending = htcGetFrameLength(endPoint); AR_DEBUG_ASSERT(endPoint->rxLengthPending); FRAME_EVENT(eventInfo, NULL, endPoint->rxLengthPending, 0, A_OK, NULL); dispatchEvent(target, endPointId, HTC_DATA_AVAILABLE, &eventInfo); return; } /* * Get the length from the lookahead register if there is nothing * pending. */ if (endPoint->rxLengthPending) { frameLength = endPoint->rxLengthPending; endPoint->rxLengthPending = 0; } else { frameLength = htcGetFrameLength(endPoint); } if (frameLength > HTC_MESSAGE_SIZE_MAX) { return; } HTC_DEBUG_PRINTF(ATH_LOG_INF | ATH_LOG_RECV, "Frame Length: %d\n", frameLength); /* Adjust the length to be a multiple of block size if appropriate */ paddedLength = (frameLength + (endPoint->blockSize - 1)) & (~(endPoint->blockSize - 1)); /* * Receive the frame(s). Pull an empty buffer from the head of the * Pending Receive Queue. */ element = removeFromMboxQueue(recvQueue); mboxBuffer = GET_MBOX_BUFFER(element); mboxBuffer->actualLength = paddedLength; dmode = (endPoint->blockSize > 1) ? HIF_BLOCK_BASIS : HIF_BYTE_BASIS; HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS, dmode, HIF_FIXED_ADDRESS); address = HIF_MBOX_END_ADDR(endPointId); status = HIFReadWrite(target->device, address, mboxBuffer->buffer, mboxBuffer->actualLength, &request, element); #ifndef HTC_SYNC if (status != A_OK) { #else if (status != A_OK && status != A_PENDING) { #endif HTC_DEBUG_PRINTF(ATH_LOG_ERR | ATH_LOG_RECV, "Frame reception failed\n"); if (!IS_ELEMENT_FREE(element)) { mboxBuffer->actualLength = 0; FRAME_EVENT(eventInfo, mboxBuffer->buffer, mboxBuffer->bufferLength, mboxBuffer->actualLength, A_ERROR, mboxBuffer->cookie); RECYCLE_DATA_REQUEST_ELEMENT(element); dispatchEvent(target, endPointId, HTC_BUFFER_RECEIVED, &eventInfo); HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "htcReceiveFrame - Exit\n"); return; } } #ifdef HTC_SYNC else if (status == A_OK) { element->completionCB(element, status); } #endif HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "htcReceiveFrame - Exit\n"); } A_UINT32 htcGetFrameLength(HTC_ENDPOINT *endPoint) { HTC_TARGET *target; A_UINT32 frameLength; HTC_ENDPOINT_ID endPointId; /* Get the context */ AR_DEBUG_ASSERT(endPoint != NULL); target = endPoint->target; AR_DEBUG_ASSERT(target != NULL); endPointId = GET_ENDPOINT_ID(endPoint); AR_DEBUG_ASSERT(target->table.rx_lookahead_valid & (1 << endPointId)); /* The length is contained in the first two bytes - HTC_HEADER_LEN */ frameLength = (target->table.rx_lookahead[endPointId] & 0xFFFF) + HTC_HEADER_LEN; AR_DEBUG_ASSERT(frameLength); return frameLength; }
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; }