#define pr_fmt(fmt) …
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/notifier.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <linux/rcupdate.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
#include "ipmi_si.h"
#include "ipmi_si_sm.h"
#include <linux/string.h>
#include <linux/ctype.h>
#undef DEBUG_TIMING
#define SI_TIMEOUT_TIME_USEC …
#define SI_USEC_PER_JIFFY …
#define SI_TIMEOUT_JIFFIES …
#define SI_SHORT_TIMEOUT_USEC …
enum si_intf_state { … };
#define IPMI_BT_INTMASK_REG …
#define IPMI_BT_INTMASK_CLEAR_IRQ_BIT …
#define IPMI_BT_INTMASK_ENABLE_IRQ_BIT …
const char *const si_to_str[] = …;
static bool initialized;
enum si_stat_indexes { … };
struct smi_info { … };
#define smi_inc_stat(smi, stat) …
#define smi_get_stat(smi, stat) …
#define IPMI_MAX_INTFS …
static int force_kipmid[IPMI_MAX_INTFS];
static int num_force_kipmid;
static unsigned int kipmid_max_busy_us[IPMI_MAX_INTFS];
static int num_max_busy_us;
static bool unload_when_empty = …;
static int try_smi_init(struct smi_info *smi);
static void cleanup_one_si(struct smi_info *smi_info);
static void cleanup_ipmi_si(void);
#ifdef DEBUG_TIMING
void debug_timestamp(struct smi_info *smi_info, char *msg)
{
struct timespec64 t;
ktime_get_ts64(&t);
dev_dbg(smi_info->io.dev, "**%s: %lld.%9.9ld\n",
msg, t.tv_sec, t.tv_nsec);
}
#else
#define debug_timestamp(smi_info, x) …
#endif
static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
static int register_xaction_notifier(struct notifier_block *nb)
{ … }
static void deliver_recv_msg(struct smi_info *smi_info,
struct ipmi_smi_msg *msg)
{ … }
static void return_hosed_msg(struct smi_info *smi_info, int cCode)
{ … }
static enum si_sm_result start_next_msg(struct smi_info *smi_info)
{ … }
static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
{ … }
static void start_new_msg(struct smi_info *smi_info, unsigned char *msg,
unsigned int size)
{ … }
static void start_check_enables(struct smi_info *smi_info)
{ … }
static void start_clear_flags(struct smi_info *smi_info)
{ … }
static void start_getting_msg_queue(struct smi_info *smi_info)
{ … }
static void start_getting_events(struct smi_info *smi_info)
{ … }
static inline bool disable_si_irq(struct smi_info *smi_info)
{ … }
static inline bool enable_si_irq(struct smi_info *smi_info)
{ … }
static struct ipmi_smi_msg *alloc_msg_handle_irq(struct smi_info *smi_info)
{ … }
static void handle_flags(struct smi_info *smi_info)
{ … }
#define GLOBAL_ENABLES_MASK …
static u8 current_global_enables(struct smi_info *smi_info, u8 base,
bool *irq_on)
{ … }
static void check_bt_irq(struct smi_info *smi_info, bool irq_on)
{ … }
static void handle_transaction_done(struct smi_info *smi_info)
{ … }
static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
int time)
{ … }
static void check_start_timer_thread(struct smi_info *smi_info)
{ … }
static void flush_messages(void *send_info)
{ … }
static void sender(void *send_info,
struct ipmi_smi_msg *msg)
{ … }
static void set_run_to_completion(void *send_info, bool i_run_to_completion)
{ … }
#define IPMI_TIME_NOT_BUSY …
static inline bool ipmi_thread_busy_wait(enum si_sm_result smi_result,
const struct smi_info *smi_info,
ktime_t *busy_until)
{ … }
static int ipmi_thread(void *data)
{ … }
static void poll(void *send_info)
{ … }
static void request_events(void *send_info)
{ … }
static void set_need_watch(void *send_info, unsigned int watch_mask)
{ … }
static void smi_timeout(struct timer_list *t)
{ … }
irqreturn_t ipmi_si_irq_handler(int irq, void *data)
{ … }
static int smi_start_processing(void *send_info,
struct ipmi_smi *intf)
{ … }
static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
{ … }
static void set_maintenance_mode(void *send_info, bool enable)
{ … }
static void shutdown_smi(void *send_info);
static const struct ipmi_smi_handlers handlers = …;
static LIST_HEAD(smi_infos);
static DEFINE_MUTEX(smi_infos_lock);
static int smi_num;
static const char * const addr_space_to_str[] = …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param(unload_when_empty, bool, 0);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
void ipmi_irq_finish_setup(struct si_sm_io *io)
{ … }
void ipmi_irq_start_cleanup(struct si_sm_io *io)
{ … }
static void std_irq_cleanup(struct si_sm_io *io)
{ … }
int ipmi_std_irq_setup(struct si_sm_io *io)
{ … }
static int wait_for_msg_done(struct smi_info *smi_info)
{ … }
static int try_get_dev_id(struct smi_info *smi_info)
{ … }
static int get_global_enables(struct smi_info *smi_info, u8 *enables)
{ … }
static int set_global_enables(struct smi_info *smi_info, u8 enables)
{ … }
static void check_clr_rcv_irq(struct smi_info *smi_info)
{ … }
static void check_set_rcv_irq(struct smi_info *smi_info)
{ … }
static int try_enable_event_buffer(struct smi_info *smi_info)
{ … }
#define IPMI_SI_ATTR(name) …
static ssize_t type_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(type);
static ssize_t interrupts_enabled_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(interrupts_enabled);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
IPMI_SI_ATTR(…);
static ssize_t params_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(params);
static struct attribute *ipmi_si_dev_attrs[] = …;
static const struct attribute_group ipmi_si_dev_attr_group = …;
static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info)
{ … }
#define DELL_POWEREDGE_8G_BMC_DEVICE_ID …
#define DELL_POWEREDGE_8G_BMC_DEVICE_REV …
#define DELL_POWEREDGE_8G_BMC_IPMI_VERSION …
#define DELL_IANA_MFR_ID …
static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info)
{ … }
#define CANNOT_RETURN_REQUESTED_LENGTH …
static void return_hosed_msg_badsize(struct smi_info *smi_info)
{ … }
#define STORAGE_NETFN …
#define STORAGE_CMD_GET_SDR …
static int dell_poweredge_bt_xaction_handler(struct notifier_block *self,
unsigned long unused,
void *in)
{ … }
static struct notifier_block dell_poweredge_bt_xaction_notifier = …;
static void
setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
{ … }
static void setup_oem_data_handler(struct smi_info *smi_info)
{ … }
static void setup_xaction_handlers(struct smi_info *smi_info)
{ … }
static void check_for_broken_irqs(struct smi_info *smi_info)
{ … }
static inline void stop_timer_and_thread(struct smi_info *smi_info)
{ … }
static struct smi_info *find_dup_si(struct smi_info *info)
{ … }
int ipmi_si_add_smi(struct si_sm_io *io)
{ … }
static int try_smi_init(struct smi_info *new_smi)
{ … }
static int __init init_ipmi_si(void)
{ … }
module_init(…) …;
static void wait_msg_processed(struct smi_info *smi_info)
{ … }
static void shutdown_smi(void *send_info)
{ … }
static void cleanup_one_si(struct smi_info *smi_info)
{ … }
void ipmi_si_remove_by_dev(struct device *dev)
{ … }
struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
unsigned long addr)
{ … }
static void cleanup_ipmi_si(void)
{ … }
module_exit(cleanup_ipmi_si);
MODULE_ALIAS(…) …;
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;