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/dev/mse/mse.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) 2004 M. Warner Losh
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD: releng/11.2/sys/dev/mse/mse.c 331722 2018-03-29 02:50:57Z eadler $
   27  */
   28 
   29 /*
   30  * Copyright 1992 by the University of Guelph
   31  *
   32  * Permission to use, copy and modify this
   33  * software and its documentation for any purpose and without
   34  * fee is hereby granted, provided that the above copyright
   35  * notice appear in all copies and that both that copyright
   36  * notice and this permission notice appear in supporting
   37  * documentation.
   38  * University of Guelph makes no representations about the suitability of
   39  * this software for any purpose.  It is provided "as is"
   40  * without express or implied warranty.
   41  */
   42 /*
   43  * Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and
   44  * the X386 port, courtesy of
   45  * Rick Macklem, rick@snowhite.cis.uoguelph.ca
   46  * Caveats: The driver currently uses spltty(), but doesn't use any
   47  * generic tty code. It could use splmse() (that only masks off the
   48  * bus mouse interrupt, but that would require hacking in i386/isa/icu.s.
   49  * (This may be worth the effort, since the Logitech generates 30/60
   50  * interrupts/sec continuously while it is open.)
   51  * NB: The ATI has NOT been tested yet!
   52  */
   53 
   54 /*
   55  * Modification history:
   56  * Sep 6, 1994 -- Lars Fredriksen(fredriks@mcs.com)
   57  *   improved probe based on input from Logitech.
   58  *
   59  * Oct 19, 1992 -- E. Stark (stark@cs.sunysb.edu)
   60  *   fixes to make it work with Microsoft InPort busmouse
   61  *
   62  * Jan, 1993 -- E. Stark (stark@cs.sunysb.edu)
   63  *   added patches for new "select" interface
   64  *
   65  * May 4, 1993 -- E. Stark (stark@cs.sunysb.edu)
   66  *   changed position of some spl()'s in mseread
   67  *
   68  * October 8, 1993 -- E. Stark (stark@cs.sunysb.edu)
   69  *   limit maximum negative x/y value to -127 to work around XFree problem
   70  *   that causes spurious button pushes.
   71  */
   72 
   73 #include <sys/param.h>
   74 #include <sys/systm.h>
   75 #include <sys/conf.h>
   76 #include <sys/kernel.h>
   77 #include <sys/module.h>
   78 #include <sys/bus.h>
   79 #include <sys/poll.h>
   80 #include <sys/selinfo.h>
   81 #include <sys/uio.h>
   82 #include <sys/mouse.h>
   83 
   84 #include <machine/bus.h>
   85 #include <machine/resource.h>
   86 #include <sys/rman.h>
   87 
   88 #include <isa/isavar.h>
   89 
   90 #include <dev/mse/msevar.h>
   91 
   92 devclass_t      mse_devclass;
   93 
   94 static  d_open_t        mseopen;
   95 static  d_close_t       mseclose;
   96 static  d_read_t        mseread;
   97 static  d_ioctl_t       mseioctl;
   98 static  d_poll_t        msepoll;
   99 
  100 static struct cdevsw mse_cdevsw = {
  101         .d_version =    D_VERSION,
  102         .d_open =       mseopen,
  103         .d_close =      mseclose,
  104         .d_read =       mseread,
  105         .d_ioctl =      mseioctl,
  106         .d_poll =       msepoll,
  107         .d_name =       "mse",
  108 };
  109 
  110 static  void            mseintr(void *);
  111 static  void            mseintr_locked(mse_softc_t *sc);
  112 static  void            msetimeout(void *);
  113 
  114 #define MSE_NBLOCKIO(dev)       (dev2unit(dev) != 0)
  115 
  116 #define MSEPRI  (PZERO + 3)
  117 
  118 int
  119 mse_common_attach(device_t dev)
  120 {
  121         mse_softc_t *sc;
  122         int unit, flags, rid;
  123 
  124         sc = device_get_softc(dev);
  125         unit = device_get_unit(dev);
  126         mtx_init(&sc->sc_lock, "mse", NULL, MTX_DEF);
  127         callout_init_mtx(&sc->sc_callout, &sc->sc_lock, 0);
  128 
  129         rid = 0;
  130         sc->sc_intr = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  131                                              RF_ACTIVE);
  132         if (sc->sc_intr == NULL) {
  133                 bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
  134                 mtx_destroy(&sc->sc_lock);
  135                 return ENXIO;
  136         }
  137 
  138         if (bus_setup_intr(dev, sc->sc_intr, INTR_TYPE_TTY | INTR_MPSAFE,
  139             NULL, mseintr, sc, &sc->sc_ih)) {
  140                 bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
  141                 bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr);
  142                 mtx_destroy(&sc->sc_lock);
  143                 return ENXIO;
  144         }
  145         flags = device_get_flags(dev);
  146         sc->mode.accelfactor = (flags & MSE_CONFIG_ACCEL) >> 4;
  147 
  148         sc->sc_dev = make_dev(&mse_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
  149             "mse%d", unit);
  150         sc->sc_dev->si_drv1 = sc;
  151         sc->sc_ndev = make_dev(&mse_cdevsw, 1, UID_ROOT, GID_WHEEL, 0600,
  152             "nmse%d", unit);
  153         sc->sc_ndev->si_drv1 = sc;
  154         return 0;
  155 }
  156 
  157 int
  158 mse_detach(device_t dev)
  159 {
  160         mse_softc_t *sc;
  161         int rid;
  162 
  163         sc = device_get_softc(dev);
  164         MSE_LOCK(sc);
  165         if (sc->sc_flags & MSESC_OPEN) {
  166                 MSE_UNLOCK(sc);
  167                 return EBUSY;
  168         }
  169 
  170         /* Sabotage subsequent opens. */
  171         sc->sc_mousetype = MSE_NONE;
  172         MSE_UNLOCK(sc);
  173 
  174         destroy_dev(sc->sc_dev);
  175         destroy_dev(sc->sc_ndev);
  176 
  177         rid = 0;
  178         bus_teardown_intr(dev, sc->sc_intr, sc->sc_ih);
  179         bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr);
  180         bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
  181 
  182         callout_drain(&sc->sc_callout);
  183         mtx_destroy(&sc->sc_lock);
  184 
  185         return 0;
  186 }
  187 
  188 /*
  189  * Exclusive open the mouse, initialize it and enable interrupts.
  190  */
  191 static  int
  192 mseopen(struct cdev *dev, int flags, int fmt, struct thread *td)
  193 {
  194         mse_softc_t *sc = dev->si_drv1;
  195 
  196         MSE_LOCK(sc);
  197         if (sc->sc_mousetype == MSE_NONE) {
  198                 MSE_UNLOCK(sc);
  199                 return (ENXIO);
  200         }
  201         if (sc->sc_flags & MSESC_OPEN) {
  202                 MSE_UNLOCK(sc);
  203                 return (EBUSY);
  204         }
  205         sc->sc_flags |= MSESC_OPEN;
  206         sc->sc_obuttons = sc->sc_buttons = MOUSE_MSC_BUTTONS;
  207         sc->sc_deltax = sc->sc_deltay = 0;
  208         sc->sc_bytesread = sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
  209         sc->sc_watchdog = FALSE;
  210         callout_reset(&sc->sc_callout, hz * 2, msetimeout, dev);
  211         sc->mode.level = 0;
  212         sc->status.flags = 0;
  213         sc->status.button = sc->status.obutton = 0;
  214         sc->status.dx = sc->status.dy = sc->status.dz = 0;
  215 
  216         /*
  217          * Initialize mouse interface and enable interrupts.
  218          */
  219         (*sc->sc_enablemouse)(sc->sc_port);
  220         MSE_UNLOCK(sc);
  221         return (0);
  222 }
  223 
  224 /*
  225  * mseclose: just turn off mouse innterrupts.
  226  */
  227 static  int
  228 mseclose(struct cdev *dev, int flags, int fmt, struct thread *td)
  229 {
  230         mse_softc_t *sc = dev->si_drv1;
  231 
  232         MSE_LOCK(sc);
  233         callout_stop(&sc->sc_callout);
  234         (*sc->sc_disablemouse)(sc->sc_port);
  235         sc->sc_flags &= ~MSESC_OPEN;
  236         MSE_UNLOCK(sc);
  237         return(0);
  238 }
  239 
  240 /*
  241  * mseread: return mouse info using the MSC serial protocol, but without
  242  * using bytes 4 and 5.
  243  * (Yes this is cheesy, but it makes the X386 server happy, so...)
  244  */
  245 static  int
  246 mseread(struct cdev *dev, struct uio *uio, int ioflag)
  247 {
  248         mse_softc_t *sc = dev->si_drv1;
  249         int xfer, error;
  250 
  251         /*
  252          * If there are no protocol bytes to be read, set up a new protocol
  253          * packet.
  254          */
  255         MSE_LOCK(sc);
  256         while (sc->sc_flags & MSESC_READING) {
  257                 if (MSE_NBLOCKIO(dev)) {
  258                         MSE_UNLOCK(sc);
  259                         return (0);
  260                 }
  261                 sc->sc_flags |= MSESC_WANT;
  262                 error = mtx_sleep(sc, &sc->sc_lock, MSEPRI | PCATCH, "mseread",
  263                     0);
  264                 if (error) {
  265                         MSE_UNLOCK(sc);
  266                         return (error);
  267                 }
  268         }
  269         sc->sc_flags |= MSESC_READING;
  270         xfer = 0;
  271         if (sc->sc_bytesread >= sc->mode.packetsize) {
  272                 while (sc->sc_deltax == 0 && sc->sc_deltay == 0 &&
  273                        (sc->sc_obuttons ^ sc->sc_buttons) == 0) {
  274                         if (MSE_NBLOCKIO(dev))
  275                                 goto out;
  276                         sc->sc_flags |= MSESC_WANT;
  277                         error = mtx_sleep(sc, &sc->sc_lock, MSEPRI | PCATCH,
  278                                 "mseread", 0);
  279                         if (error)
  280                                 goto out;
  281                 }
  282 
  283                 /*
  284                  * Generate protocol bytes.
  285                  * For some reason X386 expects 5 bytes but never uses
  286                  * the fourth or fifth?
  287                  */
  288                 sc->sc_bytes[0] = sc->mode.syncmask[1] 
  289                     | (sc->sc_buttons & ~sc->mode.syncmask[0]);
  290                 if (sc->sc_deltax > 127)
  291                         sc->sc_deltax = 127;
  292                 if (sc->sc_deltax < -127)
  293                         sc->sc_deltax = -127;
  294                 sc->sc_deltay = -sc->sc_deltay; /* Otherwise mousey goes wrong way */
  295                 if (sc->sc_deltay > 127)
  296                         sc->sc_deltay = 127;
  297                 if (sc->sc_deltay < -127)
  298                         sc->sc_deltay = -127;
  299                 sc->sc_bytes[1] = sc->sc_deltax;
  300                 sc->sc_bytes[2] = sc->sc_deltay;
  301                 sc->sc_bytes[3] = sc->sc_bytes[4] = 0;
  302                 sc->sc_bytes[5] = sc->sc_bytes[6] = 0;
  303                 sc->sc_bytes[7] = MOUSE_SYS_EXTBUTTONS;
  304                 sc->sc_obuttons = sc->sc_buttons;
  305                 sc->sc_deltax = sc->sc_deltay = 0;
  306                 sc->sc_bytesread = 0;
  307         }
  308         xfer = min(uio->uio_resid, sc->mode.packetsize - sc->sc_bytesread);
  309         MSE_UNLOCK(sc);
  310         error = uiomove(&sc->sc_bytes[sc->sc_bytesread], xfer, uio);
  311         MSE_LOCK(sc);
  312 out:
  313         sc->sc_flags &= ~MSESC_READING;
  314         if (error == 0)
  315                 sc->sc_bytesread += xfer;
  316         if (sc->sc_flags & MSESC_WANT) {
  317                 sc->sc_flags &= ~MSESC_WANT;
  318                 MSE_UNLOCK(sc);
  319                 wakeup(sc);
  320         } else
  321                 MSE_UNLOCK(sc);
  322         return (error);
  323 }
  324 
  325 /*
  326  * mseioctl: process ioctl commands.
  327  */
  328 static int
  329 mseioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
  330 {
  331         mse_softc_t *sc = dev->si_drv1;
  332         mousestatus_t status;
  333         int err = 0;
  334 
  335         switch (cmd) {
  336 
  337         case MOUSE_GETHWINFO:
  338                 MSE_LOCK(sc);
  339                 *(mousehw_t *)addr = sc->hw;
  340                 if (sc->mode.level == 0)
  341                         ((mousehw_t *)addr)->model = MOUSE_MODEL_GENERIC;
  342                 MSE_UNLOCK(sc);
  343                 break;
  344 
  345         case MOUSE_GETMODE:
  346                 MSE_LOCK(sc);
  347                 *(mousemode_t *)addr = sc->mode;
  348                 switch (sc->mode.level) {
  349                 case 0:
  350                         break;
  351                 case 1:
  352                         ((mousemode_t *)addr)->protocol = MOUSE_PROTO_SYSMOUSE;
  353                         ((mousemode_t *)addr)->syncmask[0] = MOUSE_SYS_SYNCMASK;
  354                         ((mousemode_t *)addr)->syncmask[1] = MOUSE_SYS_SYNC;
  355                         break;
  356                 }
  357                 MSE_UNLOCK(sc);
  358                 break;
  359 
  360         case MOUSE_SETMODE:
  361                 switch (((mousemode_t *)addr)->level) {
  362                 case 0:
  363                 case 1:
  364                         break;
  365                 default:
  366                         return (EINVAL);
  367                 }
  368                 MSE_LOCK(sc);
  369                 if (((mousemode_t *)addr)->accelfactor < -1) {
  370                         MSE_UNLOCK(sc);
  371                         return (EINVAL);
  372                 } else if (((mousemode_t *)addr)->accelfactor >= 0)
  373                         sc->mode.accelfactor = 
  374                             ((mousemode_t *)addr)->accelfactor;
  375                 sc->mode.level = ((mousemode_t *)addr)->level;
  376                 switch (sc->mode.level) {
  377                 case 0:
  378                         sc->sc_bytesread = sc->mode.packetsize 
  379                             = MOUSE_MSC_PACKETSIZE;
  380                         break;
  381                 case 1:
  382                         sc->sc_bytesread = sc->mode.packetsize 
  383                             = MOUSE_SYS_PACKETSIZE;
  384                         break;
  385                 }
  386                 MSE_UNLOCK(sc);
  387                 break;
  388 
  389         case MOUSE_GETLEVEL:
  390                 MSE_LOCK(sc);
  391                 *(int *)addr = sc->mode.level;
  392                 MSE_UNLOCK(sc);
  393                 break;
  394 
  395         case MOUSE_SETLEVEL:
  396                 switch (*(int *)addr) {
  397                 case 0:
  398                         MSE_LOCK(sc);
  399                         sc->mode.level = *(int *)addr;
  400                         sc->sc_bytesread = sc->mode.packetsize 
  401                             = MOUSE_MSC_PACKETSIZE;
  402                         MSE_UNLOCK(sc);
  403                         break;
  404                 case 1:
  405                         MSE_LOCK(sc);
  406                         sc->mode.level = *(int *)addr;
  407                         sc->sc_bytesread = sc->mode.packetsize 
  408                             = MOUSE_SYS_PACKETSIZE;
  409                         MSE_UNLOCK(sc);
  410                         break;
  411                 default:
  412                         return (EINVAL);
  413                 }
  414                 break;
  415 
  416         case MOUSE_GETSTATUS:
  417                 MSE_LOCK(sc);
  418                 status = sc->status;
  419                 sc->status.flags = 0;
  420                 sc->status.obutton = sc->status.button;
  421                 sc->status.button = 0;
  422                 sc->status.dx = 0;
  423                 sc->status.dy = 0;
  424                 sc->status.dz = 0;
  425                 MSE_UNLOCK(sc);
  426                 *(mousestatus_t *)addr = status;
  427                 break;
  428 
  429         case MOUSE_READSTATE:
  430         case MOUSE_READDATA:
  431                 return (ENODEV);
  432 
  433 #if (defined(MOUSE_GETVARS))
  434         case MOUSE_GETVARS:
  435         case MOUSE_SETVARS:
  436                 return (ENODEV);
  437 #endif
  438 
  439         default:
  440                 return (ENOTTY);
  441         }
  442         return (err);
  443 }
  444 
  445 /*
  446  * msepoll: check for mouse input to be processed.
  447  */
  448 static  int
  449 msepoll(struct cdev *dev, int events, struct thread *td)
  450 {
  451         mse_softc_t *sc = dev->si_drv1;
  452         int revents = 0;
  453 
  454         MSE_LOCK(sc);
  455         if (events & (POLLIN | POLLRDNORM)) {
  456                 if (sc->sc_bytesread != sc->mode.packetsize ||
  457                     sc->sc_deltax != 0 || sc->sc_deltay != 0 ||
  458                     (sc->sc_obuttons ^ sc->sc_buttons) != 0)
  459                         revents |= events & (POLLIN | POLLRDNORM);
  460                 else
  461                         selrecord(td, &sc->sc_selp);
  462         }
  463         MSE_UNLOCK(sc);
  464         return (revents);
  465 }
  466 
  467 /*
  468  * msetimeout: watchdog timer routine.
  469  */
  470 static void
  471 msetimeout(void *arg)
  472 {
  473         struct cdev *dev;
  474         mse_softc_t *sc;
  475 
  476         dev = (struct cdev *)arg;
  477         sc = dev->si_drv1;
  478         MSE_ASSERT_LOCKED(sc);
  479         if (sc->sc_watchdog) {
  480                 if (bootverbose)
  481                         printf("%s: lost interrupt?\n", devtoname(dev));
  482                 mseintr_locked(sc);
  483         }
  484         sc->sc_watchdog = TRUE;
  485         callout_schedule(&sc->sc_callout, hz);
  486 }
  487 
  488 /*
  489  * mseintr: update mouse status. sc_deltax and sc_deltay are accumulative.
  490  */
  491 static void
  492 mseintr(void *arg)
  493 {
  494         mse_softc_t *sc = arg;
  495 
  496         MSE_LOCK(sc);
  497         mseintr_locked(sc);
  498         MSE_UNLOCK(sc);
  499 }
  500 
  501 static void
  502 mseintr_locked(mse_softc_t *sc)
  503 {
  504         /*
  505          * the table to turn MouseSystem button bits (MOUSE_MSC_BUTTON?UP)
  506          * into `mousestatus' button bits (MOUSE_BUTTON?DOWN).
  507          */
  508         static int butmap[8] = {
  509                 0, 
  510                 MOUSE_BUTTON3DOWN, 
  511                 MOUSE_BUTTON2DOWN, 
  512                 MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, 
  513                 MOUSE_BUTTON1DOWN, 
  514                 MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 
  515                 MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN,
  516                 MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
  517         };
  518         int dx, dy, but;
  519         int sign;
  520 
  521 #ifdef DEBUG
  522         static int mse_intrcnt = 0;
  523         if((mse_intrcnt++ % 10000) == 0)
  524                 printf("mseintr\n");
  525 #endif /* DEBUG */
  526         if ((sc->sc_flags & MSESC_OPEN) == 0)
  527                 return;
  528 
  529         (*sc->sc_getmouse)(sc->sc_port, &dx, &dy, &but);
  530         if (sc->mode.accelfactor > 0) {
  531                 sign = (dx < 0);
  532                 dx = dx * dx / sc->mode.accelfactor;
  533                 if (dx == 0)
  534                         dx = 1;
  535                 if (sign)
  536                         dx = -dx;
  537                 sign = (dy < 0);
  538                 dy = dy * dy / sc->mode.accelfactor;
  539                 if (dy == 0)
  540                         dy = 1;
  541                 if (sign)
  542                         dy = -dy;
  543         }
  544         sc->sc_deltax += dx;
  545         sc->sc_deltay += dy;
  546         sc->sc_buttons = but;
  547 
  548         but = butmap[~but & MOUSE_MSC_BUTTONS];
  549         sc->status.dx += dx;
  550         sc->status.dy += dy;
  551         sc->status.flags |= ((dx || dy) ? MOUSE_POSCHANGED : 0)
  552             | (sc->status.button ^ but);
  553         sc->status.button = but;
  554 
  555         sc->sc_watchdog = FALSE;
  556 
  557         /*
  558          * If mouse state has changed, wake up anyone wanting to know.
  559          */
  560         if (sc->sc_deltax != 0 || sc->sc_deltay != 0 ||
  561             (sc->sc_obuttons ^ sc->sc_buttons) != 0) {
  562                 if (sc->sc_flags & MSESC_WANT) {
  563                         sc->sc_flags &= ~MSESC_WANT;
  564                         wakeup(sc);
  565                 }
  566                 selwakeuppri(&sc->sc_selp, MSEPRI);
  567         }
  568 }

Cache object: 95b66dc1cd090662e3c646baffb08921


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