ipmi.c 43 KB

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