int linux_sdio_cmd52(sdio_cmd52_t *cmd) { struct sdio_func *func = g_linux_wlan->wilc_sdio_func; int ret; u8 data; sdio_claim_host(func); func->num = cmd->function; if (cmd->read_write) { /* write */ if (cmd->raw) { sdio_writeb(func, cmd->data, cmd->address, &ret); data = sdio_readb(func, cmd->address, &ret); cmd->data = data; } else { sdio_writeb(func, cmd->data, cmd->address, &ret); } } else { /* read */ data = sdio_readb(func, cmd->address, &ret); cmd->data = data; } sdio_release_host(func); if (ret < 0) { PRINT_ER("wilc_sdio_cmd52..failed, err(%d)\n", ret); return 0; } return 1; }
/** sqn_load_firmware - loads firmware to card * @func: SDIO function, used to transfer data via SDIO interface, * also used to obtain pointer to device structure. * * But now the only work it does - is loading of bootstrapper to card, * because firmware is supposed to be loaded by a userspace program. */ int sqn_load_firmware(struct sdio_func *func) { int rv = 0; const struct firmware *fw = 0; //Create a local firmware_name with path to replace original global firmware_name -- Tony Wu. const char *firmware_name = "../../../data/wimax/Boot.bin"; struct sqn_sdio_card *sqn_card = sdio_get_drvdata(func); sqn_pr_enter(); sqn_pr_info("trying to find bootloader image: \"%s\"\n", firmware_name); if ((rv = request_firmware(&fw, firmware_name, &func->dev))) goto out; if (SQN_1130 == sqn_card->version) { sdio_claim_host(func); /* properly setup registers for firmware loading */ sqn_pr_dbg("setting up SQN_H_SDRAM_NO_EMR register\n"); sdio_writeb(func, 0, SQN_H_SDRAM_NO_EMR, &rv); if (rv) { sdio_release_host(func); goto out; } sqn_pr_dbg("setting up SQN_H_SDRAMCTL_RSTN register\n"); sdio_writeb(func, 1, SQN_H_SDRAMCTL_RSTN, &rv); sdio_release_host(func); if (rv) goto out; } sqn_pr_info("loading bootloader to the card...\n"); if ((rv = sqn_load_bootstrapper(func, (u8*) fw->data, fw->size))) goto out; /* boot the card */ sqn_pr_info("bootting the card...\n"); sdio_claim_host(func); // by daniel sdio_writeb(func, 1, SQN_H_CRSTN, &rv); sdio_release_host(func); // by daniel if (rv) goto out; sqn_pr_info(" done\n"); out: // To avoid kzalloc leakage in /drivers/base/firmware_class.c if (fw) { release_firmware(fw); fw = NULL; } sqn_pr_leave(); return rv; }
static int generic_write_bytes(unsigned int uFunc, unsigned int uHwAddr, unsigned char *pData, unsigned int uLen, unsigned int bIncAddr, unsigned int bMore) { unsigned int i; int ret; PDEBUG("%s: uFunc %d uHwAddr %d pData %x uLen %d\n", __func__, uFunc, uHwAddr, (unsigned int) pData, uLen); BUG_ON(uFunc != SDIO_CTRL_FUNC && uFunc != SDIO_WLAN_FUNC); for (i = 0; i < uLen; i++) { if (uFunc == 0) sdio_f0_writeb(tiwlan_func[uFunc], *pData, uHwAddr, &ret); else sdio_writeb(tiwlan_func[uFunc], *pData, uHwAddr, &ret); if (0 != ret) { printk(KERN_ERR "%s: function %d sdio error: %d\n", __func__, uFunc, ret); return -1; } pData++; if (bIncAddr) uHwAddr++; } return 0; }
void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) { PADAPTER padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; struct sdio_func *func; bool claim_needed; _func_enter_; padapter = pintfhdl->padapter; psdiodev = pintfhdl->pintf_dev; psdio = &psdiodev->intf_data; if(padapter->bSurpriseRemoved){ //DBG_871X(" %s (padapter->bSurpriseRemoved )!!!\n",__FUNCTION__); return ; } func = psdio->func; claim_needed = rtw_sdio_claim_host_needed(func); if (claim_needed) sdio_claim_host(func); sdio_writeb(func, v, addr, err); if (claim_needed) sdio_release_host(func); if (err && *err) DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v); _func_exit_; }
void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) { struct adapter *padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; struct sdio_func *func; bool claim_needed; padapter = pintfhdl->padapter; psdiodev = pintfhdl->pintf_dev; psdio = &psdiodev->intf_data; if (padapter->bSurpriseRemoved) { /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ return; } func = psdio->func; claim_needed = rtw_sdio_claim_host_needed(func); if (claim_needed) sdio_claim_host(func); sdio_writeb(func, v, addr, err); if (claim_needed) sdio_release_host(func); if (err && *err) DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, *err, addr, v); }
/* * Return: *0 Success *others Fail */ s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) { struct adapter *padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; int err = 0, i; struct sdio_func *func; padapter = pintfhdl->padapter; psdiodev = pintfhdl->pintf_dev; psdio = &psdiodev->intf_data; if (padapter->bSurpriseRemoved) { /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ return err; } func = psdio->func; for (i = 0; i < cnt; i++) { sdio_writeb(func, pdata[i], addr+i, &err); if (err) { DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, err, addr+i, pdata[i]); break; } } return err; }
/* * Setup SDIO RX * * Hooks up the IRQ handler and then enables IRQs. */ int i2400ms_rx_setup(struct i2400ms *i2400ms) { int result; struct sdio_func *func = i2400ms->func; struct device *dev = &func->dev; struct i2400m *i2400m = &i2400ms->i2400m; d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); init_waitqueue_head(&i2400ms->bm_wfa_wq); spin_lock(&i2400m->rx_lock); i2400ms->bm_wait_result = -EINPROGRESS; spin_unlock(&i2400m->rx_lock); sdio_claim_host(func); result = sdio_claim_irq(func, i2400ms_irq); if (result < 0) { dev_err(dev, "Cannot claim IRQ: %d\n", result); goto error_irq_claim; } result = 0; sdio_writeb(func, 1, I2400MS_INTR_ENABLE_ADDR, &result); if (result < 0) { sdio_release_irq(func); dev_err(dev, "Failed to enable interrupts %d\n", result); } error_irq_claim: sdio_release_host(func); d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result); return result; }
/** * @brief This function updates card reg based on the Cmd52 value in dev structure * * @param priv A pointer to bt_private structure * @param func A pointer to store func variable * @param reg A pointer to store reg variable * @param val A pointer to store val variable * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ int sd_write_cmd52_val(bt_private * priv, int func, int reg, int val) { int ret = BT_STATUS_SUCCESS; struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card; ENTER(); if (val >= 0) { /* Perform actual write only if val is provided */ sdio_claim_host(card->func); if (func) sdio_writeb(card->func, val, reg, &ret); else sdio_f0_writeb(card->func, val, reg, &ret); sdio_release_host(card->func); if (ret) { PRINTM(ERROR, "Cannot write value (0x%x) to func %d reg %d\n", val, func, reg); goto done; } priv->bt_dev.cmd52_val = val; } /* Save current func and reg for future read */ priv->bt_dev.cmd52_func = func; priv->bt_dev.cmd52_reg = reg; done: LEAVE(); return ret; }
/** @brief This function disables the host interrupts mask. * * @param priv A pointer to bt_private structure * @param mask the interrupt mask * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ static int sd_disable_host_int_mask(bt_private * priv, u8 mask) { int ret = BT_STATUS_FAILURE; u8 host_int_mask; struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card; ENTER(); /* Read back the host_int_mask register */ host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret); if (ret) goto done; /* Update with the mask and write back to the register */ host_int_mask &= ~mask; sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret); if (ret < 0) { PRINTM(WARN, "Unable to diable the host interrupt!\n"); goto done; } ret = BT_STATUS_SUCCESS; done: LEAVE(); return ret; }
void adapter_interrupt(struct sdio_func *func) { struct net_adapter *adapter = sdio_get_drvdata(func); int intrd = 0; struct buffer_descriptor *bufdsc; wake_lock_timeout(&adapter->pdata->g_cfg->wimax_rxtx_lock, 0.2 * HZ); /* read interrupt identification register and clear the interrupt */ intrd = sdio_readb(func, SDIO_INT_STATUS_REG, NULL); sdio_writeb(func, intrd, SDIO_INT_STATUS_CLR_REG, NULL); if (likely(intrd & SDIO_INT_DATA_READY)) { bufdsc = rx_packet(adapter); if (unlikely(!bufdsc)) return; spin_lock(&adapter->recv_lock); list_add_tail(&bufdsc->list, &adapter->q_recv); spin_unlock(&adapter->recv_lock); schedule_work(&adapter->receive_work); } else if (unlikely(intrd & SDIO_INT_ERROR)) { adapter->netstats.rx_errors++; pr_err("%s intrd = SDIO_INT_ERROR occurred", __func__); } }
/*----------------------------------------------------------------------------*/ BOOL kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData) { int ret = 0; #if (MTK_WCN_HIF_SDIO == 0) if (!in_interrupt) { sdio_claim_host(prGlueInfo->rHifInfo.func); } sdio_writeb(prGlueInfo->rHifInfo.func, ucData, u4Addr, &ret); if (!in_interrupt) { sdio_release_host(prGlueInfo->rHifInfo.func); } #else ret = mtk_wcn_hif_sdio_writeb(prGlueInfo->rHifInfo.cltCtx, u4Addr, ucData); #endif if (ret) { kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_writeb() reports error: %x", ret); DBGLOG(HAL, ERROR, ("sdio_writeb() reports error: %x", ret)); } return (ret) ? FALSE : TRUE; } /* end of kalDevWriteWithSdioCmd52() */
static int msdc_ettagent_write(struct msdc_host *host, unsigned int u4Addr, unsigned int u4Func, void *pBuffer, unsigned int u4Len, unsigned int u4Cmd) { int ret = 0; u8 *value = (u8 *) pBuffer; struct sdio_func *sdioFunc; if((pBuffer==NULL) || (host==NULL)) { printk("[%s] pBuffer = %p, host = %p\n", __func__, pBuffer, host); return -1; } if( ((u4Cmd == 53) && (u4Len < 4)) || ((u4Cmd == 52) && (u4Len > 1)) ) { printk("[%s] u4Cmd = %d, u4Len = %d\n", __func__, u4Cmd, u4Len); return -1; } sdioFunc = host->mmc->card->sdio_func[u4Func - 1]; //sdio_claim_host(sdioFunc); if(u4Cmd == 53) ret = sdio_writesb(sdioFunc, u4Addr, pBuffer, u4Len); else if(u4Cmd == 52) sdio_writeb(sdioFunc, *value, u4Addr, &ret); else { printk("[%s] Doesn't support u4Cmd = %d\n", __func__, u4Cmd); ret = -1; } //sdio_release_host(sdioFunc); return ret; }
/* * Return: * 0 Success * others Fail */ s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) { PADAPTER padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; int err=0, i; struct sdio_func *func; _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; for (i = 0; i < cnt; i++) { sdio_writeb(func, pdata[i], addr+i, &err); if (err) { DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr+i, pdata[i]); break; } } _func_exit_; return err; }
/* * Process an interrupt from the SDIO card * * FIXME: need to process other events that are not just ready-to-read * * Checks there is data ready and then proceeds to read it. */ static void i2400ms_irq(struct sdio_func *func) { int ret; struct i2400ms *i2400ms = sdio_get_drvdata(func); struct i2400m *i2400m = &i2400ms->i2400m; struct device *dev = &func->dev; int val; d_fnstart(6, dev, "(i2400ms %p)\n", i2400ms); val = sdio_readb(func, I2400MS_INTR_STATUS_ADDR, &ret); if (ret < 0) { dev_err(dev, "RX: Can't read interrupt status: %d\n", ret); goto error_no_irq; } if (!val) { dev_err(dev, "RX: BUG? got IRQ but no interrupt ready?\n"); goto error_no_irq; } sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret); if (WARN_ON(i2400m->boot_mode != 0)) dev_err(dev, "RX: SW BUG? boot mode and IRQ is up?\n"); else i2400ms_rx(i2400ms); error_no_irq: d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms); return; }
int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, uint regaddr, u8 *byte) { int err_ret; brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); if (brcmf_pm_resume_error(sdiodev)) return -EIO; if (rw && func == 0) { /* handle F0 separately */ err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte); } else { sdio_claim_host(sdiodev->func[func]); if (rw) /* CMD52 Write */ sdio_writeb(sdiodev->func[func], *byte, regaddr, &err_ret); else if (func == 0) { *byte = sdio_f0_readb(sdiodev->func[func], regaddr, &err_ret); } else { *byte = sdio_readb(sdiodev->func[func], regaddr, &err_ret); } sdio_release_host(sdiodev->func[func]); } if (err_ret) brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", rw ? "write" : "read", func, regaddr, *byte, err_ret); return err_ret; }
/** * @brief This function writes data into card register * * @param handle A Pointer to the moal_handle structure * @param reg Register offset * @param data Value * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status woal_write_reg(moal_handle * handle, t_u32 reg, t_u32 data) { mlan_status ret = MLAN_STATUS_FAILURE; sdio_writeb(((struct sdio_mmc_card *) handle->card)->func, (t_u8) data, reg, (int *) &ret); return ret; }
/** * @brief This function handles the interrupt. * * @param func A pointer to sdio_func structure * @return N/A */ static void sd_interrupt(struct sdio_func *func) { bt_private *priv; struct m_dev *m_dev = NULL; struct sdio_mmc_card *card; int ret = BT_STATUS_SUCCESS; u8 ireg = 0; u8 host_intstatus_reg = HOST_INTSTATUS_REG; ENTER(); card = sdio_get_drvdata(func); if (!card || !card->priv) { PRINTM(INFO, "BT: %s: sbi_interrupt(%p) card or priv is NULL, card=%p\n", __func__, func, card); LEAVE(); return; } priv = card->priv; m_dev = &(priv->bt_dev.m_dev[BT_SEQ]); ireg = sdio_readb(card->func, host_intstatus_reg, &ret); if (ret) { PRINTM(ERROR, "BT: sdio_read_ioreg: CMD52 read int status register failed %d\n", ret); goto done; } if (ireg != 0) { /* * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS * Clear the interrupt status register and re-enable * the interrupt */ PRINTM(INTR, "BT: INT %s: sdio_ireg = 0x%x\n", m_dev->name, ireg); priv->adapter->irq_recv = ireg; sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS), host_intstatus_reg, &ret); if (ret) { PRINTM(ERROR, "BT: sdio_write_ioreg: clear int status register failed\n"); goto done; } } else { PRINTM(ERROR, "BT: ERR: ireg=0\n"); } OS_INT_DISABLE; priv->adapter->sd_ireg |= ireg; OS_INT_RESTORE; bt_interrupt(m_dev); done: LEAVE(); }
/* Write single byte to device address (CMD52) */ static int ks7010_sdio_writeb(struct ks_wlan_private *priv, unsigned int address, unsigned char byte) { struct sdio_func *func = priv->ks_sdio_card->func; int ret; sdio_writeb(func, byte, address, &ret); return ret; }
/* Only writes to the vendor specific CCCR registers * (0xF0 - 0xFF) are permiited. */ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, int *err_ret) { if (addr < 0xF0 || addr > 0xFF) { if (err_ret) *err_ret = -EINVAL; return; } sdio_writeb(func, b, addr, err_ret); }
static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, uint regaddr, u8 *byte) { struct sdio_func *sdfunc = sdiodev->func[0]; int err_ret; /* * Can only directly write to some F0 registers. * Handle F2 enable/disable and Abort command * as a special case. */ if (regaddr == SDIO_CCCR_IOEx) { sdfunc = sdiodev->func[2]; if (sdfunc) { sdio_claim_host(sdfunc); if (*byte & SDIO_FUNC_ENABLE_2) { /* Enable Function 2 */ err_ret = sdio_enable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "enable F2 failed:%d\n", err_ret); } else { /* Disable Function 2 */ err_ret = sdio_disable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "Disable F2 failed:%d\n", err_ret); } sdio_release_host(sdfunc); } } else if ((regaddr == SDIO_CCCR_ABORT) || (regaddr == SDIO_CCCR_IENx)) { sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), GFP_KERNEL); if (!sdfunc) return -ENOMEM; sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; } else { sdio_claim_host(sdfunc); sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); } return err_ret; }
/* host claimed */ static int ssb_sdio_writeb(struct ssb_bus *bus, unsigned int addr, u8 val) { int error = 0; sdio_writeb(bus->host_sdio, val, addr, &error); if (unlikely(error)) { dev_dbg(ssb_sdio_dev(bus), "%08X <- %02x, error %d\n", addr, val, error); } return error; }
static int mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data) { struct sdio_mmc_card *card = adapter->card; int ret = -1; sdio_claim_host(card->func); sdio_writeb(card->func, (u8) data, reg, &ret); sdio_release_host(card->func); return ret; }
/** * @brief This function updates card reg based on the Cmd52 value in dev structure * * @param priv A pointer to bt_private structure * @param reg register to write * @param val value * @return BT_STATUS_SUCCESS or other error no. */ int sd_write_reg(bt_private *priv, int reg, u8 val) { int ret = BT_STATUS_SUCCESS; struct sdio_mmc_card *card = (struct sdio_mmc_card *)priv->bt_dev.card; ENTER(); sdio_claim_host(card->func); sdio_writeb(card->func, val, reg, &ret); sdio_release_host(card->func); LEAVE(); return ret; }
static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val) { int ret = 0; struct sdio_func *func = wl_to_func(wl); sdio_claim_host(func); sdio_writeb(func, val, addr, &ret); sdio_release_host(func); if (ret) wl1251_error("sdio_writeb failed (%d)", ret); }
void sdio_io_writeb(struct esp_pub *epub, u8 value, int addr, int *res) { struct esp_sdio_ctrl *sctrl = NULL; struct sdio_func *func = NULL; sctrl = (struct esp_sdio_ctrl *)epub->sif; func = sctrl->func; if(func->num == 0) sdio_f0_writeb(func, value, addr, res); else sdio_writeb(func, value, addr, res); sif_platform_check_r1_ready(epub); }
/* * Tear down SDIO RX * * Disables IRQs in the device and removes the IRQ handler. */ void i2400ms_rx_release(struct i2400ms *i2400ms) { int result; struct sdio_func *func = i2400ms->func; struct device *dev = &func->dev; d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); sdio_claim_host(func); sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result); sdio_release_irq(func); sdio_release_host(func); d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result); }
int bcmsdio_cmd52(unsigned int data, unsigned addr, unsigned rw, unsigned func,int *perrval) { struct sdio_func *function = func_data[BCM_SDIO_FN1]->func; int ret = data; int count = 0; *perrval = 0; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ** NULL FUNC PTR: x%x\n", func); 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: bremoved is non zero :%d", func_data[BCM_SDIO_FN1]->bremoved); goto rel_host; } while ( count < SDIO_CMD_RETRIES ) { if (rw) { if(func != BCM_SDIO_FN0) sdio_writeb(function, data, addr,perrval); else sdio_f0_writeb(function, data, addr,perrval); } else { if(func != 0 ) ret = sdio_readb(function, addr,perrval); else ret = sdio_f0_readb(function,addr,perrval); } if(!(*perrval)) break; count++; } if(count) BCM_DEBUG_PRINT(debuglevel, "Count is higher than 0 for cmd52: %x\n", count); if(*perrval) { BCM_DEBUG_PRINT(debuglevel, "ERR IN CMD52 %d rw: %x addr: %x, count: %x\n", *perrval, rw, addr, count); } rel_host: sdio_release_host(function); return 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; }
/** * @brief This function writes data into card register * * @param handle A Pointer to the moal_handle structure * @param reg Register offset * @param data Value * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status woal_write_reg(moal_handle *handle, t_u32 reg, t_u32 data) { mlan_status ret = MLAN_STATUS_FAILURE; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_claim_host(((struct sdio_mmc_card *)handle->card)->func); #endif sdio_writeb(((struct sdio_mmc_card *)handle->card)->func, (t_u8)data, reg, (int *)&ret); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_release_host(((struct sdio_mmc_card *)handle->card)->func); #endif return ret; }
/** * @brief This function handles the interrupt. * * @param func A pointer to sdio_func structure * @return n/a */ static void sd_interrupt(struct sdio_func *func) { bt_private *priv; struct hci_dev *hcidev; struct sdio_mmc_card *card; int ret = BT_STATUS_SUCCESS; u8 ireg = 0; ENTER(); card = sdio_get_drvdata(func); if (!card || !card->priv) { PRINTM(INFO, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n", __FUNCTION__, func, card); LEAVE(); return; } priv = card->priv; hcidev = priv->bt_dev.hcidev; ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); if (ret) { PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n"); goto done; } if (ireg != 0) { /* * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS * Clear the interrupt status register and re-enable the interrupt */ PRINTM(INTR, "INT dev%d: sdio_ireg = 0x%x\n", hcidev->id, ireg); priv->adapter->irq_recv = ireg; sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS), HOST_INTSTATUS_REG, &ret); if (ret) { PRINTM(WARN, "sdio_write_ioreg: clear int status register failed\n"); goto done; } } OS_INT_DISABLE; priv->adapter->sd_ireg |= ireg; OS_INT_RESTORE; bt_interrupt(hcidev); done: LEAVE(); }