Esempio n. 1
0
static int smssdio_sendrequest(void *context, void *buffer, size_t size)
{
	int ret = 0;
	struct smssdio_device *smsdev;

	smsdev = context;

	sdio_claim_host(smsdev->func);

	while (size >= smsdev->func->cur_blksize) {
		ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
					buffer, smsdev->func->cur_blksize);
		if (ret)
			goto out;

		buffer += smsdev->func->cur_blksize;
		size -= smsdev->func->cur_blksize;
	}

	if (size) {
		ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
					buffer, size);
	}

out:
	sdio_release_host(smsdev->func);

	return ret;
}
Esempio n. 2
0
int linux_sdio_cmd53(sdio_cmd53_t *cmd)
{
	struct sdio_func *func = g_linux_wlan->wilc_sdio_func;
	int size, ret;

	sdio_claim_host(func);

	func->num = cmd->function;
	func->cur_blksize = cmd->block_size;
	if (cmd->block_mode)
		size = cmd->count * cmd->block_size;
	else
		size = cmd->count;

	if (cmd->read_write) {  /* write */
		ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size);
	} else {        /* read */
		ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address,  size);
	}

	sdio_release_host(func);


	if (ret < 0) {
		PRINT_ER("wilc_sdio_cmd53..failed, err(%d)\n", ret);
		return 0;
	}

	return 1;
}
Esempio n. 3
0
void cmc7xx_sdio_reset(struct work_struct *work)
{
	struct net_adapter *adapter = container_of(work,
			struct net_adapter, wimax_reset);
	u8 data[100];

	sdio_claim_host(adapter->func);
	sdio_release_irq(adapter->func);
	sdio_release_host(adapter->func);

	if (wimax_cmc7xx_sdio_reset_comm(adapter->func->card))
		dump_debug("%s: cmc7xx_sdio_reset_comm fail", __func__);

	sdio_claim_host(adapter->func);
	if (sdio_enable_func(adapter->func))
		dump_debug("%s: sdio_enable_func fail", __func__);

	if (sdio_claim_irq(adapter->func, adapter_interrupt))
		dump_debug("%s: sdio_claim_irq fail", __func__);

	if (sdio_set_block_size(adapter->func, 512))
		dump_debug("%s: sdio_set_block_size fail", __func__);

	sdio_memcpy_toio(adapter->func,
		SDIO_TX_BANK_ADDR + 4,
		data, 32);

	sdio_release_host(adapter->func);
}
Esempio n. 4
0
static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
				  size_t len, bool fixed)
{
	int ret;
	struct sdio_func *func = wl_to_func(wl);

	sdio_claim_host(func);

	if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
		sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
		wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
			     addr, ((u8 *)buf)[0]);
	} else {
		wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes",
			     addr, len);
		wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);

		if (fixed)
			ret = sdio_writesb(func, addr, buf, len);
		else
			ret = sdio_memcpy_toio(func, addr, buf, len);
	}

	sdio_release_host(func);

	if (ret)
		wl1271_error("sdio write failed (%d)", ret);
}
Esempio n. 5
0
/*
 * Sends a barker buffer to the device
 *
 * This helper will allocate a kmalloced buffer and use it to transmit
 * (then free it). Reason for this is that the SDIO host controller
 * expects alignment (unknown exactly which) which the stack won't
 * really provide and certain arches/host-controller combinations
 * cannot use stack/vmalloc/text areas for DMA transfers.
 */
static
int __i2400ms_send_barker(struct i2400ms *i2400ms,
			  const __le32 *barker, size_t barker_size)
{
	int  ret;
	struct sdio_func *func = i2400ms->func;
	struct device *dev = &func->dev;
	void *buffer;

	ret = -ENOMEM;
	buffer = kmalloc(I2400MS_BLK_SIZE, GFP_KERNEL);
	if (buffer == NULL)
		goto error_kzalloc;

	memcpy(buffer, barker, barker_size);
	sdio_claim_host(func);
	ret = sdio_memcpy_toio(func, 0, buffer, I2400MS_BLK_SIZE);
	sdio_release_host(func);

	if (ret < 0)
		d_printf(0, dev, "E: barker error: %d\n", ret);

	kfree(buffer);
error_kzalloc:
	return ret;
}
Esempio n. 6
0
/* Write length bytes to device address from buffer (CMD53) */
static int ks7010_sdio_write(struct ks_wlan_private *priv, unsigned int address,
			     unsigned char *buffer, int length)
{
	struct sdio_func *func = priv->ks_sdio_card->func;

	return sdio_memcpy_toio(func, address, buffer, length);
}
int sdioDrv_WriteSync (unsigned int uFunc, 
                       unsigned int uHwAddr, 
                       void *       pData, 
                       unsigned int uLen,
                       unsigned int bIncAddr,
                       unsigned int bMore)
{
	int ret;

	PDEBUG("%s: uFunc %d uHwAddr %d pData %x uLen %d bIncAddr %d\n", __func__, uFunc, uHwAddr, (unsigned int)pData, uLen, bIncAddr);

	/* If request is either for sdio function 0 or not a multiple of 4 (OMAP DMA limit)
	    then we have to use CMD 52's */
	if (uFunc == SDIO_CTRL_FUNC || uLen % 4 != 0)
	{
		ret = generic_write_bytes(uFunc, uHwAddr, pData, uLen, bIncAddr, bMore);
	}
	else
	{
	if (bIncAddr)
		ret = sdio_memcpy_toio(tiwlan_func[uFunc], uHwAddr, pData, uLen);
	else
		ret = sdio_writesb(tiwlan_func[uFunc], uHwAddr, pData, uLen);
	}
     
	if (ret) {
		printk(KERN_ERR "%s: sdio error: %d\n", __func__, ret);
		return -1;
	}

	return 0;
}
Esempio n. 8
0
SDIO_Status SDIO_SyncWrite(SDIO_Handle Handle, SDIO_Request_t *Req)
{
    struct sdio_func *func = (struct sdio_func *)Handle;
    int rc;
    void *src = Req->buffer;

    if (Req->buffer_len >= DMA_THRESHOLD_SIZE) {
#if USE_SKETCHY_WRITES
        if (is_vmalloc_addr(src)) {
            if (!spans_page(src, Req->buffer_len)) {
                src = vmalloc_to_unity(src);
                dmac_clean_range(Req->buffer,
                                 Req->buffer + Req->buffer_len);
            } else {
#endif
                src = sdio_dma_ptr;
                memcpy(src, Req->buffer, Req->buffer_len);
#if USE_SKETCHY_WRITES
            }
        }
#endif
    }

    rc = sdio_memcpy_toio(func, Req->peripheral_addr, src,
                          Req->buffer_len);

    if (!rc)
        return SDIO_SUCCESS;

    printk(KERN_ERR "%s: failed (%d)\n", __func__, rc);
    return SDIO_FAILURE;
}
Esempio n. 9
0
u_int sd_send_data(struct net_adapter *adapter, struct buffer_descriptor *dsc)
{
	int	nRet = 0;
	int nWriteIdx;
	dsc->length += (dsc->length & 1) ? 1 : 0;

#ifdef HARDWARE_USE_ALIGN_HEADER
	if (dsc->length > SDIO_MAX_BYTE_SIZE)
		dsc->length = (dsc->length + SDIO_MAX_BYTE_SIZE)
				& ~(SDIO_MAX_BYTE_SIZE);
#endif

	if (adapter->halted) {
		dump_debug("Halted Already");
		return STATUS_UNSUCCESSFUL;
	}
	hwSdioWriteBankIndex(adapter, &nWriteIdx, &nRet);

	if (nRet || (nWriteIdx < 0)) {
		dump_debug("sd_send_data : "
			" error fetch bank index!! nRet = %d", nRet);
		return STATUS_UNSUCCESSFUL;
	}

	sdio_writeb(adapter->func, (nWriteIdx + 1) % 15,
			 SDIO_H2C_WP_REG, NULL);

	nRet = sdio_memcpy_toio(adapter->func,
			SDIO_TX_BANK_ADDR+(SDIO_BANK_SIZE * nWriteIdx)+4,
			dsc->buffer, dsc->length);

	if (nRet < 0)
		dump_debug("sd_send_data :"
			" error writing dsc packet!! nRet = %d", nRet);
	nRet = sdio_memcpy_toio(adapter->func,
			SDIO_TX_BANK_ADDR + (SDIO_BANK_SIZE * nWriteIdx),
			&(dsc->length), 4);

	if (nRet < 0)
		dump_debug("sd_send_data :"
			"error writing bank length info!! nRet = %d", nRet);
	return nRet;
}
Esempio n. 10
0
/**
 *	sdio_writew - write a 16 bit integer to a SDIO function
 *	@func: SDIO function to access
 *	@b: integer to write
 *	@addr: address to write to
 *	@err_ret: optional status value from transfer
 *
 *	Writes a 16 bit integer to the address space of a given SDIO
 *	function. @err_ret will contain the status of the actual
 *	transfer.
 */
