Exemplo n.º 1
0
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);
		}
	}
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/**
 * @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;
}