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