Diff for /src/sys/kern/tty_cons.c between versions 1.12 and 1.13

version 1.12, 2004/05/13 23:49:23 version 1.13, 2004/05/19 22:52:58
Line 60 Line 60
   
 #include <machine/cpu.h>  #include <machine/cpu.h>
   
 static  d_open_t        cnopen;  static int cnopen(struct cdevmsg_open *msg);
 static  d_close_t       cnclose;  static int cnclose(struct cdevmsg_close *msg);
 static  d_read_t        cnread;  static int cnread(struct cdevmsg_read *msg);
 static  d_write_t       cnwrite;  static int cnwrite(struct cdevmsg_write *msg);
 static  d_ioctl_t       cnioctl;  static int cnioctl(struct cdevmsg_ioctl *msg);
 static  d_poll_t        cnpoll;  static int cnpoll(struct cdevmsg_poll *msg);
 static  d_kqfilter_t    cnkqfilter;  static int cnkqfilter(struct cdevmsg_kqfilter *msg);
   
 static int console_putport(lwkt_port_t port, lwkt_msg_t lmsg);  static int console_putport(lwkt_port_t port, lwkt_msg_t lmsg);
   static int console_interceptport(lwkt_port_t port, lwkt_msg_t lmsg);
   
   static struct lwkt_port cn_port;        /* console device port */
   static struct lwkt_port cn_iport;       /* intercept port */
   
 #define CDEV_MAJOR      0  #define CDEV_MAJOR      0
 static struct cdevsw cn_cdevsw = {  static struct cdevsw cn_cdevsw = {
         /* name */      "console",          /* name */      "console",
         /* maj */       CDEV_MAJOR,          /* maj */       CDEV_MAJOR,
         /* flags */     D_TTY | D_KQFILTER,          /* flags */     D_TTY | D_KQFILTER,
         /* port */      NULL,          /* port */      &cn_port,
         /* clone */     NULL,          /* clone */     NULL
   
         /* open */      cnopen,  
         /* close */     cnclose,  
         /* read */      cnread,  
         /* write */     cnwrite,  
         /* ioctl */     cnioctl,  
         /* poll */      cnpoll,  
         /* mmap */      nommap,  
         /* strategy */  nostrategy,  
         /* dump */      nodump,  
         /* psize */     nopsize,  
         /* kqfilter */  cnkqfilter  
 };  };
   
 static dev_t    cn_dev_t;       /* seems to be never really used */  static dev_t    cn_dev_t;
 static udev_t   cn_udev_t;  static udev_t   cn_udev_t;
 SYSCTL_OPAQUE(_machdep, CPU_CONSDEV, consdev, CTLFLAG_RD,  SYSCTL_OPAQUE(_machdep, CPU_CONSDEV, consdev, CTLFLAG_RD,
         &cn_udev_t, sizeof cn_udev_t, "T,dev_t", "");          &cn_udev_t, sizeof cn_udev_t, "T,dev_t", "");
Line 112  static char *console_pausestr= Line 105  static char *console_pausestr=
 "<pause; press any key to proceed to next line or '.' to end pause mode>";  "<pause; press any key to proceed to next line or '.' to end pause mode>";
   
 static lwkt_port_t      cn_fwd_port;  static lwkt_port_t      cn_fwd_port;
 static struct lwkt_port cn_port;  
   
   
 CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL, NULL);  CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 SET_DECLARE(cons_set, struct consdev);  SET_DECLARE(cons_set, struct consdev);
Line 128  cninit() Line 119  cninit()
          */           */
         lwkt_initport(&cn_port, NULL);          lwkt_initport(&cn_port, NULL);
         cn_port.mp_putport = console_putport;          cn_port.mp_putport = console_putport;
           lwkt_initport(&cn_iport, NULL);
           cn_iport.mp_putport = console_interceptport;
   
         /*          /*
          * Find the first console with the highest priority.           * Find the first console with the highest priority.
Line 180  cninit() Line 173  cninit()
         cn_tab = best_cp;          cn_tab = best_cp;
 }  }
   
   /*
    * Hook the open and close functions on the selected device.
    */
 void  void
 cninit_finish()  cninit_finish()
 {  {
Line 187  cninit_finish() Line 183  cninit_finish()
                 return;                  return;
   
         /*          /*
          * Hook the open and close functions.           * Hook the open and close functions.  XXX bad hack.
          */           */
         if (dev_dport(cn_tab->cn_dev))          if (dev_is_good(cn_tab->cn_dev))
                 cn_fwd_port = cdevsw_dev_override(cn_tab->cn_dev, &cn_port);                  cn_fwd_port = cdevsw_dev_override(cn_tab->cn_dev, &cn_iport);
         cn_dev_t = cn_tab->cn_dev;          cn_dev_t = cn_tab->cn_dev;
         cn_udev_t = dev2udev(cn_dev_t);          cn_udev_t = dev2udev(cn_dev_t);
         console_pausing = 0;          console_pausing = 0;
Line 203  cnuninit(void) Line 199  cnuninit(void)
                 return;                  return;
   
         /*          /*
          * Unhook the open and close functions.           * Unhook the open and close functions.  XXX bad hack
          */           */
         cdevsw_dev_override(cn_tab->cn_dev, NULL);          if (cn_fwd_port)
                   cdevsw_dev_override(cn_tab->cn_dev, cn_fwd_port);
         cn_fwd_port = NULL;          cn_fwd_port = NULL;
         cn_dev_t = NODEV;          cn_dev_t = NODEV;
         cn_udev_t = NOUDEV;          cn_udev_t = NOUDEV;
Line 230  sysctl_kern_consmute(SYSCTL_HANDLER_ARGS Line 227  sysctl_kern_consmute(SYSCTL_HANDLER_ARGS
                          * if the console has been openned                           * if the console has been openned
                          */                           */
                         cninit_finish();                          cninit_finish();
                         if(cn_is_open)                          if (cn_is_open) {
                                 /* XXX curproc is not what we want really */                                  /* XXX curproc is not what we want really */
                                 error = cnopen(cn_dev_t, openflag,                                  error = dev_dopen(cn_dev_t, openflag,
                                         openmode, curthread);                                                  openmode, curthread);
                           }
                         /* if it failed, back it out */                          /* if it failed, back it out */
                         if ( error != 0) cnuninit();                          if ( error != 0) cnuninit();
                 } else if (!ocn_mute && cn_mute) {                  } else if (!ocn_mute && cn_mute) {
Line 241  sysctl_kern_consmute(SYSCTL_HANDLER_ARGS Line 239  sysctl_kern_consmute(SYSCTL_HANDLER_ARGS
                          * going from unmuted to muted.. close the physical dev                            * going from unmuted to muted.. close the physical dev 
                          * if it's only open via /dev/console                           * if it's only open via /dev/console
                          */                           */
                         if(cn_is_open)                          if (cn_is_open) {
                                 error = cnclose(cn_dev_t, openflag,                                  error = dev_dclose(cn_dev_t, openflag,
                                         openmode, curthread);                                                  openmode, curthread);
                         if ( error == 0) cnuninit();                          }
                           if (error == 0)
                                   cnuninit();
                 }                  }
                 if (error != 0) {                  if (error != 0) {
                         /*                           /* 
Line 259  sysctl_kern_consmute(SYSCTL_HANDLER_ARGS Line 259  sysctl_kern_consmute(SYSCTL_HANDLER_ARGS
 SYSCTL_PROC(_kern, OID_AUTO, consmute, CTLTYPE_INT|CTLFLAG_RW,  SYSCTL_PROC(_kern, OID_AUTO, consmute, CTLTYPE_INT|CTLFLAG_RW,
         0, sizeof cn_mute, sysctl_kern_consmute, "I", "");          0, sizeof cn_mute, sysctl_kern_consmute, "I", "");
   
   /*
    * We intercept the OPEN and CLOSE calls on the original device, and
    * forward the rest through.
    */
   static int
   console_interceptport(lwkt_port_t port, lwkt_msg_t lmsg)
   {
           cdevallmsg_t msg = (cdevallmsg_t)lmsg;
           int error;
   
           switch(msg->am_lmsg.ms_cmd.cm_op) {
           case CDEV_CMD_OPEN:
                   error = cnopen(&msg->am_open);
                   break;
           case CDEV_CMD_CLOSE:
                   error = cnclose(&msg->am_close);
                   break;
           default:
                   error = lwkt_forwardmsg(cn_fwd_port, &msg->am_lmsg);
                   break;
           }
           return(error);
   }
   
   /*
    * This is the port handler for /dev/console.  These functions will basically
    * past the request through to the actual physical device representing the
    * console. 
    *
    * Note, however, that cnopen() and cnclose() are also called from the mute
    * code and the intercept code.
    */
 static int  static int
 console_putport(lwkt_port_t port, lwkt_msg_t lmsg)  console_putport(lwkt_port_t port, lwkt_msg_t lmsg)
 {  {
Line 267  console_putport(lwkt_port_t port, lwkt_m Line 299  console_putport(lwkt_port_t port, lwkt_m
   
         switch(msg->am_lmsg.ms_cmd.cm_op) {          switch(msg->am_lmsg.ms_cmd.cm_op) {
         case CDEV_CMD_OPEN:          case CDEV_CMD_OPEN:
                 error = cnopen(                  error = cnopen(&msg->am_open);
                             msg->am_open.msg.dev,  
                             msg->am_open.oflags,  
                             msg->am_open.devtype,  
                             msg->am_open.td  
                         );  
                 break;                  break;
         case CDEV_CMD_CLOSE:          case CDEV_CMD_CLOSE:
                 error = cnclose(                  error = cnclose(&msg->am_close);
                             msg->am_close.msg.dev,                  break;
                             msg->am_close.fflag,          case CDEV_CMD_STRATEGY:
                             msg->am_close.devtype,                  nostrategy(msg->am_strategy.bp);
                             msg->am_close.td                  error = 0;
                         );                  break;
           case CDEV_CMD_IOCTL:
                   error = cnioctl(&msg->am_ioctl);
                   break;
           case CDEV_CMD_DUMP:
                   error = nodump(msg->am_dump.msg.dev, 0, 0, 0);
                   break;
           case CDEV_CMD_PSIZE:
                   error = nopsize(msg->am_psize.msg.dev);
                   break;
           case CDEV_CMD_READ:
                   error = cnread(&msg->am_read);
                   break;
           case CDEV_CMD_WRITE:
                   error = cnwrite(&msg->am_write);
                   break;
           case CDEV_CMD_POLL:
                   error = cnpoll(&msg->am_poll);
                   break;
           case CDEV_CMD_KQFILTER:
                   error = cnkqfilter(&msg->am_kqfilter);
                   break;
           case CDEV_CMD_MMAP:
                   error = nommap(msg->am_mmap.msg.dev,
                                   msg->am_mmap.offset,
                                   msg->am_mmap.nprot);
                 break;                  break;
         default:          default:
                  error = lwkt_forwardmsg(cn_fwd_port, &msg->am_lmsg);                  error = ENODEV;
                  break;                  break;
         }          }
         return(error);          return(error);
 }  }
   
   /*
    * cnopen() is called as a port intercept function (dev will be that of the
    * actual physical device representing our console), and also called from
    * the muting code and from the /dev/console switch (dev will have the
    * console's cdevsw).
    */
 static int  static int
 cnopen(dev, flag, mode, td)  cnopen(struct cdevmsg_open *msg)
         dev_t dev;  
         int flag, mode;  
         struct thread *td;  
 {  {
           dev_t dev = msg->msg.dev;
           int flag = msg->oflags;
           int mode = msg->devtype;
         dev_t cndev, physdev;          dev_t cndev, physdev;
         int retval = 0;          int retval = 0;
   
Line 302  cnopen(dev, flag, mode, td) Line 360  cnopen(dev, flag, mode, td)
                 return (0);                  return (0);
         cndev = cn_tab->cn_dev;          cndev = cn_tab->cn_dev;
         physdev = (major(dev) == major(cndev) ? dev : cndev);          physdev = (major(dev) == major(cndev) ? dev : cndev);
   
         /*          /*
          * If mute is active, then non console opens don't get here           * If mute is active, then non console opens don't get here
          * so we don't need to check for that. They            * so we don't need to check for that. They bypass this and go
          * bypass this and go straight to the device.           * straight to the device.
            *
            * XXX at the moment we assume that the port forwarding function
            * is synchronous for open.
          */           */
         if(!cn_mute)          if (!cn_mute) {
                 retval = dev_port_dopen(cn_fwd_port, physdev, flag, mode, td);                  msg->msg.dev = physdev;
                   retval = lwkt_forwardmsg(cn_fwd_port, &msg->msg.msg);
           }
         if (retval == 0) {          if (retval == 0) {
                 /*                   /* 
                  * check if we openned it via /dev/console or                    * check if we openned it via /dev/console or 
Line 326  cnopen(dev, flag, mode, td) Line 390  cnopen(dev, flag, mode, td)
         return (retval);          return (retval);
 }  }
   
   /*
    * cnclose() is called as a port intercept function (dev will be that of the
    * actual physical device representing our console), and also called from
    * the muting code and from the /dev/console switch (dev will have the
    * console's cdevsw).
    */
 static int  static int
 cnclose(dev, flag, mode, td)  cnclose(struct cdevmsg_close *msg)
         dev_t dev;  
         int flag, mode;  
         struct thread *td;  
 {  {
           dev_t dev = msg->msg.dev;
         dev_t cndev;          dev_t cndev;
         struct tty *cn_tp;          struct tty *cn_tp;
   
Line 364  cnclose(dev, flag, mode, td) Line 432  cnclose(dev, flag, mode, td)
                         return (0);                          return (0);
                 dev = cndev;                  dev = cndev;
         }          }
         if (cn_fwd_port)          if (cn_fwd_port) {
                 return (dev_port_dclose(cn_fwd_port, dev, flag, mode, td));                  msg->msg.dev = dev;
                   return(lwkt_forwardmsg(cn_fwd_port, &msg->msg.msg));
           }
         return (0);          return (0);
 }  }
   
   /*
    * The following functions are dispatched solely from the /dev/console
    * port switch.  Their job is primarily to forward the request through.
    * If the console is not attached to anything then write()'s are sunk
    * to null and reads return 0 (mostly).
    */
 static int  static int
 cnread(dev, uio, flag)  cnread(struct cdevmsg_read *msg)
         dev_t dev;  
         struct uio *uio;  
         int flag;  
 {  {
   
         if (cn_tab == NULL || cn_fwd_port == NULL)          if (cn_tab == NULL || cn_fwd_port == NULL)
                 return (0);                  return (0);
         dev = cn_tab->cn_dev;          msg->msg.dev = cn_tab->cn_dev;
         return (dev_port_dread(cn_fwd_port, dev, uio, flag));          return(lwkt_forwardmsg(cn_fwd_port, &msg->msg.msg));
 }  }
   
 static int  static int
 cnwrite(dev, uio, flag)  cnwrite(struct cdevmsg_write *msg)
         dev_t dev;  
         struct uio *uio;  
         int flag;  
 {  {
           struct uio *uio = msg->uio;
           dev_t dev;
   
         if (cn_tab == NULL || cn_fwd_port == NULL) {          if (cn_tab == NULL || cn_fwd_port == NULL) {
                 uio->uio_resid = 0; /* dump the data */                  uio->uio_resid = 0; /* dump the data */
Line 398  cnwrite(dev, uio, flag) Line 469  cnwrite(dev, uio, flag)
         else          else
                 dev = cn_tab->cn_dev;                  dev = cn_tab->cn_dev;
         log_console(uio);          log_console(uio);
         return (dev_port_dwrite(cn_fwd_port, dev, uio, flag));          msg->msg.dev = dev;
           return(lwkt_forwardmsg(cn_fwd_port, &msg->msg.msg));
 }  }
   
 static int  static int
 cnioctl(dev, cmd, data, flag, td)  cnioctl(struct cdevmsg_ioctl *msg)
         dev_t dev;  
         u_long cmd;  
         caddr_t data;  
         int flag;  
         struct thread *td;  
 {  {
           u_long cmd = msg->cmd;
         int error;          int error;
   
         if (cn_tab == NULL || cn_fwd_port == NULL)          if (cn_tab == NULL || cn_fwd_port == NULL)
                 return (0);                  return (0);
         KKASSERT(td->td_proc != NULL);          KKASSERT(msg->td->td_proc != NULL);
         /*          /*
          * Superuser can always use this to wrest control of console           * Superuser can always use this to wrest control of console
          * output from the "virtual" console.           * output from the "virtual" console.
          */           */
         if (cmd == TIOCCONS && constty) {          if (cmd == TIOCCONS && constty) {
                 error = suser(td);                  error = suser(msg->td);
                 if (error)                  if (error)
                         return (error);                          return (error);
                 constty = NULL;                  constty = NULL;
                 return (0);                  return (0);
         }          }
         dev = cn_tab->cn_dev;          msg->msg.dev = cn_tab->cn_dev;
         return (dev_port_dioctl(cn_fwd_port, dev, cmd, data, flag, td));          return(lwkt_forwardmsg(cn_fwd_port, &msg->msg.msg));
 }  }
   
 static int  static int
 cnpoll(dev, events, td)  cnpoll(struct cdevmsg_poll *msg)
         dev_t dev;  
         int events;  
         struct thread *td;  
 {  {
         if ((cn_tab == NULL) || cn_mute || cn_fwd_port == NULL)          if ((cn_tab == NULL) || cn_mute || cn_fwd_port == NULL)
                 return (1);                  return (1);
           msg->msg.dev = cn_tab->cn_dev;
         dev = cn_tab->cn_dev;          return(lwkt_forwardmsg(cn_fwd_port, &msg->msg.msg));
   
         return (dev_port_dpoll(cn_fwd_port, dev, events, td));  
 }  }
   
 static int  static int
 cnkqfilter(dev, kn)  cnkqfilter(struct cdevmsg_kqfilter *msg)
         dev_t dev;  
         struct knote *kn;  
 {  {
         if ((cn_tab == NULL) || cn_mute || cn_fwd_port == NULL)          if ((cn_tab == NULL) || cn_mute || cn_fwd_port == NULL)
                 return (1);                  return (1);
           msg->msg.dev = cn_tab->cn_dev;
         dev = cn_tab->cn_dev;          return(lwkt_forwardmsg(cn_fwd_port, &msg->msg.msg));
         return (dev_port_dkqfilter(cn_fwd_port, dev, kn));  
 }  }
   
   /*
    * These synchronous functions are primarily used the kernel needs to 
    * access the keyboard (e.g. when running the debugger), or output data
    * directly to the console.
    */
 int  int
 cngetc()  cngetc(void)
 {  {
         int c;          int c;
         if ((cn_tab == NULL) || cn_mute)          if ((cn_tab == NULL) || cn_mute)
Line 467  cngetc() Line 532  cngetc()
 }  }
   
 int  int
 cncheckc()  cncheckc(void)
 {  {
         if ((cn_tab == NULL) || cn_mute)          if ((cn_tab == NULL) || cn_mute)
                 return (-1);                  return (-1);
Line 475  cncheckc() Line 540  cncheckc()
 }  }
   
 void  void
 cnputc(c)  cnputc(int c)
         int c;  
 {  {
         char *cp;          char *cp;
   
Line 504  cnputc(c) Line 568  cnputc(c)
 }  }
   
 void  void
 cndbctl(on)  cndbctl(int on)
         int on;  
 {  {
         static int refcount;          static int refcount;
   
Line 522  cndbctl(on) Line 585  cndbctl(on)
 static void  static void
 cn_drvinit(void *unused)  cn_drvinit(void *unused)
 {  {
           cdevsw_add(&cn_cdevsw, 0, 0);
         cn_devfsdev = make_dev(&cn_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,          cn_devfsdev = make_dev(&cn_cdevsw, 0, UID_ROOT, GID_WHEEL,
             "console");                                  0600, "console");
 }  }
   
 SYSINIT(cndev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,cn_drvinit,NULL)  SYSINIT(cndev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,cn_drvinit,NULL)

Removed from v.1.12  
changed lines
  Added in v.1.13