📄 pcvt_drv.c
字号:
#if PCVT_EMU_MOUSE if(i == totalscreens) mouse.opened = 0; else#endif /* PCVT_EMU_MOUSE */ vsx->openf = 0;#if PCVT_USL_VT_COMPAT#if PCVT_EMU_MOUSE if(i == totalscreens) return (0);#endif /* PCVT_EMU_MOUSE */ reset_usl_modes(vsx);#endif /* PCVT_USL_VT_COMPAT */ return(0);}intpcread(Dev_t dev, struct uio *uio, int flag){ register struct tty *tp; if((tp = get_pccons(dev)) == NULL) return ENXIO; return ((*linesw[tp->t_line].l_read)(tp, uio, flag));}intpcwrite(Dev_t dev, struct uio *uio, int flag){ register struct tty *tp; if((tp = get_pccons(dev)) == NULL) return ENXIO; return ((*linesw[tp->t_line].l_write)(tp, uio, flag));}intpcioctl(Dev_t dev, int cmd, caddr_t data, int flag, struct proc *p){ register error; register struct tty *tp; if((tp = get_pccons(dev)) == NULL) return(ENXIO); /* note that some ioctl's are global, e.g. KBSTPMAT: There is * only one keyboard and different repeat rates for instance between * sessions are a suspicious wish. If you really need this make the * appropriate variables arrays */#if PCVT_EMU_MOUSE if(minor(dev) == totalscreens) { if((error = mouse_ioctl(dev, cmd, data)) >= 0) return error; goto do_standard; }#endif /* PCVT_EMU_MOUSE */#ifdef XSERVER#if PCVT_USL_VT_COMPAT if((error = usl_vt_ioctl(dev, cmd, data, flag, p)) >= 0) return error; /* * just for compatibility: * XFree86 < 2.0 and SuperProbe still might use it * * NB: THIS IS A HACK! Do not use it unless you explicitly need. * Especially, since the vty is not put into process-controlled * mode (this would require the application to co-operate), any * attempts to switch vtys while this kind of X mode is active * may cause serious trouble. */ switch(cmd) { case CONSOLE_X_MODE_ON: { int i; if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, p)) > 0) return error; i = KD_GRAPHICS; if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p)) > 0) return error; i = K_RAW; error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p); return error; } case CONSOLE_X_MODE_OFF: { int i; (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, p); i = KD_TEXT; (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p); i = K_XLATE; (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p); return 0; } case CONSOLE_X_BELL: /* * If `data' is non-null, the first int value denotes * the pitch, the second a duration. Otherwise, behaves * like BEL. */ if (data) {#if PCVT_NETBSD sysbeep(((int *)data)[0], ((int *)data)[1] * hz / 1000);#else /* PCVT_NETBSD */ sysbeep(PCVT_SYSBEEPF / ((int *)data)[0], ((int *)data)[1] * hz / 3000);#endif /* PCVT_NETBSD */ } else { sysbeep(PCVT_SYSBEEPF / 1493, hz / 4); } return (0); default: /* fall through */ ; }#else /* PCVT_USL_VT_COMPAT */ switch(cmd) { case CONSOLE_X_MODE_ON: return pcvt_xmode_set(1, p); case CONSOLE_X_MODE_OFF: return pcvt_xmode_set(0, p); case CONSOLE_X_BELL: /* * If `data' is non-null, the first int value denotes * the pitch, the second a duration. Otherwise, behaves * like BEL. */ if (data) {#if PCVT_NETBSD sysbeep(((int *)data)[0], ((int *)data)[1] * hz / 1000);#else /* PCVT_NETBSD */ sysbeep(PCVT_SYSBEEPF / ((int *)data)[0], ((int *)data)[1] * hz / 3000);#endif /* PCVT_NETBSD */ } else { sysbeep(PCVT_SYSBEEPF / 1493, hz / 4); } return (0); default: /* fall through */ ; }#endif /* PCVT_USL_VT_COMPAT */#endif /* XSERVER */ if((error = kbdioctl(dev,cmd,data,flag)) >= 0) return error; if((error = vgaioctl(dev,cmd,data,flag)) >= 0) return error;#if PCVT_EMU_MOUSEdo_standard:#endif#if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p)) >= 0) return (error);#else if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0) return(error);#endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */#if PCVT_NETBSD > 9 if((error = ttioctl(tp, cmd, data, flag, p)) >= 0) return (error);#else if((error = ttioctl(tp, cmd, data, flag)) >= 0) return (error);#endif /* PCVT_NETBSD > 9 */ return (ENOTTY);}intpcmmap(Dev_t dev, vm_offset_t offset, int nprot){ if (offset > 0x20000 - PAGE_SIZE) return -1; return i386_btop((0xa0000 + offset));}/*---------------------------------------------------------------------------* * * handle a keyboard receive interrupt * * NOTE: the keyboard is multiplexed by means of "pcconsp" * between virtual screens. pcconsp - switching is done in * the vgapage() routine * *---------------------------------------------------------------------------*/#if PCVT_KBD_FIFOu_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];int pcvt_kbd_wptr = 0;int pcvt_kbd_rptr = 0;short pcvt_kbd_count= 0;static u_char pcvt_timeout_scheduled = 0;static voidpcvt_timeout(void *arg){ u_char *cp;#if PCVT_SLOW_INTERRUPT int s;#endif pcvt_timeout_scheduled = 0;#if PCVT_SCREENSAVER pcvt_scrnsv_reset();#endif /* PCVT_SCREENSAVER */ while (pcvt_kbd_count) { if (((cp = sgetc(1)) != 0) && (vs[current_video_screen].openf)) {#if PCVT_NULLCHARS if(*cp == '\0') { /* pass a NULL character */ (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp); }/* XXX */ else#endif /* PCVT_NULLCHARS */ while (*cp) (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp); } PCVT_DISABLE_INTR (); if (!pcvt_kbd_count) pcvt_timeout_scheduled = 0; PCVT_ENABLE_INTR (); } return;}#endifvoidpcrint(int unit){#if PCVT_KBD_FIFO u_char dt; u_char ret = -1;# if PCVT_SLOW_INTERRUPT int s;# endif# ifdef _I386_ISA_KBDIO_H_ int c;# endif#else /* !PCVT_KBD_FIFO */ u_char *cp;#endif /* PCVT_KBD_FIFO */ /* * in case the keyboard was not plugged in while booting, kbdc * was set to NULL at that time. When a keyboard IRQ occurs and * kbdc is NULL, the keyboard was probably reconnected to the * keyboard controller and we have to initialize the keyboard. */ if(kbdc == NULL) { kbdc = kbdc_open(IO_KBD); if(kbdc == NULL) { reset_keyboard = 0; return; } reset_keyboard = 1; kbd_code_init(); }#if PCVT_SCREENSAVER pcvt_scrnsv_reset();#endif /* PCVT_SCREENSAVER */#if PCVT_KBD_FIFO if (kbd_polling) { sgetc(1); return; }# ifndef _I386_ISA_KBDIO_H_ while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */ { ret = 1; /* got something */ PCVT_KBD_DELAY(); /* 7 us delay */ dt = inb(CONTROLLER_DATA); /* get it 8042 data */# else while ((c = read_kbd_data_no_wait(kbdc)) != -1) { ret = 1; /* got something */ dt = c;# endif /* _I386_ISA_KBDIO_H_ */ if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */ { log (LOG_WARNING, "pcvt: keyboard buffer overflow\n"); } else { pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */ PCVT_DISABLE_INTR (); /* XXX necessary ? */ pcvt_kbd_count++; /* update fifo count */ PCVT_ENABLE_INTR (); if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ) pcvt_kbd_wptr = 0; /* wraparound pointer */ } } if (ret == 1) /* got data from keyboard ? */ { if (!pcvt_timeout_scheduled) /* if not already active .. */ { PCVT_DISABLE_INTR (); pcvt_timeout_scheduled = 1; /* flag active */ timeout(pcvt_timeout, NULL, hz / 100); /* fire off */ PCVT_ENABLE_INTR (); } }#else /* !PCVT_KBD_FIFO */ if((cp = sgetc(1)) == 0) return; if (kbd_polling) return; if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */ return;#if PCVT_NULLCHARS if(*cp == '\0') { /* pass a NULL character */ (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp); return; }#endif /* PCVT_NULLCHARS */ while (*cp) (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);#endif /* PCVT_KBD_FIFO */}#if PCVT_NETBSD || PCVT_FREEBSD >= 200voidpcstart(register struct tty *tp){ register struct clist *rbp; int s, len; u_char buf[PCVT_PCBURST]; s = spltty(); if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; tp->t_state |= TS_BUSY; splx(s); async_update(UPDATE_KERN); rbp = &tp->t_outq; /* * Call q_to_b() at spltty() to ensure that the queue is empty when * the loop terminates. */ s = spltty(); while (len = q_to_b(rbp, buf, PCVT_PCBURST)) { /* * We need to do this outside spl since it could be fairly * expensive and we don't want our serial ports to overflow. */ splx(s); sput(&buf[0], 0, len, minor(tp->t_dev)); s = spltty(); } tp->t_state &= ~TS_BUSY;#ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */ ttwwakeup(tp);#else if (rbp->c_cc <= tp->t_lowat) { if (tp->t_state&TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)rbp); } selwakeup(&tp->t_wsel); }#endifout: splx(s);}voidpcstop(struct tty *tp, int flag){}#else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */voidpcstart(struct tty *tp){ int s; unsigned char c; s = spltty(); if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { goto out; } for(;;) {#if !(PCVT_FREEBSD > 114)#if !(PCVT_FREEBSD > 111) if (RB_LEN(&tp->t_out) <= tp->t_lowat)#else if (RB_LEN(tp->t_out) <= tp->t_lowat)#endif { if (tp->t_state&TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP;#if !(PCVT_FREEBSD > 111) wakeup((caddr_t)&tp->t_out);#else wakeup((caddr_t)tp->t_out);#endif } if (tp->t_wsel) { selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); tp->t_wsel = 0; tp->t_state &= ~TS_WCOLL; } }#else /* PCVT_FREEBSD > 114 */ if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel) { ttwwakeup(tp); }#endif /* !PCVT_FREEBSD > 114 */#if !(PCVT_FREEBSD > 111) if (RB_LEN(&tp->t_out) == 0)#else if (RB_LEN(tp->t_out) == 0)#endif { goto out; }#if !(PCVT_FREEBSD > 111) c = getc(&tp->t_out);#else c = getc(tp->t_out);#endif tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */ splx(s); sput(&c, 0, 1, minor(tp->t_dev)); spltty();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -