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); }
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); }
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); }
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); }
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); }
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; }