root/dev/ipmi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ipmi_get_if
  2. bmc_read
  3. bmc_write
  4. _bmc_io_wait
  5. bmc_io_wait
  6. bmc_io_wait_cold
  7. bt_read
  8. bt_write
  9. bt_sendmsg
  10. bt_recvmsg
  11. bt_reset
  12. bt_probe
  13. smic_wait
  14. smic_write_cmd_data
  15. smic_read_data
  16. smic_sendmsg
  17. smic_recvmsg
  18. smic_reset
  19. smic_probe
  20. kcs_wait
  21. kcs_write_cmd
  22. kcs_write_data
  23. kcs_read_data
  24. kcs_sendmsg
  25. kcs_recvmsg
  26. kcs_reset
  27. kcs_probe
  28. scan_sig
  29. dumpb
  30. ipmi_smbios_probe
  31. bt_buildmsg
  32. cmn_buildmsg
  33. ipmi_sendcmd
  34. ipmi_recvcmd
  35. ipmi_delay
  36. get_sdr_partial
  37. get_sdr
  38. getbits
  39. ipmi_sensor_name
  40. ipow
  41. signextend
  42. ipmi_convert
  43. ipmi_test_threshold
  44. ipmi_sensor_status
  45. read_sensor
  46. ipmi_sensor_type
  47. add_sdr_sensor
  48. add_child_sensors
  49. ipmi_intr
  50. ipmi_refresh_sensors
  51. ipmi_map_regs
  52. ipmi_unmap_regs
  53. ipmi_poll_thread
  54. ipmi_create_thread
  55. ipmi_probe
  56. ipmi_match
  57. ipmi_attach
  58. ipmi_watchdog

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

/* [<][>][^][v][top][bottom][index][help] */