예제 #1
0
A_STATUS
HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
                   void *config, A_UINT32 configLen)
{
    A_UINT32 count;

    switch(opcode) {
        case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
            ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
            ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
            ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
            ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
            break;

        case HIF_DEVICE_GET_MBOX_ADDR:
            for (count = 0; count < 4; count ++) {
                ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
            }
            break;
        case HIF_DEVICE_GET_IRQ_PROC_MODE:
            *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
            break;
        case HIF_DEVICE_GET_OS_DEVICE:
                /* pass back a pointer to the SDIO function's "dev" struct */
            ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->dev;
            break; 
        default:
            AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
                            ("AR6000: Unsupported configuration opcode: %d\n", opcode));
            return A_ERROR;
    }

    return A_OK;
}
예제 #2
0
A_STATUS
HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, 
                   void *config, A_UINT32 configLen)
{
    A_UINT32 count;

    switch(opcode) {
        
        case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
            ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
            ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
            ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
            ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
            break;

        case HIF_DEVICE_GET_MBOX_ADDR:
            for (count = 0; count < 4; count ++) {
                ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
            }
            if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) {  
                HIF_DEVICE_MBOX_INFO *pInfo = (HIF_DEVICE_MBOX_INFO *)config;
                    /* SPI interface cannot handle bundled messages due to limitations
                     * in the bus protocol */  
                pInfo->Flags |= HIF_MBOX_FLAG_NO_BUNDLING; 
            }
            break;

        case HIF_DEVICE_GET_PENDING_EVENTS_FUNC:
                /* set pending events */
            *((HIF_PENDING_EVENTS_FUNC *)config) = hifGetPendingEvents;
            break;
        
        case HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC:
                /* set recv masking function */
            *((HIF_MASK_UNMASK_RECV_EVENT *)config) = hifMaskUnmaskRecvMsg;
            break;   
            
        case HIF_DEVICE_GET_IRQ_PROC_MODE:
            /* only SYNC mode supported */
            *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" SPI2 HIF requires sync mode IRQ processing \n"));
            break;
        case HIF_DEVICE_DEBUG_BUS_STATE:            
            HIFSpiDumpRegs(device);
            break;     
        default:
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Invalid configuration opcode: %d\n", opcode));
            return A_ERROR;
    }

    return A_OK;
}
예제 #3
0
파일: hif.c 프로젝트: NemProjects/WLAN
A_STATUS
HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
                   void *config, A_UINT32 configLen)
{

	A_UINT32 count;
	A_STATUS status = A_OK;

	switch(opcode) 
	{
		case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
			((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
			((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
			((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
			((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
			break;

		case HIF_DEVICE_GET_MBOX_ADDR:
			for (count = 0; count < 4; count ++) {
				((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
			}
			break;
			
		case HIF_DEVICE_GET_IRQ_PROC_MODE:
			*((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
			break;
			
		case HIF_DEVICE_GET_OS_DEVICE:
	#if 0	//bluebird		
			/* pass back a pointer to the SDIO function's "dev" struct */
			((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->dev;
	#else
			NDIS_DEBUG_PRINTF(DBG_ERR, "HIF_DEVICE_GET_OS_DEVICE isn't ready ~ must have to do something \r\n");
			return A_ERROR;
	#endif
	
			break; 

        case HIF_DEVICE_POWER_STATE_CHANGE:
            status = PowerChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config);
            break;

	
		default:
			NDIS_DEBUG_PRINTF(DBG_ERR, "AR6000: Unsupported configuration opcode: %d \r\n", opcode);
			return A_ERROR;
			
	}

    return A_OK;
}
예제 #4
0
파일: hif.c 프로젝트: AvalueAES/rev-sa01
A_STATUS
HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
                   void *config, A_UINT32 configLen)
{
    A_UINT32 count;
    A_STATUS status;
    
    switch(opcode) {
        case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
            ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
            ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
            ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
            ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
            break;

        case HIF_DEVICE_GET_MBOX_ADDR:
            for (count = 0; count < 4; count ++) {
                ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
            }
            
            if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) {    
                SetExtendedMboxWindowInfo((A_UINT16)device->func->device,
                                          (HIF_DEVICE_MBOX_INFO *)config);
            }
                        
            break;
        case HIF_DEVICE_GET_IRQ_PROC_MODE:
            *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
            break;
       case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT:
            if (!device->scatter_enabled) {
                return A_ENOTSUP;    
            }
            status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_INFO *)config);
            if (A_FAILED(status)) {
                device->scatter_enabled = FALSE;           
            }
            return status;
        case HIF_DEVICE_GET_OS_DEVICE:
                /* pass back a pointer to the SDIO function's "dev" struct */
            ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->dev;
            break; 
        default:
            AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
                            ("AR6000: Unsupported configuration opcode: %d\n", opcode));
            return A_ERROR;
    }

    return A_OK;
}
예제 #5
0
파일: hif.c 프로젝트: NemProjects/WLAN
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;
}
예제 #6
0
파일: hif.c 프로젝트: AvalueAES/rev-sa01
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;
}
예제 #7
0
파일: bmi.c 프로젝트: NemProjects/WLAN
/* BMI Access routines */
A_STATUS 
bmiBufferSend(HIF_DEVICE *device, 
              A_UCHAR *buffer, 
              A_UINT32 length) 
{
    A_STATUS status;
    A_UINT32 timeout;
    A_UINT32 address;
#ifdef ONLY_16BIT
    A_UINT16 cmdCredits;
#else
    A_UCHAR cmdCredits;
#endif
    HIF_REQUEST request;

    /* Read the counter register to get the command credits */
    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
    address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
    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_WRITE, HIF_EXTENDED_IO, 
                              HIF_SYNCHRONOUS, HIF_BYTE_BASIS, 
                              HIF_INCREMENTAL_ADDRESS);
            address = HIF_MBOX_START_ADDR(ENDPOINT1);
            status = HIFReadWrite(device, address, buffer, length, 
                                  &request, NULL);
            if (status != A_OK) {
                BMI_DEBUG_PRINTF(ATH_LOG_ERR,"Unable to send the BMI data to 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_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
        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;
}
예제 #8
0
파일: hif.c 프로젝트: NemProjects/WLAN
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;
}
예제 #9
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;
}