Dr Andrew Scott G7VAV

My photo
 
June 2025
Mo Tu We Th Fr Sa Su
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 1 2 3 4 5 6


ipmi.h
001: /*
002:  * ipmi.h
003:  *
004:  * MontaVista IPMI interface
005:  *
006:  * Author: MontaVista Software, Inc.
007:  *         Corey Minyard <minyard@mvista.com>
008:  *         source@mvista.com
009:  *
010:  * Copyright 2002 MontaVista Software Inc.
011:  *
012:  *  This program is free software; you can redistribute it and/or modify it
013:  *  under the terms of the GNU General Public License as published by the
014:  *  Free Software Foundation; either version 2 of the License, or (at your
015:  *  option) any later version.
016:  *
017:  *
018:  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
019:  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020:  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
021:  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
022:  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
023:  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
024:  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
025:  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
026:  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
027:  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:  *
029:  *  You should have received a copy of the GNU General Public License along
030:  *  with this program; if not, write to the Free Software Foundation, Inc.,
031:  *  675 Mass Ave, Cambridge, MA 02139, USA.
032:  */
033: 
034: #ifndef __LINUX_IPMI_H
035: #define __LINUX_IPMI_H
036: 
037: #include <linux/ipmi_msgdefs.h>
038: 
039: 
040: /*
041:  * This file describes an interface to an IPMI driver.  You have to
042:  * have a fairly good understanding of IPMI to use this, so go read
043:  * the specs first before actually trying to do anything.
044:  *
045:  * With that said, this driver provides a multi-user interface to the
046:  * IPMI driver, and it allows multiple IPMI physical interfaces below
047:  * the driver.  The physical interfaces bind as a lower layer on the
048:  * driver.  They appear as interfaces to the application using this
049:  * interface.
050:  *
051:  * Multi-user means that multiple applications may use the driver,
052:  * send commands, receive responses, etc.  The driver keeps track of
053:  * commands the user sends and tracks the responses.  The responses
054:  * will go back to the application that send the command.  If the
055:  * response doesn't come back in time, the driver will return a
056:  * timeout error response to the application.  Asynchronous events
057:  * from the BMC event queue will go to all users bound to the driver.
058:  * The incoming event queue in the BMC will automatically be flushed
059:  * if it becomes full and it is queried once a second to see if
060:  * anything is in it.  Incoming commands to the driver will get
061:  * delivered as commands.
062:  *
063:  * This driver provides two main interfaces: one for in-kernel
064:  * applications and another for userland applications.  The
065:  * capabilities are basically the same for both interface, although
066:  * the interfaces are somewhat different.  The stuff in the
067:  * #ifdef __KERNEL__ below is the in-kernel interface.  The userland
068:  * interface is defined later in the file.  */
069: 
070: 
071: 
072: /*
073:  * This is an overlay for all the address types, so it's easy to
074:  * determine the actual address type.  This is kind of like addresses
075:  * work for sockets.
076:  */
077: #define IPMI_MAX_ADDR_SIZE 32
078: struct ipmi_addr {
079:          /* Try to take these from the "Channel Medium Type" table
080:             in section 6.5 of the IPMI 1.5 manual. */
081:         int   addr_type;
082:         short channel;
083:         char  data[IPMI_MAX_ADDR_SIZE];
084: };
085: 
086: /*
087:  * When the address is not used, the type will be set to this value.
088:  * The channel is the BMC's channel number for the channel (usually
089:  * 0), or IPMC_BMC_CHANNEL if communicating directly with the BMC.
090:  */
091: #define IPMI_SYSTEM_INTERFACE_ADDR_TYPE 0x0c
092: struct ipmi_system_interface_addr {
093:         int           addr_type;
094:         short         channel;
095:         unsigned char lun;
096: };
097: 
098: /* An IPMB Address. */
099: #define IPMI_IPMB_ADDR_TYPE             0x01
100: /* Used for broadcast get device id as described in section 17.9 of the
101:    IPMI 1.5 manual. */
102: #define IPMI_IPMB_BROADCAST_ADDR_TYPE   0x41
103: struct ipmi_ipmb_addr {
104:         int           addr_type;
105:         short         channel;
106:         unsigned char slave_addr;
107:         unsigned char lun;
108: };
109: 
110: /*
111:  * A LAN Address.  This is an address to/from a LAN interface bridged
112:  * by the BMC, not an address actually out on the LAN.
113:  *
114:  * A conscious decision was made here to deviate slightly from the IPMI
115:  * spec.  We do not use rqSWID and rsSWID like it shows in the
116:  * message.  Instead, we use remote_SWID and local_SWID.  This means
117:  * that any message (a request or response) from another device will
118:  * always have exactly the same address.  If you didn't do this,
119:  * requests and responses from the same device would have different
120:  * addresses, and that's not too cool.
121:  *
122:  * In this address, the remote_SWID is always the SWID the remote
123:  * message came from, or the SWID we are sending the message to.
124:  * local_SWID is always our SWID.  Note that having our SWID in the
125:  * message is a little weird, but this is required.
126:  */
127: #define IPMI_LAN_ADDR_TYPE              0x04
128: struct ipmi_lan_addr {
129:         int           addr_type;
130:         short         channel;
131:         unsigned char privilege;
132:         unsigned char session_handle;
133:         unsigned char remote_SWID;
134:         unsigned char local_SWID;
135:         unsigned char lun;
136: };
137: 
138: 
139: /*
140:  * Channel for talking directly with the BMC.  When using this
141:  * channel, This is for the system interface address type only.  FIXME
142:  * - is this right, or should we use -1?
143:  */
144: #define IPMI_BMC_CHANNEL  0xf
145: #define IPMI_NUM_CHANNELS 0x10
146: 
147: /*
148:  * Used to signify an "all channel" bitmask.  This is more than the
149:  * actual number of channels because this is used in userland and
150:  * will cover us if the number of channels is extended.
151:  */
152: #define IPMI_CHAN_ALL     (~0)
153: 
154: 
155: /*
156:  * A raw IPMI message without any addressing.  This covers both
157:  * commands and responses.  The completion code is always the first
158:  * byte of data in the response (as the spec shows the messages laid
159:  * out).
160:  */
161: struct ipmi_msg {
162:         unsigned char  netfn;
163:         unsigned char  cmd;
164:         unsigned short data_len;
165:         unsigned char  *data;
166: };
167: 
168: struct kernel_ipmi_msg {
169:         unsigned char  netfn;
170:         unsigned char  cmd;
171:         unsigned short data_len;
172:         unsigned char  *data;
173: };
174: 
175: /*
176:  * Various defines that are useful for IPMI applications.
177:  */
178: #define IPMI_INVALID_CMD_COMPLETION_CODE        0xC1
179: #define IPMI_TIMEOUT_COMPLETION_CODE            0xC3
180: #define IPMI_UNKNOWN_ERR_COMPLETION_CODE        0xff
181: 
182: 
183: /*
184:  * Receive types for messages coming from the receive interface.  This
185:  * is used for the receive in-kernel interface and in the receive
186:  * IOCTL.
187:  *
188:  * The "IPMI_RESPONSE_RESPNOSE_TYPE" is a little strange sounding, but
189:  * it allows you to get the message results when you send a response
190:  * message.
191:  */
192: #define IPMI_RESPONSE_RECV_TYPE         1 /* A response to a command */
193: #define IPMI_ASYNC_EVENT_RECV_TYPE      2 /* Something from the event queue */
194: #define IPMI_CMD_RECV_TYPE              3 /* A command from somewhere else */
195: #define IPMI_RESPONSE_RESPONSE_TYPE     4 /* The response for
196:                                               a sent response, giving any
197:                                               error status for sending the
198:                                               response.  When you send a
199:                                               response message, this will
200:                                               be returned. */
201: #define IPMI_OEM_RECV_TYPE              5 /* The response for OEM Channels */
202: 
203: /* Note that async events and received commands do not have a completion
204:    code as the first byte of the incoming data, unlike a response. */
205: 
206: 
207: /*
208:  * Modes for ipmi_set_maint_mode() and the userland IOCTL.  The AUTO
209:  * setting is the default and means it will be set on certain
210:  * commands.  Hard setting it on and off will override automatic
211:  * operation.
212:  */
213: #define IPMI_MAINTENANCE_MODE_AUTO      0
214: #define IPMI_MAINTENANCE_MODE_OFF       1
215: #define IPMI_MAINTENANCE_MODE_ON        2
216: 
217: 
218: 
219: /*
220:  * The userland interface
221:  */
222: 
223: /*
224:  * The userland interface for the IPMI driver is a standard character
225:  * device, with each instance of an interface registered as a minor
226:  * number under the major character device.
227:  *
228:  * The read and write calls do not work, to get messages in and out
229:  * requires ioctl calls because of the complexity of the data.  select
230:  * and poll do work, so you can wait for input using the file
231:  * descriptor, you just can use read to get it.
232:  *
233:  * In general, you send a command down to the interface and receive
234:  * responses back.  You can use the msgid value to correlate commands
235:  * and responses, the driver will take care of figuring out which
236:  * incoming messages are for which command and find the proper msgid
237:  * value to report.  You will only receive reponses for commands you
238:  * send.  Asynchronous events, however, go to all open users, so you
239:  * must be ready to handle these (or ignore them if you don't care).
240:  *
241:  * The address type depends upon the channel type.  When talking
242:  * directly to the BMC (IPMC_BMC_CHANNEL), the address is ignored
243:  * (IPMI_UNUSED_ADDR_TYPE).  When talking to an IPMB channel, you must
244:  * supply a valid IPMB address with the addr_type set properly.
245:  *
246:  * When talking to normal channels, the driver takes care of the
247:  * details of formatting and sending messages on that channel.  You do
248:  * not, for instance, have to format a send command, you just send
249:  * whatever command you want to the channel, the driver will create
250:  * the send command, automatically issue receive command and get even
251:  * commands, and pass those up to the proper user.
252:  */
253: 
254: 
255: /* The magic IOCTL value for this interface. */
256: #define IPMI_IOC_MAGIC 'i'
257: 
258: 
259: /* Messages sent to the interface are this format. */
260: struct ipmi_req {
261:         unsigned char *addr; /* Address to send the message to. */
262:         unsigned int  addr_len;
263: 
264:         long    msgid; /* The sequence number for the message.  This
265:                           exact value will be reported back in the
266:                           response to this request if it is a command.
267:                           If it is a response, this will be used as
268:                           the sequence value for the response.  */
269: 
270:         struct ipmi_msg msg;
271: };
272: /*
273:  * Send a message to the interfaces.  error values are:
274:  *   - EFAULT - an address supplied was invalid.
275:  *   - EINVAL - The address supplied was not valid, or the command
276:  *              was not allowed.
277:  *   - EMSGSIZE - The message to was too large.
278:  *   - ENOMEM - Buffers could not be allocated for the command.
279:  */
280: #define IPMICTL_SEND_COMMAND            _IOR(IPMI_IOC_MAGIC, 13,        \
281:                                              struct ipmi_req)
282: 
283: /* Messages sent to the interface with timing parameters are this
284:    format. */
285: struct ipmi_req_settime {
286:         struct ipmi_req req;
287: 
288:         /* See ipmi_request_settime() above for details on these
289:            values. */
290:         int          retries;
291:         unsigned int retry_time_ms;
292: };
293: /*
294:  * Send a message to the interfaces with timing parameters.  error values
295:  * are:
296:  *   - EFAULT - an address supplied was invalid.
297:  *   - EINVAL - The address supplied was not valid, or the command
298:  *              was not allowed.
299:  *   - EMSGSIZE - The message to was too large.
300:  *   - ENOMEM - Buffers could not be allocated for the command.
301:  */
302: #define IPMICTL_SEND_COMMAND_SETTIME    _IOR(IPMI_IOC_MAGIC, 21,        \
303:                                              struct ipmi_req_settime)
304: 
305: /* Messages received from the interface are this format. */
306: struct ipmi_recv {
307:         int     recv_type; /* Is this a command, response or an
308:                               asyncronous event. */
309: 
310:         unsigned char *addr;    /* Address the message was from is put
311:                                    here.  The caller must supply the
312:                                    memory. */
313:         unsigned int  addr_len; /* The size of the address buffer.
314:                                    The caller supplies the full buffer
315:                                    length, this value is updated to
316:                                    the actual message length when the
317:                                    message is received. */
318: 
319:         long    msgid; /* The sequence number specified in the request
320:                           if this is a response.  If this is a command,
321:                           this will be the sequence number from the
322:                           command. */
323: 
324:         struct ipmi_msg msg; /* The data field must point to a buffer.
325:                                 The data_size field must be set to the
326:                                 size of the message buffer.  The
327:                                 caller supplies the full buffer
328:                                 length, this value is updated to the
329:                                 actual message length when the message
330:                                 is received. */
331: };
332: 
333: /*
334:  * Receive a message.  error values:
335:  *  - EAGAIN - no messages in the queue.
336:  *  - EFAULT - an address supplied was invalid.
337:  *  - EINVAL - The address supplied was not valid.
338:  *  - EMSGSIZE - The message to was too large to fit into the message buffer,
339:  *               the message will be left in the buffer. */
340: #define IPMICTL_RECEIVE_MSG             _IOWR(IPMI_IOC_MAGIC, 12,       \
341:                                               struct ipmi_recv)
342: 
343: /*
344:  * Like RECEIVE_MSG, but if the message won't fit in the buffer, it
345:  * will truncate the contents instead of leaving the data in the
346:  * buffer.
347:  */
348: #define IPMICTL_RECEIVE_MSG_TRUNC       _IOWR(IPMI_IOC_MAGIC, 11,       \
349:                                               struct ipmi_recv)
350: 
351: /* Register to get commands from other entities on this interface. */
352: struct ipmi_cmdspec {
353:         unsigned char netfn;
354:         unsigned char cmd;
355: };
356: 
357: /*
358:  * Register to receive a specific command.  error values:
359:  *   - EFAULT - an address supplied was invalid.
360:  *   - EBUSY - The netfn/cmd supplied was already in use.
361:  *   - ENOMEM - could not allocate memory for the entry.
362:  */
363: #define IPMICTL_REGISTER_FOR_CMD        _IOR(IPMI_IOC_MAGIC, 14,        \
364:                                              struct ipmi_cmdspec)
365: /*
366:  * Unregister a regsitered command.  error values:
367:  *  - EFAULT - an address supplied was invalid.
368:  *  - ENOENT - The netfn/cmd was not found registered for this user.
369:  */
370: #define IPMICTL_UNREGISTER_FOR_CMD      _IOR(IPMI_IOC_MAGIC, 15,        \
371:                                              struct ipmi_cmdspec)
372: 
373: /*
374:  * Register to get commands from other entities on specific channels.
375:  * This way, you can only listen on specific channels, or have messages
376:  * from some channels go to one place and other channels to someplace
377:  * else.  The chans field is a bitmask, (1 << channel) for each channel.
378:  * It may be IPMI_CHAN_ALL for all channels.
379:  */
380: struct ipmi_cmdspec_chans {
381:         unsigned int netfn;
382:         unsigned int cmd;
383:         unsigned int chans;
384: };
385: 
386: /*
387:  * Register to receive a specific command on specific channels.  error values:
388:  *   - EFAULT - an address supplied was invalid.
389:  *   - EBUSY - One of the netfn/cmd/chans supplied was already in use.
390:  *   - ENOMEM - could not allocate memory for the entry.
391:  */
392: #define IPMICTL_REGISTER_FOR_CMD_CHANS  _IOR(IPMI_IOC_MAGIC, 28,        \
393:                                              struct ipmi_cmdspec_chans)
394: /*
395:  * Unregister some netfn/cmd/chans.  error values:
396:  *  - EFAULT - an address supplied was invalid.
397:  *  - ENOENT - None of the netfn/cmd/chans were found registered for this user.
398:  */
399: #define IPMICTL_UNREGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 29,       \
400:                                              struct ipmi_cmdspec_chans)
401: 
402: /*
403:  * Set whether this interface receives events.  Note that the first
404:  * user registered for events will get all pending events for the
405:  * interface.  error values:
406:  *  - EFAULT - an address supplied was invalid.
407:  */
408: #define IPMICTL_SET_GETS_EVENTS_CMD     _IOR(IPMI_IOC_MAGIC, 16, int)
409: 
410: /*
411:  * Set and get the slave address and LUN that we will use for our
412:  * source messages.  Note that this affects the interface, not just
413:  * this user, so it will affect all users of this interface.  This is
414:  * so some initialization code can come in and do the OEM-specific
415:  * things it takes to determine your address (if not the BMC) and set
416:  * it for everyone else.  You should probably leave the LUN alone.
417:  */
418: struct ipmi_channel_lun_address_set {
419:         unsigned short channel;
420:         unsigned char  value;
421: };
422: #define IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD \
423:         _IOR(IPMI_IOC_MAGIC, 24, struct ipmi_channel_lun_address_set)
424: #define IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD \
425:         _IOR(IPMI_IOC_MAGIC, 25, struct ipmi_channel_lun_address_set)
426: #define IPMICTL_SET_MY_CHANNEL_LUN_CMD \
427:         _IOR(IPMI_IOC_MAGIC, 26, struct ipmi_channel_lun_address_set)
428: #define IPMICTL_GET_MY_CHANNEL_LUN_CMD \
429:         _IOR(IPMI_IOC_MAGIC, 27, struct ipmi_channel_lun_address_set)
430: /* Legacy interfaces, these only set IPMB 0. */
431: #define IPMICTL_SET_MY_ADDRESS_CMD      _IOR(IPMI_IOC_MAGIC, 17, unsigned int)
432: #define IPMICTL_GET_MY_ADDRESS_CMD      _IOR(IPMI_IOC_MAGIC, 18, unsigned int)
433: #define IPMICTL_SET_MY_LUN_CMD          _IOR(IPMI_IOC_MAGIC, 19, unsigned int)
434: #define IPMICTL_GET_MY_LUN_CMD          _IOR(IPMI_IOC_MAGIC, 20, unsigned int)
435: 
436: /*
437:  * Get/set the default timing values for an interface.  You shouldn't
438:  * generally mess with these.
439:  */
440: struct ipmi_timing_parms {
441:         int          retries;
442:         unsigned int retry_time_ms;
443: };
444: #define IPMICTL_SET_TIMING_PARMS_CMD    _IOR(IPMI_IOC_MAGIC, 22, \
445:                                              struct ipmi_timing_parms)
446: #define IPMICTL_GET_TIMING_PARMS_CMD    _IOR(IPMI_IOC_MAGIC, 23, \
447:                                              struct ipmi_timing_parms)
448: 
449: /*
450:  * Set the maintenance mode.  See ipmi_set_maintenance_mode() above
451:  * for a description of what this does.
452:  */
453: #define IPMICTL_GET_MAINTENANCE_MODE_CMD        _IOR(IPMI_IOC_MAGIC, 30, int)
454: #define IPMICTL_SET_MAINTENANCE_MODE_CMD        _IOW(IPMI_IOC_MAGIC, 31, int)
455: 
456: #endif /* __LINUX_IPMI_H */
457: 


for client (none)
© Andrew Scott 2006 - 2025,
All Rights Reserved
http://www.andrew-scott.uk/
Andrew Scott
http://www.andrew-scott.co.uk/