1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3c18ec02fSPetter Reinholdtsen *
4c18ec02fSPetter Reinholdtsen * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen * modification, are permitted provided that the following conditions
6c18ec02fSPetter Reinholdtsen * are met:
7c18ec02fSPetter Reinholdtsen *
8c18ec02fSPetter Reinholdtsen * Redistribution of source code must retain the above copyright
9c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer.
10c18ec02fSPetter Reinholdtsen *
11c18ec02fSPetter Reinholdtsen * Redistribution in binary form must reproduce the above copyright
12c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer in the
13c18ec02fSPetter Reinholdtsen * documentation and/or other materials provided with the distribution.
14c18ec02fSPetter Reinholdtsen *
15c18ec02fSPetter Reinholdtsen * Neither the name of Sun Microsystems, Inc. or the names of
16c18ec02fSPetter Reinholdtsen * contributors may be used to endorse or promote products derived
17c18ec02fSPetter Reinholdtsen * from this software without specific prior written permission.
18c18ec02fSPetter Reinholdtsen *
19c18ec02fSPetter Reinholdtsen * This software is provided "AS IS," without a warranty of any kind.
20c18ec02fSPetter Reinholdtsen * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21c18ec02fSPetter Reinholdtsen * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22c18ec02fSPetter Reinholdtsen * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23c18ec02fSPetter Reinholdtsen * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24c18ec02fSPetter Reinholdtsen * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25c18ec02fSPetter Reinholdtsen * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
26c18ec02fSPetter Reinholdtsen * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27c18ec02fSPetter Reinholdtsen * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28c18ec02fSPetter Reinholdtsen * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29c18ec02fSPetter Reinholdtsen * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30c18ec02fSPetter Reinholdtsen * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31c18ec02fSPetter Reinholdtsen */
32c18ec02fSPetter Reinholdtsen
33c18ec02fSPetter Reinholdtsen #include <stdio.h>
34c18ec02fSPetter Reinholdtsen #include <fcntl.h>
35c18ec02fSPetter Reinholdtsen #include <unistd.h>
36c18ec02fSPetter Reinholdtsen #include <sys/ioctl.h>
37c18ec02fSPetter Reinholdtsen #include <errno.h>
38c18ec02fSPetter Reinholdtsen #include <stdlib.h>
39c18ec02fSPetter Reinholdtsen #include <string.h>
40c18ec02fSPetter Reinholdtsen #include <sys/types.h>
41c18ec02fSPetter Reinholdtsen #include <sys/stat.h>
42c18ec02fSPetter Reinholdtsen
43c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
44c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
45c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
46c18ec02fSPetter Reinholdtsen
47c18ec02fSPetter Reinholdtsen #include "imbapi.h"
48c18ec02fSPetter Reinholdtsen
49c18ec02fSPetter Reinholdtsen #define IPMI_IMB_TIMEOUT (1000 * 1000)
50c18ec02fSPetter Reinholdtsen #define IPMI_IMB_MAX_RETRY 3
51c18ec02fSPetter Reinholdtsen #define IPMI_IMB_DEV "/dev/imb"
52c18ec02fSPetter Reinholdtsen #define IPMI_IMB_BUF_SIZE 64
53c18ec02fSPetter Reinholdtsen
54c18ec02fSPetter Reinholdtsen extern int verbose;
55c18ec02fSPetter Reinholdtsen
ipmi_imb_open(struct ipmi_intf * intf)56c18ec02fSPetter Reinholdtsen static int ipmi_imb_open(struct ipmi_intf * intf)
57c18ec02fSPetter Reinholdtsen {
58c18ec02fSPetter Reinholdtsen struct stat stbuf;
59c18ec02fSPetter Reinholdtsen
60c18ec02fSPetter Reinholdtsen if (stat(IPMI_IMB_DEV, &stbuf) < 0) {
61c18ec02fSPetter Reinholdtsen printf("Error: no IMB driver found at %s!\n", IPMI_IMB_DEV);
62c18ec02fSPetter Reinholdtsen return -1;
63c18ec02fSPetter Reinholdtsen }
64c18ec02fSPetter Reinholdtsen
65c18ec02fSPetter Reinholdtsen intf->opened = 1;
66c18ec02fSPetter Reinholdtsen intf->manufacturer_id = ipmi_get_oem(intf);
67c18ec02fSPetter Reinholdtsen
68c18ec02fSPetter Reinholdtsen return 0;
69c18ec02fSPetter Reinholdtsen }
70c18ec02fSPetter Reinholdtsen
ipmi_imb_close(struct ipmi_intf * intf)71c18ec02fSPetter Reinholdtsen static void ipmi_imb_close(struct ipmi_intf * intf)
72c18ec02fSPetter Reinholdtsen {
73c18ec02fSPetter Reinholdtsen intf->opened = 0;
74c18ec02fSPetter Reinholdtsen intf->manufacturer_id = IPMI_OEM_UNKNOWN;
75c18ec02fSPetter Reinholdtsen }
76c18ec02fSPetter Reinholdtsen
ipmi_imb_send_cmd(struct ipmi_intf * intf,struct ipmi_rq * req)77c18ec02fSPetter Reinholdtsen static struct ipmi_rs * ipmi_imb_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
78c18ec02fSPetter Reinholdtsen {
79c18ec02fSPetter Reinholdtsen IMBPREQUESTDATA imbreq;
80c18ec02fSPetter Reinholdtsen static struct ipmi_rs rsp;
81c18ec02fSPetter Reinholdtsen int status, i;
82c18ec02fSPetter Reinholdtsen unsigned char ccode;
83c18ec02fSPetter Reinholdtsen
84c18ec02fSPetter Reinholdtsen imbreq.rsSa = IPMI_BMC_SLAVE_ADDR;
85c18ec02fSPetter Reinholdtsen imbreq.rsLun = 0;
86c18ec02fSPetter Reinholdtsen imbreq.busType = 0;
87c18ec02fSPetter Reinholdtsen imbreq.netFn = req->msg.netfn;
88c18ec02fSPetter Reinholdtsen imbreq.cmdType = req->msg.cmd;
89c18ec02fSPetter Reinholdtsen
90c18ec02fSPetter Reinholdtsen imbreq.data = req->msg.data;
91c18ec02fSPetter Reinholdtsen imbreq.dataLength = req->msg.data_len;
92c18ec02fSPetter Reinholdtsen
93c18ec02fSPetter Reinholdtsen if (verbose > 1) {
94c18ec02fSPetter Reinholdtsen printf("IMB rsSa : %x\n", imbreq.rsSa);
95c18ec02fSPetter Reinholdtsen printf("IMB netFn : %x\n", imbreq.netFn);
96c18ec02fSPetter Reinholdtsen printf("IMB cmdType : %x\n", imbreq.cmdType);
97c18ec02fSPetter Reinholdtsen printf("IMB dataLength : %d\n", imbreq.dataLength);
98c18ec02fSPetter Reinholdtsen }
99c18ec02fSPetter Reinholdtsen
100c18ec02fSPetter Reinholdtsen rsp.data_len = IPMI_IMB_BUF_SIZE;
101c18ec02fSPetter Reinholdtsen memset(rsp.data, 0, rsp.data_len);
102c18ec02fSPetter Reinholdtsen
103c18ec02fSPetter Reinholdtsen for (i=0; i<IPMI_IMB_MAX_RETRY; i++) {
104c18ec02fSPetter Reinholdtsen if (verbose > 2)
105c18ec02fSPetter Reinholdtsen printbuf(imbreq.data, imbreq.dataLength, "ipmi_imb request");
106c18ec02fSPetter Reinholdtsen status = SendTimedImbpRequest(&imbreq, IPMI_IMB_TIMEOUT,
107c18ec02fSPetter Reinholdtsen rsp.data, &rsp.data_len, &ccode);
108c18ec02fSPetter Reinholdtsen if (status == 0) {
109c18ec02fSPetter Reinholdtsen if (verbose > 2)
110c18ec02fSPetter Reinholdtsen printbuf(rsp.data, rsp.data_len, "ipmi_imb response");
111c18ec02fSPetter Reinholdtsen break;
112c18ec02fSPetter Reinholdtsen }
113c18ec02fSPetter Reinholdtsen /* error */
114c18ec02fSPetter Reinholdtsen printf("Error sending IMB request, status=%x ccode=%x\n",
115c18ec02fSPetter Reinholdtsen status, ccode);
116c18ec02fSPetter Reinholdtsen }
117c18ec02fSPetter Reinholdtsen
118c18ec02fSPetter Reinholdtsen rsp.ccode = ccode;
119c18ec02fSPetter Reinholdtsen
120c18ec02fSPetter Reinholdtsen return &rsp;
121c18ec02fSPetter Reinholdtsen }
122c18ec02fSPetter Reinholdtsen
123c18ec02fSPetter Reinholdtsen struct ipmi_intf ipmi_imb_intf = {
124*70984dcaSZdenek Styblik .name = "imb",
125*70984dcaSZdenek Styblik .desc = "Intel IMB Interface",
126*70984dcaSZdenek Styblik .open = ipmi_imb_open,
127*70984dcaSZdenek Styblik .close = ipmi_imb_close,
128*70984dcaSZdenek Styblik .sendrecv = ipmi_imb_send_cmd,
129*70984dcaSZdenek Styblik .target_addr = IPMI_BMC_SLAVE_ADDR,
130c18ec02fSPetter Reinholdtsen };
131c18ec02fSPetter Reinholdtsen
132