The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/pcvt/pcvt_drv.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1999, 2000 Hellmuth Michaelis
    3  *
    4  * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
    5  *
    6  * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
    7  *
    8  * Copyright (c) 1993 Charles Hannum.
    9  *
   10  * All rights reserved.
   11  *
   12  * Parts of this code regarding the NetBSD interface were written
   13  * by Charles Hannum.
   14  * 
   15  * This code is derived from software contributed to Berkeley by
   16  * William Jolitz and Don Ahn.
   17  *
   18  * Redistribution and use in source and binary forms, with or without
   19  * modification, are permitted provided that the following conditions
   20  * are met:
   21  * 1. Redistributions of source code must retain the above copyright
   22  *    notice, this list of conditions and the following disclaimer.
   23  * 2. Redistributions in binary form must reproduce the above copyright
   24  *    notice, this list of conditions and the following disclaimer in the
   25  *    documentation and/or other materials provided with the distribution.
   26  * 3. All advertising materials mentioning features or use of this software
   27  *    must display the following acknowledgement:
   28  *      This product includes software developed by
   29  *      Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Scott Turner
   30  *      and Charles Hannum.
   31  * 4. The name authors may not be used to endorse or promote products
   32  *    derived from this software without specific prior written permission.
   33  *
   34  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   35  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   37  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   38  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   39  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   40  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   41  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   44  */
   45 
   46 /*---------------------------------------------------------------------------*
   47  *
   48  *      pcvt_drv.c      VT220 Driver Main Module / OS - Interface
   49  *      ---------------------------------------------------------
   50  *
   51  *      Last Edit-Date: [Sat Jul 15 15:06:06 2000]
   52  *
   53  * $FreeBSD: releng/5.3/sys/i386/isa/pcvt/pcvt_drv.c 132226 2004-07-15 20:47:41Z phk $
   54  *
   55  *---------------------------------------------------------------------------*/
   56 
   57 #define MAIN
   58 #include <i386/isa/pcvt/pcvt_hdr.h>
   59 #undef MAIN
   60 
   61 
   62 #include <sys/resource.h>
   63 #include <sys/bus.h>
   64 #include <sys/rman.h>
   65 
   66 #include <machine/resource.h>
   67 #include <machine/bus.h>
   68 
   69 #include <isa/isareg.h>
   70 #include <isa/isavar.h>
   71 
   72 static kbd_callback_func_t pcvt_event;
   73 static int pcvt_kbd_wptr = 0;
   74 static u_char pcvt_timeout_scheduled = 0;
   75 
   76 static void vgapelinit(void);
   77 static void detect_kbd(void *arg);
   78 static void pcvt_start(register struct tty *tp);
   79 static int pcvt_param(struct tty *tp, struct termios *t);
   80 
   81 static cn_probe_t       pcvt_cn_probe;
   82 static cn_init_t        pcvt_cn_init;
   83 static cn_term_t        pcvt_cn_term;
   84 static cn_getc_t        pcvt_cn_getc;
   85 static cn_checkc_t      pcvt_cn_checkc;
   86 static cn_putc_t        pcvt_cn_putc;
   87 
   88 CONS_DRIVER(vt, pcvt_cn_probe, pcvt_cn_init, pcvt_cn_term, pcvt_cn_getc,
   89                 pcvt_cn_checkc, pcvt_cn_putc, NULL);
   90 
   91 static  d_open_t        pcvt_open;
   92 static  d_close_t       pcvt_close;
   93 static  d_ioctl_t       pcvt_ioctl;
   94 static  d_mmap_t        pcvt_mmap;
   95 
   96 static struct cdevsw vt_cdevsw = {
   97         .d_version =    D_VERSION,
   98         .d_open =       pcvt_open,
   99         .d_close =      pcvt_close,
  100         .d_ioctl =      pcvt_ioctl,
  101         .d_mmap =       pcvt_mmap,
  102         .d_name =       "vt",
  103         .d_flags =      D_TTY | D_NEEDGIANT,
  104 };
  105 
  106 static int pcvt_probe(device_t dev);
  107 static int pcvt_attach(device_t dev);
  108 static void pcvt_identify (driver_t *driver, device_t parent);
  109 
  110 static device_method_t pcvt_methods[] = {
  111         DEVMETHOD(device_identify,      pcvt_identify),
  112         DEVMETHOD(device_probe,         pcvt_probe),
  113         DEVMETHOD(device_attach,        pcvt_attach),
  114         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  115         { 0, 0 }
  116 };
  117 
  118 static driver_t pcvt_driver = {
  119         "vt",
  120         pcvt_methods,
  121         0
  122 };
  123 
  124 static devclass_t pcvt_devclass;
  125 
  126 DRIVER_MODULE(pcvt, isa, pcvt_driver, pcvt_devclass, 0, 0);
  127 
  128 /*---------------------------------------------------------------------------*
  129  *      driver identify
  130  *---------------------------------------------------------------------------*/
  131 static void
  132 pcvt_identify (driver_t *driver, device_t parent)
  133 {
  134         BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "vt", 0);
  135 }
  136 
  137 /*---------------------------------------------------------------------------*
  138  *      driver probe
  139  *---------------------------------------------------------------------------*/
  140 static int
  141 pcvt_probe(device_t dev)
  142 {
  143         int i;
  144         device_t bus;
  145         
  146         int unit = device_get_unit(dev);
  147 
  148         /* No pnp support */
  149         if(isa_get_vendorid(dev))
  150                 return ENXIO;
  151 
  152         if(unit != 0)
  153                 return ENXIO;   
  154         
  155         device_set_desc(dev, "pcvt VT220 console driver");
  156         
  157         bus = device_get_parent(dev);
  158         bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3b0, 0x30);
  159         bus_set_resource(dev, SYS_RES_MEMORY, 0, (u_long) Crtat, 0x8000);
  160 
  161         if (kbd == NULL)
  162         {
  163                 reset_keyboard = 0;
  164                 kbd_configure(KB_CONF_PROBE_ONLY);
  165                 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)&vs[unit]);
  166                 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
  167                         return 0;
  168         }
  169         reset_keyboard = 1;             /* it's now safe to do kbd reset */
  170 
  171         kbd_code_init();
  172 
  173         return 0;
  174 }
  175 
  176 /*---------------------------------------------------------------------------*
  177  *      driver attach
  178  *---------------------------------------------------------------------------*/
  179 static int
  180 pcvt_attach(device_t dev)
  181 {
  182         int i;
  183         struct resource *port;
  184         struct resource *mem;
  185                 
  186         int unit = device_get_unit(dev);
  187         
  188         if(unit != 0)
  189                 return ENXIO;   
  190 
  191         i = 0;
  192         port = bus_alloc_resource(dev, SYS_RES_IOPORT, &i, 0, ~0, 0,
  193                                         RF_ACTIVE | RF_SHAREABLE);
  194 
  195         i = 0;
  196         mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &i, 0, ~0, 0,
  197                                         RF_ACTIVE | RF_SHAREABLE);
  198 
  199         vt_coldmalloc();                /* allocate memory for screens */
  200 
  201         if (kbd == NULL)
  202                 timeout(detect_kbd, (void *)&vs[unit], hz*2);
  203 
  204         printf("vt%d: ", unit);
  205 
  206         switch(adaptor_type)
  207         {
  208                 case MDA_ADAPTOR:
  209                         printf("MDA");
  210                         break;
  211 
  212                 case CGA_ADAPTOR:
  213                         printf("CGA");
  214                         break;
  215 
  216                 case EGA_ADAPTOR:
  217                         printf("EGA");
  218                         break;
  219 
  220                 case VGA_ADAPTOR:
  221                         printf("%s VGA, ", (char *)vga_string(vga_type));
  222                         if(can_do_132col)
  223                                 printf("80/132 columns");
  224                         else
  225                                 printf("80 columns");
  226                         vgapelinit();
  227                         break;
  228 
  229                 default:
  230                         printf("unknown");
  231                         break;
  232         }
  233 
  234         if(color == 0)
  235                 printf(", mono");
  236         else
  237                 printf(", color");
  238 
  239         printf(", %d screens, ", totalscreens);
  240 
  241         switch(keyboard_type)
  242         {
  243                 case KB_AT:
  244                         printf("AT-");
  245                         break;
  246 
  247                 case KB_MFII:
  248                         printf("MF2-");
  249                         break;
  250 
  251                 default:
  252                         printf("unknown ");
  253                         break;
  254         }
  255 
  256         printf("keyboard\n");
  257 
  258         for(i = 0; i < totalscreens; i++)
  259         {
  260                 pcvt_tty[i] = ttymalloc(pcvt_tty[i]);
  261                 vs[i].vs_tty = pcvt_tty[i];
  262                 make_dev(&vt_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
  263         }
  264 
  265         async_update(UPDATE_START);     /* start asynchronous updates */
  266 
  267         return 0;
  268 }
  269 
  270 /*---------------------------------------------------------------------------*
  271  *      driver open
  272  *---------------------------------------------------------------------------*/
  273 static int
  274 pcvt_open(struct cdev *dev, int flag, int mode, struct thread *td)
  275 {
  276         register struct tty *tp;
  277         register struct video_state *vsx;
  278         int s, retval;
  279         int winsz = 0;
  280         int i = minor(dev);
  281 
  282         vsx = &vs[i];
  283 
  284         if(i >= PCVT_NSCREENS)
  285                 return ENXIO;
  286 
  287         tp = pcvt_tty[i];
  288 
  289         dev->si_tty = tp;
  290 
  291         vsx->openf++;
  292 
  293         tp->t_oproc = pcvt_start;
  294         tp->t_param = pcvt_param;
  295         tp->t_stop = nottystop;
  296         tp->t_dev = dev;
  297 
  298         if ((tp->t_state & TS_ISOPEN) == 0)
  299         {
  300                 ttychars(tp);
  301                 tp->t_iflag = TTYDEF_IFLAG;
  302                 tp->t_oflag = TTYDEF_OFLAG;
  303                 tp->t_cflag = TTYDEF_CFLAG;
  304                 tp->t_lflag = TTYDEF_LFLAG;
  305                 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
  306                 pcvt_param(tp, &tp->t_termios);
  307                 ttyld_modem(tp, 1);     /* fake connection */
  308                 winsz = 1;                      /* set winsize later */
  309         }
  310         else if (tp->t_state & TS_XCLUDE && suser(td))
  311         {
  312                 return (EBUSY);
  313         }
  314 
  315         retval = (ttyld_open(tp, dev));
  316 
  317         if(winsz == 1)
  318         {
  319                 /*
  320                  * The line discipline has clobbered t_winsize if TS_ISOPEN
  321                  * was clear. (NetBSD PR #400 from Bill Sommerfeld)
  322                  * We have to do this after calling the open routine, because
  323                  * it does some other things in other/older *BSD releases -hm
  324                  */
  325 
  326                 s = spltty();
  327 
  328                 tp->t_winsize.ws_col = vsx->maxcol;
  329                 tp->t_winsize.ws_row = vsx->screen_rows;
  330                 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
  331                 tp->t_winsize.ws_ypixel = 400;
  332 
  333                 splx(s);
  334         }
  335         return(retval);
  336 }
  337 
  338 /*---------------------------------------------------------------------------*
  339  *      driver close
  340  *---------------------------------------------------------------------------*/
  341 static int
  342 pcvt_close(struct cdev *dev, int flag, int mode, struct thread *td)
  343 {
  344         register struct tty *tp;
  345         register struct video_state *vsx;
  346         int i = minor(dev);
  347 
  348         vsx = &vs[i];
  349 
  350         if(i >= PCVT_NSCREENS)
  351                 return ENXIO;
  352 
  353         tp = pcvt_tty[i];
  354 
  355         ttyld_close(tp, flag);
  356 
  357         tty_close(tp);
  358 
  359         vsx->openf = 0;
  360 
  361 #ifdef XSERVER
  362         reset_usl_modes(vsx);
  363 #endif /* XSERVER */
  364 
  365         return(0);
  366 }
  367 
  368 /*---------------------------------------------------------------------------*
  369  *      driver ioctl
  370  *---------------------------------------------------------------------------*/
  371 static int
  372 pcvt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
  373 {
  374         register int error;
  375         register struct tty *tp;
  376         int i = minor(dev);
  377         
  378         if(i >= PCVT_NSCREENS)
  379                 return ENXIO;
  380 
  381         tp = pcvt_tty[i];
  382 
  383         /* note that some ioctl's are global, e.g.  KBSTPMAT: There is
  384          * only one keyboard and different repeat rates for instance between
  385          * sessions are a suspicious wish. If you really need this make the
  386          * appropriate variables arrays
  387          */
  388 
  389 #ifdef XSERVER
  390         if((error = usl_vt_ioctl(dev, cmd, data, flag, td)) >= 0)
  391                 return error;
  392 #endif /* XSERVER */
  393 
  394         if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
  395                 return error;
  396 
  397         if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
  398                 return error;
  399 
  400         return (ttyioctl(dev, cmd, data, flag, td));
  401 }
  402 
  403 /*---------------------------------------------------------------------------*
  404  *      driver mmap
  405  *---------------------------------------------------------------------------*/
  406 static int
  407 pcvt_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
  408 {
  409         if (offset > 0x20000 - PAGE_SIZE)
  410                 return -1;
  411         *paddr = 0xa0000 + offset;
  412         return 0;
  413 }
  414 
  415 /*---------------------------------------------------------------------------*
  416  *      timeout handler
  417  *---------------------------------------------------------------------------*/
  418 static void
  419 pcvt_timeout(void *arg)
  420 {
  421         u_char *cp;
  422         struct tty *tp;
  423 
  424 #if PCVT_SLOW_INTERRUPT
  425         int     s;
  426 #endif
  427 
  428         pcvt_timeout_scheduled = 0;
  429 
  430 #if PCVT_SCREENSAVER
  431         pcvt_scrnsv_reset();
  432 #endif /* PCVT_SCREENSAVER */
  433 
  434         tp = pcvt_tty[current_video_screen];
  435         while (pcvt_kbd_count)
  436         {
  437                 if (((cp = sgetc(1)) != 0) &&
  438                     (vs[current_video_screen].openf))
  439                 {
  440 
  441 #if PCVT_NULLCHARS
  442                         if(*cp == '\0')
  443                         {
  444                                 /* pass a NULL character */
  445                                 ttyld_rint(tp, '\0');
  446                         }
  447 /* XXX */               else
  448 #endif /* PCVT_NULLCHARS */
  449 
  450                         while (*cp)
  451                                 ttyld_rint(tp, *cp++ & 0xff);
  452                 }
  453 
  454                 PCVT_DISABLE_INTR ();
  455 
  456                 if (!pcvt_kbd_count)
  457                         pcvt_timeout_scheduled = 0;
  458 
  459                 PCVT_ENABLE_INTR ();
  460         }
  461 
  462         return;
  463 }
  464 
  465 /*---------------------------------------------------------------------------*
  466  *      check for keyboard
  467  *---------------------------------------------------------------------------*/
  468 static void
  469 detect_kbd(void *arg)
  470 {
  471         int unit = (int)arg;
  472         int i;
  473 
  474         if (kbd != NULL)
  475                 return;
  476         i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
  477         if (i >= 0)
  478                 kbd = kbd_get_keyboard(i);
  479         if (kbd != NULL)
  480         {
  481                 reset_keyboard = 1;     /* ok to reset the keyboard */
  482                 kbd_code_init();
  483                 return;
  484         }
  485         reset_keyboard = 0;
  486         timeout(detect_kbd, (void *)unit, hz*2);
  487 }
  488 
  489 /*---------------------------------------------------------------------------*
  490  *      keyboard event handler
  491  *---------------------------------------------------------------------------*/
  492 static int
  493 pcvt_event(keyboard_t *thiskbd, int event, void *arg)
  494 {
  495         int unit = (int)arg;
  496 
  497         if (thiskbd != kbd)
  498                 return EINVAL;          /* shouldn't happen */
  499 
  500         switch (event) {
  501         case KBDIO_KEYINPUT:
  502                 pcvt_rint(unit);
  503                 return 0;
  504         case KBDIO_UNLOADING:
  505                 reset_keyboard = 0;
  506                 kbd = NULL;
  507                 kbd_release(thiskbd, (void *)&kbd);
  508                 timeout(detect_kbd, (void *)unit, hz*4);
  509                 return 0;
  510         default:
  511                 return EINVAL;
  512         }
  513 }
  514 
  515 /*---------------------------------------------------------------------------*
  516  *      (keyboard) interrupt handler
  517  *---------------------------------------------------------------------------*/
  518 void
  519 pcvt_rint(int unit)
  520 {
  521         u_char  dt;
  522         u_char  ret = -1;
  523         int     c;
  524         
  525 # if PCVT_SLOW_INTERRUPT
  526         int     s;
  527 # endif
  528 
  529 #if PCVT_SCREENSAVER
  530         pcvt_scrnsv_reset();
  531 #endif /* PCVT_SCREENSAVER */
  532 
  533         if (kbd_polling)
  534         {
  535                 sgetc(1);
  536                 return;
  537         }
  538 
  539         while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
  540         {
  541                 ret = 1;                                /* got something */
  542                 dt = c;
  543 
  544                 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
  545                 {
  546                         log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
  547                 }
  548                 else
  549                 {
  550                         pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
  551 
  552                         PCVT_DISABLE_INTR ();   /* XXX necessary ? */
  553                         pcvt_kbd_count++;               /* update fifo count */
  554                         PCVT_ENABLE_INTR ();
  555 
  556                         if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
  557                                 pcvt_kbd_wptr = 0;      /* wraparound pointer */
  558                 }
  559         }
  560 
  561         if (ret == 1)   /* got data from keyboard ? */
  562         {
  563                 if (!pcvt_timeout_scheduled)    /* if not already active .. */
  564                 {
  565                         PCVT_DISABLE_INTR ();
  566                         pcvt_timeout_scheduled = 1;     /* flag active */
  567                         timeout(pcvt_timeout, NULL, hz / 100);  /* fire off */
  568                         PCVT_ENABLE_INTR ();
  569                 }
  570         }
  571 }
  572 
  573 /*---------------------------------------------------------------------------*
  574  *      start output
  575  *---------------------------------------------------------------------------*/
  576 static void
  577 pcvt_start(register struct tty *tp)
  578 {
  579         register struct clist *rbp;
  580         int s, len;
  581         u_char buf[PCVT_PCBURST];
  582 
  583         s = spltty();
  584 
  585         if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
  586                 goto out;
  587 
  588         tp->t_state |= TS_BUSY;
  589 
  590         splx(s);
  591 
  592         async_update(UPDATE_KERN);
  593 
  594         rbp = &tp->t_outq;
  595 
  596         /*
  597          * Call q_to_b() at spltty() to ensure that the queue is empty when
  598          * the loop terminates.
  599          */
  600 
  601         s = spltty();
  602 
  603         while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
  604         {
  605                 if(vs[minor(tp->t_dev)].scrolling)
  606                         sgetc(SCROLLBACK_COOKIE);
  607                 
  608                 /*
  609                  * We need to do this outside spl since it could be fairly
  610                  * expensive and we don't want our serial ports to overflow.
  611                  */
  612                 splx(s);
  613                 sput(&buf[0], 0, len, minor(tp->t_dev));
  614                 s = spltty();
  615         }
  616 
  617         tp->t_state &= ~TS_BUSY;
  618 
  619         ttwwakeup(tp);
  620 
  621 out:
  622         splx(s);
  623 }
  624 
  625 /*---------------------------------------------------------------------------*
  626  *      console probe
  627  *---------------------------------------------------------------------------*/
  628 static void
  629 pcvt_cn_probe(struct consdev *cp)
  630 {
  631         int unit = 0;
  632 
  633         /* See if this driver is disabled in probe hint. */
  634         if (resource_disabled("vt", unit))
  635         {
  636                 cp->cn_pri = CN_DEAD;
  637                 return;
  638         }
  639 
  640         kbd_configure(KB_CONF_PROBE_ONLY);
  641 
  642         if (kbd_find_keyboard("*", unit) < 0)
  643         {
  644                 cp->cn_pri = CN_DEAD;
  645                 return;
  646         }
  647 
  648         /* initialize required fields */
  649 
  650         sprintf(cp->cn_name, "ttyv%r", 0);
  651         cp->cn_pri = CN_INTERNAL;
  652         pcvt_tty[0] = ttymalloc(pcvt_tty[0]);
  653         cp->cn_tp = pcvt_tty[0];
  654 }
  655 
  656 /*---------------------------------------------------------------------------*
  657  *      console init
  658  *---------------------------------------------------------------------------*/
  659 static void
  660 pcvt_cn_init(struct consdev *cp)
  661 {
  662         int unit = 0;
  663         int i;
  664 
  665         pcvt_is_console = 1;
  666         pcvt_consptr = cp;
  667 
  668         /*
  669          * Don't reset the keyboard via `kbdio' just yet.
  670          * The system clock has not been calibrated...
  671          */
  672         reset_keyboard = 0;
  673 
  674         if (kbd)
  675         {
  676                 kbd_release(kbd, (void *)&kbd);
  677                 kbd = NULL;
  678         }
  679 
  680         i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
  681 
  682         if (i >= 0)
  683                 kbd = kbd_get_keyboard(i);
  684 
  685 #if PCVT_SCANSET == 2
  686         /*
  687          * Turn off scancode translation early so that
  688          * DDB can read the keyboard.
  689          */
  690         if (kbd)
  691         {
  692                 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
  693                 set_controller_command_byte(*(KBDC *)kbd->kb_data,
  694                                             KBD_TRANSLATION, 0);
  695         }
  696 #endif /* PCVT_SCANSET == 2 */
  697 }
  698 
  699 /*---------------------------------------------------------------------------*
  700  *      console finish
  701  *---------------------------------------------------------------------------*/
  702 static void
  703 pcvt_cn_term(struct consdev *cp)
  704 {
  705         if (kbd)
  706         {
  707                 kbd_release(kbd, (void *)&kbd);
  708                 kbd = NULL;
  709         }
  710 }
  711 
  712 /*---------------------------------------------------------------------------*
  713  *      console put char
  714  *---------------------------------------------------------------------------*/
  715 static void
  716 pcvt_cn_putc(struct consdev *cd, int c)
  717 {
  718         if (c == '\n')
  719                 sput("\r", 1, 1, 0);
  720 
  721         sput((char *) &c, 1, 1, 0);
  722 
  723         async_update(UPDATE_KERN);
  724 }
  725 
  726 /*---------------------------------------------------------------------------*
  727  *      console get char
  728  *---------------------------------------------------------------------------*/
  729 static int
  730 pcvt_cn_getc(struct consdev *cd)
  731 {
  732         register int s;
  733         static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
  734         register u_char c;
  735 
  736 #ifdef XSERVER
  737         if (pcvt_kbd_raw)
  738                 return 0;
  739 #endif /* XSERVER */
  740 
  741         if (cp && *cp)
  742         {
  743                 /*
  744                  * We still have a pending key sequence, e.g.
  745                  * from an arrow key.  Deliver this one first.
  746                  */
  747                 return (*cp++);
  748         }
  749 
  750         if (kbd == NULL)
  751                 return 0;
  752 
  753         s = spltty();           /* block pcvt_rint while we poll */
  754         kbd_polling = 1;
  755         (*kbdsw[kbd->kb_index]->enable)(kbd);
  756         cp = sgetc(0);
  757         (*kbdsw[kbd->kb_index]->disable)(kbd);
  758         kbd_polling = 0;
  759         splx(s);
  760 
  761         c = *cp++;
  762 
  763         if (c && *cp)
  764         {
  765                 /* Preserve the multi-char sequence for the next call. */
  766                 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
  767                 cp = cbuf;
  768         }
  769         else
  770         {
  771                 cp = 0;
  772         }
  773         return c;
  774 }
  775 
  776 /*---------------------------------------------------------------------------*
  777  *      console check for char
  778  *---------------------------------------------------------------------------*/
  779 static int
  780 pcvt_cn_checkc(struct consdev *cd)
  781 {
  782         char *cp;
  783         int x;
  784 
  785         if (kbd == NULL)
  786                 return 0;
  787 
  788         x = spltty();
  789         kbd_polling = 1;
  790         (*kbdsw[kbd->kb_index]->enable)(kbd);
  791         cp = sgetc(1);
  792         (*kbdsw[kbd->kb_index]->disable)(kbd);
  793         kbd_polling = 0;
  794         splx(x);
  795 
  796         return (cp == NULL ? -1 : *cp);
  797 }
  798 
  799 /*---------------------------------------------------------------------------*
  800  *      Set line parameters
  801  *---------------------------------------------------------------------------*/
  802 static int
  803 pcvt_param(struct tty *tp, struct termios *t)
  804 {
  805         tp->t_ispeed = t->c_ispeed;
  806         tp->t_ospeed = t->c_ospeed;
  807         tp->t_cflag  = t->c_cflag;
  808 
  809         return(0);
  810 }
  811 
  812 /*----------------------------------------------------------------------*
  813  *      read initial VGA palette (as stored by VGA ROM BIOS) into
  814  *      palette save area
  815  *----------------------------------------------------------------------*/
  816 static void
  817 vgapelinit(void)
  818 {
  819         register unsigned idx;
  820         register struct rgb *val;
  821 
  822         /* first, read all and store to first screen's save buffer */
  823         for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
  824                 vgapaletteio(idx, val, 0 /* read it */);
  825 
  826         /* now, duplicate for remaining screens */
  827         for(idx = 1; idx < PCVT_NSCREENS; idx++)
  828                 bcopy(vs[0].palette, vs[idx].palette,
  829                       NVGAPEL * sizeof(struct rgb));
  830 }
  831 
  832 /*-------------------------- E O F -------------------------------------*/

Cache object: 447d8d0a6d061dc25f75e9411ca2432c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.