blob: 9e5c3079d2327ab362faa15a40a99e76909630c1 [file] [log] [blame]
Corey Minyard243ac212018-02-20 07:30:22 -06001/* SPDX-License-Identifier: GPL-2.0+ */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * ipmi_smi.h
4 *
5 * MontaVista IPMI system management interface
6 *
7 * Author: MontaVista Software, Inc.
8 * Corey Minyard <minyard@mvista.com>
9 * source@mvista.com
10 *
11 * Copyright 2002 MontaVista Software Inc.
12 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 */
14
15#ifndef __LINUX_IPMI_SMI_H
16#define __LINUX_IPMI_SMI_H
17
18#include <linux/ipmi_msgdefs.h>
19#include <linux/proc_fs.h>
Corey Minyard50c812b2006-03-26 01:37:21 -080020#include <linux/platform_device.h>
Zhao Yakui16f42322010-12-08 10:10:16 +080021#include <linux/ipmi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022
Paul Gortmaker313162d2012-01-30 11:46:54 -050023struct device;
24
Corey Minyard6dc11812018-04-04 08:54:05 -050025/*
26 * This files describes the interface for IPMI system management interface
27 * drivers to bind into the IPMI message handler.
28 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30/* Structure for the low-level drivers. */
31typedef struct ipmi_smi *ipmi_smi_t;
32
33/*
34 * Messages to/from the lower layer. The smi interface will take one
35 * of these to send. After the send has occurred and a response has
36 * been received, it will report this same data structure back up to
37 * the upper layer. If an error occurs, it should fill in the
38 * response with an error code in the completion code location. When
39 * asynchronous data is received, one of these is allocated, the
40 * data_size is set to zero and the response holds the data from the
41 * get message or get event command that the interface initiated.
42 * Note that it is the interfaces responsibility to detect
43 * asynchronous data and messages and request them from the
44 * interface.
45 */
Corey Minyardc70d7492008-04-29 01:01:09 -070046struct ipmi_smi_msg {
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 struct list_head link;
48
49 long msgid;
50 void *user_data;
51
52 int data_size;
53 unsigned char data[IPMI_MAX_MSG_LENGTH];
54
55 int rsp_size;
56 unsigned char rsp[IPMI_MAX_MSG_LENGTH];
57
58 /* Will be called when the system is done with the message
Corey Minyardc70d7492008-04-29 01:01:09 -070059 (presumably to free it). */
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 void (*done)(struct ipmi_smi_msg *msg);
61};
62
Corey Minyardc70d7492008-04-29 01:01:09 -070063struct ipmi_smi_handlers {
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 struct module *owner;
65
Corey Minyard6dc11812018-04-04 08:54:05 -050066 /*
67 * The low-level interface cannot start sending messages to
68 * the upper layer until this function is called. This may
69 * not be NULL, the lower layer must take the interface from
70 * this call.
71 */
Corey Minyard453823b2006-03-31 02:30:39 -080072 int (*start_processing)(void *send_info,
73 ipmi_smi_t new_intf);
74
Zhao Yakui16f42322010-12-08 10:10:16 +080075 /*
76 * Get the detailed private info of the low level interface and store
77 * it into the structure of ipmi_smi_data. For example: the
78 * ACPI device handle will be returned for the pnp_acpi IPMI device.
79 */
80 int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data);
81
Corey Minyard6dc11812018-04-04 08:54:05 -050082 /*
83 * Called to enqueue an SMI message to be sent. This
84 * operation is not allowed to fail. If an error occurs, it
85 * should report back the error in a received message. It may
86 * do this in the current call context, since no write locks
87 * are held when this is run. Message are delivered one at
88 * a time by the message handler, a new message will not be
89 * delivered until the previous message is returned.
90 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 void (*sender)(void *send_info,
Corey Minyard99ab32f2014-11-07 07:57:31 -060092 struct ipmi_smi_msg *msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
Corey Minyard6dc11812018-04-04 08:54:05 -050094 /*
95 * Called by the upper layer to request that we try to get
96 * events from the BMC we are attached to.
97 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 void (*request_events)(void *send_info);
99
Corey Minyard6dc11812018-04-04 08:54:05 -0500100 /*
101 * Called by the upper layer when some user requires that the
102 * interface watch for events, received messages, watchdog
103 * pretimeouts, or not. Used by the SMI to know if it should
104 * watch for these. This may be NULL if the SMI does not
105 * implement it.
106 */
Corey Minyard7aefac22014-04-14 09:46:56 -0500107 void (*set_need_watch)(void *send_info, bool enable);
Corey Minyard89986492014-04-14 09:46:54 -0500108
Hidehiro Kawai82802f92015-07-27 14:55:16 +0900109 /*
110 * Called when flushing all pending messages.
111 */
112 void (*flush_messages)(void *send_info);
113
Corey Minyard6dc11812018-04-04 08:54:05 -0500114 /*
115 * Called when the interface should go into "run to
116 * completion" mode. If this call sets the value to true, the
117 * interface should make sure that all messages are flushed
118 * out and that none are pending, and any new requests are run
119 * to completion immediately.
120 */
Corey Minyard7aefac22014-04-14 09:46:56 -0500121 void (*set_run_to_completion)(void *send_info, bool run_to_completion);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
Corey Minyard6dc11812018-04-04 08:54:05 -0500123 /*
124 * Called to poll for work to do. This is so upper layers can
125 * poll for operations during things like crash dumps.
126 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 void (*poll)(void *send_info);
128
Corey Minyard6dc11812018-04-04 08:54:05 -0500129 /*
130 * Enable/disable firmware maintenance mode. Note that this
131 * is *not* the modes defined, this is simply an on/off
132 * setting. The message handler does the mode handling. Note
133 * that this is called from interrupt context, so it cannot
134 * block.
135 */
Corey Minyard7aefac22014-04-14 09:46:56 -0500136 void (*set_maintenance_mode)(void *send_info, bool enable);
Corey Minyardb9675132006-12-06 20:41:02 -0800137
Corey Minyard6dc11812018-04-04 08:54:05 -0500138 /*
139 * Tell the handler that we are using it/not using it. The
140 * message handler get the modules that this handler belongs
141 * to; this function lets the SMI claim any modules that it
142 * uses. These may be NULL if this is not required.
143 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 int (*inc_usecount)(void *send_info);
145 void (*dec_usecount)(void *send_info);
146};
147
Corey Minyard50c812b2006-03-26 01:37:21 -0800148struct ipmi_device_id {
149 unsigned char device_id;
150 unsigned char device_revision;
151 unsigned char firmware_revision_1;
152 unsigned char firmware_revision_2;
153 unsigned char ipmi_version;
154 unsigned char additional_device_support;
155 unsigned int manufacturer_id;
156 unsigned int product_id;
157 unsigned char aux_firmware_revision[4];
158 unsigned int aux_firmware_revision_set : 1;
159};
160
161#define ipmi_version_major(v) ((v)->ipmi_version & 0xf)
162#define ipmi_version_minor(v) ((v)->ipmi_version >> 4)
163
Corey Minyard6dc11812018-04-04 08:54:05 -0500164/*
165 * Take a pointer to an IPMI response and extract device id information from
Jeremy Kerrc468f912017-08-25 15:47:23 +0800166 * it. @netfn is in the IPMI_NETFN_ format, so may need to be shifted from
167 * a SI response.
168 */
169static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd,
170 const unsigned char *data,
Corey Minyardd8c98612007-10-18 03:07:11 -0700171 unsigned int data_len,
172 struct ipmi_device_id *id)
Corey Minyard50c812b2006-03-26 01:37:21 -0800173{
Jeremy Kerrc468f912017-08-25 15:47:23 +0800174 if (data_len < 7)
Corey Minyardd8c98612007-10-18 03:07:11 -0700175 return -EINVAL;
Jeremy Kerrc468f912017-08-25 15:47:23 +0800176 if (netfn != IPMI_NETFN_APP_RESPONSE || cmd != IPMI_GET_DEVICE_ID_CMD)
Corey Minyardd8c98612007-10-18 03:07:11 -0700177 /* Strange, didn't get the response we expected. */
178 return -EINVAL;
Jeremy Kerrc468f912017-08-25 15:47:23 +0800179 if (data[0] != 0)
Corey Minyardd8c98612007-10-18 03:07:11 -0700180 /* That's odd, it shouldn't be able to fail. */
181 return -EINVAL;
182
Jeremy Kerrc468f912017-08-25 15:47:23 +0800183 data++;
184 data_len--;
185
Corey Minyard50c812b2006-03-26 01:37:21 -0800186 id->device_id = data[0];
187 id->device_revision = data[1];
188 id->firmware_revision_1 = data[2];
189 id->firmware_revision_2 = data[3];
190 id->ipmi_version = data[4];
191 id->additional_device_support = data[5];
Corey Minyard64e862a2007-10-29 14:37:13 -0700192 if (data_len >= 11) {
Corey Minyardd8c98612007-10-18 03:07:11 -0700193 id->manufacturer_id = (data[6] | (data[7] << 8) |
194 (data[8] << 16));
195 id->product_id = data[9] | (data[10] << 8);
196 } else {
197 id->manufacturer_id = 0;
198 id->product_id = 0;
199 }
Corey Minyard50c812b2006-03-26 01:37:21 -0800200 if (data_len >= 15) {
201 memcpy(id->aux_firmware_revision, data+11, 4);
202 id->aux_firmware_revision_set = 1;
203 } else
204 id->aux_firmware_revision_set = 0;
Corey Minyardd8c98612007-10-18 03:07:11 -0700205
206 return 0;
Corey Minyard50c812b2006-03-26 01:37:21 -0800207}
208
Corey Minyard6dc11812018-04-04 08:54:05 -0500209/*
210 * Add a low-level interface to the IPMI driver. Note that if the
211 * interface doesn't know its slave address, it should pass in zero.
212 * The low-level interface should not deliver any messages to the
213 * upper layer until the start_processing() function in the handlers
214 * is called, and the lower layer must get the interface from that
215 * call.
216 */
Corey Minyard81d02b72015-06-13 10:34:25 -0500217int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 void *send_info,
Corey Minyard50c812b2006-03-26 01:37:21 -0800219 struct device *dev,
Corey Minyard453823b2006-03-31 02:30:39 -0800220 unsigned char slave_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221
222/*
223 * Remove a low-level interface from the IPMI driver. This will
224 * return an error if the interface is still in use by a user.
225 */
226int ipmi_unregister_smi(ipmi_smi_t intf);
227
228/*
229 * The lower layer reports received messages through this interface.
Adam Buchbinderb3834be2012-09-19 21:48:02 -0400230 * The data_size should be zero if this is an asynchronous message. If
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 * the lower layer gets an error sending a message, it should format
232 * an error response in the message response.
233 */
234void ipmi_smi_msg_received(ipmi_smi_t intf,
235 struct ipmi_smi_msg *msg);
236
237/* The lower layer received a watchdog pre-timeout on interface. */
238void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf);
239
240struct ipmi_smi_msg *ipmi_alloc_smi_msg(void);
241static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg)
242{
243 msg->done(msg);
244}
245
Corey Minyard55f91cb2017-09-16 15:51:25 -0500246#ifdef CONFIG_IPMI_PROC_INTERFACE
Corey Minyard6dc11812018-04-04 08:54:05 -0500247/*
248 * Allow the lower layer to add things to the proc filesystem
249 * directory for this interface. Note that the entry will
250 * automatically be dstroyed when the interface is destroyed.
251 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
Alexey Dobriyan07412732011-05-26 16:25:55 -0700253 const struct file_operations *proc_ops,
Alexey Dobriyan99b76232009-03-25 22:48:06 +0300254 void *data);
Corey Minyard55f91cb2017-09-16 15:51:25 -0500255#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
257#endif /* __LINUX_IPMI_SMI_H */