📄 interface.c
字号:
if (!cs->open_count) warn("%s: device not opened", __func__); else if (atomic_read(&cs->mstate) != MS_LOCKED) { warn("can't write to unlocked device"); retval = -EBUSY; } else if (!cs->connected) { gig_dbg(DEBUG_ANY, "can't write to unplugged device"); retval = -EBUSY; //FIXME } else { retval = cs->ops->write_cmd(cs, buf, count, &cs->if_wake_tasklet); } mutex_unlock(&cs->mutex); return retval;}static int if_write_room(struct tty_struct *tty){ struct cardstate *cs; int retval = -ENODEV; cs = (struct cardstate *) tty->driver_data; if (!cs) { err("cs==NULL in %s", __func__); return -ENODEV; } gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); if (mutex_lock_interruptible(&cs->mutex)) return -ERESTARTSYS; // FIXME -EINTR? if (!cs->open_count) warn("%s: device not opened", __func__); else if (atomic_read(&cs->mstate) != MS_LOCKED) { warn("can't write to unlocked device"); retval = -EBUSY; //FIXME } else if (!cs->connected) { gig_dbg(DEBUG_ANY, "can't write to unplugged device"); retval = -EBUSY; //FIXME } else retval = cs->ops->write_room(cs); mutex_unlock(&cs->mutex); return retval;}static int if_chars_in_buffer(struct tty_struct *tty){ struct cardstate *cs; int retval = -ENODEV; cs = (struct cardstate *) tty->driver_data; if (!cs) { err("cs==NULL in %s", __func__); return -ENODEV; } gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); if (mutex_lock_interruptible(&cs->mutex)) return -ERESTARTSYS; // FIXME -EINTR? if (!cs->open_count) warn("%s: device not opened", __func__); else if (atomic_read(&cs->mstate) != MS_LOCKED) { warn("can't write to unlocked device"); retval = -EBUSY; } else if (!cs->connected) { gig_dbg(DEBUG_ANY, "can't write to unplugged device"); retval = -EBUSY; //FIXME } else retval = cs->ops->chars_in_buffer(cs); mutex_unlock(&cs->mutex); return retval;}static void if_throttle(struct tty_struct *tty){ struct cardstate *cs; cs = (struct cardstate *) tty->driver_data; if (!cs) { err("cs==NULL in %s", __func__); return; } gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); mutex_lock(&cs->mutex); if (!cs->open_count) warn("%s: device not opened", __func__); else { //FIXME } mutex_unlock(&cs->mutex);}static void if_unthrottle(struct tty_struct *tty){ struct cardstate *cs; cs = (struct cardstate *) tty->driver_data; if (!cs) { err("cs==NULL in %s", __func__); return; } gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); mutex_lock(&cs->mutex); if (!cs->open_count) warn("%s: device not opened", __func__); else { //FIXME } mutex_unlock(&cs->mutex);}static void if_set_termios(struct tty_struct *tty, struct ktermios *old){ struct cardstate *cs; unsigned int iflag; unsigned int cflag; unsigned int old_cflag; unsigned int control_state, new_state; cs = (struct cardstate *) tty->driver_data; if (!cs) { err("cs==NULL in %s", __func__); return; } gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); mutex_lock(&cs->mutex); if (!cs->open_count) { warn("%s: device not opened", __func__); goto out; } if (!cs->connected) { gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); goto out; } // stolen from mct_u232.c iflag = tty->termios->c_iflag; cflag = tty->termios->c_cflag; old_cflag = old ? old->c_cflag : cflag; //FIXME? gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", cs->minor_index, iflag, cflag, old_cflag); /* get a local copy of the current port settings */ control_state = cs->control_state; /* * Update baud rate. * Do not attempt to cache old rates and skip settings, * disconnects screw such tricks up completely. * Premature optimization is the root of all evil. */ /* reassert DTR and (maybe) RTS on transition from B0 */ if ((old_cflag & CBAUD) == B0) { new_state = control_state | TIOCM_DTR; /* don't set RTS if using hardware flow control */ if (!(old_cflag & CRTSCTS)) new_state |= TIOCM_RTS; gig_dbg(DEBUG_IF, "%u: from B0 - set DTR%s", cs->minor_index, (new_state & TIOCM_RTS) ? " only" : "/RTS"); cs->ops->set_modem_ctrl(cs, control_state, new_state); control_state = new_state; } cs->ops->baud_rate(cs, cflag & CBAUD); if ((cflag & CBAUD) == B0) { /* Drop RTS and DTR */ gig_dbg(DEBUG_IF, "%u: to B0 - drop DTR/RTS", cs->minor_index); new_state = control_state & ~(TIOCM_DTR | TIOCM_RTS); cs->ops->set_modem_ctrl(cs, control_state, new_state); control_state = new_state; } /* * Update line control register (LCR) */ cs->ops->set_line_ctrl(cs, cflag);#if 0 //FIXME this hangs M101 [ts 2005-03-09] //FIXME do we need this? /* * Set flow control: well, I do not really now how to handle DTR/RTS. * Just do what we have seen with SniffUSB on Win98. */ /* Drop DTR/RTS if no flow control otherwise assert */ gig_dbg(DEBUG_IF, "%u: control_state %x", cs->minor_index, control_state); new_state = control_state; if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) new_state |= TIOCM_DTR | TIOCM_RTS; else new_state &= ~(TIOCM_DTR | TIOCM_RTS); if (new_state != control_state) { gig_dbg(DEBUG_IF, "%u: new_state %x", cs->minor_index, new_state); gigaset_set_modem_ctrl(cs, control_state, new_state); control_state = new_state; }#endif /* save off the modified port settings */ cs->control_state = control_state;out: mutex_unlock(&cs->mutex);}/* wakeup tasklet for the write operation */static void if_wake(unsigned long data){ struct cardstate *cs = (struct cardstate *) data; if (cs->tty) tty_wakeup(cs->tty);}/*** interface to common ***/void gigaset_if_init(struct cardstate *cs){ struct gigaset_driver *drv; drv = cs->driver; if (!drv->have_tty) return; tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); mutex_lock(&cs->mutex); cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL); if (!IS_ERR(cs->tty_dev)) dev_set_drvdata(cs->tty_dev, cs); else { warn("could not register device to the tty subsystem"); cs->tty_dev = NULL; } mutex_unlock(&cs->mutex);}void gigaset_if_free(struct cardstate *cs){ struct gigaset_driver *drv; drv = cs->driver; if (!drv->have_tty) return; tasklet_disable(&cs->if_wake_tasklet); tasklet_kill(&cs->if_wake_tasklet); cs->tty_dev = NULL; tty_unregister_device(drv->tty, cs->minor_index);}void gigaset_if_receive(struct cardstate *cs, unsigned char *buffer, size_t len){ unsigned long flags; struct tty_struct *tty; spin_lock_irqsave(&cs->lock, flags); if ((tty = cs->tty) == NULL) gig_dbg(DEBUG_ANY, "receive on closed device"); else { tty_buffer_request_room(tty, len); tty_insert_flip_string(tty, buffer, len); tty_flip_buffer_push(tty); } spin_unlock_irqrestore(&cs->lock, flags);}EXPORT_SYMBOL_GPL(gigaset_if_receive);/* gigaset_if_initdriver * Initialize tty interface. * parameters: * drv Driver * procname Name of the driver (e.g. for /proc/tty/drivers) * devname Name of the device files (prefix without minor number) */void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, const char *devname){ unsigned minors = drv->minors; int ret; struct tty_driver *tty; drv->have_tty = 0; if ((drv->tty = alloc_tty_driver(minors)) == NULL) goto enomem; tty = drv->tty; tty->magic = TTY_DRIVER_MAGIC, tty->major = GIG_MAJOR, tty->type = TTY_DRIVER_TYPE_SERIAL, tty->subtype = SERIAL_TYPE_NORMAL, tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty->driver_name = procname; tty->name = devname; tty->minor_start = drv->minor; tty->num = drv->minors; tty->owner = THIS_MODULE; tty->init_termios = tty_std_termios; //FIXME tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME tty_set_operations(tty, &if_ops); ret = tty_register_driver(tty); if (ret < 0) { warn("failed to register tty driver (error %d)", ret); goto error; } gig_dbg(DEBUG_IF, "tty driver initialized"); drv->have_tty = 1; return;enomem: warn("could not allocate tty structures");error: if (drv->tty) put_tty_driver(drv->tty);}void gigaset_if_freedriver(struct gigaset_driver *drv){ if (!drv->have_tty) return; drv->have_tty = 0; tty_unregister_driver(drv->tty); put_tty_driver(drv->tty);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -