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.0/sys/i386/isa/pcvt/pcvt_drv.c 94275 2002-04-09 11:18:46Z 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 #define CDEV_MAJOR      12
   97 
   98 static struct cdevsw vt_cdevsw = {
   99         /* open */      pcvt_open,
  100         /* close */     pcvt_close,
  101         /* read */      ttyread,
  102         /* write */     ttywrite,
  103         /* ioctl */     pcvt_ioctl,
  104         /* poll */      ttypoll,
  105         /* mmap */      pcvt_mmap,
  106         /* strategy */  nostrategy,
  107         /* name */      "vt",
  108         /* maj */       CDEV_MAJOR,
  109         /* dump */      nodump,
  110         /* psize */     nopsize,
  111         /* flags */     D_TTY | D_KQFILTER,
  112         /* kqfilter */  ttykqfilter,
  113 };
  114 
  115 static int pcvt_probe(device_t dev);
  116 static int pcvt_attach(device_t dev);
  117 static void pcvt_identify (driver_t *driver, device_t parent);
  118 
  119 static device_method_t pcvt_methods[] = {
  120         DEVMETHOD(device_identify,      pcvt_identify),
  121         DEVMETHOD(device_probe,         pcvt_probe),
  122         DEVMETHOD(device_attach,        pcvt_attach),
  123         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  124         { 0, 0 }
  125 };
  126 
  127 static driver_t pcvt_driver = {
  128         "vt",
  129         pcvt_methods,
  130         0
  131 };
  132 
  133 static devclass_t pcvt_devclass;
  134 
  135 DRIVER_MODULE(pcvt, isa, pcvt_driver, pcvt_devclass, 0, 0);
  136 
  137 /*---------------------------------------------------------------------------*
  138  *      driver identify
  139  *---------------------------------------------------------------------------*/
  140 static void
  141 pcvt_identify (driver_t *driver, device_t parent)
  142 {
  143         BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "vt", 0);
  144 }
  145 
  146 /*---------------------------------------------------------------------------*
  147  *      driver probe
  148  *---------------------------------------------------------------------------*/
  149 static int
  150 pcvt_probe(device_t dev)
  151 {
  152         int i;
  153         device_t bus;
  154         
  155         int unit = device_get_unit(dev);
  156 
  157         /* No pnp support */
  158         if(isa_get_vendorid(dev))
  159                 return ENXIO;
  160 
  161         if(unit != 0)
  162                 return ENXIO;   
  163         
  164         device_set_desc(dev, "pcvt VT220 console driver");
  165         
  166         bus = device_get_parent(dev);
  167         bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3b0, 0x30);
  168         bus_set_resource(dev, SYS_RES_MEMORY, 0, (u_long) Crtat, 0x8000);
  169 
  170         if (kbd == NULL)
  171         {
  172                 reset_keyboard = 0;
  173                 kbd_configure(KB_CONF_PROBE_ONLY);
  174                 i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)&vs[unit]);
  175                 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
  176                         return 0;
  177         }
  178         reset_keyboard = 1;             /* it's now safe to do kbd reset */
  179 
  180         kbd_code_init();
  181 
  182         return 0;
  183 }
  184 
  185 /*---------------------------------------------------------------------------*
  186  *      driver attach
  187  *---------------------------------------------------------------------------*/
  188 static int
  189 pcvt_attach(device_t dev)
  190 {
  191         int i;
  192         struct resource *port;
  193         struct resource *mem;
  194                 
  195         int unit = device_get_unit(dev);
  196         
  197         if(unit != 0)
  198                 return ENXIO;   
  199 
  200         i = 0;
  201         port = bus_alloc_resource(dev, SYS_RES_IOPORT, &i, 0, ~0, 0,
  202                                         RF_ACTIVE | RF_SHAREABLE);
  203 
  204         i = 0;
  205         mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &i, 0, ~0, 0,
  206                                         RF_ACTIVE | RF_SHAREABLE);
  207 
  208         vt_coldmalloc();                /* allocate memory for screens */
  209 
  210         if (kbd == NULL)
  211                 timeout(detect_kbd, (void *)&vs[unit], hz*2);
  212 
  213         printf("vt%d: ", unit);
  214 
  215         switch(adaptor_type)
  216         {
  217                 case MDA_ADAPTOR:
  218                         printf("MDA");
  219                         break;
  220 
  221                 case CGA_ADAPTOR:
  222                         printf("CGA");
  223                         break;
  224 
  225                 case EGA_ADAPTOR:
  226                         printf("EGA");
  227                         break;
  228 
  229                 case VGA_ADAPTOR:
  230                         printf("%s VGA, ", (char *)vga_string(vga_type));
  231                         if(can_do_132col)
  232                                 printf("80/132 columns");
  233                         else
  234                                 printf("80 columns");
  235                         vgapelinit();
  236                         break;
  237 
  238                 default:
  239                         printf("unknown");
  240                         break;
  241         }
  242 
  243         if(color == 0)
  244                 printf(", mono");
  245         else
  246                 printf(", color");
  247 
  248         printf(", %d screens, ", totalscreens);
  249 
  250         switch(keyboard_type)
  251         {
  252                 case KB_AT:
  253                         printf("AT-");
  254                         break;
  255 
  256                 case KB_MFII:
  257                         printf("MF2-");
  258                         break;
  259 
  260                 default:
  261                         printf("unknown ");
  262                         break;
  263         }
  264 
  265         printf("keyboard\n");
  266 
  267         for(i = 0; i < totalscreens; i++)
  268         {
  269                 ttyregister(&pcvt_tty[i]);
  270                 vs[i].vs_tty = &pcvt_tty[i];
  271                 make_dev(&vt_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
  272         }
  273 
  274         async_update(UPDATE_START);     /* start asynchronous updates */
  275 
  276         return 0;
  277 }
  278 
  279 /*---------------------------------------------------------------------------*
  280  *      driver open
  281  *---------------------------------------------------------------------------*/
  282 static int
  283 pcvt_open(dev_t dev, int flag, int mode, struct thread *td)
  284 {
  285         register struct tty *tp;
  286         register struct video_state *vsx;
  287         int s, retval;
  288         int winsz = 0;
  289         int i = minor(dev);
  290 
  291         vsx = &vs[i];
  292 
  293         if(i >= PCVT_NSCREENS)
  294                 return ENXIO;
  295 
  296         tp = &pcvt_tty[i];
  297 
  298         dev->si_tty = tp;
  299 
  300         vsx->openf++;
  301 
  302         tp->t_oproc = pcvt_start;
  303         tp->t_param = pcvt_param;
  304         tp->t_stop = nottystop;
  305         tp->t_dev = dev;
  306 
  307         if ((tp->t_state & TS_ISOPEN) == 0)
  308         {
  309                 ttychars(tp);
  310                 tp->t_iflag = TTYDEF_IFLAG;
  311                 tp->t_oflag = TTYDEF_OFLAG;
  312                 tp->t_cflag = TTYDEF_CFLAG;
  313                 tp->t_lflag = TTYDEF_LFLAG;
  314                 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
  315                 pcvt_param(tp, &tp->t_termios);
  316                 (*linesw[tp->t_line].l_modem)(tp, 1);   /* fake connection */
  317                 winsz = 1;                      /* set winsize later */
  318         }
  319         else if (tp->t_state & TS_XCLUDE && suser(td))
  320         {
  321                 return (EBUSY);
  322         }
  323 
  324         retval = ((*linesw[tp->t_line].l_open)(dev, tp));
  325 
  326         if(winsz == 1)
  327         {
  328                 /*
  329                  * The line discipline has clobbered t_winsize if TS_ISOPEN
  330                  * was clear. (NetBSD PR #400 from Bill Sommerfeld)
  331                  * We have to do this after calling the open routine, because
  332                  * it does some other things in other/older *BSD releases -hm
  333                  */
  334 
  335                 s = spltty();
  336 
  337                 tp->t_winsize.ws_col = vsx->maxcol;
  338                 tp->t_winsize.ws_row = vsx->screen_rows;
  339                 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
  340                 tp->t_winsize.ws_ypixel = 400;
  341 
  342                 splx(s);
  343         }
  344         return(retval);
  345 }
  346 
  347 /*---------------------------------------------------------------------------*
  348  *      driver close
  349  *---------------------------------------------------------------------------*/
  350 static int
  351 pcvt_close(dev_t dev, int flag, int mode, struct thread *td)
  352 {
  353         register struct tty *tp;
  354         register struct video_state *vsx;
  355         int i = minor(dev);
  356 
  357         vsx = &vs[i];
  358 
  359         if(i >= PCVT_NSCREENS)
  360                 return ENXIO;
  361 
  362         tp = &pcvt_tty[i];
  363 
  364         (*linesw[tp->t_line].l_close)(tp, flag);
  365 
  366         ttyclose(tp);
  367 
  368         vsx->openf = 0;
  369 
  370 #ifdef XSERVER
  371         reset_usl_modes(vsx);
  372 #endif /* XSERVER */
  373 
  374         return(0);
  375 }
  376 
  377 /*---------------------------------------------------------------------------*
  378  *      driver ioctl
  379  *---------------------------------------------------------------------------*/
  380 static int
  381 pcvt_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
  382 {
  383         register int error;
  384         register struct tty *tp;
  385         int i = minor(dev);
  386         
  387         if(i >= PCVT_NSCREENS)
  388                 return ENXIO;
  389 
  390         tp = &pcvt_tty[i];
  391 
  392         /* note that some ioctl's are global, e.g.  KBSTPMAT: There is
  393          * only one keyboard and different repeat rates for instance between
  394          * sessions are a suspicious wish. If you really need this make the
  395          * appropriate variables arrays
  396          */
  397 
  398 #ifdef XSERVER
  399         if((error = usl_vt_ioctl(dev, cmd, data, flag, td)) >= 0)
  400                 return error;
  401 #endif /* XSERVER */
  402 
  403         if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
  404                 return error;
  405 
  406         if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
  407                 return error;
  408 
  409         if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td))
  410             != ENOIOCTL)
  411                 return (error);
  412 
  413         if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
  414                 return (error);
  415 
  416         return (ENOTTY);
  417 }
  418 
  419 /*---------------------------------------------------------------------------*
  420  *      driver mmap
  421  *---------------------------------------------------------------------------*/
  422 static int
  423 pcvt_mmap(dev_t dev, vm_offset_t offset, int nprot)
  424 {
  425         if (offset > 0x20000 - PAGE_SIZE)
  426                 return -1;
  427         return i386_btop((0xa0000 + offset));
  428 }
  429 
  430 /*---------------------------------------------------------------------------*
  431  *      timeout handler
  432  *---------------------------------------------------------------------------*/
  433 static void
  434 pcvt_timeout(void *arg)
  435 {
  436         u_char *cp;
  437 
  438 #if PCVT_SLOW_INTERRUPT
  439         int     s;
  440 #endif
  441 
  442         pcvt_timeout_scheduled = 0;
  443 
  444 #if PCVT_SCREENSAVER
  445         pcvt_scrnsv_reset();
  446 #endif /* PCVT_SCREENSAVER */
  447 
  448         while (pcvt_kbd_count)
  449         {
  450                 if (((cp = sgetc(1)) != 0) &&
  451                     (vs[current_video_screen].openf))
  452                 {
  453 
  454 #if PCVT_NULLCHARS
  455                         if(*cp == '\0')
  456                         {
  457                                 /* pass a NULL character */
  458                                 (*linesw[pcvt_ttyp->t_line].l_rint)('\0', pcvt_ttyp);
  459                         }
  460 /* XXX */               else
  461 #endif /* PCVT_NULLCHARS */
  462 
  463                         while (*cp)
  464                                 (*linesw[pcvt_ttyp->t_line].l_rint)(*cp++ & 0xff, pcvt_ttyp);
  465                 }
  466 
  467                 PCVT_DISABLE_INTR ();
  468 
  469                 if (!pcvt_kbd_count)
  470                         pcvt_timeout_scheduled = 0;
  471 
  472                 PCVT_ENABLE_INTR ();
  473         }
  474 
  475         return;
  476 }
  477 
  478 /*---------------------------------------------------------------------------*
  479  *      check for keyboard
  480  *---------------------------------------------------------------------------*/
  481 static void
  482 detect_kbd(void *arg)
  483 {
  484         int unit = (int)arg;
  485         int i;
  486 
  487         if (kbd != NULL)
  488                 return;
  489         i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
  490         if (i >= 0)
  491                 kbd = kbd_get_keyboard(i);
  492         if (kbd != NULL)
  493         {
  494                 reset_keyboard = 1;     /* ok to reset the keyboard */
  495                 kbd_code_init();
  496                 return;
  497         }
  498         reset_keyboard = 0;
  499         timeout(detect_kbd, (void *)unit, hz*2);
  500 }
  501 
  502 /*---------------------------------------------------------------------------*
  503  *      keyboard event handler
  504  *---------------------------------------------------------------------------*/
  505 static int
  506 pcvt_event(keyboard_t *thiskbd, int event, void *arg)
  507 {
  508         int unit = (int)arg;
  509 
  510         if (thiskbd != kbd)
  511                 return EINVAL;          /* shouldn't happen */
  512 
  513         switch (event) {
  514         case KBDIO_KEYINPUT:
  515                 pcvt_rint(unit);
  516                 return 0;
  517         case KBDIO_UNLOADING:
  518                 reset_keyboard = 0;
  519                 kbd = NULL;
  520                 kbd_release(thiskbd, (void *)&kbd);
  521                 timeout(detect_kbd, (void *)unit, hz*4);
  522                 return 0;
  523         default:
  524                 return EINVAL;
  525         }
  526 }
  527 
  528 /*---------------------------------------------------------------------------*
  529  *      (keyboard) interrupt handler
  530  *---------------------------------------------------------------------------*/
  531 void
  532 pcvt_rint(int unit)
  533 {
  534         u_char  dt;
  535         u_char  ret = -1;
  536         int     c;
  537         
  538 # if PCVT_SLOW_INTERRUPT
  539         int     s;
  540 # endif
  541 
  542 #if PCVT_SCREENSAVER
  543         pcvt_scrnsv_reset();
  544 #endif /* PCVT_SCREENSAVER */
  545 
  546         if (kbd_polling)
  547         {
  548                 sgetc(1);
  549                 return;
  550         }
  551 
  552         while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
  553         {
  554                 ret = 1;                                /* got something */
  555                 dt = c;
  556 
  557                 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
  558                 {
  559                         log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
  560                 }
  561                 else
  562                 {
  563                         pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
  564 
  565                         PCVT_DISABLE_INTR ();   /* XXX necessary ? */
  566                         pcvt_kbd_count++;               /* update fifo count */
  567                         PCVT_ENABLE_INTR ();
  568 
  569                         if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
  570                                 pcvt_kbd_wptr = 0;      /* wraparound pointer */
  571                 }
  572         }
  573 
  574         if (ret == 1)   /* got data from keyboard ? */
  575         {
  576                 if (!pcvt_timeout_scheduled)    /* if not already active .. */
  577                 {
  578                         PCVT_DISABLE_INTR ();
  579                         pcvt_timeout_scheduled = 1;     /* flag active */
  580                         timeout(pcvt_timeout, NULL, hz / 100);  /* fire off */
  581                         PCVT_ENABLE_INTR ();
  582                 }
  583         }
  584 }
  585 
  586 /*---------------------------------------------------------------------------*
  587  *      start output
  588  *---------------------------------------------------------------------------*/
  589 static void
  590 pcvt_start(register struct tty *tp)
  591 {
  592         register struct clist *rbp;
  593         int s, len;
  594         u_char buf[PCVT_PCBURST];
  595 
  596         s = spltty();
  597 
  598         if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
  599                 goto out;
  600 
  601         tp->t_state |= TS_BUSY;
  602 
  603         splx(s);
  604 
  605         async_update(UPDATE_KERN);
  606 
  607         rbp = &tp->t_outq;
  608 
  609         /*
  610          * Call q_to_b() at spltty() to ensure that the queue is empty when
  611          * the loop terminates.
  612          */
  613 
  614         s = spltty();
  615 
  616         while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
  617         {
  618                 if(vs[minor(tp->t_dev)].scrolling)
  619                         sgetc(SCROLLBACK_COOKIE);
  620                 
  621                 /*
  622                  * We need to do this outside spl since it could be fairly
  623                  * expensive and we don't want our serial ports to overflow.
  624                  */
  625                 splx(s);
  626                 sput(&buf[0], 0, len, minor(tp->t_dev));
  627                 s = spltty();
  628         }
  629 
  630         tp->t_state &= ~TS_BUSY;
  631 
  632         ttwwakeup(tp);
  633 
  634 out:
  635         splx(s);
  636 }
  637 
  638 /*---------------------------------------------------------------------------*
  639  *      console probe
  640  *---------------------------------------------------------------------------*/
  641 static void
  642 pcvt_cn_probe(struct consdev *cp)
  643 {
  644         int unit = 0;
  645         int i;
  646 
  647         /* See if this driver is disabled in probe hint. */ 
  648         if (resource_int_value("vt", unit, "disabled", &i) == 0 && i)
  649         {
  650                 cp->cn_pri = CN_DEAD;
  651                 return;
  652         }
  653 
  654         kbd_configure(KB_CONF_PROBE_ONLY);
  655 
  656         if (kbd_find_keyboard("*", unit) < 0)
  657         {
  658                 cp->cn_pri = CN_DEAD;
  659                 return;
  660         }
  661 
  662         /* initialize required fields */
  663 
  664         cp->cn_dev = makedev(CDEV_MAJOR, 0);
  665         cp->cn_pri = CN_INTERNAL;
  666         cp->cn_tp = &pcvt_tty[0];
  667 }
  668 
  669 /*---------------------------------------------------------------------------*
  670  *      console init
  671  *---------------------------------------------------------------------------*/
  672 static void
  673 pcvt_cn_init(struct consdev *cp)
  674 {
  675         int unit = 0;
  676         int i;
  677 
  678         pcvt_is_console = 1;
  679 
  680         /*
  681          * Don't reset the keyboard via `kbdio' just yet.
  682          * The system clock has not been calibrated...
  683          */
  684         reset_keyboard = 0;
  685 
  686         if (kbd)
  687         {
  688                 kbd_release(kbd, (void *)&kbd);
  689                 kbd = NULL;
  690         }
  691 
  692         i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
  693 
  694         if (i >= 0)
  695                 kbd = kbd_get_keyboard(i);
  696 
  697 #if PCVT_SCANSET == 2
  698         /*
  699          * Turn off scancode translation early so that
  700          * DDB can read the keyboard.
  701          */
  702         if (kbd)
  703         {
  704                 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
  705                 set_controller_command_byte(*(KBDC *)kbd->kb_data,
  706                                             KBD_TRANSLATION, 0);
  707         }
  708 #endif /* PCVT_SCANSET == 2 */
  709 }
  710 
  711 /*---------------------------------------------------------------------------*
  712  *      console finish
  713  *---------------------------------------------------------------------------*/
  714 static void
  715 pcvt_cn_term(struct consdev *cp)
  716 {
  717         if (kbd)
  718         {
  719                 kbd_release(kbd, (void *)&kbd);
  720                 kbd = NULL;
  721         }
  722 }
  723 
  724 /*---------------------------------------------------------------------------*
  725  *      console put char
  726  *---------------------------------------------------------------------------*/
  727 static void
  728 pcvt_cn_putc(dev_t dev, int c)
  729 {
  730         if (c == '\n')
  731                 sput("\r", 1, 1, 0);
  732 
  733         sput((char *) &c, 1, 1, 0);
  734 
  735         async_update(UPDATE_KERN);
  736 }
  737 
  738 /*---------------------------------------------------------------------------*
  739  *      console get char
  740  *---------------------------------------------------------------------------*/
  741 static int
  742 pcvt_cn_getc(dev_t dev)
  743 {
  744         register int s;
  745         static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
  746         register u_char c;
  747 
  748 #ifdef XSERVER
  749         if (pcvt_kbd_raw)
  750                 return 0;
  751 #endif /* XSERVER */
  752 
  753         if (cp && *cp)
  754         {
  755                 /*
  756                  * We still have a pending key sequence, e.g.
  757                  * from an arrow key.  Deliver this one first.
  758                  */
  759                 return (*cp++);
  760         }
  761 
  762         if (kbd == NULL)
  763                 return 0;
  764 
  765         s = spltty();           /* block pcvt_rint while we poll */
  766         kbd_polling = 1;
  767         (*kbdsw[kbd->kb_index]->enable)(kbd);
  768         cp = sgetc(0);
  769         (*kbdsw[kbd->kb_index]->disable)(kbd);
  770         kbd_polling = 0;
  771         splx(s);
  772 
  773         c = *cp++;
  774 
  775         if (c && *cp)
  776         {
  777                 /* Preserve the multi-char sequence for the next call. */
  778                 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
  779                 cp = cbuf;
  780         }
  781         else
  782         {
  783                 cp = 0;
  784         }
  785         return c;
  786 }
  787 
  788 /*---------------------------------------------------------------------------*
  789  *      console check for char
  790  *---------------------------------------------------------------------------*/
  791 static int
  792 pcvt_cn_checkc(dev_t dev)
  793 {
  794         char *cp;
  795         int x;
  796 
  797         if (kbd == NULL)
  798                 return 0;
  799 
  800         x = spltty();
  801         kbd_polling = 1;
  802         (*kbdsw[kbd->kb_index]->enable)(kbd);
  803         cp = sgetc(1);
  804         (*kbdsw[kbd->kb_index]->disable)(kbd);
  805         kbd_polling = 0;
  806         splx(x);
  807 
  808         return (cp == NULL ? -1 : *cp);
  809 }
  810 
  811 /*---------------------------------------------------------------------------*
  812  *      Set line parameters
  813  *---------------------------------------------------------------------------*/
  814 static int
  815 pcvt_param(struct tty *tp, struct termios *t)
  816 {
  817         tp->t_ispeed = t->c_ispeed;
  818         tp->t_ospeed = t->c_ospeed;
  819         tp->t_cflag  = t->c_cflag;
  820 
  821         return(0);
  822 }
  823 
  824 /*----------------------------------------------------------------------*
  825  *      read initial VGA palette (as stored by VGA ROM BIOS) into
  826  *      palette save area
  827  *----------------------------------------------------------------------*/
  828 static void
  829 vgapelinit(void)
  830 {
  831         register unsigned idx;
  832         register struct rgb *val;
  833 
  834         /* first, read all and store to first screen's save buffer */
  835         for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
  836                 vgapaletteio(idx, val, 0 /* read it */);
  837 
  838         /* now, duplicate for remaining screens */
  839         for(idx = 1; idx < PCVT_NSCREENS; idx++)
  840                 bcopy(vs[0].palette, vs[idx].palette,
  841                       NVGAPEL * sizeof(struct rgb));
  842 }
  843 
  844 /*-------------------------- E O F -------------------------------------*/

Cache object: 4edcf5d327da39b4a4090ad02b63d86d


[ 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.