void chardev_put(struct char_dev *dev) { if (dev) { struct m_dev *m_dev = dev->m_dev; PRINTM(INFO, "dev put kobj\n"); kobject_put(&dev->kobj); if (m_dev) { bt_priv_put(m_dev->driver_data); } } }
struct kobject * chardev_get(struct char_dev *dev) { struct kobject *kobj; kobj = bt_priv_get(dev->m_dev->driver_data); if (!kobj) return NULL; PRINTM(INFO, "dev get kobj\n"); kobj = kobject_get(&dev->kobj); if (!kobj) bt_priv_put(dev->m_dev->driver_data); return kobj; }
/** * @brief request_firmware callback * * @param fw_firmware A pointer to firmware structure * @param context A Pointer to bt_private structure * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ static int sd_request_fw_dpc(const struct firmware *fw_firmware, void *context) { int ret = BT_STATUS_SUCCESS; bt_private *priv = (bt_private *)context; struct sdio_mmc_card *card = NULL; struct m_dev *m_dev_bt = NULL; struct m_dev *m_dev_fm = NULL; struct m_dev *m_dev_nfc = NULL; struct timeval tstamp; ENTER(); m_dev_bt = &priv->bt_dev.m_dev[BT_SEQ]; m_dev_fm = &priv->bt_dev.m_dev[FM_SEQ]; m_dev_nfc = &priv->bt_dev.m_dev[NFC_SEQ]; if ((priv == NULL) || (priv->adapter == NULL) || (priv->bt_dev.card == NULL) || (m_dev_bt == NULL) || (m_dev_fm == NULL) || (m_dev_nfc == NULL)) { LEAVE(); return BT_STATUS_FAILURE; } card = (struct sdio_mmc_card *)priv->bt_dev.card; if (!fw_firmware) { do_gettimeofday(&tstamp); if (tstamp.tv_sec > (priv->req_fw_time.tv_sec + REQUEST_FW_TIMEOUT)) { PRINTM(ERROR, "BT: No firmware image found. Skipping download\n"); ret = BT_STATUS_FAILURE; goto done; } PRINTM(ERROR, "BT: No firmware image found! Retrying download\n"); /* Wait a second here before calling the callback again */ os_sched_timeout(1000); sd_download_firmware_w_helper(priv); LEAVE(); return ret; } priv->firmware = fw_firmware; if (BT_STATUS_FAILURE == sd_init_fw_dpc(priv, (u8 *)priv->firmware->data, priv->firmware->size)) { PRINTM(ERROR, "BT: sd_init_fw_dpc failed (download fw with nowait: %d). Terminating download\n", bt_req_fw_nowait); sdio_release_host(card->func); ret = BT_STATUS_FAILURE; goto done; } /* check if the fimware is downloaded successfully or not */ if (sd_verify_fw_download(priv, MAX_FIRMWARE_POLL_TRIES)) { PRINTM(ERROR, "BT: FW failed to be active in time!\n"); ret = BT_STATUS_FAILURE; sdio_release_host(card->func); goto done; } sdio_release_host(card->func); sd_enable_host_int(priv); if (BT_STATUS_FAILURE == sbi_register_conf_dpc(priv)) { PRINTM(ERROR, "BT: sbi_register_conf_dpc failed. Terminating download\n"); ret = BT_STATUS_FAILURE; goto done; } if (fw_firmware) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) if (!bt_req_fw_nowait) #endif release_firmware(fw_firmware); } LEAVE(); return ret; done: if (fw_firmware) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) if (!bt_req_fw_nowait) #endif release_firmware(fw_firmware); } /* For synchronous download cleanup will be done in add_card */ if (!bt_req_fw_nowait) return ret; PRINTM(INFO, "unregister device\n"); sbi_unregister_dev(priv); ((struct sdio_mmc_card *)card)->priv = NULL; /* Stop the thread servicing the interrupts */ priv->adapter->SurpriseRemoved = TRUE; wake_up_interruptible(&priv->MainThread.waitQ); while (priv->MainThread.pid) os_sched_timeout(1); bt_proc_remove(priv); clean_up_m_devs(priv); bt_free_adapter(priv); bt_priv_put(priv); LEAVE(); return ret; }