void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret)
{
	int ret;

	*(__le16 *)func->tmpbuf = cpu_to_le16(b);

	ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
	if (err_ret)
		*err_ret = ret;
}
Esempio n. 11
0
/**
 *	sdio_writel - write a 32 bit integer to a SDIO function
 *	@func: SDIO function to access
 *	@b: integer to write
 *	@addr: address to write to
 *	@err_ret: optional status value from transfer
 *
 *	Writes a 32 bit integer to the address space of a given SDIO
 *	function. @err_ret will contain the status of the actual
 *	transfer.
 */
void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret)
{
	int ret;

	*(__le32 *)func->tmpbuf = cpu_to_le32(b);

	ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
	if (err_ret)
		*err_ret = ret;
}
Esempio n. 12
0
static int smssdio_sendrequest(void *context, void *buffer, size_t size)
{
	int ret = 0;
	struct smssdio_device *smsdev;
	void* auxbuf = NULL;

	smsdev = context;
	
	if (size & 3)
	{
		/* Make sure size is aligned to 32 bits, round up if required*/			
		auxbuf = kmalloc((size + 3) & 0xfffffffc, GFP_KERNEL);
		memcpy (auxbuf, buffer, size);
		buffer = auxbuf;
		size = (size + 3) & 0xfffffffc;
	}


	sdio_claim_host(smsdev->func);

	while (size >= smsdev->func->cur_blksize) {
		ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
					buffer, smsdev->func->cur_blksize);
		if (ret)
			goto out;

		buffer += smsdev->func->cur_blksize;
		size -= smsdev->func->cur_blksize;
	}

	if (size) {
		ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
					buffer, size);
	}

out:
	if (auxbuf)
		kfree(auxbuf);
	sdio_release_host(smsdev->func);

	return ret;
}
Esempio n. 13
0
static void wl1251_sdio_write(struct wl1251 *wl, int addr,
			      void *buf, size_t len)
{
	int ret;
	struct sdio_func *func = wl_to_func(wl);

	sdio_claim_host(func);
	ret = sdio_memcpy_toio(func, addr, buf, len);
	if (ret)
		wl1251_error("sdio write failed (%d)", ret);
	sdio_release_host(func);
}
/* precondition: host controller is claimed */
static int
brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo,
			 uint func, uint addr, struct sk_buff *pkt, uint pktlen)
{
	int err_ret = 0;

	if ((write) && (!fifo)) {
		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
					   ((u8 *) (pkt->data)), pktlen);
	} else if (write) {
		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
					   ((u8 *) (pkt->data)), pktlen);
	} else if (fifo) {
		err_ret = sdio_readsb(sdiodev->func[func],
				      ((u8 *) (pkt->data)), addr, pktlen);
	} else {
		err_ret = sdio_memcpy_fromio(sdiodev->func[func],
					     ((u8 *) (pkt->data)),
					     addr, pktlen);
	}

	return err_ret;
}
/*
 * Use CMD53 to write data to SDIO device.
 * This function MUST be called after sdio_claim_host() or
 * in SDIO ISR(host had been claimed).
 *
 * Parameters:
 *	psdio	pointer of SDIO_DATA
 *	addr	address to write
 *	cnt		amount to write
 *	pdata	data pointer, this should be a "DMA:able scratch buffer"!
 *
 * Return:
 *	0		Success
 *	others	Fail
 */
