int ipmi_openipmi_ctx_io_init (ipmi_openipmi_ctx_t ctx) { unsigned int addr = IPMI_SLAVE_ADDRESS_BMC; char *driver_device; int flags; if (!ctx || ctx->magic != IPMI_OPENIPMI_CTX_MAGIC) { ERR_TRACE (ipmi_openipmi_ctx_errormsg (ctx), ipmi_openipmi_ctx_errnum (ctx)); return (-1); } if (ctx->io_init) goto out; if (ctx->driver_device) driver_device = ctx->driver_device; else driver_device = IPMI_OPENIPMI_DRIVER_DEVICE_DEFAULT; if ((ctx->device_fd = open (driver_device, O_RDWR)) < 0) { OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); goto cleanup; } flags = fcntl(ctx->device_fd, F_GETFD); if (flags < 0) { OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); goto cleanup; } flags |= FD_CLOEXEC; if (fcntl(ctx->device_fd, F_SETFD, flags) < 0) { OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); goto cleanup; } if (ioctl (ctx->device_fd, IPMICTL_SET_MY_ADDRESS_CMD, &addr) < 0) { OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); goto cleanup; } ctx->io_init = 1; out: ctx->errnum = IPMI_OPENIPMI_ERR_SUCCESS; return (0); cleanup: /* ignore potential error, error path */ close (ctx->device_fd); ctx->device_fd = -1; return (-1); }
static int _openipmi_read (ipmi_openipmi_ctx_t ctx, fiid_obj_t obj_cmd_rs) { uint8_t rs_buf_temp[IPMI_OPENIPMI_BUFLEN]; uint8_t rs_buf[IPMI_OPENIPMI_BUFLEN]; struct ipmi_system_interface_addr rs_addr; struct ipmi_recv rs_packet; fd_set read_fds; struct timeval tv; int n; assert (ctx); assert (ctx->magic == IPMI_OPENIPMI_CTX_MAGIC); assert (fiid_obj_valid (obj_cmd_rs)); rs_packet.addr = (unsigned char *)&rs_addr; rs_packet.addr_len = sizeof (struct ipmi_system_interface_addr); rs_packet.msg.data = rs_buf_temp; rs_packet.msg.data_len = IPMI_OPENIPMI_BUFLEN; FD_ZERO (&read_fds); FD_SET (ctx->device_fd, &read_fds); tv.tv_sec = IPMI_OPENIPMI_TIMEOUT; tv.tv_usec = 0; if ((n = select (ctx->device_fd + 1, &read_fds, NULL, NULL, &tv)) < 0) { OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); return (-1); } if (!n) { /* Could be due to a different error, but we assume a timeout */ OPENIPMI_SET_ERRNUM (ctx, IPMI_OPENIPMI_ERR_DRIVER_TIMEOUT); return (-1); } if (ioctl (ctx->device_fd, IPMICTL_RECEIVE_MSG_TRUNC, &rs_packet) < 0) { OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); return (-1); } /* achu: atleast the completion code should be returned */ if (!rs_packet.msg.data_len) { OPENIPMI_SET_ERRNUM (ctx, IPMI_OPENIPMI_ERR_SYSTEM_ERROR); return (-1); } rs_buf[0] = rs_packet.msg.cmd; /* -1 b/c of cmd */ if (rs_packet.msg.data_len >= (IPMI_OPENIPMI_BUFLEN - 1)) rs_packet.msg.data_len = IPMI_OPENIPMI_BUFLEN - 1; memcpy (rs_buf + 1, rs_buf_temp, rs_packet.msg.data_len); if (fiid_obj_set_all (obj_cmd_rs, rs_buf, rs_packet.msg.data_len + 1) < 0) { OPENIPMI_SET_ERRNUM (ctx, IPMI_OPENIPMI_ERR_INTERNAL_ERROR); return (-1); } return (0); }
static int _openipmi_write (ipmi_openipmi_ctx_t ctx, uint8_t channel_number, uint8_t rs_addr, uint8_t lun, uint8_t net_fn, fiid_obj_t obj_cmd_rq, unsigned int is_ipmb) { uint8_t rq_buf_temp[IPMI_OPENIPMI_BUFLEN]; uint8_t rq_buf[IPMI_OPENIPMI_BUFLEN]; uint8_t rq_cmd; unsigned int rq_buf_len; int len; struct ipmi_system_interface_addr system_interface_addr; struct ipmi_ipmb_addr ipmb_addr; struct ipmi_req rq_packet; assert (ctx); assert (ctx->magic == IPMI_OPENIPMI_CTX_MAGIC); assert (IPMI_CHANNEL_NUMBER_VALID (channel_number)); assert (IPMI_BMC_LUN_VALID (lun)); assert (IPMI_NET_FN_RQ_VALID (net_fn)); assert (fiid_obj_valid (obj_cmd_rq)); assert (fiid_obj_packet_valid (obj_cmd_rq) == 1); /* Due to API differences, we need to extract the cmd out of the * request. */ memset (rq_buf_temp, '\0', IPMI_OPENIPMI_BUFLEN); if ((len = fiid_obj_get_all (obj_cmd_rq, rq_buf_temp, IPMI_OPENIPMI_BUFLEN)) <= 0) { OPENIPMI_SET_ERRNUM (ctx, IPMI_OPENIPMI_ERR_INTERNAL_ERROR); return (-1); } rq_cmd = rq_buf_temp[0]; if (len > 1) { /* -1 b/c of cmd */ memcpy (rq_buf, &rq_buf_temp[1], len - 1); rq_buf_len = len - 1; } else rq_buf_len = 0; if (!is_ipmb) { system_interface_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; /* openipmi macro */ system_interface_addr.channel = IPMI_CHANNEL_NUMBER_SYSTEM_INTERFACE; /* freeipmi macro */ system_interface_addr.lun = lun; rq_packet.addr = (unsigned char *)&system_interface_addr; rq_packet.addr_len = sizeof (struct ipmi_system_interface_addr); } else { ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE; /* openipmi macro */ ipmb_addr.channel = channel_number; ipmb_addr.slave_addr = rs_addr; ipmb_addr.lun = lun; rq_packet.addr = (unsigned char *)&ipmb_addr; rq_packet.addr_len = sizeof (struct ipmi_ipmb_addr); } rq_packet.msgid = 0; rq_packet.msg.netfn = net_fn; rq_packet.msg.cmd = rq_cmd; rq_packet.msg.data_len = rq_buf_len; rq_packet.msg.data = rq_buf; if (ioctl (ctx->device_fd, IPMICTL_SEND_COMMAND, &rq_packet) < 0) { OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); return (-1); } return (0); }