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

📄 tubtty.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		tty3270_proc_index,		tty3270_proc_data,		tty3270_proc_misc);	/*	 * Display info for the tube with minor nr in index	 */	len += tty3270_show_tube(tty3270_proc_index, buf+len, count-len);	*eof = 1;	if (off >= begin + len)		return 0;	*start = buf + off - begin;	return MIN(count, begin + len - off);}static inttty3270_write_proc(struct file *file, const char *buffer,		unsigned long count, void *data){	char mybuf[GEOM_MAXINPLEN];	int mycount;	tub_t *tubp;	struct tty_struct *tty;	kdev_t device;	int rc;	mycount = MIN(count, sizeof mybuf - 1);	if (copy_from_user(mybuf, buffer, mycount) != 0)		return -EFAULT;	mybuf[mycount] = '\0';	/*	 * User-mode settings affect only the current tty ---	 */	tubp = NULL;	tty = current->tty;	device = tty? tty->device: 0;	if (device) {		if (MAJOR(device) == IBM_TTY3270_MAJOR)			tubp = (*tubminors)[MINOR(device)];#ifdef CONFIG_TN3270_CONSOLE#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))		if (CONSOLE_IS_3270 && device == S390_CONSOLE_DEV)			tubp = tub3270_con_tubp;#endif /* LINUX_VERSION_CODE */#endif /* CONFIG_TN3270_CONSOLE */	}	if (tubp) {		if ((rc = tty3270_aid_set(tubp, mybuf, mycount + 1)))			return rc > 0? count: rc;		if ((rc = tty3270_rcl_set(tubp, mybuf, mycount + 1)))			return rc > 0? count: rc;		if ((rc = tty3270_scl_set(tubp, mybuf, mycount + 1)))			return rc > 0? count: rc;	}	/*	 * Superuser-mode settings affect the driver overall ---	 */	if (!suser()) {		return -EPERM;	} else if (strncmp(mybuf, "index=", 6) == 0) {		tty3270_proc_index = simple_strtoul(mybuf + 6, 0,0);		return count;	} else if (strncmp(mybuf, "data=", 5) == 0) {		tty3270_proc_data = simple_strtoul(mybuf + 5, 0, 0);		return count;	} else if (strncmp(mybuf, "misc=", 5) == 0) {		tty3270_proc_misc = simple_strtoul(mybuf + 5, 0, 0);		return count;	} else if (strncmp(mybuf, "what=", 5) == 0) {		if (strcmp(mybuf+5, "bogus") == 0)			tty3270_proc_what = 0;		else if (strncmp(mybuf+5, "config", 6) == 0)			tty3270_proc_what = TW_CONFIG;		return count;	} else {		return -EINVAL;	}}static voidtty3270_hangup(struct tty_struct *tty){	tub_t *tubp;	extern void fs3270_release(tub_t *);	if ((tubp = tty->driver_data) == NULL)		return;	tty3270_rcl_purge(tubp);	tty3270_aid_reinit(tubp);	fs3270_release(tubp);}/* * tty3270_bh(tubp) -- Perform back-half processing */static voidtty3270_bh(void *data){	long flags;	tub_t *tubp;	struct tty_struct *tty;	tubp = data;	TUBLOCK(tubp->irq, flags);	tubp->flags &= ~TUB_BHPENDING;	tty = tubp->tty;	if (tubp->flags & TUB_UNSOL_DE) {		tubp->flags &= ~TUB_UNSOL_DE;		if (tty != NULL) {			tty_hangup(tty);			wake_up_interruptible(&tubp->waitq);			goto do_unlock;		}	}	if (tubp->flags & TUB_IACTIVE) {        /* If read ended, */		tty3270_do_input(tubp);		tubp->flags &= ~TUB_IACTIVE;	}	if ((tubp->flags & TUB_WORKING) == 0) {		if (tubp->flags & TUB_ATTN) {			tty3270_start_input(tubp);			tubp->flags &= ~TUB_ATTN;		} else if (tty3270_try_logging(tubp) == 0) {			wake_up_interruptible(&tubp->waitq);		}	}	if (tty != NULL) {		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&		    tty->ldisc.write_wakeup != NULL)			(tty->ldisc.write_wakeup)(tty);		wake_up_interruptible(&tty->write_wait);	}do_unlock:	TUBUNLOCK(tubp->irq, flags);}/* * tty3270_sched_bh(tubp) -- Schedule the back half * Irq lock must be held on entry and remains held on exit. */voidtty3270_sched_bh(tub_t *tubp){	if (tubp->flags & TUB_BHPENDING)		return;	tubp->flags |= TUB_BHPENDING;	tubp->tqueue.routine = tty3270_bh;	tubp->tqueue.data = tubp;	queue_task(&tubp->tqueue, &tq_immediate);	mark_bh(IMMEDIATE_BH);}/* * tty3270_io() -- Perform line-mode reads and writes here */int tty3270_io(tub_t *tubp){	int rc;	ccw1_t *ccwp;	tubp->flags |= TUB_WORKING;	tubp->dstat = 0;	ccwp = &tubp->ttyccw;	rc = do_IO(tubp->irq, ccwp, tubp->irq, 0, 0);	return rc;}/* * tty3270_wait(tubp) -- Wait until TUB_WORKING is off * On entry the lock must not be held; on exit it is held. */static inttty3270_wait(tub_t *tubp, long *flags){	DECLARE_WAITQUEUE(wait, current);	TUBLOCK(tubp->irq, *flags);	add_wait_queue(&tubp->waitq, &wait);	while (!signal_pending(current) &&	    (tubp->flags & TUB_WORKING) != 0) {		current->state = TASK_INTERRUPTIBLE;		TUBUNLOCK(tubp->irq, *flags);		schedule();		current->state = TASK_RUNNING;		TUBLOCK(tubp->irq, *flags);	}	remove_wait_queue(&tubp->waitq, &wait);	return signal_pending(current)? -ERESTARTSYS: 0;}voidtty3270_int(tub_t *tubp, devstat_t *dsp){#define	DEV_UE_BUSY \	(DEV_STAT_CHN_END | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP)#define DEV_NOT_WORKING \	(DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_CHECK)	tubp->dstat = dsp->dstat;	/* Handle CE-DE-UE and subsequent UDE */	if (dsp->dstat == DEV_UE_BUSY) {		tubp->flags |= TUB_UE_BUSY;		return;	} else if (tubp->flags & TUB_UE_BUSY) {		tubp->flags &= ~TUB_UE_BUSY;		if (dsp->dstat == DEV_STAT_DEV_END &&		    (tubp->flags & TUB_WORKING) != 0) {			tty3270_io(tubp);			return;		}	}	/* Handle ATTN */	if (dsp->dstat & DEV_STAT_ATTENTION)		tubp->flags |= TUB_ATTN;	if (dsp->dstat & DEV_STAT_CHN_END) {		tubp->cswl = dsp->rescnt;		if ((dsp->dstat & DEV_STAT_DEV_END) == 0)			tubp->flags |= TUB_EXPECT_DE;		else			tubp->flags &= ~TUB_EXPECT_DE;	} else if (dsp->dstat & DEV_STAT_DEV_END) {		if ((tubp->flags & TUB_EXPECT_DE) == 0)			tubp->flags |= TUB_UNSOL_DE;		tubp->flags &= ~TUB_EXPECT_DE;	}	if (dsp->dstat & DEV_NOT_WORKING)		tubp->flags &= ~TUB_WORKING;	if (dsp->dstat & DEV_STAT_UNIT_CHECK)		tubp->sense = dsp->ii.sense;	if ((tubp->flags & TUB_WORKING) == 0)		tty3270_sched_bh(tubp);}/* * tty3270_refresh(), called by fs3270_close() when tubp->fsopen == 0. * On entry, lock is held. */voidtty3270_refresh(tub_t *tubp){	if (tubp->lnopen) {		tubp->mode = TBM_LN;		tubp->intv = tty3270_int;		tty3270_scl_resettimer(tubp);		tubp->cmd = TBC_UPDATE;		tty3270_build(tubp);	}}inttty3270_try_logging(tub_t *tubp){	if (tubp->flags & TUB_WORKING)		return 0;	if (tubp->mode == TBM_FS)		return 0;	if (tubp->stat == TBS_HOLD)		return 0;	if (tubp->stat == TBS_MORE)		return 0;#ifdef CONFIG_TN3270_CONSOLE	if (CONSOLE_IS_3270 && tub3270_con_tubp == tubp)		tub3270_con_copy(tubp);#endif /* CONFIG_TN3270_CONSOLE */	if (tubp->tty_bcb.bc_cnt == 0)		return 0;	if (tubp->intv != tty3270_int)		return 0;	tubp->cmd = TBC_UPDLOG;	return tty3270_build(tubp);}/* tty3270 utility functions */static voidtty3270_start_input(tub_t *tubp){	tubp->ttyccw.cda = virt_to_phys(&tubp->tty_input);	tubp->ttyccw.cmd_code = TC_READMOD;	tubp->ttyccw.count = GEOM_INPLEN;	tubp->ttyccw.flags = CCW_FLAG_SLI;	tty3270_io(tubp);	tubp->flags |= TUB_IACTIVE;}static voidtty3270_do_input(tub_t *tubp){	int count;	char *in;	int aidflags;	char *aidstring;	count = GEOM_INPLEN - tubp->cswl;	in = tubp->tty_input;	tty3270_aid_get(tubp, in[0], &aidflags, &aidstring);	if (aidflags & TA_CLEARKEY) {		tubp->stat = TBS_RUNNING;		tty3270_scl_resettimer(tubp);		tubp->cmd = TBC_UPDATE;	} else if (aidflags & TA_CLEARLOG) {		tubp->stat = TBS_RUNNING;		tty3270_scl_resettimer(tubp);		tubp->cmd = TBC_CLRUPDLOG;	} else if (aidflags & TA_DOENTER) {		if (count <= 6) {			switch(tubp->stat) {			case TBS_MORE:				tubp->stat = TBS_HOLD;				tty3270_scl_resettimer(tubp);				break;			case TBS_HOLD:				tubp->stat = TBS_MORE;				tty3270_scl_settimer(tubp);				break;			case TBS_RUNNING:                                tty3270_do_enter(tubp, in + 6, 0);				break;			}			tubp->cmd = TBC_UPDSTAT;			goto do_build;		}		in += 6;		count -= 6;		TUB_EBCASC(in, count);		tubp->cmd = TBC_CLRINPUT;		tty3270_do_enter(tubp, in, count);	} else if ((aidflags & TA_DOSTRING) != 0 && aidstring != NULL) {		tubp->cmd = TBC_KRUPDLOG;		tty3270_do_enter(tubp, aidstring, strlen(aidstring));	} else if ((aidflags & TA_DOSTRINGD) != 0 && aidstring != NULL) {		tty3270_do_showi(tubp, aidstring, strlen(aidstring));		tubp->cmd = TBC_UPDINPUT;	} else {		if (in[0] != 0x60)			tubp->flags |= TUB_ALARM;		tubp->cmd = TBC_KRUPDLOG;	}do_build:	tty3270_build(tubp);}static voidtty3270_do_enter(tub_t *tubp, char *cp, int count){	struct tty_struct *tty;	int func = -1;	if ((tty = tubp->tty) == NULL)		return;	if (count < 0)		return;	if (count == 2 && (cp[0] == '^' || cp[0] == '\252')) {		switch(cp[1]) {		case 'c':  case 'C':			func = INTR_CHAR(tty);			break;		case 'd':  case 'D':			func = EOF_CHAR(tty);			break;		case 'z':  case 'Z':			func = SUSP_CHAR(tty);			break;		}	} else if (count == 2 && cp[0] == 0x1b) {        /* if ESC */		int inc = 0;		char buf[GEOM_INPLEN + 1];		int len;		switch(cp[1]) {		case 'k':  case 'K':			inc = -1;			break;		case 'j':  case 'J':			inc = 1;			break;		}		if (inc == 0)			goto not_rcl;		len = tty3270_rcl_get(tubp, buf, sizeof buf, inc);		if (len == 0) {			tubp->flags |= TUB_ALARM;			return;		}		tty3270_do_showi(tubp, buf, len);		tubp->cmd = TBC_UPDINPUT;		return;	}not_rcl:	if (func != -1) {		*tty->flip.flag_buf_ptr++ = TTY_NORMAL;		*tty->flip.char_buf_ptr++ = func;		tty->flip.count++;	} else {		tty3270_rcl_put(tubp, cp, count);		memcpy(tty->flip.char_buf_ptr, cp, count);		/* Add newline unless line ends with "^n" */		if (count < 2 || cp[count - 1] != 'n' ||		    (cp[count - 2] != '^' && cp[count - 2] != '\252')) {			tty->flip.char_buf_ptr[count] = '\n';			count++;		} else {			count -= 2;     /* Lop trailing "^n" from text */		}		memset(tty->flip.flag_buf_ptr, TTY_NORMAL, count);		tty->flip.char_buf_ptr += count;		tty->flip.flag_buf_ptr += count;		tty->flip.count += count;	}	tty_flip_buffer_push(tty);}static voidtty3270_do_showi(tub_t *tubp, char *cp, int cl){	if (cl > GEOM_INPLEN)		cl = GEOM_INPLEN;	memset(tubp->tty_input, 0, GEOM_INPLEN);	memcpy(tubp->tty_input, cp, cl);	TUB_ASCEBC(tubp->tty_input, cl);}/* Debugging routine */static inttty3270_show_tube(int minor, char *buf, int count){	tub_t *tubp;	struct tty_struct *tty;	struct termios *mp;	int len;/*012345678901234567890123456789012345678901234567890123456789       *//*Info for tub_t[dd] at xxxxxxxx:                                    *//*    geom:  rows=dd cols=dd model=d                                 *//*    lnopen=dd     fsopen=dd   waitq=xxxxxxxx                       *//*    dstat=xx      mode=dd     stat=dd     flags=xxxx               *//*    oucount=dddd  ourd=ddddd  ouwr=ddddd  nextlogx=ddddd           *//*    tty=xxxxxxxx                                                   *//*    write_wait=xxxxxxxx read_wait=xxxxxxxx                         *//*    iflag=xxxxxxxx oflag=xxxxxxxx cflag=xxxxxxxx lflag=xxxxxxxx    */	if (minor < 0 || minor > tubnummins ||	    (tubp = (*tubminors)[minor]) == NULL)		return sprintf(buf, "No tube at index=%d\n", minor);		tty = tubp->tty;	len = 0;	len += sprintf(buf+len, "Info for tub_t[%d] at %p:\n", minor, tubp);	len += sprintf(buf+len, "inattr is at %p\n", &tubp->tty_inattr);	len += sprintf(buf+len, "    geom:  rows=%.2d cols=%.2d model=%.1d\n",		       tubp->geom_rows, tubp->geom_cols, tubp->tubiocb.model);	len += sprintf(buf+len,		       "    lnopen=%-2d     fsopen=%-2d   waitq=%p\n",		       tubp->lnopen, tubp->fsopen, &tubp->waitq);	len += sprintf(buf+len, "    dstat=%.2x      mode=%-2d     "		       "stat=%-2d     flags=%-4x\n", tubp->dstat,		       tubp->mode, tubp->stat, tubp->flags);#ifdef RBH_FIXTHIS	len += sprintf(buf+len,		       "    oucount=%-4d  ourd=%-5d  ouwr=%-5d"		       "  nextlogx=%-5d\n", tubp->tty_oucount,		       tubp->tty_ourd, tubp->tty_ouwr, tubp->tty_nextlogx);#endif	len += sprintf(buf+len, "    tty=%p\n",tubp->tty);	if (tty)		len += sprintf(buf+len,				"    write_wait=%p read_wait=%p\n",				&tty->write_wait, &tty->read_wait);	if (tty && ((mp = tty->termios)))		len += sprintf(buf+len,"    iflag=%.8x oflag=%.8x "			       "cflag=%.8x lflag=%.8x\n", mp->c_iflag,			       mp->c_oflag, mp->c_cflag, mp->c_lflag);	return len;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -