Beispiel #1
0
static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
{
	struct rmnet_ctrl_port *port =
			container_of(w, struct rmnet_ctrl_port, connect_w);
	struct smd_ch_info *c = &port->ctrl_ch;
	unsigned long flags;
	int ret;

	pr_debug("%s:\n", __func__);

	if (!test_bit(CH_READY, &c->flags))
		return;

	ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
	if (ret) {
		pr_err("%s: Unable to open smd ch:%s err:%d\n",
				__func__, c->name, ret);
		return;
	}

	spin_lock_irqsave(&port->port_lock, flags);
	if (port->port_usb)
		smd_tiocmset(c->ch, c->cbits_tomodem, ~c->cbits_tomodem);
	spin_unlock_irqrestore(&port->port_lock, flags);
}
static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
{
	struct rmnet_ctrl_port *port =
			container_of(w, struct rmnet_ctrl_port, connect_w.work);
	struct smd_ch_info *c = &port->ctrl_ch;
	unsigned long flags;
	int ret;

	pr_debug("%s:\n", __func__);

	if (!test_bit(CH_READY, &c->flags))
		return;

	ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
	if (ret) {
		if (ret == -EAGAIN) {
			/* port not ready  - retry */
			pr_debug("%s: SMD port not ready - rescheduling:%s err:%d\n",
					__func__, c->name, ret);
			queue_delayed_work(grmnet_ctrl_wq, &port->connect_w,
				msecs_to_jiffies(250));
		} else {
			pr_err("%s: unable to open smd port:%s err:%d\n",
					__func__, c->name, ret);
		}
		return;
	}

	spin_lock_irqsave(&port->port_lock, flags);
	if (port->port_usb)
		smd_tiocmset(c->ch, c->cbits_tomodem, ~c->cbits_tomodem);
	spin_unlock_irqrestore(&port->port_lock, flags);
}
Beispiel #3
0
static int smd_tty_tiocmset(struct tty_struct *tty, struct file *file,
				unsigned int set, unsigned int clear)
{
	struct smd_tty_info *info = tty->driver_data;

	return smd_tiocmset(info->ch, set, clear);
}
Beispiel #4
0
static int smd_tty_tiocmset(struct tty_struct *tty,
				unsigned int set, unsigned int clear)
{
	struct smd_tty_info *info = tty->driver_data;

	if (info->in_reset)
		return -ENETRESET;

	return smd_tiocmset(info->ch, set, clear);
}
Beispiel #5
0
static int smd_tty_tiocmset(struct tty_struct *tty,
				unsigned int set, unsigned int clear)
{
	struct smd_tty_info *info = tty->driver_data;

	if (info->in_reset)
		return -ENETRESET;

	SMD_TTY_INFO("PID %u --> %s Set: %x Clear: %x",
			current->pid, __func__, set, clear);
	return smd_tiocmset(info->ch, set, clear);
}
Beispiel #6
0
static void
gsmd_ctrl_send_cbits_tomodem(struct grmnet *gr, u8 portno, int cbits)
{
	struct rmnet_ctrl_port	*port;
	struct smd_ch_info	*c;
	int			set_bits = 0;
	int			clear_bits = 0;
	int			temp = 0;

	if (portno >= n_ports) {
		pr_err("%s: Invalid portno#%d\n", __func__, portno);
		return;
	}

	if (!gr) {
		pr_err("%s: grmnet is null\n", __func__);
		return;
	}

	port = ports[portno].port;
	cbits = cbits & ACM_CTRL_DTR;
	c = &port->ctrl_ch;

	/* host driver will only send DTR, but to have generic
	 * set and clear bit implementation using two separate
	 * checks
	 */
	if (cbits & ACM_CTRL_DTR)
		set_bits |= TIOCM_DTR;
	else
		clear_bits |= TIOCM_DTR;

	temp |= set_bits;
	temp &= ~clear_bits;

	if (temp == c->cbits_tomodem)
		return;

	c->cbits_tomodem = temp;

	if (!test_bit(CH_OPENED, &c->flags))
		return;

	pr_debug("%s: ctrl_tomodem:%d ctrl_bits:%d setbits:%d clearbits:%d\n",
			__func__, temp, cbits, set_bits, clear_bits);

	smd_tiocmset(c->ch, set_bits, clear_bits);
}
void gsmd_ctrl_disconnect(struct grmnet *gr, u8 port_num)
{
	struct rmnet_ctrl_port	*port;
	unsigned long		flags;
	struct smd_ch_info	*c;
	struct rmnet_ctrl_pkt	*cpkt;

	pr_debug("%s: grmnet:%p port#%d\n", __func__, gr, port_num);

	if (port_num >= n_rmnet_ctrl_ports) {
		pr_err("%s: invalid portno#%d\n", __func__, port_num);
		return;
	}

	if (!gr) {
		pr_err("%s: grmnet port is null\n", __func__);
		return;
	}

	port = ctrl_smd_ports[port_num].port;
	c = &port->ctrl_ch;

	spin_lock_irqsave(&port->port_lock, flags);
	port->port_usb = 0;
	gr->send_encap_cmd = 0;
	gr->notify_modem = 0;
	c->cbits_tomodem = 0;

	while (!list_empty(&c->tx_q)) {
		cpkt = list_first_entry(&c->tx_q, struct rmnet_ctrl_pkt, list);

		list_del(&cpkt->list);
		free_rmnet_ctrl_pkt(cpkt);
	}

	spin_unlock_irqrestore(&port->port_lock, flags);

	if (test_and_clear_bit(CH_OPENED, &c->flags))
		/* send dtr zero */
		smd_tiocmset(c->ch, c->cbits_tomodem, ~c->cbits_tomodem);

	if (c->ch) {
		smd_close(c->ch);
		c->ch = NULL;
	}
}
void gsmd_ctrl_disconnect(struct grmnet *gr, u8 port_num)
{
	struct rmnet_ctrl_port	*port;
	unsigned long		flags;
	struct smd_ch_info	*c;
	struct rmnet_ctrl_pkt	*cpkt;
	int clear_bits;

	pr_debug("%s: grmnet:%p port#%d\n", __func__, gr, port_num);

	if (!is_legal_port_num(port_num)) {
		pr_err("%s: Invalid port_num#%d\n", __func__, port_num);
		return;
	}

	if (!gr) {
		pr_err("%s: grmnet port is null\n", __func__);
		return;
	}

	port = ctrl_smd_ports[port_num].port;
	c = &port->ctrl_ch;

	spin_lock_irqsave(&port->port_lock, flags);
	port->port_usb = 0;
	gr->send_encap_cmd = 0;
	gr->notify_modem = 0;
	c->cbits_tomodem = 0;

	while (!list_empty(&c->tx_q)) {
		cpkt = list_first_entry(&c->tx_q, struct rmnet_ctrl_pkt, list);

		list_del(&cpkt->list);
		free_rmnet_ctrl_pkt(cpkt);
	}

	spin_unlock_irqrestore(&port->port_lock, flags);

	if (test_and_clear_bit(CH_OPENED, &c->flags)) {
		clear_bits = ~(c->cbits_tomodem | TIOCM_RTS);
		/* send dtr zero */
		smd_tiocmset(c->ch, c->cbits_tomodem, clear_bits);
	}

	queue_delayed_work(grmnet_ctrl_wq, &port->disconnect_w, 0);
}
static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
{
	struct rmnet_ctrl_port *port =
			container_of(w, struct rmnet_ctrl_port, connect_w.work);
	struct rmnet_ctrl_ports *port_entry = &ctrl_smd_ports[port->port_num];
	struct smd_ch_info *c = &port->ctrl_ch;
	unsigned long flags;
	int	set_bits = 0;
	int	clear_bits = 0;
	int ret;

	pr_debug("%s:\n", __func__);

	if (!test_bit(CH_READY, &c->flags)) {
		if (!test_bit(CH_PREPARE_READY, &c->flags)) {
			set_bit(CH_PREPARE_READY, &c->flags);
			platform_driver_register(&(port_entry->pdrv));
		}
		return;
	}

	ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
	if (ret) {
		if (ret == -EAGAIN) {
			/* port not ready  - retry */
			pr_debug("%s: SMD port not ready - rescheduling:%s err:%d\n",
					__func__, c->name, ret);
			queue_delayed_work(grmnet_ctrl_wq, &port->connect_w,
				msecs_to_jiffies(250));
		} else {
			pr_err("%s: unable to open smd port:%s err:%d\n",
					__func__, c->name, ret);
		}
		return;
	}

	set_bits = c->cbits_tomodem;
	clear_bits = ~(c->cbits_tomodem | TIOCM_RTS);
	spin_lock_irqsave(&port->port_lock, flags);
	if (port->port_usb)
		smd_tiocmset(c->ch, set_bits, clear_bits);
	spin_unlock_irqrestore(&port->port_lock, flags);
}
Beispiel #10
0
static long smd_vt_ioctl(struct file *file,
		    unsigned int cmd,
		    unsigned long arg)
{
    int ret;

    // SMD bug fix. 0811
    if((smd_vt_devp->open_count == 0) ||( smd_vt_devp->ch == 0)) return -1;

    switch (cmd) {
        case TIOCMGET:
            ret = smd_tiocmget(smd_vt_devp->ch);
            break;
        case TIOCMSET:
            ret = smd_tiocmset(smd_vt_devp->ch, arg, ~arg);
            break;
        default:
            ret = -1;
    }

    return ret;
}