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/ir/irframe.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 /*      $NetBSD: irframe.c,v 1.28 2003/10/21 06:22:46 simonb Exp $      */
    2 
    3 /*
    4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Lennart Augustsson (lennart@augustsson.net).
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: irframe.c,v 1.28 2003/10/21 06:22:46 simonb Exp $");
   41 
   42 #include "irframe.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/ioctl.h>
   47 #include <sys/kernel.h>
   48 #include <sys/device.h>
   49 #include <sys/conf.h>
   50 #include <sys/malloc.h>
   51 #include <sys/poll.h>
   52 #include <sys/select.h>
   53 #include <sys/vnode.h>
   54 
   55 #include <dev/ir/ir.h>
   56 #include <dev/ir/irdaio.h>
   57 #include <dev/ir/irframevar.h>
   58 
   59 #ifdef IRFRAME_DEBUG
   60 #define DPRINTF(x)      if (irframedebug) printf x
   61 #define Static
   62 int irframedebug = 0;
   63 #else
   64 #define DPRINTF(x)
   65 #define Static static
   66 #endif
   67 
   68 dev_type_open(irframeopen);
   69 dev_type_close(irframeclose);
   70 dev_type_read(irframeread);
   71 dev_type_write(irframewrite);
   72 dev_type_ioctl(irframeioctl);
   73 dev_type_poll(irframepoll);
   74 dev_type_kqfilter(irframekqfilter);
   75 
   76 const struct cdevsw irframe_cdevsw = {
   77         irframeopen, irframeclose, irframeread, irframewrite, irframeioctl,
   78         nostop, notty, irframepoll, nommap, irframekqfilter,
   79 };
   80 
   81 int irframe_match(struct device *parent, struct cfdata *match, void *aux);
   82 void irframe_attach(struct device *parent, struct device *self, void *aux);
   83 int irframe_activate(struct device *self, enum devact act);
   84 int irframe_detach(struct device *self, int flags);
   85 
   86 Static int irf_set_params(struct irframe_softc *sc, struct irda_params *p);
   87 Static int irf_reset_params(struct irframe_softc *sc);
   88 
   89 #if NIRFRAME == 0
   90 /* In case we just have tty attachment. */
   91 CFDRIVER_DECL(irframe, DV_DULL, NULL);
   92 #endif
   93 
   94 CFATTACH_DECL(irframe, sizeof(struct irframe_softc),
   95     irframe_match, irframe_attach, irframe_detach, irframe_activate);
   96 
   97 extern struct cfdriver irframe_cd;
   98 
   99 #define IRFRAMEUNIT(dev) (minor(dev))
  100 
  101 int
  102 irframe_match(struct device *parent, struct cfdata *match, void *aux)
  103 {
  104         struct ir_attach_args *ia = aux;
  105 
  106         return (ia->ia_type == IR_TYPE_IRFRAME);
  107 }
  108 
  109 void
  110 irframe_attach(struct device *parent, struct device *self, void *aux)
  111 {
  112         struct irframe_softc *sc = (struct irframe_softc *)self;
  113         struct ir_attach_args *ia = aux;
  114         const char *delim;
  115         int speeds = 0;
  116 
  117         sc->sc_methods = ia->ia_methods;
  118         sc->sc_handle = ia->ia_handle;
  119 
  120 #ifdef DIAGNOSTIC
  121         if (sc->sc_methods->im_read == NULL ||
  122             sc->sc_methods->im_write == NULL ||
  123             sc->sc_methods->im_poll == NULL ||
  124             sc->sc_methods->im_kqfilter == NULL ||
  125             sc->sc_methods->im_set_params == NULL ||
  126             sc->sc_methods->im_get_speeds == NULL ||
  127             sc->sc_methods->im_get_turnarounds == NULL)
  128                 panic("%s: missing methods", sc->sc_dev.dv_xname);
  129 #endif
  130 
  131         (void)sc->sc_methods->im_get_speeds(sc->sc_handle, &speeds);
  132         sc->sc_speedmask = speeds;
  133         delim = ":";
  134         if (speeds & IRDA_SPEEDS_SIR) {
  135                 printf("%s SIR", delim);
  136                 delim = ",";
  137         }
  138         if (speeds & IRDA_SPEEDS_MIR) {
  139                 printf("%s MIR", delim);
  140                 delim = ",";
  141         }
  142         if (speeds & IRDA_SPEEDS_FIR) {
  143                 printf("%s FIR", delim);
  144                 delim = ",";
  145         }
  146         if (speeds & IRDA_SPEEDS_VFIR) {
  147                 printf("%s VFIR", delim);
  148                 delim = ",";
  149         }
  150         printf("\n");
  151 }
  152 
  153 int
  154 irframe_activate(struct device *self, enum devact act)
  155 {
  156         /*struct irframe_softc *sc = (struct irframe_softc *)self;*/
  157 
  158         switch (act) {
  159         case DVACT_ACTIVATE:
  160                 return (EOPNOTSUPP);
  161 
  162         case DVACT_DEACTIVATE:
  163                 break;
  164         }
  165         return (0);
  166 }
  167 
  168 int
  169 irframe_detach(struct device *self, int flags)
  170 {
  171         /*struct irframe_softc *sc = (struct irframe_softc *)self;*/
  172         int maj, mn;
  173 
  174         /* XXX needs reference count */
  175 
  176         /* locate the major number */
  177         maj = cdevsw_lookup_major(&irframe_cdevsw);
  178 
  179         /* Nuke the vnodes for any open instances (calls close). */
  180         mn = self->dv_unit;
  181         vdevgone(maj, mn, mn, VCHR);
  182 
  183         return (0);
  184 }
  185 
  186 int
  187 irframeopen(dev_t dev, int flag, int mode, struct proc *p)
  188 {
  189         struct irframe_softc *sc;
  190         int error;
  191 
  192         sc = device_lookup(&irframe_cd, IRFRAMEUNIT(dev));
  193         if (sc == NULL)
  194                 return (ENXIO);
  195         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
  196                 return (EIO);
  197         if (sc->sc_open)
  198                 return (EBUSY);
  199         if (sc->sc_methods->im_open != NULL) {
  200                 error = sc->sc_methods->im_open(sc->sc_handle, flag, mode, p);
  201                 if (error)
  202                         return (error);
  203         }
  204         sc->sc_open = 1;
  205 #ifdef DIAGNOSTIC
  206         sc->sc_speed = IRDA_DEFAULT_SPEED;
  207 #endif
  208         (void)irf_reset_params(sc);
  209         return (0);
  210 }
  211 
  212 int
  213 irframeclose(dev_t dev, int flag, int mode, struct proc *p)
  214 {
  215         struct irframe_softc *sc;
  216         int error;
  217 
  218         sc = device_lookup(&irframe_cd, IRFRAMEUNIT(dev));
  219         if (sc == NULL)
  220                 return (ENXIO);
  221         sc->sc_open = 0;
  222         if (sc->sc_methods->im_close != NULL)
  223                 error = sc->sc_methods->im_close(sc->sc_handle, flag, mode, p);
  224         else
  225                 error = 0;
  226         return (error);
  227 }
  228 
  229 int
  230 irframeread(dev_t dev, struct uio *uio, int flag)
  231 {
  232         struct irframe_softc *sc;
  233 
  234         sc = device_lookup(&irframe_cd, IRFRAMEUNIT(dev));
  235         if (sc == NULL)
  236                 return (ENXIO);
  237         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  238                 return (EIO);
  239         if (uio->uio_resid < sc->sc_params.maxsize) {
  240 #ifdef DIAGNOSTIC
  241                 printf("irframeread: short read %ld < %d\n",
  242                        (long)uio->uio_resid, sc->sc_params.maxsize);
  243 #endif
  244                 return (EINVAL);
  245         }
  246         return (sc->sc_methods->im_read(sc->sc_handle, uio, flag));
  247 }
  248 
  249 int
  250 irframewrite(dev_t dev, struct uio *uio, int flag)
  251 {
  252         struct irframe_softc *sc;
  253 
  254         sc = device_lookup(&irframe_cd, IRFRAMEUNIT(dev));
  255         if (sc == NULL)
  256                 return (ENXIO);
  257         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  258                 return (EIO);
  259         if (uio->uio_resid > sc->sc_params.maxsize) {
  260 #ifdef DIAGNOSTIC
  261                 printf("irframeread: long write %ld > %d\n",
  262                        (long)uio->uio_resid, sc->sc_params.maxsize);
  263 #endif
  264                 return (EINVAL);
  265         }
  266         return (sc->sc_methods->im_write(sc->sc_handle, uio, flag));
  267 }
  268 
  269 int
  270 irf_set_params(struct irframe_softc *sc, struct irda_params *p)
  271 {
  272         int error;
  273 
  274         DPRINTF(("irf_set_params: set params speed=%u ebofs=%u maxsize=%u "
  275                  "speedmask=0x%x\n", p->speed, p->ebofs, p->maxsize,
  276                  sc->sc_speedmask));
  277 
  278         if (p->maxsize > IRDA_MAX_FRAME_SIZE) {
  279 #ifdef IRFRAME_DEBUG
  280                 printf("irf_set_params: bad maxsize=%u\n", p->maxsize);
  281 #endif
  282                 return (EINVAL);
  283         }
  284 
  285         if (p->ebofs > IRDA_MAX_EBOFS) {
  286 #ifdef IRFRAME_DEBUG
  287                 printf("irf_set_params: bad maxsize=%u\n", p->maxsize);
  288 #endif
  289                 return (EINVAL);
  290         }
  291 
  292 #define CONC(x,y) x##y
  293 #define CASE(s) case s: if (!(sc->sc_speedmask & CONC(IRDA_SPEED_,s))) return (EINVAL); break
  294         switch (p->speed) {
  295         CASE(2400);
  296         CASE(9600);
  297         CASE(19200);
  298         CASE(38400);
  299         CASE(57600);
  300         CASE(115200);
  301         CASE(576000);
  302         CASE(1152000);
  303         CASE(4000000);
  304         CASE(16000000);
  305         default: return (EINVAL);
  306         }
  307 #undef CONC
  308 #undef CASE
  309 
  310         error = sc->sc_methods->im_set_params(sc->sc_handle, p);
  311         if (!error) {
  312                 sc->sc_params = *p;
  313                 DPRINTF(("irf_set_params: ok\n"));
  314 #ifdef DIAGNOSTIC
  315                 if (p->speed != sc->sc_speed) {
  316                         sc->sc_speed = p->speed;
  317                         printf("%s: set speed %u\n", sc->sc_dev.dv_xname,
  318                                sc->sc_speed);
  319                 }
  320 #endif
  321         } else {
  322 #ifdef IRFRAME_DEBUG
  323                 printf("irf_set_params: error=%d\n", error);
  324 #endif
  325         }
  326         return (error);
  327 }
  328 
  329 int
  330 irf_reset_params(struct irframe_softc *sc)
  331 {
  332         struct irda_params params;
  333 
  334         params.speed = IRDA_DEFAULT_SPEED;
  335         params.ebofs = IRDA_DEFAULT_EBOFS;
  336         params.maxsize = IRDA_DEFAULT_SIZE;
  337         return (irf_set_params(sc, &params));
  338 }
  339 
  340 int
  341 irframeioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
  342 {
  343         struct irframe_softc *sc;
  344         void *vaddr = addr;
  345         int error;
  346 
  347         sc = device_lookup(&irframe_cd, IRFRAMEUNIT(dev));
  348         if (sc == NULL)
  349                 return (ENXIO);
  350         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  351                 return (EIO);
  352 
  353         switch (cmd) {
  354         case FIONBIO:
  355                 /* All handled in the upper FS layer. */
  356                 error = 0;
  357                 break;
  358 
  359         case IRDA_SET_PARAMS:
  360                 error = irf_set_params(sc, vaddr);
  361                 break;
  362 
  363         case IRDA_RESET_PARAMS:
  364                 error = irf_reset_params(sc);
  365                 break;
  366 
  367         case IRDA_GET_SPEEDMASK:
  368                 error = sc->sc_methods->im_get_speeds(sc->sc_handle, vaddr);
  369                 break;
  370 
  371         case IRDA_GET_TURNAROUNDMASK:
  372                 error = sc->sc_methods->im_get_turnarounds(sc->sc_handle,vaddr);
  373                 break;
  374 
  375         default:
  376                 error = EINVAL;
  377                 break;
  378         }
  379         return (error);
  380 }
  381 
  382 int
  383 irframepoll(dev_t dev, int events, struct proc *p)
  384 {
  385         struct irframe_softc *sc;
  386 
  387         sc = device_lookup(&irframe_cd, IRFRAMEUNIT(dev));
  388         if (sc == NULL)
  389                 return (ENXIO);
  390         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  391                 return (EIO);
  392 
  393         return (sc->sc_methods->im_poll(sc->sc_handle, events, p));
  394 }
  395 
  396 int
  397 irframekqfilter(dev_t dev, struct knote *kn)
  398 {
  399         struct irframe_softc *sc;
  400 
  401         sc = device_lookup(&irframe_cd, IRFRAMEUNIT(dev));
  402         if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 || !sc->sc_open)
  403                 return (1);
  404 
  405         return (sc->sc_methods->im_kqfilter(sc->sc_handle, kn));
  406 }
  407 
  408 
  409 /*********/
  410 
  411 
  412 struct device *
  413 irframe_alloc(size_t size, const struct irframe_methods *m, void *h)
  414 {
  415         struct cfdriver *cd = &irframe_cd;
  416         struct device *dev;
  417         struct ir_attach_args ia;
  418         int unit;
  419 
  420         for (unit = 0; unit < cd->cd_ndevs; unit++)
  421                 if (cd->cd_devs[unit] == NULL)
  422                         break;
  423         dev = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO);
  424         snprintf(dev->dv_xname, sizeof dev->dv_xname, "irframe%d", unit);
  425         dev->dv_unit = unit;
  426         dev->dv_flags = DVF_ACTIVE;     /* always initially active */
  427 
  428         config_makeroom(unit, cd);
  429         cd->cd_devs[unit] = dev;
  430 
  431         ia.ia_methods = m;
  432         ia.ia_handle = h;
  433         printf("%s", dev->dv_xname);
  434         irframe_attach(NULL, dev, &ia);
  435 
  436         return (dev);
  437 }
  438 
  439 void
  440 irframe_dealloc(struct device *dev)
  441 {
  442         struct cfdriver *cd = &irframe_cd;
  443         int unit;
  444 
  445         for (unit = 0; unit < cd->cd_ndevs; unit++) {
  446                 if (cd->cd_devs[unit] == dev) {
  447                         cd->cd_devs[unit] = NULL;
  448                         free(dev, M_DEVBUF);
  449                         return;
  450                 }
  451         }
  452         panic("irframe_dealloc: device not found");
  453 }

Cache object: 9d582d0f314c3ce775b7b06360628190


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