cregit-Linux how code gets into the kernel

Release 4.18 include/linux/ipmi_smi.h

Directory: include/linux
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * ipmi_smi.h
 *
 * MontaVista IPMI system management interface
 *
 * Author: MontaVista Software, Inc.
 *         Corey Minyard <minyard@mvista.com>
 *         source@mvista.com
 *
 * Copyright 2002 MontaVista Software Inc.
 *
 */

#ifndef __LINUX_IPMI_SMI_H

#define __LINUX_IPMI_SMI_H

#include <linux/ipmi_msgdefs.h>
#include <linux/proc_fs.h>
#include <linux/platform_device.h>
#include <linux/ipmi.h>

struct device;

/*
 * This files describes the interface for IPMI system management interface
 * drivers to bind into the IPMI message handler.
 */

/* Structure for the low-level drivers. */

typedef struct ipmi_smi *ipmi_smi_t;

/*
 * Messages to/from the lower layer.  The smi interface will take one
 * of these to send. After the send has occurred and a response has
 * been received, it will report this same data structure back up to
 * the upper layer.  If an error occurs, it should fill in the
 * response with an error code in the completion code location. When
 * asynchronous data is received, one of these is allocated, the
 * data_size is set to zero and the response holds the data from the
 * get message or get event command that the interface initiated.
 * Note that it is the interfaces responsibility to detect
 * asynchronous data and messages and request them from the
 * interface.
 */

struct ipmi_smi_msg {
	
struct list_head link;

	
long    msgid;
	
void    *user_data;

	
int           data_size;
	
unsigned char data[IPMI_MAX_MSG_LENGTH];

	
int           rsp_size;
	
unsigned char rsp[IPMI_MAX_MSG_LENGTH];

	/* Will be called when the system is done with the message
           (presumably to free it). */
	
void (*done)(struct ipmi_smi_msg *msg);
};


struct ipmi_smi_handlers {
	
struct module *owner;

	/*
         * The low-level interface cannot start sending messages to
         * the upper layer until this function is called.  This may
         * not be NULL, the lower layer must take the interface from
         * this call.
         */
	
int (*start_processing)(void            *send_info,
				struct ipmi_smi *new_intf);

	/*
         * When called, the low-level interface should disable all
         * processing, it should be complete shut down when it returns.
         */
	
void (*shutdown)(void *send_info);

	/*
         * Get the detailed private info of the low level interface and store
         * it into the structure of ipmi_smi_data. For example: the
         * ACPI device handle will be returned for the pnp_acpi IPMI device.
         */
	
int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data);

	/*
         * Called to enqueue an SMI message to be sent.  This
         * operation is not allowed to fail.  If an error occurs, it
         * should report back the error in a received message.  It may
         * do this in the current call context, since no write locks
         * are held when this is run.  Message are delivered one at
         * a time by the message handler, a new message will not be
         * delivered until the previous message is returned.
         */
	
void (*sender)(void                *send_info,
		       struct ipmi_smi_msg *msg);

	/*
         * Called by the upper layer to request that we try to get
         * events from the BMC we are attached to.
         */
	
void (*request_events)(void *send_info);

	/*
         * Called by the upper layer when some user requires that the
         * interface watch for events, received messages, watchdog
         * pretimeouts, or not.  Used by the SMI to know if it should
         * watch for these.  This may be NULL if the SMI does not
         * implement it.
         */
	
void (*set_need_watch)(void *send_info, bool enable);

	/*
         * Called when flushing all pending messages.
         */
	
void (*flush_messages)(void *send_info);

	/*
         * Called when the interface should go into "run to
         * completion" mode.  If this call sets the value to true, the
         * interface should make sure that all messages are flushed
         * out and that none are pending, and any new requests are run
         * to completion immediately.
         */
	
void (*set_run_to_completion)(void *send_info, bool run_to_completion);

	/*
         * Called to poll for work to do.  This is so upper layers can
         * poll for operations during things like crash dumps.
         */
	
