ipmi_devintf: Small lock rework
[linux-2.6-block.git] / include / linux / ipmi_smi.h
CommitLineData
243ac210 1/* SPDX-License-Identifier: GPL-2.0+ */
1da177e4
LT
2/*
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 *
1da177e4
LT
13 */
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>
50c812b2 20#include <linux/platform_device.h>
16f4232c 21#include <linux/ipmi.h>
1da177e4 22
313162d0
PG
23struct device;
24
6dc1181f
CM
25/*
26 * This files describes the interface for IPMI system management interface
27 * drivers to bind into the IPMI message handler.
28 */
1da177e4
LT
29
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 */
c70d7499 46struct ipmi_smi_msg {
1da177e4
LT
47 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
c70d7499 59 (presumably to free it). */
1da177e4
LT
60 void (*done)(struct ipmi_smi_msg *msg);
61};
62
c70d7499 63struct ipmi_smi_handlers {
1da177e4
LT
64 struct module *owner;
65
6dc1181f
CM
66 /*
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 */
453823ba
CM
72 int (*start_processing)(void *send_info,
73 ipmi_smi_t new_intf);
74
16f4232c
ZY
75 /*
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
6dc1181f
CM
82 /*
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 */
1da177e4 91 void (*sender)(void *send_info,
99ab32f3 92 struct ipmi_smi_msg *msg);
1da177e4 93
6dc1181f
CM
94 /*
95 * Called by the upper layer to request that we try to get
96 * events from the BMC we are attached to.
97 */
1da177e4
LT
98 void (*request_events)(void *send_info);
99
6dc1181f
CM
100 /*
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 */
7aefac26 107 void (*set_need_watch)(void *send_info, bool enable);
89986496 108
82802f96
HK
109 /*
110 * Called when flushing all pending messages.
111 */
112 void (*flush_messages)(void *send_info);
113
6dc1181f
CM
114 /*
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 */
7aefac26 121 void (*set_run_to_completion)(void *send_info, bool run_to_completion);
1da177e4 122
6dc1181f
CM
123 /*
124 * Called to poll for work to do. This is so upper layers can
125 * poll for operations during things like crash dumps.
126 */
1da177e4
LT
127 void (*poll)(void *send_info);
128
6dc1181f
CM
129 /*
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 */
7aefac26 136 void (*set_maintenance_mode)(void *send_info, bool enable);
b9675136 137
6dc1181f
CM
138 /*
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 */
1da177e4
LT
144 int (*inc_usecount)(void *send_info);
145 void (*dec_usecount)(void *send_info);
146};
147
50c812b2
CM
148struct 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
6dc1181f
CM
164/*
165 * Take a pointer to an IPMI response and extract device id information from
c468f911
JK
166 * 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,
d8c98618
CM
171 unsigned int data_len,
172 struct ipmi_device_id *id)
50c812b2 173{
c468f911 174 if (data_len < 7)
d8c98618 175 return -EINVAL;
c468f911 176 if (netfn != IPMI_NETFN_APP_RESPONSE || cmd != IPMI_GET_DEVICE_ID_CMD)
d8c98618
CM
177 /* Strange, didn't get the response we expected. */
178 return -EINVAL;
c468f911 179 if (data[0] != 0)
d8c98618
CM
180 /* That's odd, it shouldn't be able to fail. */
181 return -EINVAL;
182
c468f911
JK
183 data++;
184 data_len--;
185
50c812b2
CM
186 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];
64e862a5 192 if (data_len >= 11) {
d8c98618
CM
193 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 }
50c812b2
CM
200 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;
d8c98618
CM
205
206 return 0;
50c812b2
CM
207}
208
6dc1181f
CM
209/*
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 */
81d02b7f 217int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
1da177e4 218 void *send_info,
50c812b2 219 struct device *dev,
453823ba 220 unsigned char slave_addr);
1da177e4
LT
221
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.
b3834be5 230 * The data_size should be zero if this is an asynchronous message. If
1da177e4
LT
231 * 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
55f91cb6 246#ifdef CONFIG_IPMI_PROC_INTERFACE
6dc1181f
CM
247/*
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 */
1da177e4 252int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
07412736 253 const struct file_operations *proc_ops,
99b76233 254 void *data);
55f91cb6 255#endif
1da177e4
LT
256
257#endif /* __LINUX_IPMI_SMI_H */