コード例 #1
0
/*
 * functions called from TTY layer
 */
static int st_tty_open(struct tty_struct *tty)
{
	int err = 0;
	struct st_data_s *st_gdata;
	pr_info("%s ", __func__);

	st_kim_ref(&st_gdata, 0);
	st_gdata->tty = tty;
	tty->disc_data = st_gdata;

	/* don't do an wakeup for now */
	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

	/* mem already allocated
	 */
	tty->receive_room = 65536;
	/* Flush any pending characters in the driver and discipline. */
	tty_ldisc_flush(tty);
	tty_driver_flush_buffer(tty);
	/*
	 * signal to UIM via KIM that -
	 * installation of N_TI_WL ldisc is complete
	 */
	st_kim_complete(st_gdata->kim_data);
	pr_debug("done %s", __func__);
	return err;
}
コード例 #2
0
ファイル: st_core.c プロジェクト: AnwariJr/Zenfone-Kernel
/*
 * called in protocol stack drivers
 * via the write function pointer
 */
long st_write(struct sk_buff *skb)
{
	struct st_data_s *st_gdata;
	long len;

	st_kim_ref(&st_gdata, 0);
	if (unlikely(skb == NULL || st_gdata == NULL
		|| st_gdata->tty == NULL)) {
		pr_err("data/tty unavailable to perform write");
		return -EINVAL;
	}

	pr_debug("%d to be written", skb->len);
	len = skb->len;

	/*
	 * Refresh inactivity timeout for Power Management protection mechanism
	 * It will prevent from S3 sleeping for a while as it is very likely
	 * some incoming data will be received soon.
	 */
	wake_lock_timeout(&st_gdata->wake_lock,
			ST_PM_PROTECT_INACTIVITY_TIMEOUT);

	/* st_ll to decide where to enqueue the skb */
	st_int_enqueue(st_gdata, skb);
	/* wake up */
	st_tx_wakeup(st_gdata);

	/* return number of bytes written */
	return len;
}
コード例 #3
0
ファイル: st_core.c プロジェクト: HuChundong/Endeavor3.1.10
/* to unregister a protocol -
 * to be called from protocol stack driver
 */
long st_unregister(struct st_proto_s *proto)
{
	long err = 0;
	unsigned long flags = 0;
	struct st_data_s	*st_gdata;

	pr_debug("%s: %d \n", __func__, proto->chnl_id);

	st_kim_ref(&st_gdata, 0);
	if (proto->chnl_id >= ST_MAX_CHANNELS) {
		pr_err(" chnl_id %d not supported\n", proto->chnl_id);
		return -EPROTONOSUPPORT;
	}

	spin_lock_irqsave(&st_gdata->lock, flags);

    if (st_gdata->is_registered[proto->chnl_id] == false) {
		pr_err(" chnl_id %d not registered\n", proto->chnl_id);
		spin_unlock_irqrestore(&st_gdata->lock, flags);
		return -EPROTONOSUPPORT;
	}

	st_gdata->protos_registered--;
	remove_channel_from_table(st_gdata, proto);
	spin_unlock_irqrestore(&st_gdata->lock, flags);

    /* paranoid check */
    if (st_gdata->protos_registered < ST_EMPTY)
        st_gdata->protos_registered = ST_EMPTY;

	if ((st_gdata->protos_registered == ST_EMPTY) &&
	    (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
		pr_info(" all chnl_ids unregistered \n");

		/* stop traffic on tty */
		if (st_gdata->tty) {
			tty_ldisc_flush(st_gdata->tty);
			stop_tty(st_gdata->tty);
		}

		/* all chnl_ids now unregistered */
		st_kim_stop(st_gdata->kim_data);

		/* disable ST LL */
		st_ll_disable(st_gdata);
	}
	return err;
}
コード例 #4
0
/*
 * called in protocol stack drivers
 * via the write function pointer
 */
long st_write(struct sk_buff *skb)
{
	struct st_data_s *st_gdata;
	long len;

	st_kim_ref(&st_gdata, 0);
	if (unlikely(skb == NULL || st_gdata == NULL
		|| st_gdata->tty == NULL)) {
		pr_err("data/tty unavailable to perform write");
		return -EINVAL;
	}

	pr_debug("%d to be written", skb->len);
	len = skb->len;

	/* st_ll to decide where to enqueue the skb */
	st_int_enqueue(st_gdata, skb);
	/* wake up */
	st_tx_wakeup(st_gdata);

	/* return number of bytes written */
	return len;
}
コード例 #5
0
ファイル: st_core.c プロジェクト: AnwariJr/Zenfone-Kernel
/*
 * functions called from TTY layer
 */
static int st_tty_open(struct tty_struct *tty)
{
	int err = 0;
	struct st_data_s *st_gdata;
	pr_info("%s ", __func__);

	st_kim_ref(&st_gdata, 0);
	st_gdata->tty = tty;
	tty->disc_data = st_gdata;

	if (tty->dev->parent)
		st_gdata->tty_dev = tty->dev->parent;
	else
		return -EINVAL;

	/* Asynchronous Get is enough here since we just want to avoid
	 * interface to be released too early
	 */
	pm_runtime_get(st_gdata->tty_dev);

	/* don't do an wakeup for now */
	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

	/* mem already allocated
	 */
	tty->receive_room = 65536;
	/* Flush any pending characters in the driver and discipline. */
	tty_ldisc_flush(tty);
	tty_driver_flush_buffer(tty);
	/*
	 * signal to UIM via KIM that -
	 * installation of N_TI_WL ldisc is complete
	 */
	st_kim_complete(st_gdata->kim_data);
	pr_debug("done %s", __func__);
	return err;
}
コード例 #6
0
/*
 * functions called from protocol stack drivers
 * to be EXPORT-ed
 */
long st_register(struct st_proto_s *new_proto)
{
	struct st_data_s	*st_gdata;
	long err = 0;
	unsigned long flags = 0;

	st_kim_ref(&st_gdata, 0);
	if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL
	    || new_proto->reg_complete_cb == NULL) {
		pr_err("gdata/new_proto/recv or reg_complete_cb not ready");
		return -EINVAL;
	}

	if (new_proto->chnl_id >= ST_MAX_CHANNELS) {
		pr_err("chnl_id %d not supported", new_proto->chnl_id);
		return -EPROTONOSUPPORT;
	}

	if (st_gdata->is_registered[new_proto->chnl_id] == true) {
		pr_err("chnl_id %d already registered", new_proto->chnl_id);
		return -EALREADY;
	}

	/* can be from process context only */
	spin_lock_irqsave(&st_gdata->lock, flags);

	if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) {
		pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->chnl_id);
		/* fw download in progress */

		add_channel_to_table(st_gdata, new_proto);
		st_gdata->protos_registered++;
		new_proto->write = st_write;

		set_bit(ST_REG_PENDING, &st_gdata->st_state);
		spin_unlock_irqrestore(&st_gdata->lock, flags);
		return -EINPROGRESS;
	} else if (st_gdata->protos_registered == ST_EMPTY) {
		pr_info(" chnl_id list empty :%d ", new_proto->chnl_id);
		set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
		st_recv = st_kim_recv;

		/* enable the ST LL - to set default chip state */
		st_ll_enable(st_gdata);

		/* release lock previously held - re-locked below */
		spin_unlock_irqrestore(&st_gdata->lock, flags);

		/* this may take a while to complete
		 * since it involves BT fw download
		 */
		err = st_kim_start(st_gdata->kim_data);
		if (err != 0) {
			clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
			if ((st_gdata->protos_registered != ST_EMPTY) &&
			    (test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
				pr_err(" KIM failure complete callback ");
				st_reg_complete(st_gdata, err);
				clear_bit(ST_REG_PENDING, &st_gdata->st_state);
			}
			return -EINVAL;
		}

		spin_lock_irqsave(&st_gdata->lock, flags);

		clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
		st_recv = st_int_recv;

		/* this is where all pending registration
		 * are signalled to be complete by calling callback functions
		 */
		if ((st_gdata->protos_registered != ST_EMPTY) &&
		    (test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
			pr_debug(" call reg complete callback ");
			st_reg_complete(st_gdata, 0);
		}
		clear_bit(ST_REG_PENDING, &st_gdata->st_state);

		/* check for already registered once more,
		 * since the above check is old
		 */
		if (st_gdata->is_registered[new_proto->chnl_id] == true) {
			pr_err(" proto %d already registered ",
				   new_proto->chnl_id);
			spin_unlock_irqrestore(&st_gdata->lock, flags);
			return -EALREADY;
		}

		add_channel_to_table(st_gdata, new_proto);
		st_gdata->protos_registered++;
		new_proto->write = st_write;
		spin_unlock_irqrestore(&st_gdata->lock, flags);
		return err;
	}
	/* if fw is already downloaded & new stack registers protocol */
	else {
		add_channel_to_table(st_gdata, new_proto);
		st_gdata->protos_registered++;
		new_proto->write = st_write;

		/* lock already held before entering else */
		spin_unlock_irqrestore(&st_gdata->lock, flags);
		return err;
	}
	pr_debug("done %s(%d) ", __func__, new_proto->chnl_id);
}