void (*poll)(void *send_info);

	/*
         * Enable/disable firmware maintenance mode.  Note that this
         * is *not* the modes defined, this is simply an on/off
         * setting.  The message handler does the mode handling.  Note
         * that this is called from interrupt context, so it cannot
         * block.
         */
	
void (*set_maintenance_mode)(void *send_info, bool enable);
};


struct ipmi_device_id {
	
unsigned char device_id;
	
unsigned char device_revision;
	
unsigned char firmware_revision_1;
	
unsigned char firmware_revision_2;
	
unsigned char ipmi_version;
	
unsigned char additional_device_support;
	
unsigned int  manufacturer_id;
	
unsigned int  product_id;
	
unsigned char aux_firmware_revision[4];
	
unsigned int  aux_firmware_revision_set : 1;
};


#define ipmi_version_major(v) ((v)->ipmi_version & 0xf)

#define ipmi_version_minor(v) ((v)->ipmi_version >> 4)

/*
 * Take a pointer to an IPMI response and extract device id information from
 * it. @netfn is in the IPMI_NETFN_ format, so may need to be shifted from
 * a SI response.
 */

static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd, const unsigned char *data, unsigned int data_len, struct ipmi_device_id *id) { if (data_len < 7) return -EINVAL; if (netfn != IPMI_NETFN_APP_RESPONSE || cmd != IPMI_GET_DEVICE_ID_CMD) /* Strange, didn't get the response we expected. */ return -EINVAL; if (data[0] != 0) /* That's odd, it shouldn't be able to fail. */ return -EINVAL; data++; data_len--; id->device_id = data[0]; id->device_revision = data[1]; id->firmware_revision_1 = data[2]; id->firmware_revision_2 = data[3]; id->ipmi_version = data[4]; id->additional_device_support = data[5]; if (data_len >= 11) { id->manufacturer_id = (data[6] | (data[7] << 8) | (data[8] << 16)); id->product_id = data[9] | (data[10] << 8); } else { id->manufacturer_id = 0; id->product_id = 0; } if (data_len >= 15) { memcpy(id->aux_firmware_revision, data+11, 4); id->aux_firmware_revision_set = 1; } else id->aux_firmware_revision_set = 0; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Corey Minyard22294.87%375.00%
Jeremy Kerr125.13%125.00%
Total234100.00%4100.00%

/* * Add a low-level interface to the IPMI driver. Note that if the * interface doesn't know its slave address, it should pass in zero. * The low-level interface should not deliver any messages to the * upper layer until the start_processing() function in the handlers * is called, and the lower layer must get the interface from that * call. */ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, void *send_info, struct device *dev, unsigned char slave_addr); /* * Remove a low-level interface from the IPMI driver. This will * return an error if the interface is still in use by a user. */ void ipmi_unregister_smi(struct ipmi_smi *intf); /* * The lower layer reports received messages through this interface. * The data_size should be zero if this is an asynchronous message. If * the lower layer gets an error sending a message, it should format * an error response in the message response. */ void ipmi_smi_msg_received(struct ipmi_smi *intf, struct ipmi_smi_msg *msg); /* The lower layer received a watchdog pre-timeout on interface. */ void ipmi_smi_watchdog_pretimeout(struct ipmi_smi *intf); struct ipmi_smi_msg *ipmi_alloc_smi_msg(void);
static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg) { msg->done(msg); }

Contributors

PersonTokensPropCommitsCommitProp
Corey Minyard19100.00%1100.00%
Total19100.00%1100.00%

#endif /* __LINUX_IPMI_SMI_H */

Overall Contributors

PersonTokensPropCommitsCommitProp
Corey Minyard56490.53%1872.00%
Yakui Zhao203.21%14.00%
Jeremy Kerr121.93%14.00%
Hidehiro Kawai121.93%14.00%
Andrew Morton60.96%14.00%
Christoph Hellwig50.80%14.00%
Paul Gortmaker30.48%14.00%
Adam Buchbinder10.16%14.00%
Total623100.00%25100.00%
Directory: include/linux
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.