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/ipmi.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 /*      $OpenBSD: ipmi.c,v 1.118 2022/04/08 13:13:14 mbuhl Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2015 Masao Uebayashi
    5  * Copyright (c) 2005 Jordan Hargrave
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
   21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/kernel.h>
   33 #include <sys/device.h>
   34 #include <sys/ioctl.h>
   35 #include <sys/extent.h>
   36 #include <sys/sensors.h>
   37 #include <sys/malloc.h>
   38 #include <sys/kthread.h>
   39 #include <sys/task.h>
   40 
   41 #include <machine/bus.h>
   42 #include <machine/smbiosvar.h>
   43 
   44 #include <dev/ipmivar.h>
   45 #include <dev/ipmi.h>
   46 
   47 struct ipmi_sensor {
   48         u_int8_t        *i_sdr;
   49         int             i_num;
   50         int             stype;
   51         int             etype;
   52         struct          ksensor i_sensor;
   53         SLIST_ENTRY(ipmi_sensor) list;
   54 };
   55 
   56 int     ipmi_enabled = 0;
   57 
   58 #define SENSOR_REFRESH_RATE 5   /* seconds */
   59 
   60 #define DEVNAME(s)  ((s)->sc_dev.dv_xname)
   61 
   62 #define IPMI_BTMSG_LEN                  0
   63 #define IPMI_BTMSG_NFLN                 1
   64 #define IPMI_BTMSG_SEQ                  2
   65 #define IPMI_BTMSG_CMD                  3
   66 #define IPMI_BTMSG_CCODE                4
   67 #define IPMI_BTMSG_DATASND              4
   68 #define IPMI_BTMSG_DATARCV              5
   69 
   70 /* IPMI 2.0, Table 42-3: Sensor Type Codes */
   71 #define IPMI_SENSOR_TYPE_TEMP           0x0101
   72 #define IPMI_SENSOR_TYPE_VOLT           0x0102
   73 #define IPMI_SENSOR_TYPE_CURRENT        0x0103
   74 #define IPMI_SENSOR_TYPE_FAN            0x0104
   75 #define IPMI_SENSOR_TYPE_INTRUSION      0x6F05
   76 #define IPMI_SENSOR_TYPE_PWRSUPPLY      0x6F08
   77 
   78 /* IPMI 2.0, Table 43-15: Sensor Unit Type Codes */
   79 #define IPMI_UNIT_TYPE_DEGREE_C         1
   80 #define IPMI_UNIT_TYPE_DEGREE_F         2
   81 #define IPMI_UNIT_TYPE_DEGREE_K         3
   82 #define IPMI_UNIT_TYPE_VOLTS            4
   83 #define IPMI_UNIT_TYPE_AMPS             5
   84 #define IPMI_UNIT_TYPE_WATTS            6
   85 #define IPMI_UNIT_TYPE_RPM              18
   86 
   87 #define IPMI_NAME_UNICODE               0x00
   88 #define IPMI_NAME_BCDPLUS               0x01
   89 #define IPMI_NAME_ASCII6BIT             0x02
   90 #define IPMI_NAME_ASCII8BIT             0x03
   91 
   92 #define IPMI_ENTITY_PWRSUPPLY           0x0A
   93 
   94 #define IPMI_INVALID_SENSOR             (1L << 5)
   95 #define IPMI_DISABLED_SENSOR            (1L << 6)
   96 
   97 #define IPMI_SDR_TYPEFULL               1
   98 #define IPMI_SDR_TYPECOMPACT            2
   99 
  100 #define byteof(x) ((x) >> 3)
  101 #define bitof(x)  (1L << ((x) & 0x7))
  102 #define TB(b,m)   (data[2+byteof(b)] & bitof(b))
  103 
  104 #ifdef IPMI_DEBUG
  105 int     ipmi_dbg = 0;
  106 #define dbg_printf(lvl, fmt...) \
  107         if (ipmi_dbg >= lvl) \
  108                 printf(fmt);
  109 #define dbg_dump(lvl, msg, len, buf) \
  110         if (len && ipmi_dbg >= lvl) \
  111                 dumpb(msg, len, (const u_int8_t *)(buf));
  112 #else
  113 #define dbg_printf(lvl, fmt...)
  114 #define dbg_dump(lvl, msg, len, buf)
  115 #endif
  116 
  117 long signextend(unsigned long, int);
  118 
  119 SLIST_HEAD(ipmi_sensors_head, ipmi_sensor);
  120 struct ipmi_sensors_head ipmi_sensor_list =
  121     SLIST_HEAD_INITIALIZER(ipmi_sensor_list);
  122 
  123 void    dumpb(const char *, int, const u_int8_t *);
  124 
  125 int     read_sensor(struct ipmi_softc *, struct ipmi_sensor *);
  126 int     add_sdr_sensor(struct ipmi_softc *, u_int8_t *, int);
  127 int     get_sdr_partial(struct ipmi_softc *, u_int16_t, u_int16_t,
  128             u_int8_t, u_int8_t, void *, u_int16_t *);
  129 int     get_sdr(struct ipmi_softc *, u_int16_t, u_int16_t *);
  130 
  131 int     ipmi_sendcmd(struct ipmi_cmd *);
  132 int     ipmi_recvcmd(struct ipmi_cmd *);
  133 void    ipmi_cmd(struct ipmi_cmd *);
  134 void    ipmi_cmd_poll(struct ipmi_cmd *);
  135 void    ipmi_cmd_wait(struct ipmi_cmd *);
  136 void    ipmi_cmd_wait_cb(void *);
  137 
  138 int     ipmi_watchdog(void *, int);
  139 void    ipmi_watchdog_tickle(void *);
  140 void    ipmi_watchdog_set(void *);
  141 
  142 struct ipmi_softc *ipmilookup(dev_t dev);
  143 
  144 int     ipmiopen(dev_t, int, int, struct proc *);
  145 int     ipmiclose(dev_t, int, int, struct proc *);
  146 int     ipmiioctl(dev_t, u_long, caddr_t, int, struct proc *);
  147 
  148 long    ipow(long, int);
  149 long    ipmi_convert(u_int8_t, struct sdrtype1 *, long);
  150 int     ipmi_sensor_name(char *, int, u_int8_t, u_int8_t *, int);
  151 
  152 /* BMC Helper Functions */
  153 u_int8_t bmc_read(struct ipmi_softc *, int);
  154 void    bmc_write(struct ipmi_softc *, int, u_int8_t);
  155 int     bmc_io_wait(struct ipmi_softc *, struct ipmi_iowait *);
  156 
  157 void    bt_buildmsg(struct ipmi_cmd *);
  158 void    cmn_buildmsg(struct ipmi_cmd *);
  159 
  160 int     getbits(u_int8_t *, int, int);
  161 int     ipmi_sensor_type(int, int, int, int);
  162 
  163 void    ipmi_refresh_sensors(struct ipmi_softc *sc);
  164 int     ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia);
  165 void    ipmi_unmap_regs(struct ipmi_softc *);
  166 
  167 int     ipmi_sensor_status(struct ipmi_softc *, struct ipmi_sensor *,
  168     u_int8_t *);
  169 
  170 int      add_child_sensors(struct ipmi_softc *, u_int8_t *, int, int, int,
  171     int, int, int, const char *);
  172 
  173 void    ipmi_create_thread(void *);
  174 void    ipmi_poll_thread(void *);
  175 
  176 int     kcs_probe(struct ipmi_softc *);
  177 int     kcs_reset(struct ipmi_softc *);
  178 int     kcs_sendmsg(struct ipmi_cmd *);
  179 int     kcs_recvmsg(struct ipmi_cmd *);
  180 
  181 int     bt_probe(struct ipmi_softc *);
  182 int     bt_reset(struct ipmi_softc *);
  183 int     bt_sendmsg(struct ipmi_cmd *);
  184 int     bt_recvmsg(struct ipmi_cmd *);
  185 
  186 int     smic_probe(struct ipmi_softc *);
  187 int     smic_reset(struct ipmi_softc *);
  188 int     smic_sendmsg(struct ipmi_cmd *);
  189 int     smic_recvmsg(struct ipmi_cmd *);
  190 
  191 struct ipmi_if kcs_if = {
  192         "KCS",
  193         IPMI_IF_KCS_NREGS,
  194         cmn_buildmsg,
  195         kcs_sendmsg,
  196         kcs_recvmsg,
  197         kcs_reset,
  198         kcs_probe,
  199         IPMI_MSG_DATASND,
  200         IPMI_MSG_DATARCV,
  201 };
  202 
  203 struct ipmi_if smic_if = {
  204         "SMIC",
  205         IPMI_IF_SMIC_NREGS,
  206         cmn_buildmsg,
  207         smic_sendmsg,
  208         smic_recvmsg,
  209         smic_reset,
  210         smic_probe,
  211         IPMI_MSG_DATASND,
  212         IPMI_MSG_DATARCV,
  213 };
  214 
  215 struct ipmi_if bt_if = {
  216         "BT",
  217         IPMI_IF_BT_NREGS,
  218         bt_buildmsg,
  219         bt_sendmsg,
  220         bt_recvmsg,
  221         bt_reset,
  222         bt_probe,
  223         IPMI_BTMSG_DATASND,
  224         IPMI_BTMSG_DATARCV,
  225 };
  226 
  227 struct ipmi_if *ipmi_get_if(int);
  228 
  229 struct ipmi_if *
  230 ipmi_get_if(int iftype)
  231 {
  232         switch (iftype) {
  233         case IPMI_IF_KCS:
  234                 return (&kcs_if);
  235         case IPMI_IF_SMIC:
  236                 return (&smic_if);
  237         case IPMI_IF_BT:
  238                 return (&bt_if);
  239         }
  240 
  241         return (NULL);
  242 }
  243 
  244 /*
  245  * BMC Helper Functions
  246  */
  247 u_int8_t
  248 bmc_read(struct ipmi_softc *sc, int offset)
  249 {
  250         if (sc->sc_if_iosize == 4)
  251                 return (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
  252                     offset * sc->sc_if_iospacing));
  253         else    
  254                 return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
  255                     offset * sc->sc_if_iospacing));
  256 }
  257 
  258 void
  259 bmc_write(struct ipmi_softc *sc, int offset, u_int8_t val)
  260 {
  261         if (sc->sc_if_iosize == 4)
  262                 bus_space_write_4(sc->sc_iot, sc->sc_ioh,
  263                     offset * sc->sc_if_iospacing, val);
  264         else
  265                 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
  266                     offset * sc->sc_if_iospacing, val);
  267 }
  268 
  269 int
  270 bmc_io_wait(struct ipmi_softc *sc, struct ipmi_iowait *a)
  271 {
  272         volatile u_int8_t       v;
  273         int                     count = 5000000; /* == 5s XXX can be shorter */
  274 
  275         while (count--) {
  276                 v = bmc_read(sc, a->offset);
  277                 if ((v & a->mask) == a->value)
  278                         return v;
  279 
  280                 delay(1);
  281         }
  282 
  283         dbg_printf(1, "%s: bmc_io_wait fails : *v=%.2x m=%.2x b=%.2x %s\n",
  284             DEVNAME(sc), v, a->mask, a->value, a->lbl);
  285         return (-1);
  286 
  287 }
  288 
  289 #define RSSA_MASK 0xff
  290 #define LUN_MASK 0x3
  291 #define NETFN_LUN(nf,ln) (((nf) << 2) | ((ln) & LUN_MASK))
  292 
  293 /*
  294  * BT interface
  295  */
  296 #define _BT_CTRL_REG                    0
  297 #define   BT_CLR_WR_PTR                 (1L << 0)
  298 #define   BT_CLR_RD_PTR                 (1L << 1)
  299 #define   BT_HOST2BMC_ATN               (1L << 2)
  300 #define   BT_BMC2HOST_ATN               (1L << 3)
  301 #define   BT_EVT_ATN                    (1L << 4)
  302 #define   BT_HOST_BUSY                  (1L << 6)
  303 #define   BT_BMC_BUSY                   (1L << 7)
  304 
  305 #define   BT_READY      (BT_HOST_BUSY|BT_HOST2BMC_ATN|BT_BMC2HOST_ATN)
  306 
  307 #define _BT_DATAIN_REG                  1
  308 #define _BT_DATAOUT_REG                 1
  309 
  310 #define _BT_INTMASK_REG                 2
  311 #define  BT_IM_HIRQ_PEND                (1L << 1)
  312 #define  BT_IM_SCI_EN                   (1L << 2)
  313 #define  BT_IM_SMI_EN                   (1L << 3)
  314 #define  BT_IM_NMI2SMI                  (1L << 4)
  315 
  316 int bt_read(struct ipmi_softc *, int);
  317 int bt_write(struct ipmi_softc *, int, uint8_t);
  318 
  319 int
  320 bt_read(struct ipmi_softc *sc, int reg)
  321 {
  322         return bmc_read(sc, reg);
  323 }
  324 
  325 int
  326 bt_write(struct ipmi_softc *sc, int reg, uint8_t data)
  327 {
  328         struct ipmi_iowait a;
  329 
  330         a.offset = _BT_CTRL_REG;
  331         a.mask = BT_BMC_BUSY;
  332         a.value = 0;
  333         a.lbl = "bt_write";
  334         if (bmc_io_wait(sc, &a) < 0)
  335                 return (-1);
  336 
  337         bmc_write(sc, reg, data);
  338         return (0);
  339 }
  340 
  341 int
  342 bt_sendmsg(struct ipmi_cmd *c)
  343 {
  344         struct ipmi_softc *sc = c->c_sc;
  345         struct ipmi_iowait a;
  346         int i;
  347 
  348         bt_write(sc, _BT_CTRL_REG, BT_CLR_WR_PTR);
  349         for (i = 0; i < c->c_txlen; i++)
  350                 bt_write(sc, _BT_DATAOUT_REG, sc->sc_buf[i]);
  351 
  352         bt_write(sc, _BT_CTRL_REG, BT_HOST2BMC_ATN);
  353         a.offset = _BT_CTRL_REG;
  354         a.mask = BT_HOST2BMC_ATN | BT_BMC_BUSY;
  355         a.value = 0;
  356         a.lbl = "bt_sendwait";
  357         if (bmc_io_wait(sc, &a) < 0)
  358                 return (-1);
  359 
  360         return (0);
  361 }
  362 
  363 int
  364 bt_recvmsg(struct ipmi_cmd *c)
  365 {
  366         struct ipmi_softc *sc = c->c_sc;
  367         struct ipmi_iowait a;
  368         u_int8_t len, v, i, j;
  369 
  370         a.offset = _BT_CTRL_REG;
  371         a.mask = BT_BMC2HOST_ATN;
  372         a.value = BT_BMC2HOST_ATN;
  373         a.lbl = "bt_recvwait";
  374         if (bmc_io_wait(sc, &a) < 0)
  375                 return (-1);
  376 
  377         bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY);
  378         bt_write(sc, _BT_CTRL_REG, BT_BMC2HOST_ATN);
  379         bt_write(sc, _BT_CTRL_REG, BT_CLR_RD_PTR);
  380         len = bt_read(sc, _BT_DATAIN_REG);
  381         for (i = IPMI_BTMSG_NFLN, j = 0; i <= len; i++) {
  382                 v = bt_read(sc, _BT_DATAIN_REG);
  383                 if (i != IPMI_BTMSG_SEQ)
  384                         *(sc->sc_buf + j++) = v;
  385         }
  386         bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY);
  387         c->c_rxlen = len - 1;
  388 
  389         return (0);
  390 }
  391 
  392 int
  393 bt_reset(struct ipmi_softc *sc)
  394 {
  395         return (-1);
  396 }
  397 
  398 int
  399 bt_probe(struct ipmi_softc *sc)
  400 {
  401         u_int8_t rv;
  402 
  403         rv = bmc_read(sc, _BT_CTRL_REG);
  404         rv &= BT_HOST_BUSY;
  405         rv |= BT_CLR_WR_PTR|BT_CLR_RD_PTR|BT_BMC2HOST_ATN|BT_HOST2BMC_ATN;
  406         bmc_write(sc, _BT_CTRL_REG, rv);
  407 
  408         rv = bmc_read(sc, _BT_INTMASK_REG);
  409         rv &= BT_IM_SCI_EN|BT_IM_SMI_EN|BT_IM_NMI2SMI;
  410         rv |= BT_IM_HIRQ_PEND;
  411         bmc_write(sc, _BT_INTMASK_REG, rv);
  412 
  413 #if 0
  414         printf("bt_probe: %2x\n", v);
  415         printf(" WR    : %2x\n", v & BT_CLR_WR_PTR);
  416         printf(" RD    : %2x\n", v & BT_CLR_RD_PTR);
  417         printf(" H2B   : %2x\n", v & BT_HOST2BMC_ATN);
  418         printf(" B2H   : %2x\n", v & BT_BMC2HOST_ATN);
  419         printf(" EVT   : %2x\n", v & BT_EVT_ATN);
  420         printf(" HBSY  : %2x\n", v & BT_HOST_BUSY);
  421         printf(" BBSY  : %2x\n", v & BT_BMC_BUSY);
  422 #endif
  423         return (0);
  424 }
  425 
  426 /*
  427  * SMIC interface
  428  */
  429 #define _SMIC_DATAIN_REG                0
  430 #define _SMIC_DATAOUT_REG               0
  431 
  432 #define _SMIC_CTRL_REG                  1
  433 #define   SMS_CC_GET_STATUS              0x40
  434 #define   SMS_CC_START_TRANSFER          0x41
  435 #define   SMS_CC_NEXT_TRANSFER           0x42
  436 #define   SMS_CC_END_TRANSFER            0x43
  437 #define   SMS_CC_START_RECEIVE           0x44
  438 #define   SMS_CC_NEXT_RECEIVE            0x45
  439 #define   SMS_CC_END_RECEIVE             0x46
  440 #define   SMS_CC_TRANSFER_ABORT          0x47
  441 
  442 #define   SMS_SC_READY                   0xc0
  443 #define   SMS_SC_WRITE_START             0xc1
  444 #define   SMS_SC_WRITE_NEXT              0xc2
  445 #define   SMS_SC_WRITE_END               0xc3
  446 #define   SMS_SC_READ_START              0xc4
  447 #define   SMS_SC_READ_NEXT               0xc5
  448 #define   SMS_SC_READ_END                0xc6
  449 
  450 #define _SMIC_FLAG_REG                  2
  451 #define   SMIC_BUSY                     (1L << 0)
  452 #define   SMIC_SMS_ATN                  (1L << 2)
  453 #define   SMIC_EVT_ATN                  (1L << 3)
  454 #define   SMIC_SMI                      (1L << 4)
  455 #define   SMIC_TX_DATA_RDY              (1L << 6)
  456 #define   SMIC_RX_DATA_RDY              (1L << 7)
  457 
  458 int     smic_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *);
  459 int     smic_write_cmd_data(struct ipmi_softc *, u_int8_t, const u_int8_t *);
  460 int     smic_read_data(struct ipmi_softc *, u_int8_t *);
  461 
  462 int
  463 smic_wait(struct ipmi_softc *sc, u_int8_t mask, u_int8_t val, const char *lbl)
  464 {
  465         struct ipmi_iowait a;
  466         int v;
  467 
  468         /* Wait for expected flag bits */
  469         a.offset = _SMIC_FLAG_REG;
  470         a.mask = mask;
  471         a.value = val;
  472         a.lbl = "smicwait";
  473         v = bmc_io_wait(sc, &a);
  474         if (v < 0)
  475                 return (-1);
  476 
  477         /* Return current status */
  478         v = bmc_read(sc, _SMIC_CTRL_REG);
  479         dbg_printf(99, "smic_wait = %.2x\n", v);
  480         return (v);
  481 }
  482 
  483 int
  484 smic_write_cmd_data(struct ipmi_softc *sc, u_int8_t cmd, const u_int8_t *data)
  485 {
  486         int     sts, v;
  487 
  488         dbg_printf(50, "smic_wcd: %.2x %.2x\n", cmd, data ? *data : -1);
  489         sts = smic_wait(sc, SMIC_TX_DATA_RDY | SMIC_BUSY, SMIC_TX_DATA_RDY,
  490             "smic_write_cmd_data ready");
  491         if (sts < 0)
  492                 return (sts);
  493 
  494         bmc_write(sc, _SMIC_CTRL_REG, cmd);
  495         if (data)
  496                 bmc_write(sc, _SMIC_DATAOUT_REG, *data);
  497 
  498         /* Toggle BUSY bit, then wait for busy bit to clear */
  499         v = bmc_read(sc, _SMIC_FLAG_REG);
  500         bmc_write(sc, _SMIC_FLAG_REG, v | SMIC_BUSY);
  501 
  502         return (smic_wait(sc, SMIC_BUSY, 0, "smic_write_cmd_data busy"));
  503 }
  504 
  505 int
  506 smic_read_data(struct ipmi_softc *sc, u_int8_t *data)
  507 {
  508         int sts;
  509 
  510         sts = smic_wait(sc, SMIC_RX_DATA_RDY | SMIC_BUSY, SMIC_RX_DATA_RDY,
  511             "smic_read_data");
  512         if (sts >= 0) {
  513                 *data = bmc_read(sc, _SMIC_DATAIN_REG);
  514                 dbg_printf(50, "smic_readdata: %.2x\n", *data);
  515         }
  516         return (sts);
  517 }
  518 
  519 #define ErrStat(a,b) if (a) printf(b);
  520 
  521 int
  522 smic_sendmsg(struct ipmi_cmd *c)
  523 {
  524         struct ipmi_softc *sc = c->c_sc;
  525         int sts, idx;
  526 
  527         sts = smic_write_cmd_data(sc, SMS_CC_START_TRANSFER, &sc->sc_buf[0]);
  528         ErrStat(sts != SMS_SC_WRITE_START, "wstart");
  529         for (idx = 1; idx < c->c_txlen - 1; idx++) {
  530                 sts = smic_write_cmd_data(sc, SMS_CC_NEXT_TRANSFER,
  531                     &sc->sc_buf[idx]);
  532                 ErrStat(sts != SMS_SC_WRITE_NEXT, "write");
  533         }
  534         sts = smic_write_cmd_data(sc, SMS_CC_END_TRANSFER, &sc->sc_buf[idx]);
  535         if (sts != SMS_SC_WRITE_END) {
  536                 dbg_printf(50, "smic_sendmsg %d/%d = %.2x\n", idx, c->c_txlen, sts);
  537                 return (-1);
  538         }
  539 
  540         return (0);
  541 }
  542 
  543 int
  544 smic_recvmsg(struct ipmi_cmd *c)
  545 {
  546         struct ipmi_softc *sc = c->c_sc;
  547         int sts, idx;
  548 
  549         c->c_rxlen = 0;
  550         sts = smic_wait(sc, SMIC_RX_DATA_RDY, SMIC_RX_DATA_RDY, "smic_recvmsg");
  551         if (sts < 0)
  552                 return (-1);
  553 
  554         sts = smic_write_cmd_data(sc, SMS_CC_START_RECEIVE, NULL);
  555         ErrStat(sts != SMS_SC_READ_START, "rstart");
  556         for (idx = 0;; ) {
  557                 sts = smic_read_data(sc, &sc->sc_buf[idx++]);
  558                 if (sts != SMS_SC_READ_START && sts != SMS_SC_READ_NEXT)
  559                         break;
  560                 smic_write_cmd_data(sc, SMS_CC_NEXT_RECEIVE, NULL);
  561         }
  562         ErrStat(sts != SMS_SC_READ_END, "rend");
  563 
  564         c->c_rxlen = idx;
  565 
  566         sts = smic_write_cmd_data(sc, SMS_CC_END_RECEIVE, NULL);
  567         if (sts != SMS_SC_READY) {
  568                 dbg_printf(50, "smic_recvmsg %d/%d = %.2x\n", idx, c->c_maxrxlen, sts);
  569                 return (-1);
  570         }
  571 
  572         return (0);
  573 }
  574 
  575 int
  576 smic_reset(struct ipmi_softc *sc)
  577 {
  578         return (-1);
  579 }
  580 
  581 int
  582 smic_probe(struct ipmi_softc *sc)
  583 {
  584         /* Flag register should not be 0xFF on a good system */
  585         if (bmc_read(sc, _SMIC_FLAG_REG) == 0xFF)
  586                 return (-1);
  587 
  588         return (0);
  589 }
  590 
  591 /*
  592  * KCS interface
  593  */
  594 #define _KCS_DATAIN_REGISTER            0
  595 #define _KCS_DATAOUT_REGISTER           0
  596 #define   KCS_READ_NEXT                 0x68
  597 
  598 #define _KCS_COMMAND_REGISTER           1
  599 #define   KCS_GET_STATUS                0x60
  600 #define   KCS_WRITE_START               0x61
  601 #define   KCS_WRITE_END                 0x62
  602 
  603 #define _KCS_STATUS_REGISTER            1
  604 #define   KCS_OBF                       (1L << 0)
  605 #define   KCS_IBF                       (1L << 1)
  606 #define   KCS_SMS_ATN                   (1L << 2)
  607 #define   KCS_CD                        (1L << 3)
  608 #define   KCS_OEM1                      (1L << 4)
  609 #define   KCS_OEM2                      (1L << 5)
  610 #define   KCS_STATE_MASK                0xc0
  611 #define     KCS_IDLE_STATE              0x00
  612 #define     KCS_READ_STATE              0x40
  613 #define     KCS_WRITE_STATE             0x80
  614 #define     KCS_ERROR_STATE             0xC0
  615 
  616 int     kcs_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *);
  617 int     kcs_write_cmd(struct ipmi_softc *, u_int8_t);
  618 int     kcs_write_data(struct ipmi_softc *, u_int8_t);
  619 int     kcs_read_data(struct ipmi_softc *, u_int8_t *);
  620 
  621 int
  622 kcs_wait(struct ipmi_softc *sc, u_int8_t mask, u_int8_t value, const char *lbl)
  623 {
  624         struct ipmi_iowait a;
  625         int v;
  626 
  627         a.offset = _KCS_STATUS_REGISTER;
  628         a.mask = mask;
  629         a.value = value;
  630         a.lbl = lbl;
  631         v = bmc_io_wait(sc, &a);
  632         if (v < 0)
  633                 return (v);
  634 
  635         /* Check if output buffer full, read dummy byte  */
  636         if ((v & (KCS_OBF | KCS_STATE_MASK)) == (KCS_OBF | KCS_WRITE_STATE))
  637                 bmc_read(sc, _KCS_DATAIN_REGISTER);
  638 
  639         /* Check for error state */
  640         if ((v & KCS_STATE_MASK) == KCS_ERROR_STATE) {
  641                 bmc_write(sc, _KCS_COMMAND_REGISTER, KCS_GET_STATUS);
  642                 while (bmc_read(sc, _KCS_STATUS_REGISTER) & KCS_IBF)
  643                         continue;
  644                 printf("%s: error code: %x\n", DEVNAME(sc),
  645                     bmc_read(sc, _KCS_DATAIN_REGISTER));
  646         }
  647 
  648         return (v & KCS_STATE_MASK);
  649 }
  650 
  651 int
  652 kcs_write_cmd(struct ipmi_softc *sc, u_int8_t cmd)
  653 {
  654         /* ASSERT: IBF and OBF are clear */
  655         dbg_printf(50, "kcswritecmd: %.2x\n", cmd);
  656         bmc_write(sc, _KCS_COMMAND_REGISTER, cmd);
  657 
  658         return (kcs_wait(sc, KCS_IBF, 0, "write_cmd"));
  659 }
  660 
  661 int
  662 kcs_write_data(struct ipmi_softc *sc, u_int8_t data)
  663 {
  664         /* ASSERT: IBF and OBF are clear */
  665         dbg_printf(50, "kcswritedata: %.2x\n", data);
  666         bmc_write(sc, _KCS_DATAOUT_REGISTER, data);
  667 
  668         return (kcs_wait(sc, KCS_IBF, 0, "write_data"));
  669 }
  670 
  671 int
  672 kcs_read_data(struct ipmi_softc *sc, u_int8_t * data)
  673 {
  674         int sts;
  675 
  676         sts = kcs_wait(sc, KCS_IBF | KCS_OBF, KCS_OBF, "read_data");
  677         if (sts != KCS_READ_STATE)
  678                 return (sts);
  679 
  680         /* ASSERT: OBF is set read data, request next byte */
  681         *data = bmc_read(sc, _KCS_DATAIN_REGISTER);
  682         bmc_write(sc, _KCS_DATAOUT_REGISTER, KCS_READ_NEXT);
  683 
  684         dbg_printf(50, "kcsreaddata: %.2x\n", *data);
  685 
  686         return (sts);
  687 }
  688 
  689 /* Exported KCS functions */
  690 int
  691 kcs_sendmsg(struct ipmi_cmd *c)
  692 {
  693         struct ipmi_softc *sc = c->c_sc;
  694         int idx, sts;
  695 
  696         /* ASSERT: IBF is clear */
  697         dbg_dump(50, "kcs sendmsg", c->c_txlen, sc->sc_buf);
  698         sts = kcs_write_cmd(sc, KCS_WRITE_START);
  699         for (idx = 0; idx < c->c_txlen; idx++) {
  700                 if (idx == c->c_txlen - 1)
  701                         sts = kcs_write_cmd(sc, KCS_WRITE_END);
  702 
  703                 if (sts != KCS_WRITE_STATE)
  704                         break;
  705 
  706                 sts = kcs_write_data(sc, sc->sc_buf[idx]);
  707         }
  708         if (sts != KCS_READ_STATE) {
  709                 dbg_printf(1, "kcs sendmsg = %d/%d <%.2x>\n", idx, c->c_txlen, sts);
  710                 dbg_dump(1, "kcs_sendmsg", c->c_txlen, sc->sc_buf);
  711                 return (-1);
  712         }
  713 
  714         return (0);
  715 }
  716 
  717 int
  718 kcs_recvmsg(struct ipmi_cmd *c)
  719 {
  720         struct ipmi_softc *sc = c->c_sc;
  721         int idx, sts;
  722 
  723         for (idx = 0; idx < c->c_maxrxlen; idx++) {
  724                 sts = kcs_read_data(sc, &sc->sc_buf[idx]);
  725                 if (sts != KCS_READ_STATE)
  726                         break;
  727         }
  728         sts = kcs_wait(sc, KCS_IBF, 0, "recv");
  729         c->c_rxlen = idx;
  730         if (sts != KCS_IDLE_STATE) {
  731                 dbg_printf(1, "kcs recvmsg = %d/%d <%.2x>\n", idx, c->c_maxrxlen, sts);
  732                 return (-1);
  733         }
  734 
  735         dbg_dump(50, "kcs recvmsg", idx, sc->sc_buf);
  736 
  737         return (0);
  738 }
  739 
  740 int
  741 kcs_reset(struct ipmi_softc *sc)
  742 {
  743         return (-1);
  744 }
  745 
  746 int
  747 kcs_probe(struct ipmi_softc *sc)
  748 {
  749         u_int8_t v;
  750 
  751         v = bmc_read(sc, _KCS_STATUS_REGISTER);
  752         if ((v & KCS_STATE_MASK) == KCS_ERROR_STATE)
  753                 return (1);
  754 #if 0
  755         printf("kcs_probe: %2x\n", v);
  756         printf(" STS: %2x\n", v & KCS_STATE_MASK);
  757         printf(" ATN: %2x\n", v & KCS_SMS_ATN);
  758         printf(" C/D: %2x\n", v & KCS_CD);
  759         printf(" IBF: %2x\n", v & KCS_IBF);
  760         printf(" OBF: %2x\n", v & KCS_OBF);
  761 #endif
  762         return (0);
  763 }
  764 
  765 /*
  766  * IPMI code
  767  */
  768 #define READ_SMS_BUFFER         0x37
  769 #define WRITE_I2C               0x50
  770 
  771 #define GET_MESSAGE_CMD         0x33
  772 #define SEND_MESSAGE_CMD        0x34
  773 
  774 #define IPMB_CHANNEL_NUMBER     0
  775 
  776 #define PUBLIC_BUS              0
  777 
  778 #define MIN_I2C_PACKET_SIZE     3
  779 #define MIN_IMB_PACKET_SIZE     7       /* one byte for cksum */
  780 
  781 #define MIN_BTBMC_REQ_SIZE      4
  782 #define MIN_BTBMC_RSP_SIZE      5
  783 #define MIN_BMC_REQ_SIZE        2
  784 #define MIN_BMC_RSP_SIZE        3
  785 
  786 #define BMC_SA                  0x20    /* BMC/ESM3 */
  787 #define FPC_SA                  0x22    /* front panel */
  788 #define BP_SA                   0xC0    /* Primary Backplane */
  789 #define BP2_SA                  0xC2    /* Secondary Backplane */
  790 #define PBP_SA                  0xC4    /* Peripheral Backplane */
  791 #define DRAC_SA                 0x28    /* DRAC-III */
  792 #define DRAC3_SA                0x30    /* DRAC-III */
  793 #define BMC_LUN                 0
  794 #define SMS_LUN                 2
  795 
  796 struct ipmi_request {
  797         u_int8_t        rsSa;
  798         u_int8_t        rsLun;
  799         u_int8_t        netFn;
  800         u_int8_t        cmd;
  801         u_int8_t        data_len;
  802         u_int8_t        *data;
  803 };
  804 
  805 struct ipmi_response {
  806         u_int8_t        cCode;
  807         u_int8_t        data_len;
  808         u_int8_t        *data;
  809 };
  810 
  811 struct ipmi_bmc_request {
  812         u_int8_t        bmc_nfLn;
  813         u_int8_t        bmc_cmd;
  814         u_int8_t        bmc_data_len;
  815         u_int8_t        bmc_data[1];
  816 };
  817 
  818 struct ipmi_bmc_response {
  819         u_int8_t        bmc_nfLn;
  820         u_int8_t        bmc_cmd;
  821         u_int8_t        bmc_cCode;
  822         u_int8_t        bmc_data_len;
  823         u_int8_t        bmc_data[1];
  824 };
  825 
  826 struct cfdriver ipmi_cd = {
  827         NULL, "ipmi", DV_DULL
  828 };
  829 
  830 void
  831 dumpb(const char *lbl, int len, const u_int8_t *data)
  832 {
  833         int idx;
  834 
  835         printf("%s: ", lbl);
  836         for (idx = 0; idx < len; idx++)
  837                 printf("%.2x ", data[idx]);
  838 
  839         printf("\n");
  840 }
  841 
  842 /*
  843  * bt_buildmsg builds an IPMI message from a nfLun, cmd, and data
  844  * This is used by BT protocol
  845  */
  846 void
  847 bt_buildmsg(struct ipmi_cmd *c)
  848 {
  849         struct ipmi_softc *sc = c->c_sc;
  850         u_int8_t *buf = sc->sc_buf;
  851 
  852         buf[IPMI_BTMSG_LEN] = c->c_txlen + (IPMI_BTMSG_DATASND - 1);
  853         buf[IPMI_BTMSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun);
  854         buf[IPMI_BTMSG_SEQ] = sc->sc_btseq++;
  855         buf[IPMI_BTMSG_CMD] = c->c_cmd;
  856         if (c->c_txlen && c->c_data)
  857                 memcpy(buf + IPMI_BTMSG_DATASND, c->c_data, c->c_txlen);
  858 }
  859 
  860 /*
  861  * cmn_buildmsg builds an IPMI message from a nfLun, cmd, and data
  862  * This is used by both SMIC and KCS protocols
  863  */
  864 void
  865 cmn_buildmsg(struct ipmi_cmd *c)
  866 {
  867         struct ipmi_softc *sc = c->c_sc;
  868         u_int8_t *buf = sc->sc_buf;
  869 
  870         buf[IPMI_MSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun);
  871         buf[IPMI_MSG_CMD] = c->c_cmd;
  872         if (c->c_txlen && c->c_data)
  873                 memcpy(buf + IPMI_MSG_DATASND, c->c_data, c->c_txlen);
  874 }
  875 
  876 /* Send an IPMI command */
  877 int
  878 ipmi_sendcmd(struct ipmi_cmd *c)
  879 {
  880         struct ipmi_softc       *sc = c->c_sc;
  881         int             rc = -1;
  882 
  883         dbg_printf(50, "ipmi_sendcmd: rssa=%.2x nfln=%.2x cmd=%.2x len=%.2x\n",
  884             c->c_rssa, NETFN_LUN(c->c_netfn, c->c_rslun), c->c_cmd, c->c_txlen);
  885         dbg_dump(10, " send", c->c_txlen, c->c_data);
  886         if (c->c_rssa != BMC_SA) {
  887 #if 0
  888                 sc->sc_if->buildmsg(c);
  889                 pI2C->bus = (sc->if_ver == 0x09) ?
  890                     PUBLIC_BUS :
  891                     IPMB_CHANNEL_NUMBER;
  892 
  893                 imbreq->rsSa = rssa;
  894                 imbreq->nfLn = NETFN_LUN(netfn, rslun);
  895                 imbreq->cSum1 = -(imbreq->rsSa + imbreq->nfLn);
  896                 imbreq->rqSa = BMC_SA;
  897                 imbreq->seqLn = NETFN_LUN(sc->imb_seq++, SMS_LUN);
  898                 imbreq->cmd = cmd;
  899                 if (txlen)
  900                         memcpy(imbreq->data, data, txlen);
  901                 /* Set message checksum */
  902                 imbreq->data[txlen] = cksum8(&imbreq->rqSa, txlen + 3);
  903 #endif
  904                 goto done;
  905         } else
  906                 sc->sc_if->buildmsg(c);
  907 
  908         c->c_txlen += sc->sc_if->datasnd;
  909         rc = sc->sc_if->sendmsg(c);
  910 
  911 done:
  912         return (rc);
  913 }
  914 
  915 /* Receive an IPMI command */
  916 int
  917 ipmi_recvcmd(struct ipmi_cmd *c)
  918 {
  919         struct ipmi_softc *sc = c->c_sc;
  920         u_int8_t        *buf = sc->sc_buf, rc = 0;
  921 
  922         /* Receive message from interface, copy out result data */
  923         c->c_maxrxlen += sc->sc_if->datarcv;
  924         if (sc->sc_if->recvmsg(c) ||
  925             c->c_rxlen < sc->sc_if->datarcv) {
  926                 return (-1);
  927         }
  928 
  929         c->c_rxlen -= sc->sc_if->datarcv;
  930         if (c->c_rxlen > 0 && c->c_data)
  931                 memcpy(c->c_data, buf + sc->sc_if->datarcv, c->c_rxlen);
  932 
  933         rc = buf[IPMI_MSG_CCODE];
  934 #ifdef IPMI_DEBUG
  935         if (rc != 0)
  936                 dbg_printf(1, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x\n",
  937                     buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE]);
  938 #endif
  939 
  940         dbg_printf(50, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x len=%.2x\n",
  941             buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE],
  942             c->c_rxlen);
  943         dbg_dump(10, " recv", c->c_rxlen, c->c_data);
  944 
  945         return (rc);
  946 }
  947 
  948 void
  949 ipmi_cmd(struct ipmi_cmd *c)
  950 {
  951         if (cold || panicstr != NULL)
  952                 ipmi_cmd_poll(c);
  953         else
  954                 ipmi_cmd_wait(c);
  955 }
  956 
  957 void
  958 ipmi_cmd_poll(struct ipmi_cmd *c)
  959 {
  960         if ((c->c_ccode = ipmi_sendcmd(c)))
  961                 printf("%s: sendcmd fails\n", DEVNAME(c->c_sc));
  962         else
  963                 c->c_ccode = ipmi_recvcmd(c);
  964 }
  965 
  966 void
  967 ipmi_cmd_wait(struct ipmi_cmd *c)
  968 {
  969         struct task t;
  970         int res;
  971 
  972         task_set(&t, ipmi_cmd_wait_cb, c);
  973         res = task_add(c->c_sc->sc_cmd_taskq, &t);
  974         KASSERT(res == 1);
  975 
  976         tsleep_nsec(c, PWAIT, "ipmicmd", INFSLP);
  977 
  978         res = task_del(c->c_sc->sc_cmd_taskq, &t);
  979         KASSERT(res == 0);
  980 }
  981 
  982 void
  983 ipmi_cmd_wait_cb(void *arg)
  984 {
  985         struct ipmi_cmd *c = arg;
  986 
  987         ipmi_cmd_poll(c);
  988         wakeup(c);
  989 }
  990 
  991 /* Read a partial SDR entry */
  992 int
  993 get_sdr_partial(struct ipmi_softc *sc, u_int16_t recordId, u_int16_t reserveId,
  994     u_int8_t offset, u_int8_t length, void *buffer, u_int16_t *nxtRecordId)
  995 {
  996         u_int8_t        cmd[IPMI_GET_WDOG_MAX + 255];   /* 8 + max of length */
  997         int             len;
  998 
  999         ((u_int16_t *) cmd)[0] = reserveId;
 1000         ((u_int16_t *) cmd)[1] = recordId;
 1001         cmd[4] = offset;
 1002         cmd[5] = length;
 1003 
 1004         struct ipmi_cmd c;
 1005         c.c_sc = sc;
 1006         c.c_rssa = BMC_SA;
 1007         c.c_rslun = BMC_LUN;
 1008         c.c_netfn = STORAGE_NETFN;
 1009         c.c_cmd = STORAGE_GET_SDR;
 1010         c.c_txlen = IPMI_SET_WDOG_MAX;
 1011         c.c_rxlen = 0;
 1012         c.c_maxrxlen = 8 + length;
 1013         c.c_data = cmd;
 1014         ipmi_cmd(&c);
 1015         len = c.c_rxlen;
 1016 
 1017         if (nxtRecordId)
 1018                 *nxtRecordId = *(uint16_t *) cmd;
 1019         if (len > 2)
 1020                 memcpy(buffer, cmd + 2, len - 2);
 1021         else
 1022                 return (1);
 1023 
 1024         return (0);
 1025 }
 1026 
 1027 int maxsdrlen = 0x10;
 1028 
 1029 /* Read an entire SDR; pass to add sensor */
 1030 int
 1031 get_sdr(struct ipmi_softc *sc, u_int16_t recid, u_int16_t *nxtrec)
 1032 {
 1033         u_int16_t       resid = 0;
 1034         int             len, sdrlen, offset;
 1035         u_int8_t        *psdr;
 1036         struct sdrhdr   shdr;
 1037 
 1038         /* Reserve SDR */
 1039         struct ipmi_cmd c;
 1040         c.c_sc = sc;
 1041         c.c_rssa = BMC_SA;
 1042         c.c_rslun = BMC_LUN;
 1043         c.c_netfn = STORAGE_NETFN;
 1044         c.c_cmd = STORAGE_RESERVE_SDR;
 1045         c.c_txlen = 0;
 1046         c.c_maxrxlen = sizeof(resid);
 1047         c.c_rxlen = 0;
 1048         c.c_data = &resid;
 1049         ipmi_cmd(&c);
 1050 
 1051         /* Get SDR Header */
 1052         if (get_sdr_partial(sc, recid, resid, 0, sizeof shdr, &shdr, nxtrec)) {
 1053                 printf("%s: get header fails\n", DEVNAME(sc));
 1054                 return (1);
 1055         }
 1056         /* Allocate space for entire SDR Length of SDR in header does not
 1057          * include header length */
 1058         sdrlen = sizeof(shdr) + shdr.record_length;
 1059         psdr = malloc(sdrlen, M_DEVBUF, M_NOWAIT);
 1060         if (psdr == NULL)
 1061                 return (1);
 1062 
 1063         memcpy(psdr, &shdr, sizeof(shdr));
 1064 
 1065         /* Read SDR Data maxsdrlen bytes at a time */
 1066         for (offset = sizeof(shdr); offset < sdrlen; offset += maxsdrlen) {
 1067                 len = sdrlen - offset;
 1068                 if (len > maxsdrlen)
 1069                         len = maxsdrlen;
 1070 
 1071                 if (get_sdr_partial(sc, recid, resid, offset, len,
 1072                     psdr + offset, NULL)) {
 1073                         printf("%s: get chunk: %d,%d fails\n", DEVNAME(sc),
 1074                             offset, len);
 1075                         free(psdr, M_DEVBUF, sdrlen);
 1076                         return (1);
 1077                 }
 1078         }
 1079 
 1080         /* Add SDR to sensor list, if not wanted, free buffer */
 1081         if (add_sdr_sensor(sc, psdr, sdrlen) == 0)
 1082                 free(psdr, M_DEVBUF, sdrlen);
 1083 
 1084         return (0);
 1085 }
 1086 
 1087 int
 1088 getbits(u_int8_t *bytes, int bitpos, int bitlen)
 1089 {
 1090         int     v;
 1091         int     mask;
 1092 
 1093         bitpos += bitlen - 1;
 1094         for (v = 0; bitlen--;) {
 1095                 v <<= 1;
 1096                 mask = 1L << (bitpos & 7);
 1097                 if (bytes[bitpos >> 3] & mask)
 1098                         v |= 1;
 1099                 bitpos--;
 1100         }
 1101 
 1102         return (v);
 1103 }
 1104 
 1105 /* Decode IPMI sensor name */
 1106 int
 1107 ipmi_sensor_name(char *name, int len, u_int8_t typelen, u_int8_t *bits,
 1108     int bitslen)
 1109 {
 1110         int     i, slen;
 1111         char    bcdplus[] = "0123456789 -.:,_";
 1112 
 1113         slen = typelen & 0x1F;
 1114         switch (typelen >> 6) {
 1115         case IPMI_NAME_UNICODE:
 1116                 //unicode
 1117                 break;
 1118 
 1119         case IPMI_NAME_BCDPLUS:
 1120                 /* Characters are encoded in 4-bit BCDPLUS */
 1121                 if (len < slen * 2 + 1)
 1122                         slen = (len >> 1) - 1;
 1123                 if (slen > bitslen)
 1124                         return (0);
 1125                 for (i = 0; i < slen; i++) {
 1126                         *(name++) = bcdplus[bits[i] >> 4];
 1127                         *(name++) = bcdplus[bits[i] & 0xF];
 1128                 }
 1129                 break;
 1130 
 1131         case IPMI_NAME_ASCII6BIT:
 1132                 /* Characters are encoded in 6-bit ASCII
 1133                  *   0x00 - 0x3F maps to 0x20 - 0x5F */
 1134                 /* XXX: need to calculate max len: slen = 3/4 * len */
 1135                 if (len < slen + 1)
 1136                         slen = len - 1;
 1137                 if (slen * 6 / 8 > bitslen)
 1138                         return (0);
 1139                 for (i = 0; i < slen * 8; i += 6) {
 1140                         *(name++) = getbits(bits, i, 6) + ' ';
 1141                 }
 1142                 break;
 1143 
 1144         case IPMI_NAME_ASCII8BIT:
 1145                 /* Characters are 8-bit ascii */
 1146                 if (len < slen + 1)
 1147                         slen = len - 1;
 1148                 if (slen > bitslen)
 1149                         return (0);
 1150                 while (slen--)
 1151                         *(name++) = *(bits++);
 1152                 break;
 1153         }
 1154         *name = 0;
 1155 
 1156         return (1);
 1157 }
 1158 
 1159 /* Calculate val * 10^exp */
 1160 long
 1161 ipow(long val, int exp)
 1162 {
 1163         while (exp > 0) {
 1164                 val *= 10;
 1165                 exp--;
 1166         }
 1167 
 1168         while (exp < 0) {
 1169                 val /= 10;
 1170                 exp++;
 1171         }
 1172 
 1173         return (val);
 1174 }
 1175 
 1176 /* Sign extend a n-bit value */
 1177 long
 1178 signextend(unsigned long val, int bits)
 1179 {
 1180         long msk = (1L << (bits-1))-1;
 1181 
 1182         return (-(val & ~msk) | val);
 1183 }
 1184 
 1185 /* Convert IPMI reading from sensor factors */
 1186 long
 1187 ipmi_convert(u_int8_t v, struct sdrtype1 *s1, long adj)
 1188 {
 1189         int16_t M, B;
 1190         int8_t  K1, K2;
 1191         long    val;
 1192 
 1193         /* Calculate linear reading variables */
 1194         M  = signextend((((short)(s1->m_tolerance & 0xC0)) << 2) + s1->m, 10);
 1195         B  = signextend((((short)(s1->b_accuracy & 0xC0)) << 2) + s1->b, 10);
 1196         K1 = signextend(s1->rbexp & 0xF, 4);
 1197         K2 = signextend(s1->rbexp >> 4, 4);
 1198 
 1199         /* Calculate sensor reading:
 1200          *  y = L((M * v + (B * 10^K1)) * 10^(K2+adj)
 1201          *
 1202          * This commutes out to:
 1203          *  y = L(M*v * 10^(K2+adj) + B * 10^(K1+K2+adj)); */
 1204         val = ipow(M * v, K2 + adj) + ipow(B, K1 + K2 + adj);
 1205 
 1206         /* Linearization function: y = f(x) 0 : y = x 1 : y = ln(x) 2 : y =
 1207          * log10(x) 3 : y = log2(x) 4 : y = e^x 5 : y = 10^x 6 : y = 2^x 7 : y
 1208          * = 1/x 8 : y = x^2 9 : y = x^3 10 : y = square root(x) 11 : y = cube
 1209          * root(x) */
 1210         return (val);
 1211 }
 1212 
 1213 int
 1214 ipmi_sensor_status(struct ipmi_softc *sc, struct ipmi_sensor *psensor,
 1215     u_int8_t *reading)
 1216 {
 1217         struct sdrtype1 *s1 = (struct sdrtype1 *)psensor->i_sdr;
 1218         int             etype;
 1219 
 1220         /* Get reading of sensor */
 1221         switch (psensor->i_sensor.type) {
 1222         case SENSOR_TEMP:
 1223                 psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6);
 1224                 psensor->i_sensor.value += 273150000;
 1225                 break;
 1226 
 1227         case SENSOR_VOLTS_DC:
 1228         case SENSOR_VOLTS_AC:
 1229         case SENSOR_AMPS:
 1230         case SENSOR_WATTS:
 1231                 psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6);
 1232                 break;
 1233 
 1234         case SENSOR_FANRPM:
 1235                 psensor->i_sensor.value = ipmi_convert(reading[0], s1, 0);
 1236                 if (((s1->units1>>3)&0x7) == 0x3)
 1237                         psensor->i_sensor.value *= 60; // RPS -> RPM
 1238                 break;
 1239         default:
 1240                 break;
 1241         }
 1242 
 1243         /* Return Sensor Status */
 1244         etype = (psensor->etype << 8) + psensor->stype;
 1245         switch (etype) {
 1246         case IPMI_SENSOR_TYPE_TEMP:
 1247         case IPMI_SENSOR_TYPE_VOLT:
 1248         case IPMI_SENSOR_TYPE_CURRENT:
 1249         case IPMI_SENSOR_TYPE_FAN:
 1250                 /* non-recoverable threshold */
 1251                 if (reading[2] & ((1 << 5) | (1 << 2)))
 1252                         return (SENSOR_S_CRIT);
 1253                 /* critical threshold */
 1254                 else if (reading[2] & ((1 << 4) | (1 << 1)))
 1255                         return (SENSOR_S_CRIT);
 1256                 /* non-critical threshold */
 1257                 else if (reading[2] & ((1 << 3) | (1 << 0)))
 1258                         return (SENSOR_S_WARN);
 1259                 break;
 1260 
 1261         case IPMI_SENSOR_TYPE_INTRUSION:
 1262                 psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0;
 1263                 if (reading[2] & 0x1)
 1264                         return (SENSOR_S_CRIT);
 1265                 break;
 1266 
 1267         case IPMI_SENSOR_TYPE_PWRSUPPLY:
 1268                 /* Reading: 1 = present+powered, 0 = otherwise */
 1269                 psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0;
 1270                 if (reading[2] & 0x10) {
 1271                         /* XXX: Need sysctl type for Power Supply types
 1272                          *   ok: power supply installed && powered
 1273                          * warn: power supply installed && !powered
 1274                          * crit: power supply !installed
 1275                          */
 1276                         return (SENSOR_S_CRIT);
 1277                 }
 1278                 if (reading[2] & 0x08) {
 1279                         /* Power supply AC lost */
 1280                         return (SENSOR_S_WARN);
 1281                 }
 1282                 break;
 1283         }
 1284 
 1285         return (SENSOR_S_OK);
 1286 }
 1287 
 1288 int
 1289 read_sensor(struct ipmi_softc *sc, struct ipmi_sensor *psensor)
 1290 {
 1291         struct sdrtype1 *s1 = (struct sdrtype1 *) psensor->i_sdr;
 1292         u_int8_t        data[8];
 1293         int             rv = -1;
 1294 
 1295         memset(data, 0, sizeof(data));
 1296         data[0] = psensor->i_num;
 1297 
 1298         struct ipmi_cmd c;
 1299         c.c_sc = sc;
 1300         c.c_rssa = s1->owner_id;
 1301         c.c_rslun = s1->owner_lun;
 1302         c.c_netfn = SE_NETFN;
 1303         c.c_cmd = SE_GET_SENSOR_READING;
 1304         c.c_txlen = 1;
 1305         c.c_maxrxlen = sizeof(data);
 1306         c.c_rxlen = 0;
 1307         c.c_data = data;
 1308         ipmi_cmd(&c);
 1309 
 1310         if (c.c_ccode != 0) {
 1311                 dbg_printf(1, "sensor reading command for %s failed: %.2x\n",
 1312                         psensor->i_sensor.desc, c.c_ccode);
 1313                 return (rv);
 1314         }
 1315         dbg_printf(10, "values=%.2x %.2x %.2x %.2x %s\n",
 1316             data[0],data[1],data[2],data[3], psensor->i_sensor.desc);
 1317         psensor->i_sensor.flags &= ~SENSOR_FINVALID;
 1318         if ((data[1] & IPMI_INVALID_SENSOR) ||
 1319             ((data[1] & IPMI_DISABLED_SENSOR) == 0 && data[0] == 0))
 1320                 psensor->i_sensor.flags |= SENSOR_FINVALID;
 1321         psensor->i_sensor.status = ipmi_sensor_status(sc, psensor, data);
 1322         rv = 0;
 1323         return (rv);
 1324 }
 1325 
 1326 int
 1327 ipmi_sensor_type(int type, int ext_type, int units2, int entity)
 1328 {
 1329         switch (units2) {
 1330         case IPMI_UNIT_TYPE_AMPS:
 1331                 return (SENSOR_AMPS);
 1332 
 1333         case IPMI_UNIT_TYPE_RPM:
 1334                 return (SENSOR_FANRPM);
 1335 
 1336         /* XXX sensors framework distinguishes AC/DC but ipmi does not */
 1337         case IPMI_UNIT_TYPE_VOLTS:
 1338                 return (SENSOR_VOLTS_DC);
 1339 
 1340         case IPMI_UNIT_TYPE_WATTS:
 1341                 return (SENSOR_WATTS);
 1342         }
 1343 
 1344         switch (ext_type << 8L | type) {
 1345         case IPMI_SENSOR_TYPE_TEMP:
 1346                 return (SENSOR_TEMP);
 1347 
 1348         case IPMI_SENSOR_TYPE_PWRSUPPLY:
 1349                 if (entity == IPMI_ENTITY_PWRSUPPLY)
 1350                         return (SENSOR_INDICATOR);
 1351                 break;
 1352 
 1353         case IPMI_SENSOR_TYPE_INTRUSION:
 1354                 return (SENSOR_INDICATOR);
 1355         }
 1356 
 1357         return (-1);
 1358 }
 1359 
 1360 /* Add Sensor to BSD Sysctl interface */
 1361 int
 1362 add_sdr_sensor(struct ipmi_softc *sc, u_int8_t *psdr, int sdrlen)
 1363 {
 1364         int                     rc;
 1365         struct sdrtype1         *s1 = (struct sdrtype1 *)psdr;
 1366         struct sdrtype2         *s2 = (struct sdrtype2 *)psdr;
 1367         char                    name[64];
 1368 
 1369         switch (s1->sdrhdr.record_type) {
 1370         case IPMI_SDR_TYPEFULL:
 1371                 rc = ipmi_sensor_name(name, sizeof(name), s1->typelen,
 1372                     s1->name, sdrlen - (int)offsetof(struct sdrtype1, name));
 1373                 if (rc == 0)
 1374                         return (0);
 1375                 rc = add_child_sensors(sc, psdr, 1, s1->sensor_num,
 1376                     s1->sensor_type, s1->event_code, 0, s1->entity_id, name);
 1377                 break;
 1378 
 1379         case IPMI_SDR_TYPECOMPACT:
 1380                 rc = ipmi_sensor_name(name, sizeof(name), s2->typelen,
 1381                     s2->name, sdrlen - (int)offsetof(struct sdrtype2, name));
 1382                 if (rc == 0)
 1383                         return (0);
 1384                 rc = add_child_sensors(sc, psdr, s2->share1 & 0xF,
 1385                     s2->sensor_num, s2->sensor_type, s2->event_code,
 1386                     s2->share2 & 0x7F, s2->entity_id, name);
 1387                 break;
 1388 
 1389         default:
 1390                 return (0);
 1391         }
 1392 
 1393         return rc;
 1394 }
 1395 
 1396 int
 1397 add_child_sensors(struct ipmi_softc *sc, u_int8_t *psdr, int count,
 1398     int sensor_num, int sensor_type, int ext_type, int sensor_base,
 1399     int entity, const char *name)
 1400 {
 1401         int                     typ, idx, rc = 0;
 1402         struct ipmi_sensor      *psensor;
 1403         struct sdrtype1         *s1 = (struct sdrtype1 *)psdr;
 1404 
 1405         typ = ipmi_sensor_type(sensor_type, ext_type, s1->units2, entity);
 1406         if (typ == -1) {
 1407                 dbg_printf(5, "Unknown sensor type:%.2x et:%.2x sn:%.2x "
 1408                     "units2:%u name:%s\n", sensor_type, ext_type, sensor_num,
 1409                     s1->units2, name);
 1410                 return 0;
 1411         }
 1412         for (idx = 0; idx < count; idx++) {
 1413                 psensor = malloc(sizeof(*psensor), M_DEVBUF, M_NOWAIT | M_ZERO);
 1414                 if (psensor == NULL)
 1415                         break;
 1416 
 1417                 /* Initialize BSD Sensor info */
 1418                 psensor->i_sdr = psdr;
 1419                 psensor->i_num = sensor_num + idx;
 1420                 psensor->stype = sensor_type;
 1421                 psensor->etype = ext_type;
 1422                 psensor->i_sensor.type = typ;
 1423                 if (count > 1)
 1424                         snprintf(psensor->i_sensor.desc,
 1425                             sizeof(psensor->i_sensor.desc),
 1426                             "%s - %d", name, sensor_base + idx);
 1427                 else
 1428                         strlcpy(psensor->i_sensor.desc, name,
 1429                             sizeof(psensor->i_sensor.desc));
 1430 
 1431                 dbg_printf(5, "add sensor:%.4x %.2x:%d ent:%.2x:%.2x %s\n",
 1432                     s1->sdrhdr.record_id, s1->sensor_type,
 1433                     typ, s1->entity_id, s1->entity_instance,
 1434                     psensor->i_sensor.desc);
 1435                 if (read_sensor(sc, psensor) == 0) {
 1436                         SLIST_INSERT_HEAD(&ipmi_sensor_list, psensor, list);
 1437                         sensor_attach(&sc->sc_sensordev, &psensor->i_sensor);
 1438                         dbg_printf(5, "  reading: %lld [%s]\n",
 1439                             psensor->i_sensor.value,
 1440                             psensor->i_sensor.desc);
 1441                         rc = 1;
 1442                 } else
 1443                         free(psensor, M_DEVBUF, sizeof(*psensor));
 1444         }
 1445 
 1446         return (rc);
 1447 }
 1448 
 1449 /* Handle IPMI Timer - reread sensor values */
 1450 void
 1451 ipmi_refresh_sensors(struct ipmi_softc *sc)
 1452 {
 1453         if (SLIST_EMPTY(&ipmi_sensor_list))
 1454                 return;
 1455 
 1456         sc->current_sensor = SLIST_NEXT(sc->current_sensor, list);
 1457         if (sc->current_sensor == NULL)
 1458                 sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
 1459 
 1460         if (read_sensor(sc, sc->current_sensor)) {
 1461                 dbg_printf(1, "%s: error reading: %s\n", DEVNAME(sc),
 1462                     sc->current_sensor->i_sensor.desc);
 1463                 return;
 1464         }
 1465 }
 1466 
 1467 int
 1468 ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia)
 1469 {
 1470         if (sc->sc_if && sc->sc_if->nregs == 0)
 1471                 return (0);
 1472 
 1473         sc->sc_if = ipmi_get_if(ia->iaa_if_type);
 1474         if (sc->sc_if == NULL)
 1475                 return (-1);
 1476 
 1477         if (ia->iaa_if_iotype == 'i')
 1478                 sc->sc_iot = ia->iaa_iot;
 1479         else
 1480                 sc->sc_iot = ia->iaa_memt;
 1481 
 1482         sc->sc_if_rev = ia->iaa_if_rev;
 1483         sc->sc_if_iosize = ia->iaa_if_iosize;
 1484         sc->sc_if_iospacing = ia->iaa_if_iospacing;
 1485         if (bus_space_map(sc->sc_iot, ia->iaa_if_iobase,
 1486             sc->sc_if->nregs * sc->sc_if_iospacing,
 1487             0, &sc->sc_ioh)) {
 1488                 printf("%s: bus_space_map(%lx %lx %x 0 %p) failed\n",
 1489                     DEVNAME(sc),
 1490                     (unsigned long)sc->sc_iot, ia->iaa_if_iobase,
 1491                     sc->sc_if->nregs * sc->sc_if_iospacing, &sc->sc_ioh);
 1492                 return (-1);
 1493         }
 1494         return (0);
 1495 }
 1496 
 1497 void
 1498 ipmi_unmap_regs(struct ipmi_softc *sc)
 1499 {
 1500         if (sc->sc_if->nregs > 0) {
 1501                 bus_space_unmap(sc->sc_iot, sc->sc_ioh,
 1502                     sc->sc_if->nregs * sc->sc_if_iospacing);
 1503         }
 1504 }
 1505 
 1506 void
 1507 ipmi_poll_thread(void *arg)
 1508 {
 1509         struct ipmi_thread      *thread = arg;
 1510         struct ipmi_softc       *sc = thread->sc;
 1511         u_int16_t               rec;
 1512 
 1513         /* Scan SDRs, add sensors */
 1514         for (rec = 0; rec != 0xFFFF;) {
 1515                 if (get_sdr(sc, rec, &rec)) {
 1516                         ipmi_unmap_regs(sc);
 1517                         printf("%s: no SDRs IPMI disabled\n", DEVNAME(sc));
 1518                         goto done;
 1519                 }
 1520                 tsleep_nsec(sc, PWAIT, "ipmirun", MSEC_TO_NSEC(1));
 1521         }
 1522 
 1523         /* initialize sensor list for thread */
 1524         if (SLIST_EMPTY(&ipmi_sensor_list))
 1525                 goto done;
 1526         else
 1527                 sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
 1528 
 1529         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
 1530             sizeof(sc->sc_sensordev.xname));
 1531         sensordev_install(&sc->sc_sensordev);
 1532 
 1533         while (thread->running) {
 1534                 ipmi_refresh_sensors(sc);
 1535                 tsleep_nsec(thread, PWAIT, "ipmi_poll",
 1536                     SEC_TO_NSEC(SENSOR_REFRESH_RATE));
 1537         }
 1538 
 1539 done:
 1540         kthread_exit(0);
 1541 }
 1542 
 1543 void
 1544 ipmi_create_thread(void *arg)
 1545 {
 1546         struct ipmi_softc       *sc = arg;
 1547 
 1548         if (kthread_create(ipmi_poll_thread, sc->sc_thread, NULL,
 1549             DEVNAME(sc)) != 0) {
 1550                 printf("%s: unable to create run thread, ipmi disabled\n",
 1551                     DEVNAME(sc));
 1552                 return;
 1553         }
 1554 }
 1555 
 1556 void
 1557 ipmi_attach_common(struct ipmi_softc *sc, struct ipmi_attach_args *ia)
 1558 {
 1559         struct ipmi_cmd         *c = &sc->sc_ioctl.cmd;
 1560 
 1561         /* Map registers */
 1562         ipmi_map_regs(sc, ia);
 1563 
 1564         sc->sc_thread = malloc(sizeof(struct ipmi_thread), M_DEVBUF, M_NOWAIT);
 1565         if (sc->sc_thread == NULL) {
 1566                 printf(": unable to allocate thread\n");
 1567                 return;
 1568         }
 1569         sc->sc_thread->sc = sc;
 1570         sc->sc_thread->running = 1;
 1571 
 1572         /* Setup threads */
 1573         kthread_create_deferred(ipmi_create_thread, sc);
 1574 
 1575         printf(": version %d.%d interface %s",
 1576             ia->iaa_if_rev >> 4, ia->iaa_if_rev & 0xF, sc->sc_if->name);
 1577         if (sc->sc_if->nregs > 0)
 1578                 printf(" %sbase 0x%lx/%x spacing %d",
 1579                     ia->iaa_if_iotype == 'i' ? "io" : "mem", ia->iaa_if_iobase,
 1580                     ia->iaa_if_iospacing * sc->sc_if->nregs,
 1581                     ia->iaa_if_iospacing);
 1582         if (ia->iaa_if_irq != -1)
 1583                 printf(" irq %d", ia->iaa_if_irq);
 1584         printf("\n");
 1585 
 1586         /* setup flag to exclude iic */
 1587         ipmi_enabled = 1;
 1588 
 1589         /* Setup Watchdog timer */
 1590         sc->sc_wdog_period = 0;
 1591         task_set(&sc->sc_wdog_tickle_task, ipmi_watchdog_tickle, sc);
 1592         wdog_register(ipmi_watchdog, sc);
 1593 
 1594         rw_init(&sc->sc_ioctl.lock, DEVNAME(sc));
 1595         sc->sc_ioctl.req.msgid = -1;
 1596         c->c_sc = sc;
 1597         c->c_ccode = -1;
 1598 
 1599         sc->sc_cmd_taskq = taskq_create("ipmicmd", 1, IPL_NONE, TASKQ_MPSAFE);
 1600 }
 1601 
 1602 int
 1603 ipmi_activate(struct device *self, int act)
 1604 {
 1605         switch (act) {
 1606         case DVACT_POWERDOWN:
 1607                 wdog_shutdown(self);
 1608                 break;
 1609         }
 1610 
 1611         return (0);
 1612 }
 1613 
 1614 struct ipmi_softc *
 1615 ipmilookup(dev_t dev)
 1616 {
 1617         return (struct ipmi_softc *)device_lookup(&ipmi_cd, minor(dev));
 1618 }
 1619 
 1620 int
 1621 ipmiopen(dev_t dev, int flags, int mode, struct proc *p)
 1622 {
 1623         struct ipmi_softc       *sc = ipmilookup(dev);
 1624 
 1625         if (sc == NULL)
 1626                 return (ENXIO);
 1627         return (0);
 1628 }
 1629 
 1630 int
 1631 ipmiclose(dev_t dev, int flags, int mode, struct proc *p)
 1632 {
 1633         struct ipmi_softc       *sc = ipmilookup(dev);
 1634 
 1635         if (sc == NULL)
 1636                 return (ENXIO);
 1637         return (0);
 1638 }
 1639 
 1640 int
 1641 ipmiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *proc)
 1642 {
 1643         struct ipmi_softc       *sc = ipmilookup(dev);
 1644         struct ipmi_req         *req = (struct ipmi_req *)data;
 1645         struct ipmi_recv        *recv = (struct ipmi_recv *)data;
 1646         struct ipmi_cmd         *c = &sc->sc_ioctl.cmd;
 1647         int                     iv;
 1648         int                     len;
 1649         u_char                  ccode;
 1650         int                     rc = 0;
 1651 
 1652         if (sc == NULL)
 1653                 return (ENXIO);
 1654 
 1655         rw_enter_write(&sc->sc_ioctl.lock);
 1656 
 1657         c->c_maxrxlen = sizeof(sc->sc_ioctl.buf);
 1658         c->c_data = sc->sc_ioctl.buf;
 1659 
 1660         switch (cmd) {
 1661         case IPMICTL_SEND_COMMAND:
 1662                 if (req->msgid == -1) {
 1663                         rc = EINVAL;
 1664                         goto reset;
 1665                 }
 1666                 if (sc->sc_ioctl.req.msgid != -1) {
 1667                         rc = EBUSY;
 1668                         goto reset;
 1669                 }
 1670                 len = req->msg.data_len;
 1671                 if (len < 0) {
 1672                         rc = EINVAL;
 1673                         goto reset;
 1674                 }
 1675                 if (len > c->c_maxrxlen) {
 1676                         rc = E2BIG;
 1677                         goto reset;
 1678                 }
 1679                 sc->sc_ioctl.req = *req;
 1680                 c->c_ccode = -1;
 1681                 rc = copyin(req->msg.data, c->c_data, len);
 1682                 if (rc != 0)
 1683                         goto reset;
 1684                 KASSERT(c->c_ccode == -1);
 1685 
 1686                 /* Execute a command synchronously. */
 1687                 c->c_netfn = req->msg.netfn;
 1688                 c->c_cmd = req->msg.cmd;
 1689                 c->c_txlen = req->msg.data_len;
 1690                 c->c_rxlen = 0;
 1691                 ipmi_cmd(c);
 1692                 break;
 1693         case IPMICTL_RECEIVE_MSG_TRUNC:
 1694         case IPMICTL_RECEIVE_MSG:
 1695                 if (sc->sc_ioctl.req.msgid == -1) {
 1696                         rc = EINVAL;
 1697                         goto reset;
 1698                 }
 1699                 if (c->c_ccode == -1) {
 1700                         rc = EAGAIN;
 1701                         goto reset;
 1702                 }
 1703                 ccode = c->c_ccode & 0xff;
 1704                 rc = copyout(&ccode, recv->msg.data, 1);
 1705                 if (rc != 0)
 1706                         goto reset;
 1707 
 1708                 /* Return a command result. */
 1709                 recv->recv_type = IPMI_RESPONSE_RECV_TYPE;
 1710                 recv->msgid = sc->sc_ioctl.req.msgid;
 1711                 recv->msg.netfn = sc->sc_ioctl.req.msg.netfn;
 1712                 recv->msg.cmd = sc->sc_ioctl.req.msg.cmd;
 1713                 recv->msg.data_len = c->c_rxlen + 1;
 1714 
 1715                 rc = copyout(c->c_data, recv->msg.data + 1, c->c_rxlen);
 1716                 /* Always reset state after command completion. */
 1717                 goto reset;
 1718         case IPMICTL_SET_MY_ADDRESS_CMD:
 1719                 iv = *(int *)data;
 1720                 if (iv < 0 || iv > RSSA_MASK) {
 1721                         rc = EINVAL;
 1722                         goto reset;
 1723                 }
 1724                 c->c_rssa = iv;
 1725                 break;
 1726         case IPMICTL_GET_MY_ADDRESS_CMD:
 1727                 *(int *)data = c->c_rssa;
 1728                 break;
 1729         case IPMICTL_SET_MY_LUN_CMD:
 1730                 iv = *(int *)data;
 1731                 if (iv < 0 || iv > LUN_MASK) {
 1732                         rc = EINVAL;
 1733                         goto reset;
 1734                 }
 1735                 c->c_rslun = iv;
 1736                 break;
 1737         case IPMICTL_GET_MY_LUN_CMD:
 1738                 *(int *)data = c->c_rslun;
 1739                 break;
 1740         case IPMICTL_SET_GETS_EVENTS_CMD:
 1741                 break;
 1742         case IPMICTL_REGISTER_FOR_CMD:
 1743         case IPMICTL_UNREGISTER_FOR_CMD:
 1744         default:
 1745                 break;
 1746         }
 1747 done:
 1748         rw_exit_write(&sc->sc_ioctl.lock);
 1749         return (rc);
 1750 reset:
 1751         sc->sc_ioctl.req.msgid = -1;
 1752         c->c_ccode = -1;
 1753         goto done;
 1754 }
 1755 
 1756 #define         MIN_PERIOD      10
 1757 
 1758 int
 1759 ipmi_watchdog(void *arg, int period)
 1760 {
 1761         struct ipmi_softc       *sc = arg;
 1762 
 1763         if (sc->sc_wdog_period == period) {
 1764                 if (period != 0) {
 1765                         struct task *t;
 1766                         int res;
 1767 
 1768                         t = &sc->sc_wdog_tickle_task;
 1769                         (void)task_del(systq, t);
 1770                         res = task_add(systq, t);
 1771                         KASSERT(res == 1);
 1772                 }
 1773                 return (period);
 1774         }
 1775 
 1776         if (period < MIN_PERIOD && period > 0)
 1777                 period = MIN_PERIOD;
 1778         sc->sc_wdog_period = period;
 1779         ipmi_watchdog_set(sc);
 1780         printf("%s: watchdog %sabled\n", DEVNAME(sc),
 1781             (period == 0) ? "dis" : "en");
 1782         return (period);
 1783 }
 1784 
 1785 void
 1786 ipmi_watchdog_tickle(void *arg)
 1787 {
 1788         struct ipmi_softc       *sc = arg;
 1789         struct ipmi_cmd         c;
 1790 
 1791         c.c_sc = sc;
 1792         c.c_rssa = BMC_SA;
 1793         c.c_rslun = BMC_LUN;
 1794         c.c_netfn = APP_NETFN;
 1795         c.c_cmd = APP_RESET_WATCHDOG;
 1796         c.c_txlen = 0;
 1797         c.c_maxrxlen = 0;
 1798         c.c_rxlen = 0;
 1799         c.c_data = NULL;
 1800         ipmi_cmd(&c);
 1801 }
 1802 
 1803 void
 1804 ipmi_watchdog_set(void *arg)
 1805 {
 1806         struct ipmi_softc       *sc = arg;
 1807         uint8_t                 wdog[IPMI_GET_WDOG_MAX];
 1808         struct ipmi_cmd         c;
 1809 
 1810         c.c_sc = sc;
 1811         c.c_rssa = BMC_SA;
 1812         c.c_rslun = BMC_LUN;
 1813         c.c_netfn = APP_NETFN;
 1814         c.c_cmd = APP_GET_WATCHDOG_TIMER;
 1815         c.c_txlen = 0;
 1816         c.c_maxrxlen = IPMI_GET_WDOG_MAX;
 1817         c.c_rxlen = 0;
 1818         c.c_data = wdog;
 1819         ipmi_cmd(&c);
 1820 
 1821         /* Period is 10ths/sec */
 1822         uint16_t timo = htole16(sc->sc_wdog_period * 10);
 1823 
 1824         memcpy(&wdog[IPMI_SET_WDOG_TIMOL], &timo, 2);
 1825         wdog[IPMI_SET_WDOG_TIMER] &= ~IPMI_WDOG_DONTSTOP;
 1826         wdog[IPMI_SET_WDOG_TIMER] |= (sc->sc_wdog_period == 0) ?
 1827             0 : IPMI_WDOG_DONTSTOP;
 1828         wdog[IPMI_SET_WDOG_ACTION] &= ~IPMI_WDOG_MASK;
 1829         wdog[IPMI_SET_WDOG_ACTION] |= (sc->sc_wdog_period == 0) ?
 1830             IPMI_WDOG_DISABLED : IPMI_WDOG_REBOOT;
 1831 
 1832         c.c_cmd = APP_SET_WATCHDOG_TIMER;
 1833         c.c_txlen = IPMI_SET_WDOG_MAX;
 1834         c.c_maxrxlen = 0;
 1835         c.c_rxlen = 0;
 1836         c.c_data = wdog;
 1837         ipmi_cmd(&c);
 1838 }
 1839 
 1840 #if defined(__amd64__) || defined(__i386__)
 1841 
 1842 #include <dev/isa/isareg.h>
 1843 #include <dev/isa/isavar.h>
 1844 
 1845 /*
 1846  * Format of SMBIOS IPMI Flags
 1847  *
 1848  * bit0: interrupt trigger mode (1=level, 0=edge)
 1849  * bit1: interrupt polarity (1=active high, 0=active low)
 1850  * bit2: reserved
 1851  * bit3: address LSB (1=odd,0=even)
 1852  * bit4: interrupt (1=specified, 0=not specified)
 1853  * bit5: reserved
 1854  * bit6/7: register spacing (1,4,2,err)
 1855  */
 1856 #define SMIPMI_FLAG_IRQLVL              (1L << 0)
 1857 #define SMIPMI_FLAG_IRQEN               (1L << 3)
 1858 #define SMIPMI_FLAG_ODDOFFSET           (1L << 4)
 1859 #define SMIPMI_FLAG_IFSPACING(x)        (((x)>>6)&0x3)
 1860 #define  IPMI_IOSPACING_BYTE             0
 1861 #define  IPMI_IOSPACING_WORD             2
 1862 #define  IPMI_IOSPACING_DWORD            1
 1863 
 1864 struct dmd_ipmi {
 1865         u_int8_t        dmd_sig[4];             /* Signature 'IPMI' */
 1866         u_int8_t        dmd_i2c_address;        /* Address of BMC */
 1867         u_int8_t        dmd_nvram_address;      /* Address of NVRAM */
 1868         u_int8_t        dmd_if_type;            /* IPMI Interface Type */
 1869         u_int8_t        dmd_if_rev;             /* IPMI Interface Revision */
 1870 } __packed;
 1871 
 1872 void    *scan_sig(long, long, int, int, const void *);
 1873 
 1874 void    ipmi_smbios_probe(struct smbios_ipmi *, struct ipmi_attach_args *);
 1875 int     ipmi_match(struct device *, void *, void *);
 1876 void    ipmi_attach(struct device *, struct device *, void *);
 1877 
 1878 const struct cfattach ipmi_ca = {
 1879         sizeof(struct ipmi_softc), ipmi_match, ipmi_attach,
 1880         NULL, ipmi_activate
 1881 };
 1882 
 1883 int
 1884 ipmi_match(struct device *parent, void *match, void *aux)
 1885 {
 1886         struct ipmi_softc       *sc;
 1887         struct ipmi_attach_args *ia = aux;
 1888         struct cfdata           *cf = match;
 1889         u_int8_t                cmd[32];
 1890         int                     rv = 0;
 1891 
 1892         if (strcmp(ia->iaa_name, cf->cf_driver->cd_name))
 1893                 return (0);
 1894 
 1895         /* XXX local softc is wrong wrong wrong */
 1896         sc = malloc(sizeof(*sc), M_TEMP, M_WAITOK | M_ZERO);
 1897         strlcpy(sc->sc_dev.dv_xname, "ipmi0", sizeof(sc->sc_dev.dv_xname));
 1898 
 1899         /* Map registers */
 1900         if (ipmi_map_regs(sc, ia) == 0) {
 1901                 sc->sc_if->probe(sc);
 1902 
 1903                 /* Identify BMC device early to detect lying bios */
 1904                 struct ipmi_cmd c;
 1905                 c.c_sc = sc;
 1906                 c.c_rssa = BMC_SA;
 1907                 c.c_rslun = BMC_LUN;
 1908                 c.c_netfn = APP_NETFN;
 1909                 c.c_cmd = APP_GET_DEVICE_ID;
 1910                 c.c_txlen = 0;
 1911                 c.c_maxrxlen = sizeof(cmd);
 1912                 c.c_rxlen = 0;
 1913                 c.c_data = cmd;
 1914                 ipmi_cmd(&c);
 1915 
 1916                 dbg_dump(1, "bmc data", c.c_rxlen, cmd);
 1917                 rv = 1; /* GETID worked, we got IPMI */
 1918                 ipmi_unmap_regs(sc);
 1919         }
 1920 
 1921         free(sc, M_TEMP, sizeof(*sc));
 1922 
 1923         return (rv);
 1924 }
 1925 
 1926 void
 1927 ipmi_attach(struct device *parent, struct device *self, void *aux)
 1928 {
 1929         ipmi_attach_common((struct ipmi_softc *)self, aux);
 1930 }
 1931 
 1932 /* Scan memory for signature */
 1933 void *
 1934 scan_sig(long start, long end, int skip, int len, const void *data)
 1935 {
 1936         void *va;
 1937 
 1938         while (start < end) {
 1939                 va = ISA_HOLE_VADDR(start);
 1940                 if (memcmp(va, data, len) == 0)
 1941                         return (va);
 1942 
 1943                 start += skip;
 1944         }
 1945 
 1946         return (NULL);
 1947 }
 1948 
 1949 void
 1950 ipmi_smbios_probe(struct smbios_ipmi *pipmi, struct ipmi_attach_args *ia)
 1951 {
 1952 
 1953         dbg_printf(1, "ipmi_smbios_probe: %02x %02x %02x %02x %08llx %02x "
 1954             "%02x\n",
 1955             pipmi->smipmi_if_type,
 1956             pipmi->smipmi_if_rev,
 1957             pipmi->smipmi_i2c_address,
 1958             pipmi->smipmi_nvram_address,
 1959             pipmi->smipmi_base_address,
 1960             pipmi->smipmi_base_flags,
 1961             pipmi->smipmi_irq);
 1962 
 1963         ia->iaa_if_type = pipmi->smipmi_if_type;
 1964         ia->iaa_if_rev = pipmi->smipmi_if_rev;
 1965         ia->iaa_if_irq = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQEN) ?
 1966             pipmi->smipmi_irq : -1;
 1967         ia->iaa_if_irqlvl = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQLVL) ?
 1968             IST_LEVEL : IST_EDGE;
 1969         ia->iaa_if_iosize = 1;
 1970 
 1971         switch (SMIPMI_FLAG_IFSPACING(pipmi->smipmi_base_flags)) {
 1972         case IPMI_IOSPACING_BYTE:
 1973                 ia->iaa_if_iospacing = 1;
 1974                 break;
 1975 
 1976         case IPMI_IOSPACING_DWORD:
 1977                 ia->iaa_if_iospacing = 4;
 1978                 break;
 1979 
 1980         case IPMI_IOSPACING_WORD:
 1981                 ia->iaa_if_iospacing = 2;
 1982                 break;
 1983 
 1984         default:
 1985                 ia->iaa_if_iospacing = 1;
 1986                 printf("ipmi: unknown register spacing\n");
 1987         }
 1988 
 1989         /* Calculate base address (PCI BAR format) */
 1990         if (pipmi->smipmi_base_address & 0x1) {
 1991                 ia->iaa_if_iotype = 'i';
 1992                 ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0x1;
 1993         } else {
 1994                 ia->iaa_if_iotype = 'm';
 1995                 ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0xF;
 1996         }
 1997         if (pipmi->smipmi_base_flags & SMIPMI_FLAG_ODDOFFSET)
 1998                 ia->iaa_if_iobase++;
 1999 
 2000         if (pipmi->smipmi_base_flags == 0x7f) {
 2001                 /* IBM 325 eServer workaround */
 2002                 ia->iaa_if_iospacing = 1;
 2003                 ia->iaa_if_iobase = pipmi->smipmi_base_address;
 2004                 ia->iaa_if_iotype = 'i';
 2005                 return;
 2006         }
 2007 }
 2008 
 2009 int
 2010 ipmi_probe(void *aux)
 2011 {
 2012         struct ipmi_attach_args *ia = aux;
 2013         struct dmd_ipmi *pipmi;
 2014         struct smbtable tbl;
 2015 
 2016         tbl.cookie = 0;
 2017         if (smbios_find_table(SMBIOS_TYPE_IPMIDEV, &tbl))
 2018                 ipmi_smbios_probe(tbl.tblhdr, ia);
 2019         else {
 2020                 pipmi = (struct dmd_ipmi *)scan_sig(0xC0000L, 0xFFFFFL, 16, 4,
 2021                     "IPMI");
 2022                 /* XXX hack to find Dell PowerEdge 8450 */
 2023                 if (pipmi == NULL) {
 2024                         /* no IPMI found */
 2025                         return (0);
 2026                 }
 2027 
 2028                 /* we have an IPMI signature, fill in attach arg structure */
 2029                 ia->iaa_if_type = pipmi->dmd_if_type;
 2030                 ia->iaa_if_rev = pipmi->dmd_if_rev;
 2031         }
 2032 
 2033         return (1);
 2034 }
 2035 
 2036 #endif

Cache object: 7825461f093126bbd1c48eaf2f210750


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