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/smbus/smbconf.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) 1998, 2001 Nicolas Souchu
    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  *
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/lock.h>
   36 #include <sys/module.h>
   37 #include <sys/mutex.h>
   38 #include <sys/bus.h>
   39 
   40 #include <dev/smbus/smbconf.h>
   41 #include <dev/smbus/smbus.h>
   42 #include "smbus_if.h"
   43 
   44 /*
   45  * smbus_intr()
   46  */
   47 void
   48 smbus_intr(device_t bus, u_char devaddr, char low, char high, int error)
   49 {
   50         struct smbus_softc *sc = device_get_softc(bus);
   51 
   52         /* call owner's intr routine */
   53         mtx_lock(&sc->lock);
   54         if (sc->owner)
   55                 SMBUS_INTR(sc->owner, devaddr, low, high, error);
   56         mtx_unlock(&sc->lock);
   57 }
   58 
   59 /*
   60  * smbus_error()
   61  *
   62  * Converts an smbus error to a unix error.
   63  */
   64 int
   65 smbus_error(int smb_error)
   66 {
   67         int error = 0;
   68 
   69         if (smb_error == SMB_ENOERR)
   70                 return (0);
   71 
   72         if (smb_error & (SMB_ENOTSUPP))
   73                 error = ENODEV;
   74         else if (smb_error & (SMB_ENOACK))
   75                 error = ENXIO;
   76         else if (smb_error & (SMB_ETIMEOUT))
   77                 error = EWOULDBLOCK;
   78         else if (smb_error & (SMB_EBUSY))
   79                 error = EBUSY;
   80         else if (smb_error & (SMB_EABORT | SMB_EBUSERR | SMB_ECOLLI))
   81                 error = EIO;
   82         else
   83                 error = EINVAL;
   84 
   85         return (error);
   86 }
   87 
   88 static int
   89 smbus_poll(struct smbus_softc *sc, int how)
   90 {
   91         int error;
   92 
   93         switch (how) {
   94         case SMB_WAIT | SMB_INTR:               
   95                 error = msleep(sc, &sc->lock, SMBPRI|PCATCH, "smbreq", 0);
   96                 break;
   97 
   98         case SMB_WAIT | SMB_NOINTR:
   99                 error = msleep(sc, &sc->lock, SMBPRI, "smbreq", 0);
  100                 break;
  101 
  102         default:
  103                 error = EWOULDBLOCK;
  104                 break;
  105         }
  106 
  107         return (error);
  108 }
  109 
  110 /*
  111  * smbus_request_bus()
  112  *
  113  * Allocate the device to perform transfers.
  114  *
  115  * how  : SMB_WAIT or SMB_DONTWAIT
  116  */
  117 int
  118 smbus_request_bus(device_t bus, device_t dev, int how)
  119 {
  120         struct smbus_softc *sc = device_get_softc(bus);
  121         device_t parent;
  122         int error;
  123 
  124         /* first, ask the underlying layers if the request is ok */
  125         parent = device_get_parent(bus);
  126         mtx_lock(&sc->lock);
  127         do {
  128                 mtx_unlock(&sc->lock);
  129                 error = SMBUS_CALLBACK(parent, SMB_REQUEST_BUS, &how);
  130                 mtx_lock(&sc->lock);
  131 
  132                 if (error)
  133                         error = smbus_poll(sc, how);
  134         } while (error == EWOULDBLOCK);
  135 
  136         while (error == 0) {
  137                 if (sc->owner && sc->owner != dev)
  138                         error = smbus_poll(sc, how);
  139                 else {
  140                         sc->owner = dev;
  141                         break;
  142                 }
  143 
  144                 /* free any allocated resource */
  145                 if (error) {
  146                         mtx_unlock(&sc->lock);
  147                         SMBUS_CALLBACK(parent, SMB_RELEASE_BUS, &how);
  148                         return (error);
  149                 }
  150         }
  151         mtx_unlock(&sc->lock);
  152 
  153         return (error);
  154 }
  155 
  156 /*
  157  * smbus_release_bus()
  158  *
  159  * Release the device allocated with smbus_request_dev()
  160  */
  161 int
  162 smbus_release_bus(device_t bus, device_t dev)
  163 {
  164         struct smbus_softc *sc = device_get_softc(bus);
  165         int error;
  166 
  167         /* first, ask the underlying layers if the release is ok */
  168         error = SMBUS_CALLBACK(device_get_parent(bus), SMB_RELEASE_BUS, NULL);
  169 
  170         if (error)
  171                 return (error);
  172 
  173         mtx_lock(&sc->lock);
  174         if (sc->owner == dev) {
  175                 sc->owner = NULL;
  176 
  177                 /* wakeup waiting processes */
  178                 wakeup(sc);
  179         } else
  180                 error = EACCES;
  181         mtx_unlock(&sc->lock);
  182 
  183         return (error);
  184 }

Cache object: 0f64de5181188914d6900dd5d6bcd917


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