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/6.1/sys/i386/isa/pcvt/pcvt_drv.c 139790 2005-01-06 22:18:23Z imp $
   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                 ttyinitmode(tp, 1, 0);
  301                 pcvt_param(tp, &tp->t_termios);
  302                 ttyld_modem(tp, 1);     /* fake connection */
  303                 winsz = 1;                      /* set winsize later */
  304         }
  305         else if (tp->t_state & TS_XCLUDE && suser(td))
  306         {
  307                 return (EBUSY);
  308         }
  309 
  310         retval = (ttyld_open(tp, dev));
  311 
  312         if(winsz == 1)
  313         {
  314                 /*
  315                  * The line discipline has clobbered t_winsize if TS_ISOPEN
  316                  * was clear. (NetBSD PR #400 from Bill Sommerfeld)
  317                  * We have to do this after calling the open routine, because
  318                  * it does some other things in other/older *BSD releases -hm
  319                  */
  320 
  321                 s = spltty();
  322 
  323                 tp->t_winsize.ws_col = vsx->maxcol;
  324                 tp->t_winsize.ws_row = vsx->screen_rows;
  325                 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
  326                 tp->t_winsize.ws_ypixel = 400;
  327 
  328                 splx(s);
  329         }
  330         return(retval);
  331 }
  332 
  333 /*---------------------------------------------------------------------------*
  334  *      driver close
  335  *---------------------------------------------------------------------------*/
  336 static int
  337 pcvt_close(struct cdev *dev, int flag, int mode, struct thread *td)
  338 {
  339         register struct tty *tp;
  340         register struct video_state *vsx;
  341         int i = minor(dev);
  342 
  343         vsx = &vs[i];
  344 
  345         if(i >= PCVT_NSCREENS)
  346                 return ENXIO;
  347 
  348         tp = pcvt_tty[i];
  349 
  350         ttyld_close(tp, flag);
  351 
  352         tty_close(tp);
  353 
  354         vsx->openf = 0;
  355 
  356 #ifdef XSERVER
  357         reset_usl_modes(vsx);
  358 #endif /* XSERVER */
  359 
  360         return(0);
  361 }
  362 
  363 /*---------------------------------------------------------------------------*
  364  *      driver ioctl
  365  *---------------------------------------------------------------------------*/
  366 static int
  367 pcvt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
  368 {
  369         register int error;
  370         register struct tty *tp;
  371         int i = minor(dev);
  372         
  373         if(i >= PCVT_NSCREENS)
  374                 return ENXIO;
  375 
  376         tp = pcvt_tty[i];
  377 
  378         /* note that some ioctl's are global, e.g.  KBSTPMAT: There is
  379          * only one keyboard and different repeat rates for instance between
  380          * sessions are a suspicious wish. If you really need this make the
  381          * appropriate variables arrays
  382          */
  383 
  384 #ifdef XSERVER
  385         if((error = usl_vt_ioctl(dev, cmd, data, flag, td)) >= 0)
  386                 return error;
  387 #endif /* XSERVER */
  388 
  389         if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
  390                 return error;
  391 
  392         if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
  393                 return error;
  394 
  395         return (ttyioctl(dev, cmd, data, flag, td));
  396 }
  397 
  398 /*---------------------------------------------------------------------------*
  399  *      driver mmap
  400  *---------------------------------------------------------------------------*/
  401 static int
  402 pcvt_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
  403 {
  404         if (offset > 0x20000 - PAGE_SIZE)
  405                 return -1;
  406         *paddr = 0xa0000 + offset;
  407         return 0;
  408 }
  409 
  410 /*---------------------------------------------------------------------------*
  411  *      timeout handler
  412  *---------------------------------------------------------------------------*/
  413 static void
  414 pcvt_timeout(void *arg)
  415 {
  416         u_char *cp;
  417         struct tty *tp;
  418 
  419 #if PCVT_SLOW_INTERRUPT
  420         int     s;
  421 #endif
  422 
  423         pcvt_timeout_scheduled = 0;
  424 
  425 #if PCVT_SCREENSAVER
  426         pcvt_scrnsv_reset();
  427 #endif /* PCVT_SCREENSAVER */
  428 
  429         tp = pcvt_tty[current_video_screen];
  430         while (pcvt_kbd_count)
  431         {
  432                 if (((cp = sgetc(1)) != 0) &&
  433                     (vs[current_video_screen].openf))
  434                 {
  435 
  436 #if PCVT_NULLCHARS
  437                         if(*cp == '\0')
  438                         {
  439                                 /* pass a NULL character */
  440                                 ttyld_rint(tp, '\0');
  441                         }
  442 /* XXX */               else
  443 #endif /* PCVT_NULLCHARS */
  444 
  445                         while (*cp)
  446                                 ttyld_rint(tp, *cp++ & 0xff);
  447                 }
  448 
  449                 PCVT_DISABLE_INTR ();
  450 
  451                 if (!pcvt_kbd_count)
  452                         pcvt_timeout_scheduled = 0;
  453 
  454                 PCVT_ENABLE_INTR ();
  455         }
  456 
  457         return;
  458 }
  459 
  460 /*---------------------------------------------------------------------------*
  461  *      check for keyboard
  462  *---------------------------------------------------------------------------*/
  463 static void
  464 detect_kbd(void *arg)
  465 {
  466         int unit = (int)arg;
  467         int i;
  468 
  469         if (kbd != NULL)
  470                 return;
  471         i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
  472         if (i >= 0)
  473                 kbd = kbd_get_keyboard(i);
  474         if (kbd != NULL)
  475         {
  476                 reset_keyboard = 1;     /* ok to reset the keyboard */
  477                 kbd_code_init();
  478                 return;
  479         }
  480         reset_keyboard = 0;
  481         timeout(detect_kbd, (void *)unit, hz*2);
  482 }
  483 
  484 /*---------------------------------------------------------------------------*
  485  *      keyboard event handler
  486  *---------------------------------------------------------------------------*/
  487 static int
  488 pcvt_event(keyboard_t *thiskbd, int event, void *arg)
  489 {
  490         int unit = (int)arg;
  491 
  492         if (thiskbd != kbd)
  493                 return EINVAL;          /* shouldn't happen */
  494 
  495         switch (event) {
  496         case KBDIO_KEYINPUT:
  497                 pcvt_rint(unit);
  498                 return 0;
  499         case KBDIO_UNLOADING:
  500                 reset_keyboard = 0;
  501                 kbd = NULL;
  502                 kbd_release(thiskbd, (void *)&kbd);
  503                 timeout(detect_kbd, (void *)unit, hz*4);
  504                 return 0;
  505         default:
  506                 return EINVAL;
  507         }
  508 }
  509 
  510 /*---------------------------------------------------------------------------*
  511  *      (keyboard) interrupt handler
  512  *---------------------------------------------------------------------------*/
  513 void
  514 pcvt_rint(int unit)
  515 {
  516         u_char  dt;
  517         u_char  ret = -1;
  518         int     c;
  519         
  520 # if PCVT_SLOW_INTERRUPT
  521         int     s;
  522 # endif
  523 
  524 #if PCVT_SCREENSAVER
  525         pcvt_scrnsv_reset();
  526 #endif /* PCVT_SCREENSAVER */
  527 
  528         if (kbd_polling)
  529         {
  530                 sgetc(1);
  531                 return;
  532         }
  533 
  534         while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
  535         {
  536                 ret = 1;                                /* got something */
  537                 dt = c;
  538 
  539                 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
  540                 {
  541                         log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
  542                 }
  543                 else
  544                 {
  545                         pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
  546 
  547                         PCVT_DISABLE_INTR ();   /* XXX necessary ? */
  548                         pcvt_kbd_count++;               /* update fifo count */
  549                         PCVT_ENABLE_INTR ();
  550 
  551                         if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
  552                                 pcvt_kbd_wptr = 0;      /* wraparound pointer */
  553                 }
  554         }
  555 
  556         if (ret == 1)   /* got data from keyboard ? */
  557         {
  558                 if (!pcvt_timeout_scheduled)    /* if not already active .. */
  559                 {
  560                         PCVT_DISABLE_INTR ();
  561                         pcvt_timeout_scheduled = 1;     /* flag active */
  562                         timeout(pcvt_timeout, NULL, hz / 100);  /* fire off */
  563                         PCVT_ENABLE_INTR ();
  564                 }
  565         }
  566 }
  567 
  568 /*---------------------------------------------------------------------------*
  569  *      start output
  570  *---------------------------------------------------------------------------*/
  571 static void
  572 pcvt_start(register struct tty *tp)
  573 {
  574         register struct clist *rbp;
  575         int s, len;
  576         u_char buf[PCVT_PCBURST];
  577 
  578         s = spltty();
  579 
  580         if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
  581                 goto out;
  582 
  583         tp->t_state |= TS_BUSY;
  584 
  585         splx(s);
  586 
  587         async_update(UPDATE_KERN);
  588 
  589         rbp = &tp->t_outq;
  590 
  591         /*
  592          * Call q_to_b() at spltty() to ensure that the queue is empty when
  593          * the loop terminates.
  594          */
  595 
  596         s = spltty();
  597 
  598         while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
  599         {
  600                 if(vs[minor(tp->t_dev)].scrolling)
  601                         sgetc(SCROLLBACK_COOKIE);
  602                 
  603                 /*
  604                  * We need to do this outside spl since it could be fairly
  605                  * expensive and we don't want our serial ports to overflow.
  606                  */
  607                 splx(s);
  608                 sput(&buf[0], 0, len, minor(tp->t_dev));
  609                 s = spltty();
  610         }
  611 
  612         tp->t_state &= ~TS_BUSY;
  613 
  614         ttwwakeup(tp);
  615 
  616 out:
  617         splx(s);
  618 }
  619 
  620 /*---------------------------------------------------------------------------*
  621  *      console probe
  622  *---------------------------------------------------------------------------*/
  623 static void
  624 pcvt_cn_probe(struct consdev *cp)
  625 {
  626         int unit = 0;
  627 
  628         /* See if this driver is disabled in probe hint. */
  629         if (resource_disabled("vt", unit))
  630         {
  631                 cp->cn_pri = CN_DEAD;
  632                 return;
  633         }
  634 
  635         kbd_configure(KB_CONF_PROBE_ONLY);
  636 
  637         if (kbd_find_keyboard("*", unit) < 0)
  638         {
  639                 cp->cn_pri = CN_DEAD;
  640                 return;
  641         }
  642 
  643         /* initialize required fields */
  644 
  645         sprintf(cp->cn_name, "ttyv%r", 0);
  646         cp->cn_pri = CN_INTERNAL;
  647         pcvt_tty[0] = ttymalloc(pcvt_tty[0]);
  648         cp->cn_tp = pcvt_tty[0];
  649 }
  650 
  651 /*---------------------------------------------------------------------------*
  652  *      console init
  653  *---------------------------------------------------------------------------*/
  654 static void
  655 pcvt_cn_init(struct consdev *cp)
  656 {
  657         int unit = 0;
  658         int i;
  659 
  660         pcvt_is_console = 1;
  661         pcvt_consptr = cp;
  662 
  663         /*
  664          * Don't reset the keyboard via `kbdio' just yet.
  665          * The system clock has not been calibrated...
  666          */
  667         reset_keyboard = 0;
  668 
  669         if (kbd)
  670         {
  671                 kbd_release(kbd, (void *)&kbd);
  672                 kbd = NULL;
  673         }
  674 
  675         i = kbd_allocate("*", -1, (void *)&kbd, pcvt_event, (void *)unit);
  676 
  677         if (i >= 0)
  678                 kbd = kbd_get_keyboard(i);
  679 
  680 #if PCVT_SCANSET == 2
  681         /*
  682          * Turn off scancode translation early so that
  683          * DDB can read the keyboard.
  684          */
  685         if (kbd)
  686         {
  687                 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
  688                 set_controller_command_byte(*(KBDC *)kbd->kb_data,
  689                                             KBD_TRANSLATION, 0);
  690         }
  691 #endif /* PCVT_SCANSET == 2 */
  692 }
  693 
  694 /*---------------------------------------------------------------------------*
  695  *      console finish
  696  *---------------------------------------------------------------------------*/
  697 static void
  698 pcvt_cn_term(struct consdev *cp)
  699 {
  700         if (kbd)
  701         {
  702                 kbd_release(kbd, (void *)&kbd);
  703                 kbd = NULL;
  704         }
  705 }
  706 
  707 /*---------------------------------------------------------------------------*
  708  *      console put char
  709  *---------------------------------------------------------------------------*/
  710 static void
  711 pcvt_cn_putc(struct consdev *cd, int c)
  712 {
  713         if (c == '\n')
  714                 sput("\r", 1, 1, 0);
  715 
  716         sput((char *) &c, 1, 1, 0);
  717 
  718         async_update(UPDATE_KERN);
  719 }
  720 
  721 /*---------------------------------------------------------------------------*
  722  *      console get char
  723  *---------------------------------------------------------------------------*/
  724 static int
  725 pcvt_cn_getc(struct consdev *cd)
  726 {
  727         register int s;
  728         static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
  729         register u_char c;
  730 
  731 #ifdef XSERVER
  732         if (pcvt_kbd_raw)
  733                 return 0;
  734 #endif /* XSERVER */
  735 
  736         if (cp && *cp)
  737         {
  738                 /*
  739                  * We still have a pending key sequence, e.g.
  740                  * from an arrow key.  Deliver this one first.
  741                  */
  742                 return (*cp++);
  743         }
  744 
  745         if (kbd == NULL)
  746                 return 0;
  747 
  748         s = spltty();           /* block pcvt_rint while we poll */
  749         kbd_polling = 1;
  750         (*kbdsw[kbd->kb_index]->enable)(kbd);
  751         cp = sgetc(0);
  752         (*kbdsw[kbd->kb_index]->disable)(kbd);
  753         kbd_polling = 0;
  754         splx(s);
  755 
  756         c = *cp++;
  757 
  758         if (c && *cp)
  759         {
  760                 /* Preserve the multi-char sequence for the next call. */
  761                 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
  762                 cp = cbuf;
  763         }
  764         else
  765         {
  766                 cp = 0;
  767         }
  768         return c;
  769 }
  770 
  771 /*---------------------------------------------------------------------------*
  772  *      console check for char
  773  *---------------------------------------------------------------------------*/
  774 static int
  775 pcvt_cn_checkc(struct consdev *cd)
  776 {
  777         char *cp;
  778         int x;
  779 
  780         if (kbd == NULL)
  781                 return 0;
  782 
  783         x = spltty();
  784         kbd_polling = 1;
  785         (*kbdsw[kbd->kb_index]->enable)(kbd);
  786         cp = sgetc(1);
  787         (*kbdsw[kbd->kb_index]->disable)(kbd);
  788         kbd_polling = 0;
  789         splx(x);
  790 
  791         return (cp == NULL ? -1 : *cp);
  792 }
  793 
  794 /*---------------------------------------------------------------------------*
  795  *      Set line parameters
  796  *---------------------------------------------------------------------------*/
  797 static int
  798 pcvt_param(struct tty *tp, struct termios *t)
  799 {
  800         tp->t_ispeed = t->c_ispeed;
  801         tp->t_ospeed = t->c_ospeed;
  802         tp->t_cflag  = t->c_cflag;
  803 
  804         return(0);
  805 }
  806 
  807 /*----------------------------------------------------------------------*
  808  *      read initial VGA palette (as stored by VGA ROM BIOS) into
  809  *      palette save area
  810  *----------------------------------------------------------------------*/
  811 static void
  812 vgapelinit(void)
  813 {
  814         register unsigned idx;
  815         register struct rgb *val;
  816 
  817         /* first, read all and store to first screen's save buffer */
  818         for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
  819                 vgapaletteio(idx, val, 0 /* read it */);
  820 
  821         /* now, duplicate for remaining screens */
  822         for(idx = 1; idx < PCVT_NSCREENS; idx++)
  823                 bcopy(vs[0].palette, vs[idx].palette,
  824                       NVGAPEL * sizeof(struct rgb));
  825 }
  826 
  827 /*-------------------------- E O F -------------------------------------*/

Cache object: 4317f8e75df8fc03dd841066be016476


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