s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
{
	PADAPTER padapter;
	struct dvobj_priv *psdiodev;
	PSDIO_DATA psdio;
	
	struct sdio_func *func;
	u32 size;
	s32 err=-EPERM;

_func_enter_;
	padapter = pintfhdl->padapter;
	psdiodev = pintfhdl->pintf_dev;
	psdio = &psdiodev->intf_data;
	
	if(padapter->bSurpriseRemoved){
		//DBG_871X(" %s (padapter->bSurpriseRemoved )!!!\n",__FUNCTION__);
		return err;
	}
	
	func = psdio->func;
//	size = sdio_align_size(func, cnt);

	if (unlikely((cnt==1) || (cnt==2)))
	{
		int i;
		u8 *pbuf = (u8*)pdata;

		for (i = 0; i < cnt; i++)
		{
			sdio_writeb(func, *(pbuf+i), addr+i, &err);
			if (err) {
				DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, *(pbuf+i));
				break;
			}
		}

		return err;
	}

	size = cnt;
	err = sdio_memcpy_toio(func, addr, pdata, size);
	if (err) {
		DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR=%#x Size=%d(%d)\n", __func__, err, addr, cnt, size);
	}

_func_exit_;

	return err;
}
ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m,
				const struct i2400m_bootrom_header *_cmd,
				size_t cmd_size, int flags)
{
	ssize_t result;
	struct device *dev = i2400m_dev(i2400m);
	struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
	int opcode = _cmd == NULL ? -1 : i2400m_brh_get_opcode(_cmd);
	struct i2400m_bootrom_header *cmd;
	
	size_t cmd_size_a = ALIGN(cmd_size, I2400MS_BLK_SIZE);

	d_fnstart(5, dev, "(i2400m %p cmd %p size %zu)\n",
		  i2400m, _cmd, cmd_size);
	result = -E2BIG;
	if (cmd_size > I2400M_BM_CMD_BUF_SIZE)
		goto error_too_big;

	if (_cmd != i2400m->bm_cmd_buf)
		memmove(i2400m->bm_cmd_buf, _cmd, cmd_size);
	cmd = i2400m->bm_cmd_buf;
	if (cmd_size_a > cmd_size)			
		memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size);
	if ((flags & I2400M_BM_CMD_RAW) == 0) {
		if (WARN_ON(i2400m_brh_get_response_required(cmd) == 0))
			dev_warn(dev, "SW BUG: response_required == 0\n");
		i2400m_bm_cmd_prepare(cmd);
	}
	d_printf(4, dev, "BM cmd %d: %zu bytes (%zu padded)\n",
		 opcode, cmd_size, cmd_size_a);
	d_dump(5, dev, cmd, cmd_size);

	sdio_claim_host(i2400ms->func);			
	result = sdio_memcpy_toio(i2400ms->func, I2400MS_DATA_ADDR,
				  i2400m->bm_cmd_buf, cmd_size_a);
	sdio_release_host(i2400ms->func);
	if (result < 0) {
		dev_err(dev, "BM cmd %d: cannot send: %ld\n",
			opcode, (long) result);
		goto error_cmd_send;
	}
	result = cmd_size;
error_cmd_send:
error_too_big:
	d_fnend(5, dev, "(i2400m %p cmd %p size %zu) = %d\n",
		i2400m, _cmd, cmd_size, (int) result);
	return result;
}
Esempio n. 17
0
static int brcmf_sdiod_skbuff_write(struct brcmf_sdio_dev *sdiodev,
				    struct sdio_func *func, u32 addr,
				    struct sk_buff *skb)
{
	unsigned int req_sz;
	int err;

	/* Single skb use the standard mmc interface */
	req_sz = skb->len + 3;
	req_sz &= (uint)~3;

	err = sdio_memcpy_toio(func, addr, ((u8 *)(skb->data)), req_sz);

	if (err == -ENOMEDIUM)
		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);

	return err;
}
Esempio n. 18
0
static int ks7010_sdio_write(struct ks_wlan_private *priv, unsigned int address,
			     unsigned char *buffer, int length)
{
	struct ks_sdio_card *card;
	int rc;

	card = priv->ks_wlan_hw.sdio_card;

	if (length == 1)	/* CMD52 */
		sdio_writeb(card->func, *buffer, (unsigned int)address, &rc);
	else	/* CMD53 */
		rc = sdio_memcpy_toio(card->func, (unsigned int)address, buffer,
				      length);

	if (rc != 0)
		DPRINTK(1, "sdio error=%d size=%d\n", rc, length);

	return rc;
}
Esempio n. 19
0
static int if_sdio_send_chunk(struct iwm_priv *iwm, u8 *buf, int count)
{
	struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
	int aligned_count = ALIGN(count, hw->blk_size);
	int ret;

	if ((unsigned long)buf & 0x3) {
		IWM_ERR(iwm, "buf <%p> is not dword aligned\n", buf);
		/* TODO: Is this a hardware limitation? use get_unligned */
		return -EINVAL;
	}

	sdio_claim_host(hw->func);
	ret = sdio_memcpy_toio(hw->func, IWM_SDIO_DATA_ADDR, buf,
			       aligned_count);
	sdio_release_host(hw->func);

	return ret;
}
Esempio n. 20
0
INT	hwDeviceWakeup(PMINIPORT_ADAPTER pAdapter)
{
	CHAR str[] = "WAKE";
	UCHAR	nCount = 0;
	int nRet = 0;
	
	ENTER;
	do {
		nRet = sdio_memcpy_toio(pAdapter->func, SDIO_DATA_PORT_REG, str, 4);	
		nCount++;
		DumpDebug(HARDWARE, "device wakeup fail..");
	}while((nRet) && (!pAdapter->bHaltPending) && (nCount < HARDWARE_WAKE_MAX_COUNTER) );

	if(nRet) {
		DumpDebug(HARDWARE, "Retry wake-up sequence");
		msleep(HARDWARE_WAKEUP_TIMEOUT);
	}
	LEAVE;
	return nRet;
}
Esempio n. 21
0
unsigned int SendDataOut(MINIPORT_ADAPTER *Adapter, PBUFFER_DESCRIPTOR dsc)
{
	int nRet = 0;
	//ENTER;
	// sangam dbg : For control packet padding
	dsc->data.Length  += (dsc->data.Length & 1) ? 1: 0;
	
	//DumpDebug(MP_SEND, "sangam dbg  before padding len = %ld", dsc->data.Length);
#ifdef HARDWARE_USE_ALIGN_HEADER
	if(dsc->data.Length > SDIO_MAX_BYTE_SIZE)
		dsc->data.Length = (dsc->data.Length +(SDIO_MAX_BYTE_SIZE)) & ~(SDIO_MAX_BYTE_SIZE); //DF03 modify the right padding size 
#endif

	if (Adapter->bHaltPending) {
		DumpDebug(DRV_ENTRY, "Halted Already");
		return STATUS_UNSUCCESSFUL;
	}
	nRet = sdio_memcpy_toio(Adapter->func, SDIO_DATA_PORT_REG, dsc->Buffer, dsc->data.Length);	
	if(nRet < 0) {
		DumpDebug(DRV_ENTRY,"SendOut but error occurred!! nRet = %d",nRet);
	}
	//else	
	//	DumpDebug(DRV_ENTRY, "Tx length = %ld",dsc->data.Length);
#if 0
	{
	    // dump packets
		UINT i;
		PUCHAR  b = (PUCHAR)dsc->Buffer;
		DumpDebug(MP_SEND, "Sent packet LEN = %ld\n", dsc->data.Length);
	    DumpDebug(MP_SEND, "Sent packet = ");
	    for (i = 0; i < dsc->data.Length; i++) {
		DumpDebug(MP_SEND, "%02x", b[i]);
		if (i != (dsc->data.Length - 1)) DumpDebug(MP_SEND, ",");
		if ((i != 0) && ((i%32) == 0)) DumpDebug(MP_SEND, "\n");
	    }
	    DumpDebug(MP_SEND, "\n");
	}
#endif
	//LEAVE;
	return nRet;
}
Esempio n. 22
0
/*
 * Use CMD53 to write data to SDIO device.
 * This function MUST be called after sdio_claim_host() or
 * in SDIO ISR(host had been claimed).
 *
 * Parameters:
 *	psdio	pointer of SDIO_DATA
 *	addr	address to write
 *	cnt		amount to write
 *	pdata	data pointer, this should be a "DMA:able scratch buffer"!
 *
 * Return:
 *	0		Success
 *	others	Fail
 */
s32 _chris_sd_write(struct sdio_func *func, u32 addr, u32 cnt, void *pdata)
{
	
	struct sdio_func *pfunc;
	u32 size;
	s32 err=-EPERM;
	
_func_enter_;
	
	pfunc = func;
//	size = sdio_align_size(func, cnt);
	printk("%s()==> cnt is %d\n", __FUNCTION__, cnt);	
	if (unlikely((cnt==1) || (cnt==2)))
	{
		int i;
		u8 *pbuf = (u8*)pdata;
	
		for (i = 0; i < cnt; i++)
		{
//			sdio_writeb(pfunc, *(pbuf+i), addr+i, &err);
			if (err) {
				printk("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, *(pbuf+i));
				break;
			}
		}
	
		return err;
	}
	
	size = cnt;
	printk("%s(): write to addr 0x%x\n", __func__, addr);
	printk("%s(): write size %d\n", __func__, size);
	err = sdio_memcpy_toio(pfunc, addr, pdata, size);
	if (err) {
		printk("%s: FAIL(%d)! ADDR=%#x Size=%d(%d)\n", __func__, err, addr, cnt, size);
	}
	
_func_exit_;
	
	return err;
}
Esempio n. 23
0
// used only during firmware download
unsigned int sd_send(MINIPORT_ADAPTER *Adapter, UCHAR* pBuffer, UINT cbBuffer)
{
	int nRet = 0;
	PUCHAR buf = (PUCHAR) pBuffer;
	UINT size=cbBuffer;
//	UINT remainder=0;

	cbBuffer  += (cbBuffer & 1) ? 1: 0;

	if (Adapter->bHaltPending || Adapter->SurpriseRemoval) {
		DumpDebug(FW_DNLD, "Halted Already");
		return STATUS_UNSUCCESSFUL;
	}
	
	nRet = sdio_memcpy_toio(Adapter->func, SDIO_DATA_PORT_REG, pBuffer, cbBuffer);

	if(nRet < 0) {
		DumpDebug(FW_DNLD,"SendOut but error occurred!! nRet = %d",nRet);
	}
//	else	
	//	DumpDebug(FW_DNLD, "Tx length = %d",cbBuffer);

#if 0
		{
	    	// dump packets
			UINT i;
			PUCHAR  b = (PUCHAR)pBuffer;
			DumpDebug(MP_SEND, "Sent packet LEN = %ld\n",cbBuffer);
	    		DumpDebug(MP_SEND, "Sent packet = ");
	    		for (i = 0; i < cbBuffer; i++) {
				DumpDebug(MP_SEND, "%02x", b[i]);
				if (i != (cbBuffer - 1)) printk(",");
				if ((i != 0) && ((i%32) == 0)) printk("\n");
	    		}
	    		DumpDebug(MP_SEND, "\n");
		}
#endif

	return nRet;
}
Esempio n. 24
0
/*
 * Use CMD53 to write data to SDIO device.
 * This function MUST be called after sdio_claim_host() or
 * in SDIO ISR(host had been claimed).
 *
 * Parameters:
 *	psdio	pointer of SDIO_DATA
 *	addr	address to write
 *	cnt		amount to write
 *	pdata	data pointer, this should be a "DMA:able scratch buffer"!
 *
 * Return:
 *	0		Success
 *	others	Fail
 */
s32 _sd_write(PSDIO_DATA psdio, u32 addr, u32 cnt, void *pdata)
{
	int err;
	struct sdio_func *func;
	u32 size;

_func_enter_;

	func = psdio->func;
//	size = sdio_align_size(func, cnt);

	if (unlikely((cnt==1) || (cnt==2)))
	{
		int i;
		u8 *pbuf = (u8*)pdata;

		for (i = 0; i < cnt; i++)
		{
			sdio_writeb(func, *(pbuf+i), addr+i, &err);
			if (err) {
				DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, *(pbuf+i));
				break;
			}
		}

		return err;
	}

	size = cnt;
	err = sdio_memcpy_toio(func, addr, pdata, size);
	if (err) {
		DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR=%#x Size=%d(%d)\n", __func__, err, addr, cnt, size);
	}

_func_exit_;

	return err;
}
Esempio n. 25
0
static int __must_check wl12xx_sdio_raw_write(struct device *child, int addr,
					      void *buf, size_t len, bool fixed)
{
	int ret;
	struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
	struct sdio_func *func = dev_to_sdio_func(glue->dev);

	sdio_claim_host(func);

	if (unlikely(dump)) {
		printk(KERN_DEBUG "wlcore_sdio: WRITE to 0x%04x\n", addr);
		print_hex_dump(KERN_DEBUG, "wlcore_sdio: WRITE ",
				DUMP_PREFIX_OFFSET, 16, 1,
				buf, len, false);
	}

	if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
		sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
		dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n",
			addr, ((u8 *)buf)[0]);
	} else {
		dev_dbg(child->parent, "sdio write 53 addr 0x%x, %zu bytes\n",
			addr, len);

		if (fixed)
			ret = sdio_writesb(func, addr, buf, len);
		else
			ret = sdio_memcpy_toio(func, addr, buf, len);
	}

	sdio_release_host(func);

	if (WARN_ON(ret))
		dev_err(child->parent, "sdio write failed (%d)\n", ret);

	return ret;
}
Esempio n. 26
0
static int
brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
			   uint write, uint func, uint addr,
			   struct sk_buff *pkt)
{
	bool fifo = (fix_inc == SDIOH_DATA_FIX);
	u32 SGCount = 0;
	int err_ret = 0;

	struct sk_buff *pnext;

	brcmf_dbg(TRACE, "Enter\n");

	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_packet_wait);
	if (brcmf_pm_resume_error(sdiodev))
		return -EIO;

	/* Claim host controller */
	sdio_claim_host(sdiodev->func[func]);
	for (pnext = pkt; pnext; pnext = pnext->next) {
		uint pkt_len = pnext->len;
		pkt_len += 3;
		pkt_len &= 0xFFFFFFFC;

		if ((write) && (!fifo)) {
			err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
						   ((u8 *) (pnext->data)),
						   pkt_len);
		} else if (write) {
			err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
						   ((u8 *) (pnext->data)),
						   pkt_len);
		} else if (fifo) {
			err_ret = sdio_readsb(sdiodev->func[func],
					      ((u8 *) (pnext->data)),
					      addr, pkt_len);
		} else {
			err_ret = sdio_memcpy_fromio(sdiodev->func[func],
						     ((u8 *) (pnext->data)),
						     addr, pkt_len);
		}

		if (err_ret) {
			brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
				  write ? "TX" : "RX", pnext, SGCount, addr,
				  pkt_len, err_ret);
		} else {
			brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
				  write ? "TX" : "RX", pnext, SGCount, addr,
				  pkt_len);
		}

		if (!fifo)
			addr += pkt_len;
		SGCount++;

	}

	/* Release host controller */
	sdio_release_host(sdiodev->func[func]);

	brcmf_dbg(TRACE, "Exit\n");
	return err_ret;
}
Esempio n. 27
0
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;
}
Esempio n. 28
0
uint sdbus_write_reg_int(struct intf_priv *pintfpriv, u32 addr, u32 cnt, void *pdata)
{
	struct dvobj_priv *pdvobjpriv = (struct dvobj_priv*)pintfpriv->intf_dev;
	struct sdio_func *func = pdvobjpriv->func;
	int status;
#ifdef CONFIG_IO_4B
	u32 addr_org = addr, addr_offset = 0;
	u32 cnt_org = cnt;
	void *pdata_org = pdata;
#endif

_func_enter_;

#ifdef CONFIG_IO_4B
	addr_offset = addr % 4;
	if (addr_offset) {
		addr = addr - addr_offset;
		cnt = cnt + addr_offset;
	}
	if (cnt % 4)
		cnt = ((cnt + 4) >> 2) << 2;
	if (cnt != cnt_org) {
		pdata = rtw_malloc(cnt);
		if (pdata == NULL) {
			RT_TRACE(_module_hci_ops_os_c_, _drv_emerg_,
				 ("SDIO_STATUS_NO_RESOURCES - rtw_malloc fail\n"));
			return _FAIL;
		}
		status = sdio_memcpy_fromio(func, pdata, addr&0x1FFFF, cnt);
		if (status) {
			RT_TRACE(_module_hci_ops_os_c_,_drv_emerg_,
				 ("sdbus_write_reg_int read failed 0x%x\n "
				  "***** Addr = %x *****\n"
				  "***** Length = %d *****\n", status, addr, cnt));
			rtw_mfree(pdata, cnt);
			return _FAIL;
		}
		_rtw_memcpy(pdata + addr_offset, pdata_org, cnt_org);
		/* if data been modify between this read and write, may cause a problem */
	}
#endif
	status = sdio_memcpy_toio(func, addr&0x1FFFF, pdata, cnt);
	if (status) {
		//error
		RT_TRACE(_module_hci_ops_os_c_, _drv_emerg_,
			 ("sdbus_write_reg_int failed 0x%x\n"
			  "***** Addr = %x *****\n"
			  "***** Length = %d *****\n", status, addr, cnt));

		status = _FAIL;
	} else
		status = _SUCCESS;

#ifdef CONFIG_IO_4B
	if (cnt != cnt_org)
		rtw_mfree(pdata, cnt);
#endif

_func_exit_;

	return status;
}
Esempio n. 29
0
static inline int __iwmct_tx(struct iwmct_priv *priv, void *src, int count)
{
	return sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, src, count);

}
Esempio n. 30
0
int bcmsdio_cmd53(unsigned int offset, int rw, int func, int blk_mode, int opcode, int buflen, char *buff)
{
	struct sdio_func *function = func_data[BCM_SDIO_FN1]->func;
	int ret = -1;
	int count = 0;

	if (function == NULL) {
		BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ***Error: %s %d ***\n", __func__, __LINE__);
		return -ENON_INTF_ERR;
	}

	sdio_claim_host(function);
	if(func_data[BCM_SDIO_FN1]->bremoved) {
		ret = -ENON_INTF_ERR;
		BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT "Error :%s,%d removed flag var is non-zero :%d \n", __func__, __LINE__,func_data[BCM_SDIO_FN1]->bremoved);
		goto rel_host;
	}

	/* NOTE: blk_mode is not used here. If buflen exceeds corresponding 
	 * block size then SDIO stack will internally convert the request to 
	 * block req
	 * */
	if(buflen%4) {
		int i;
		
		/* Some SDIO controllers don't like CMD53 for 
 		 * request len not-multiple of 4. */
		ret = 0;
		for(i=0; i<buflen; i++) {

			buff[i] = bcmsdio_cmd52_nolock(buff[i], offset, rw, func,&ret);
			if(ret) {
				BCM_DEBUG_PRINT(debuglevel, "FAILED IN INDEX: %d for CMD52 %d rw: %x addr: %x\n", i, ret, rw, offset);
				goto rel_host;
			} else {
				if(opcode) 
					offset++;
			}
		}
	}
	else 
	{
		while( count < SDIO_CMD_RETRIES )
		{
			if(func != BCM_SDIO_FN0)
			{
				if (rw) {
					if (opcode)
						ret = sdio_memcpy_toio(function, offset, buff, buflen);
					else
						ret = sdio_writesb(function, offset, buff, buflen);
				} else {
					if (opcode)
						ret = sdio_memcpy_fromio(function, buff, offset, buflen);
					else
						ret = sdio_readsb(function, buff, offset, buflen);
				}
			}
			else
			{
				ret = bcm_sdio_cmd53(function,rw,offset,opcode,buff,buflen,BCM_SDIO_FN0_BLK_SIZE);
			}

			if(!ret)
				break;
			
			count++;
		}
		
		if(count)
			BCM_DEBUG_PRINT(debuglevel, "Count is higher than 0 for cmd53: %x\n", count);
		
		if(ret)
			BCM_DEBUG_PRINT(debuglevel, "FAILED IN CMD53 %d rw: %x addr: %x count: %x\n", ret, rw, offset, count);
	}
	//BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "cmd53-fn-%d-%d: addr:x%x w:x%x sz:x%x ret:x%x\n", func, function->num, offset, rw, buflen, ret);
rel_host:
	sdio_release_host(function);

	return ret;
}