⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interface.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -