coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ipmi_kcs_ops.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * Place in devicetree.cb:
5  *
6  * chip drivers/ipmi
7  * device pnp ca2.0 on end # IPMI KCS
8  * end
9  */
10 
11 #include <arch/io.h>
12 #include <bootstate.h>
13 #include <console/console.h>
14 #include <device/device.h>
15 #include <device/gpio.h>
16 #include <device/pnp.h>
17 #if CONFIG(HAVE_ACPI_TABLES)
18 #include <acpi/acpi.h>
19 #include <acpi/acpigen.h>
20 #endif
21 #if CONFIG(GENERATE_SMBIOS_TABLES)
22 #include <smbios.h>
23 #endif
24 #include <version.h>
25 #include <delay.h>
26 #include <timer.h>
27 #include "ipmi_kcs.h"
28 #include "ipmi_supermicro_oem.h"
29 #include "chip.h"
30 
31 /* 4 bit encoding */
32 static u8 ipmi_revision_major = 0x1;
33 static u8 ipmi_revision_minor = 0x0;
34 
35 static u8 bmc_revision_major = 0x0;
36 static u8 bmc_revision_minor = 0x0;
37 
39 
40 static int ipmi_get_device_id(struct device *dev, struct ipmi_devid_rsp *rsp)
41 {
42  int ret;
43 
45  IPMI_BMC_GET_DEVICE_ID, NULL, 0, (u8 *)rsp,
46  sizeof(*rsp));
47  if (ret < sizeof(struct ipmi_rsp) || rsp->resp.completion_code) {
48  printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
49  __func__, ret, rsp->resp.completion_code);
50  return 1;
51  }
52  if (ret != sizeof(*rsp)) {
53  printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__);
54  return 1;
55  }
56  return 0;
57 }
58 
59 static int ipmi_get_bmc_self_test_result(struct device *dev, struct ipmi_selftest_rsp *rsp)
60 {
61  int ret;
62 
65  sizeof(*rsp));
66 
67  if (ret < sizeof(struct ipmi_rsp) || rsp->resp.completion_code) {
68  printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
69  __func__, ret, rsp->resp.completion_code);
70  return 1;
71  }
72  if (ret != sizeof(*rsp)) {
73  printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__);
74  return 1;
75  }
76 
77  return 0;
78 }
79 
81 {
82  struct drivers_ipmi_config *conf = arg;
83  const struct gpio_operations *gpio_ops;
84 
85  if (!conf || !conf->post_complete_gpio)
86  return;
87 
89  if (!gpio_ops) {
90  printk(BIOS_WARNING, "IPMI: specified gpio device is missing gpio ops!\n");
91  return;
92  }
93 
94  /* Set POST Complete pin. The `invert` field controls the polarity. */
96 
97  printk(BIOS_DEBUG, "BMC: POST complete gpio set\n");
98 }
99 
100 static void ipmi_kcs_init(struct device *dev)
101 {
102  struct ipmi_devid_rsp rsp;
103  uint32_t man_id = 0, prod_id = 0;
104  struct drivers_ipmi_config *conf = dev->chip_info;
105  const struct gpio_operations *gpio_ops;
106  struct ipmi_selftest_rsp selftestrsp = {0};
107  uint8_t retry_count;
108 
109  if (!conf) {
110  printk(BIOS_WARNING, "IPMI: chip_info is missing! Skip init.\n");
111  return;
112  }
113 
114  if (conf->bmc_jumper_gpio) {
116  if (!gpio_ops) {
117  printk(BIOS_WARNING, "IPMI: gpio device is missing gpio ops!\n");
118  } else {
119  /* Get jumper value and set device state accordingly */
120  dev->enabled = gpio_ops->get(conf->bmc_jumper_gpio);
121  if (!dev->enabled)
122  printk(BIOS_INFO, "IPMI: Disabled by jumper\n");
123  }
124  }
125 
126  if (!dev->enabled)
127  return;
128 
129  printk(BIOS_DEBUG, "IPMI: PNP KCS 0x%x\n", dev->path.pnp.port);
130 
131  /* Set up boot state callback for POST_COMPLETE# */
132  if (conf->post_complete_gpio) {
134  bscb_post_complete.arg = conf;
136  }
137 
138  /* Get IPMI version for ACPI and SMBIOS */
139  if (conf->wait_for_bmc && conf->bmc_boot_timeout) {
140  struct stopwatch sw;
142  printk(BIOS_INFO, "IPMI: Waiting for BMC...\n");
143 
144  while (!stopwatch_expired(&sw)) {
145  if (inb(dev->path.pnp.port) != 0xff)
146  break;
147  mdelay(100);
148  }
149  if (stopwatch_expired(&sw)) {
150  printk(BIOS_INFO, "IPMI: Waiting for BMC timed out\n");
151  /* Don't write tables if communication failed */
152  dev->enabled = 0;
153  return;
154  }
155  }
156 
157  printk(BIOS_INFO, "Get BMC self test result...");
158  for (retry_count = 0; retry_count < conf->bmc_boot_timeout; retry_count++) {
159  if (!ipmi_get_bmc_self_test_result(dev, &selftestrsp))
160  break;
161 
162  mdelay(1000);
163  }
164 
165  switch (selftestrsp.result) {
166  case IPMI_APP_SELFTEST_NO_ERROR: /* 0x55 */
167  printk(BIOS_DEBUG, "No Error\n");
168  break;
169  case IPMI_APP_SELFTEST_NOT_IMPLEMENTED: /* 0x56 */
170  printk(BIOS_DEBUG, "Function Not Implemented\n");
171  break;
172  case IPMI_APP_SELFTEST_ERROR: /* 0x57 */
173  printk(BIOS_ERR, "BMC: Corrupted or inaccessible data or device\n");
174  /* Don't write tables if communication failed */
175  dev->enabled = 0;
176  break;
177  case IPMI_APP_SELFTEST_FATAL_HW_ERROR: /* 0x58 */
178  printk(BIOS_ERR, "BMC: Fatal Hardware Error\n");
179  /* Don't write tables if communication failed */
180  dev->enabled = 0;
181  break;
182  case IPMI_APP_SELFTEST_RESERVED: /* 0xFF */
183  printk(BIOS_DEBUG, "Reserved\n");
184  break;
185 
186  default: /* Other Device Specific Hardware Error */
187  printk(BIOS_ERR, "BMC: Device Specific Error\n");
188  /* Don't write tables if communication failed */
189  dev->enabled = 0;
190  break;
191  }
192 
193  if (!ipmi_get_device_id(dev, &rsp)) {
194  /* Queried the IPMI revision from BMC */
197 
200 
201  memcpy(&man_id, rsp.manufacturer_id,
202  sizeof(rsp.manufacturer_id));
203 
204  memcpy(&prod_id, rsp.product_id, sizeof(rsp.product_id));
205 
206  printk(BIOS_INFO, "IPMI: Found man_id 0x%06x, prod_id 0x%04x\n",
207  man_id, prod_id);
208 
209  printk(BIOS_INFO, "IPMI: Version %01x.%01x\n",
211  } else {
212  /* Don't write tables if communication failed */
213  dev->enabled = 0;
214  }
215 
216  if (!dev->enabled)
217  return;
218 
219  if (CONFIG(DRIVERS_IPMI_SUPERMICRO_OEM))
221 }
222 
223 #if CONFIG(HAVE_ACPI_TABLES)
224 static uint32_t uid_cnt = 0;
225 
226 static unsigned long
227 ipmi_write_acpi_tables(const struct device *dev, unsigned long current,
228  struct acpi_rsdp *rsdp)
229 {
230  struct drivers_ipmi_config *conf = dev->chip_info;
231  struct acpi_spmi *spmi;
232  s8 gpe_interrupt = -1;
233  u32 apic_interrupt = 0;
234  acpi_addr_t addr = {
235  .space_id = ACPI_ADDRESS_SPACE_IO,
236  .access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS,
237  .addrl = dev->path.pnp.port,
238  .bit_width = 8,
239  };
240 
241  switch (CONFIG_IPMI_KCS_REGISTER_SPACING) {
242  case 4:
243  addr.bit_offset = 32;
244  break;
245  case 16:
246  addr.bit_offset = 128;
247  break;
248  default:
249  printk(BIOS_ERR, "IPMI: Unsupported register spacing for SPMI\n");
251  case 1:
252  addr.bit_offset = 8;
253  break;
254  }
255 
256  current = ALIGN_UP(current, 8);
257  printk(BIOS_DEBUG, "ACPI: * SPMI at %lx\n", current);
258  spmi = (struct acpi_spmi *)current;
259 
260  if (conf) {
261  if (conf->have_gpe)
262  gpe_interrupt = conf->gpe_interrupt;
263  if (conf->have_apic)
264  apic_interrupt = conf->apic_interrupt;
265 
266  /* Use command to get UID from ipmi_ssdt */
267  acpi_create_ipmi(dev, spmi, (ipmi_revision_major << 8) |
268  (ipmi_revision_minor << 4), &addr,
269  IPMI_INTERFACE_KCS, gpe_interrupt, apic_interrupt,
270  conf->uid);
271 
272  acpi_add_table(rsdp, spmi);
273 
274  current += spmi->header.length;
275  } else {
276  printk(BIOS_WARNING, "IPMI: chip_info is missing!\n");
277  }
278 
279  return current;
280 }
281 
282 static void ipmi_ssdt(const struct device *dev)
283 {
284  const char *scope = acpi_device_scope(dev);
285  struct drivers_ipmi_config *conf = dev->chip_info;
286 
287  if (!scope) {
288  printk(BIOS_ERR, "IPMI: Missing ACPI scope for %s\n",
289  dev_path(dev));
290  return;
291  }
292 
293  if (!conf) {
294  printk(BIOS_WARNING, "IPMI: chip_info is missing!\n");
295  return;
296  }
297 
298  /* Use command to pass UID to ipmi_write_acpi_tables */
299  conf->uid = uid_cnt++;
300 
301  /* write SPMI device */
302  acpigen_write_scope(scope);
303  acpigen_write_device("SPMI");
304  acpigen_write_name_string("_HID", "IPI0001");
305  acpigen_write_name_unicode("_STR", "IPMI_KCS");
306  acpigen_write_name_byte("_UID", conf->uid);
307  acpigen_write_STA(0xf);
308  acpigen_write_name("_CRS");
310  acpigen_write_io16(dev->path.pnp.port, dev->path.pnp.port, 1, 1, 1);
311  acpigen_write_io16(dev->path.pnp.port + CONFIG_IPMI_KCS_REGISTER_SPACING,
312  dev->path.pnp.port + CONFIG_IPMI_KCS_REGISTER_SPACING, 1, 1, 1);
313 
314  // FIXME: is that correct?
315  if (conf->have_apic)
316  acpigen_write_irq(1 << conf->apic_interrupt);
317 
319 
320  acpigen_write_method("_IFT", 0);
321  acpigen_write_return_byte(1); // KCS
322  acpigen_pop_len();
323 
324  acpigen_write_method("_SRV", 0);
326  (ipmi_revision_minor << 4));
327  acpigen_pop_len();
328 
329  acpigen_pop_len(); /* pop device */
330  acpigen_pop_len(); /* pop scope */
331 }
332 #endif
333 
334 void ipmi_bmc_version(uint8_t *ipmi_bmc_major_revision, uint8_t *ipmi_bmc_minor_revision)
335 {
337  printk(BIOS_ERR, "IPMI: BMC revision missing\n");
338  *ipmi_bmc_major_revision = 0;
339  *ipmi_bmc_minor_revision = 0;
340  } else {
341  *ipmi_bmc_major_revision = bmc_revision_major;
342  *ipmi_bmc_minor_revision = bmc_revision_minor;
343  }
344 }
345 
346 #if CONFIG(GENERATE_SMBIOS_TABLES)
347 static int ipmi_smbios_data(struct device *dev, int *handle,
348  unsigned long *current)
349 {
350  struct drivers_ipmi_config *conf = dev->chip_info;
351  u8 nv_storage = 0xff;
352  u8 i2c_address = 0;
353  u8 register_spacing;
354 
355  int len = 0;
356 
357  if (conf) {
358  if (conf->have_nv_storage)
359  nv_storage = conf->nv_storage_device_address;
360  i2c_address = conf->bmc_i2c_address;
361  }
362 
363  switch (CONFIG_IPMI_KCS_REGISTER_SPACING) {
364  case 4:
365  register_spacing = 1 << 6;
366  break;
367  case 16:
368  register_spacing = 2 << 6;
369  break;
370  default:
371  printk(BIOS_ERR, "IPMI: Unsupported register spacing for SMBIOS\n");
373  case 1:
374  register_spacing = 0 << 6;
375  break;
376  }
377 
378  // add IPMI Device Information
379  len += smbios_write_type38(
380  current, handle,
383  i2c_address, // I2C address
384  nv_storage, // NV storage
385  dev->path.pnp.port | 1, // IO interface
386  register_spacing,
387  0); // no IRQ
388 
389  len += get_smbios_data(dev, handle, current);
390 
391  return len;
392 }
393 #endif
394 
395 static void ipmi_set_resources(struct device *dev)
396 {
397  struct resource *res;
398 
399  for (res = dev->resource_list; res; res = res->next) {
400  if (!(res->flags & IORESOURCE_ASSIGNED))
401  continue;
402 
403  res->flags |= IORESOURCE_STORED;
404  report_resource_stored(dev, res, "");
405  }
406 }
407 
408 static void ipmi_read_resources(struct device *dev)
409 {
410  struct resource *res = new_resource(dev, 0);
411  res->base = dev->path.pnp.port;
412  res->size = 2;
414 }
415 
416 static struct device_operations ops = {
418  .set_resources = ipmi_set_resources,
419  .init = ipmi_kcs_init,
420 #if CONFIG(HAVE_ACPI_TABLES)
421  .write_acpi_tables = ipmi_write_acpi_tables,
422  .acpi_fill_ssdt = ipmi_ssdt,
423 #endif
424 #if CONFIG(GENERATE_SMBIOS_TABLES)
425  .get_smbios_data = ipmi_smbios_data,
426 #endif
427 };
428 
429 static void enable_dev(struct device *dev)
430 {
431  if (dev->path.type != DEVICE_PATH_PNP)
432  printk(BIOS_ERR, "%s: Unsupported device type\n",
433  dev_path(dev));
434  else if (dev->path.pnp.port & 1)
435  printk(BIOS_ERR, "%s: Base address needs to be aligned to 2\n",
436  dev_path(dev));
437  else
438  dev->ops = &ops;
439 }
440 
442  CHIP_NAME("IPMI KCS")
443  .enable_dev = enable_dev,
444 };
void acpi_create_ipmi(const struct device *device, struct acpi_spmi *spmi, const u16 ipmi_revision, const acpi_addr_t *addr, const enum acpi_ipmi_interface_type type, const s8 gpe_interrupt, const u32 apic_interrupt, const u32 uid)
Definition: acpi.c:1032
void acpi_add_table(acpi_rsdp_t *rsdp, void *table)
Add an ACPI table to the RSDT (and XSDT) structure, recalculate length and checksum.
Definition: acpi.c:49
const char * acpi_device_scope(const struct device *dev)
Definition: device.c:158
void acpigen_write_return_integer(uint64_t arg)
Definition: acpigen.c:1583
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_name_byte(const char *name, uint8_t val)
Definition: acpigen.c:152
void acpigen_write_scope(const char *name)
Definition: acpigen.c:326
void acpigen_write_return_byte(uint8_t arg)
Definition: acpigen.c:1577
void acpigen_write_resourcetemplate_footer(void)
Definition: acpigen.c:1165
void acpigen_write_irq(u16 mask)
Definition: acpigen.c:1109
void acpigen_write_STA(uint8_t status)
Definition: acpigen.c:783
void acpigen_write_name_unicode(const char *name, const char *string)
Definition: acpigen.c:182
void acpigen_write_resourcetemplate_header(void)
Definition: acpigen.c:1147
void acpigen_write_device(const char *name)
Definition: acpigen.c:769
void acpigen_write_io16(u16 min, u16 max, u8 align, u8 len, u8 decode16)
Definition: acpigen.c:1123
void acpigen_write_method(const char *name, int nargs)
Definition: acpigen.c:758
void acpigen_write_name(const char *name)
Definition: acpigen.c:320
void acpigen_write_name_string(const char *name, const char *string)
Definition: acpigen.c:176
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
int get_smbios_data(struct device *dev, int *handle, unsigned long *current)
Definition: smbios.c:1261
int smbios_write_type38(unsigned long *current, int *handle, const enum smbios_bmc_interface_type interface_type, const u8 ipmi_rev, const u8 i2c_addr, const u8 nv_addr, const u64 base_addr, const u8 base_modifier, const u8 irq)
Definition: smbios.c:1064
@ BS_PAYLOAD_BOOT
Definition: bootstate.h:89
int boot_state_sched_on_entry(struct boot_state_callback *bscb, boot_state_t state)
Definition: hardwaremain.c:395
#define ALIGN_UP(x, a)
Definition: helpers.h:17
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
#define __fallthrough
Definition: compiler.h:39
void mdelay(unsigned int msecs)
Definition: delay.c:2
const struct gpio_operations * dev_get_gpio_ops(struct device *dev)
Definition: gpio.c:7
u8 inb(u16 port)
struct resource * new_resource(struct device *dev, unsigned int index)
See if a resource structure already exists for a given index and if not allocate one.
Definition: device_util.c:346
void report_resource_stored(struct device *dev, const struct resource *resource, const char *comment)
Print the resource that was just stored.
Definition: device_util.c:508
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
@ CONFIG
Definition: dsi_common.h:201
static struct gpio_operations gpio_ops
Definition: gpio_dev.c:9
@ IPMI_INTERFACE_KCS
Definition: acpi.h:1062
#define ACPI_ACCESS_SIZE_BYTE_ACCESS
Definition: acpi.h:127
#define ACPI_ADDRESS_SPACE_IO
Definition: acpi.h:105
#define CHIP_NAME(X)
Definition: device.h:32
@ SMBIOS_BMC_INTERFACE_KCS
Definition: smbios.h:933
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
int ipmi_kcs_message(int port, int netfn, int lun, int cmd, const unsigned char *inmsg, int inlen, unsigned char *outmsg, int outlen)
Definition: ipmi_kcs.c:222
#define IPMI_IPMI_VERSION_MAJOR(x)
Definition: ipmi_kcs.h:12
#define IPMI_APP_SELFTEST_NOT_IMPLEMENTED
Definition: ipmi_kcs.h:16
#define IPMI_BMC_GET_DEVICE_ID
Definition: ipmi_kcs.h:10
#define IPMI_APP_SELFTEST_RESERVED
Definition: ipmi_kcs.h:14
#define IPMI_NETFN_APPLICATION
Definition: ipmi_kcs.h:9
#define IPMI_BMC_GET_SELFTEST_RESULTS
Definition: ipmi_kcs.h:13
#define IPMI_IPMI_VERSION_MINOR(x)
Definition: ipmi_kcs.h:11
#define IPMI_APP_SELFTEST_ERROR
Definition: ipmi_kcs.h:17
#define IPMI_APP_SELFTEST_FATAL_HW_ERROR
Definition: ipmi_kcs.h:18
#define IPMI_APP_SELFTEST_NO_ERROR
Definition: ipmi_kcs.h:15
static void bmc_set_post_complete_gpio_callback(void *arg)
Definition: ipmi_kcs_ops.c:80
static u8 ipmi_revision_major
Definition: ipmi_kcs_ops.c:32
static int ipmi_get_device_id(struct device *dev, struct ipmi_devid_rsp *rsp)
Definition: ipmi_kcs_ops.c:40
static int ipmi_get_bmc_self_test_result(struct device *dev, struct ipmi_selftest_rsp *rsp)
Definition: ipmi_kcs_ops.c:59
static u8 bmc_revision_major
Definition: ipmi_kcs_ops.c:35
static void enable_dev(struct device *dev)
Definition: ipmi_kcs_ops.c:429
static void ipmi_read_resources(struct device *dev)
Definition: ipmi_kcs_ops.c:408
static struct device_operations ops
Definition: ipmi_kcs_ops.c:416
void ipmi_bmc_version(uint8_t *ipmi_bmc_major_revision, uint8_t *ipmi_bmc_minor_revision)
Definition: ipmi_kcs_ops.c:334
static u8 ipmi_revision_minor
Definition: ipmi_kcs_ops.c:33
static void ipmi_set_resources(struct device *dev)
Definition: ipmi_kcs_ops.c:395
static void ipmi_kcs_init(struct device *dev)
Definition: ipmi_kcs_ops.c:100
static struct boot_state_callback bscb_post_complete
Definition: ipmi_kcs_ops.c:38
struct chip_operations drivers_ipmi_ops
Definition: ipmi_kcs_ops.c:441
static u8 bmc_revision_minor
Definition: ipmi_kcs_ops.c:36
void supermicro_ipmi_oem(const uint16_t kcs_port)
struct bootblock_arg arg
Definition: decompressor.c:22
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
@ DEVICE_PATH_PNP
Definition: path.h:10
#define IORESOURCE_STORED
Definition: resource.h:32
#define IORESOURCE_ASSIGNED
Definition: resource.h:34
#define IORESOURCE_IO
Definition: resource.h:9
#define IORESOURCE_FIXED
Definition: resource.h:36
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
int8_t s8
Definition: stdint.h:44
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
Definition: acpi.h:82
acpi_header_t header
Definition: acpi.h:1074
void(* callback)(void *arg)
Definition: bootstate.h:101
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct pnp_path pnp
Definition: path.h:117
enum device_path_type type
Definition: path.h:114
Definition: device.h:107
struct device_path path
Definition: device.h:115
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct resource * resource_list
Definition: device.h:134
DEVTREE_CONST void * chip_info
Definition: device.h:164
unsigned int enabled
Definition: device.h:122
u8 bmc_i2c_address
Definition: chip.h:11
unsigned int uid
Definition: chip.h:39
bool wait_for_bmc
Definition: chip.h:33
u32 post_complete_gpio
Definition: chip.h:26
bool post_complete_invert
Definition: chip.h:27
DEVTREE_CONST struct device * gpio_dev
Definition: chip.h:19
u8 nv_storage_device_address
Definition: chip.h:13
u16 bmc_boot_timeout
Definition: chip.h:38
u8 have_nv_storage
Definition: chip.h:12
u32 apic_interrupt
Definition: chip.h:17
u32 bmc_jumper_gpio
Definition: chip.h:24
int(* get)(uint32_t gpio)
Definition: gpio.h:9
void(* output)(uint32_t gpio, int value)
Definition: gpio.h:14
uint8_t fw_rev2
Definition: ipmi_kcs.h:50
uint8_t fw_rev1
Definition: ipmi_kcs.h:49
struct ipmi_rsp resp
Definition: ipmi_kcs.h:46
uint8_t ipmi_version
Definition: ipmi_kcs.h:51
uint8_t product_id[2]
Definition: ipmi_kcs.h:54
uint8_t manufacturer_id[3]
Definition: ipmi_kcs.h:53
uint8_t completion_code
Definition: ipmi_kcs.h:41
struct ipmi_rsp resp
Definition: ipmi_kcs.h:59
uint8_t result
Definition: ipmi_kcs.h:60
unsigned int port
Definition: path.h:58
unsigned long flags
Definition: resource.h:49
resource_t base
Definition: resource.h:45
resource_t size
Definition: resource.h:46
DEVTREE_CONST struct resource * next
Definition: resource.h:48
struct mono_time current
Definition: timer.h:113