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

Cache object: 3a46aff83c520a7e99c0f4e0719a3c5c


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