Example #1
0
/*
 * function_felica_uart
 */
static ssize_t felica_uart_write(struct file *filp, const char __user *data, size_t len, loff_t *ppos)
{
	ssize_t result;
	struct file *tty;

	result = uart_write(filp, data, len, ppos);
	if (result > 0) {
		MFCUART_DRV_DBG_LOG("tty_wait_until_sent");
		tty = (struct file *)filp->private_data;
		if (tty) {
			tty_wait_until_sent(file_tty(tty), 0);
		}
	}

	return result;
}
Example #2
0
struct file *ptmx_open(int index, unsigned int flags)
{
	struct file *file;
	struct file **stack = NULL;
	int depth = 0;

	for (;;) {
		struct tty_struct *tty;

		file = filp_open("/dev/ptmx", flags|O_NONBLOCK|O_NOCTTY|O_RDWR, 0);
		if (IS_ERR(file))
			break;
		tty = file_tty(file);
		if (tty->index == index)
			break;

		if (depth == PAGE_SIZE/sizeof(struct file *)) {
			fput(file);
			file = ERR_PTR(-EBUSY);
			break;
		}
		if (stack == NULL) {
			stack = (struct file **)__get_free_page(GFP_KERNEL);
			if (!stack) {
				fput(file);
				file = ERR_PTR(-ENOMEM);
				break;
			}
		}
		stack[depth] = file;
		depth++;
	}
	while (depth > 0) {
		depth--;
		fput(stack[depth]);
	}
	if (stack)
		free_page((unsigned long)stack);
	return file;
}
Example #3
0
struct file * rst_open_tty(cpt_object_t *mntobj, char *name,
			   struct cpt_file_image *fi, struct cpt_inode_image *ii,
			   unsigned flags, struct cpt_context *ctx)
{
	int err;
	cpt_object_t *obj;
	struct file *master, *slave;
	struct tty_struct *stty;
	struct cpt_tty_image *pi;
	static char *a = "pqrstuvwxyzabcde";
	static char *b = "0123456789abcdef";
	char pairname[16];
	unsigned master_flags, slave_flags;

	if (fi->cpt_priv == CPT_NULL)
		return ERR_PTR(-EINVAL);

	obj = lookup_cpt_obj_bypos(CPT_OBJ_TTY, fi->cpt_priv, ctx);
	if (obj && obj->o_parent) {
		dprintk_ctx("obtained pty as pair to existing\n");
		master = obj->o_parent;
		stty = file_tty(master);

		if (stty->driver->subtype == PTY_TYPE_MASTER &&
		    (stty->driver->flags&TTY_DRIVER_DEVPTS_MEM)) {
			wprintk_ctx("cloning ptmx\n");
			get_file(master);
			return master;
		}

		master = dentry_open(dget(master->f_dentry),
				     mntget(master->f_vfsmnt), flags,
				     current_cred());
		if (!IS_ERR(master)) {
			stty = file_tty(master);
			if (stty->driver->subtype != PTY_TYPE_MASTER)
				fixup_tty_attrs(ii, master, ctx);
		}
		return master;
	}

	pi = cpt_get_buf(ctx);
	err = rst_get_object(CPT_OBJ_TTY, fi->cpt_priv, pi, ctx);
	if (err) {
		cpt_release_buf(ctx);
		return ERR_PTR(err);
	}

	if (MAJOR(ii->cpt_rdev) == TTY_MAJOR ||
	    ii->cpt_rdev == MKDEV(TTYAUX_MAJOR, 1)) {
		if (mntobj && (mntobj->o_flags & CPT_VFSMOUNT_DELAYFS))
		       return ERR_PTR(-ENOTSUPP);
		master = rst_open_file(mntobj, name, fi,
				flags|O_NONBLOCK|O_NOCTTY, ctx);
		if (IS_ERR(master)) {
			eprintk_ctx("rst_open_tty: %s %Ld %ld\n",
					name, (long long)fi->cpt_priv,
					PTR_ERR(master));
			return master;
		}

		stty = file_tty(master);
		obj = cpt_object_add(CPT_OBJ_TTY, stty, ctx);
		obj->o_parent = master;
		cpt_obj_setpos(obj, fi->cpt_priv, ctx);

		obj = cpt_object_add(CPT_OBJ_FILE, master, ctx);
		cpt_obj_setpos(obj, CPT_NULL, ctx);
		get_file(master);

		/* Do not restore /dev/ttyX state */
		cpt_release_buf(ctx);
		return master;
	}

	master_flags = slave_flags = 0;
	if (pi->cpt_drv_subtype == PTY_TYPE_MASTER)
		master_flags = flags;
	else
		slave_flags = flags;

	/*
	 * Open pair master/slave.
	 */
	if (pi->cpt_drv_flags&TTY_DRIVER_DEVPTS_MEM) {
		master = ptmx_open(pi->cpt_index, master_flags);
	} else {
		sprintf(pairname, "/dev/pty%c%c", a[pi->cpt_index/16], b[pi->cpt_index%16]);
		master = filp_open(pairname, master_flags|O_NONBLOCK|O_NOCTTY|O_RDWR, 0);
	}
	if (IS_ERR(master)) {
		eprintk_ctx("filp_open master: %Ld %ld\n", (long long)fi->cpt_priv, PTR_ERR(master));
		cpt_release_buf(ctx);
		return master;
	}
	stty = file_tty(master);
	clear_bit(TTY_PTY_LOCK, &stty->flags);
	if (pi->cpt_drv_flags&TTY_DRIVER_DEVPTS_MEM)
		sprintf(pairname, "/dev/pts/%d", stty->index);
	else
		sprintf(pairname, "/dev/tty%c%c", a[stty->index/16], b[stty->index%16]);
	slave = filp_open(pairname, slave_flags|O_NONBLOCK|O_NOCTTY|O_RDWR, 0);
	if (IS_ERR(slave)) {
		eprintk_ctx("filp_open slave %s: %ld\n", pairname, PTR_ERR(slave));
		fput(master);
		cpt_release_buf(ctx);
		return slave;
	}

	if (pi->cpt_drv_subtype != PTY_TYPE_MASTER)
		fixup_tty_attrs(ii, slave, ctx);

	cpt_object_add(CPT_OBJ_TTY, file_tty(master), ctx);
	cpt_object_add(CPT_OBJ_TTY, file_tty(slave), ctx);
	cpt_object_add(CPT_OBJ_FILE, master, ctx);
	cpt_object_add(CPT_OBJ_FILE, slave, ctx);

	if (pi->cpt_drv_subtype == PTY_TYPE_MASTER) {
		loff_t pos;
		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(master), ctx);
		obj->o_parent = master;
		cpt_obj_setpos(obj, fi->cpt_priv, ctx);
		pty_setup(stty, fi->cpt_priv, pi, ctx);

		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(slave), ctx);
		obj->o_parent = slave;
		pos = find_pty_pair(stty->link, fi->cpt_priv, pi, ctx);
		cpt_obj_setpos(obj, pos, ctx);

		obj = lookup_cpt_object(CPT_OBJ_FILE, slave, ctx);
		cpt_obj_setpos(obj, CPT_NULL, ctx);
		get_file(master);
		cpt_release_buf(ctx);
		return master;
	} else {
		loff_t pos;
		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(slave), ctx);
		obj->o_parent = slave;
		cpt_obj_setpos(obj, fi->cpt_priv, ctx);
		pty_setup(stty->link, fi->cpt_priv, pi, ctx);

		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(master), ctx);
		obj->o_parent = master;
		pos = find_pty_pair(stty, fi->cpt_priv, pi, ctx);
		cpt_obj_setpos(obj, pos, ctx);

		obj = lookup_cpt_object(CPT_OBJ_FILE, master, ctx);
		cpt_obj_setpos(obj, CPT_NULL, ctx);
		get_file(slave);
		cpt_release_buf(ctx);
		return slave;
	}
}