linux/drivers/char/ipmi/ipmi_ssif.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * ipmi_ssif.c
 *
 * The interface to the IPMI driver for SMBus access to a SMBus
 * compliant device.  Called SSIF by the IPMI spec.
 *
 * Author: Intel Corporation
 *         Todd Davis <[email protected]>
 *
 * Rewritten by Corey Minyard <[email protected]> to support the
 * non-blocking I2C interface, add support for multi-part
 * transactions, add PEC support, and general clenaup.
 *
 * Copyright 2003 Intel Corporation
 * Copyright 2005 MontaVista Software
 */

/*
 * This file holds the "policy" for the interface to the SSIF state
 * machine.  It does the configuration, handles timers and interrupts,
 * and drives the real SSIF state machine.
 */

#define pr_fmt(fmt)
#define dev_fmt(fmt)

#if defined(MODVERSIONS)
#include <linux/modversions.h>
#endif

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/i2c.h>
#include <linux/ipmi_smi.h>
#include <linux/init.h>
#include <linux/dmi.h>
#include <linux/kthread.h>
#include <linux/acpi.h>
#include <linux/ctype.h>
#include <linux/time64.h>
#include "ipmi_dmi.h"

#define DEVICE_NAME

#define IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD

#define SSIF_IPMI_REQUEST
#define SSIF_IPMI_MULTI_PART_REQUEST_START
#define SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE
#define SSIF_IPMI_MULTI_PART_REQUEST_END
#define SSIF_IPMI_RESPONSE
#define SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE

/* ssif_debug is a bit-field
 *	SSIF_DEBUG_MSG -	commands and their responses
 *	SSIF_DEBUG_STATES -	message states
 *	SSIF_DEBUG_TIMING -	 Measure times between events in the driver
 */
#define SSIF_DEBUG_TIMING
#define SSIF_DEBUG_STATE
#define SSIF_DEBUG_MSG
#define SSIF_NODEBUG
#define SSIF_DEFAULT_DEBUG

/*
 * Timer values
 */
#define SSIF_MSG_USEC
#define SSIF_REQ_RETRY_USEC
#define SSIF_MSG_PART_USEC

/* How many times to we retry sending/receiving the message. */
#define SSIF_SEND_RETRIES
#define SSIF_RECV_RETRIES

#define SSIF_MSG_MSEC
#define SSIF_REQ_RETRY_MSEC
#define SSIF_MSG_JIFFIES
#define SSIF_REQ_RETRY_JIFFIES
#define SSIF_MSG_PART_JIFFIES

/*
 * Timeout for the watch, only used for get flag timer.
 */
#define SSIF_WATCH_MSG_TIMEOUT
#define SSIF_WATCH_WATCHDOG_TIMEOUT

enum ssif_intf_state {};

#define IS_SSIF_IDLE(ssif)

/*
 * Indexes into stats[] in ssif_info below.
 */
enum ssif_stat_indexes {};

struct ssif_addr_info {};

struct ssif_info;

ssif_i2c_done;

struct ssif_info {};

#define ssif_inc_stat(ssif, stat)
#define ssif_get_stat(ssif, stat)

static bool initialized;
static bool platform_registered;

static void return_hosed_msg(struct ssif_info *ssif_info,
			     struct ipmi_smi_msg *msg);
static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags);
static int start_send(struct ssif_info *ssif_info,
		      unsigned char   *data,
		      unsigned int    len);

static unsigned long *ipmi_ssif_lock_cond(struct ssif_info *ssif_info,
					  unsigned long *flags)
	__acquires(&ssif_info->lock)
{}

static void ipmi_ssif_unlock_cond(struct ssif_info *ssif_info,
				  unsigned long *flags)
	__releases(&ssif_info->lock)
{}

static void deliver_recv_msg(struct ssif_info *ssif_info,
			     struct ipmi_smi_msg *msg)
{}

static void return_hosed_msg(struct ssif_info *ssif_info,
			     struct ipmi_smi_msg *msg)
{}

/*
 * Must be called with the message lock held.  This will release the
 * message lock.  Note that the caller will check IS_SSIF_IDLE and
 * start a new operation, so there is no need to check for new
 * messages to start in here.
 */
static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags)
{}

static void start_flag_fetch(struct ssif_info *ssif_info, unsigned long *flags)
{}

static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags,
			     struct ipmi_smi_msg *msg)
{}

static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags)
{}

static void start_recv_msg_fetch(struct ssif_info *ssif_info,
				 unsigned long *flags)
{}

/*
 * Must be called with the message lock held.  This will release the
 * message lock.  Note that the caller will check IS_SSIF_IDLE and
 * start a new operation, so there is no need to check for new
 * messages to start in here.
 */
static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags)
{}

static int ipmi_ssif_thread(void *data)
{}

static void ssif_i2c_send(struct ssif_info *ssif_info,
			ssif_i2c_done handler,
			int read_write, int command,
			unsigned char *data, unsigned int size)
{}


static void msg_done_handler(struct ssif_info *ssif_info, int result,
			     unsigned char *data, unsigned int len);

static void start_get(struct ssif_info *ssif_info)
{}

static void start_resend(struct ssif_info *ssif_info);

static void retry_timeout(struct timer_list *t)
{}

static void watch_timeout(struct timer_list *t)
{}

static void ssif_alert(struct i2c_client *client, enum i2c_alert_protocol type,
		       unsigned int data)
{}

static void msg_done_handler(struct ssif_info *ssif_info, int result,
			     unsigned char *data, unsigned int len)
{}

static void msg_written_handler(struct ssif_info *ssif_info, int result,
				unsigned char *data, unsigned int len)
{}

static void start_resend(struct ssif_info *ssif_info)
{}

static int start_send(struct ssif_info *ssif_info,
		      unsigned char   *data,
		      unsigned int    len)
{}

/* Must be called with the message lock held. */
static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags)
{}

static void sender(void                *send_info,
		   struct ipmi_smi_msg *msg)
{}

static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
{}

/*
 * Upper layer wants us to request events.
 */
static void request_events(void *send_info)
{}

/*
 * Upper layer is changing the flag saying whether we need to request
 * flags periodically or not.
 */
static void ssif_set_need_watch(void *send_info, unsigned int watch_mask)
{}

static int ssif_start_processing(void            *send_info,
				 struct ipmi_smi *intf)
{}

#define MAX_SSIF_BMCS

static unsigned short addr[MAX_SSIF_BMCS];
static int num_addrs;
module_param_array();
MODULE_PARM_DESC();

static char *adapter_name[MAX_SSIF_BMCS];
static int num_adapter_names;
module_param_array();
MODULE_PARM_DESC();

static int slave_addrs[MAX_SSIF_BMCS];
static int num_slave_addrs;
module_param_array();
MODULE_PARM_DESC();

static bool alerts_broken;
module_param(alerts_broken, bool, 0);
MODULE_PARM_DESC();

/*
 * Bit 0 enables message debugging, bit 1 enables state debugging, and
 * bit 2 enables timing debugging.  This is an array indexed by
 * interface number"
 */
static int dbg[MAX_SSIF_BMCS];
static int num_dbg;
module_param_array();
MODULE_PARM_DESC();

static bool ssif_dbg_probe;
module_param_named(dbg_probe, ssif_dbg_probe, bool, 0);
MODULE_PARM_DESC();

static bool ssif_tryacpi =;
module_param_named(tryacpi, ssif_tryacpi, bool, 0);
MODULE_PARM_DESC();

static bool ssif_trydmi =;
module_param_named(trydmi, ssif_trydmi, bool, 0);
MODULE_PARM_DESC();

static DEFINE_MUTEX(ssif_infos_mutex);
static LIST_HEAD(ssif_infos);

#define IPMI_SSIF_ATTR(name)

static ssize_t ipmi_type_show(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
{}
static DEVICE_ATTR(type, S_IRUGO, ipmi_type_show, NULL);

IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();
IPMI_SSIF_ATTR();

static struct attribute *ipmi_ssif_dev_attrs[] =;

static const struct attribute_group ipmi_ssif_dev_attr_group =;

static void shutdown_ssif(void *send_info)
{}

static void ssif_remove(struct i2c_client *client)
{}

static int read_response(struct i2c_client *client, unsigned char *resp)
{}

static int do_cmd(struct i2c_client *client, int len, unsigned char *msg,
		  int *resp_len, unsigned char *resp)
{}

static int ssif_detect(struct i2c_client *client, struct i2c_board_info *info)
{}

static int strcmp_nospace(char *s1, char *s2)
{}

static struct ssif_addr_info *ssif_info_find(unsigned short addr,
					     char *adapter_name,
					     bool match_null_name)
{}

static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
{}

static int find_slave_address(struct i2c_client *client, int slave_addr)
{}

static int start_multipart_test(struct i2c_client *client,
				unsigned char *msg, bool do_middle)
{}

static void test_multipart_messages(struct i2c_client *client,
				    struct ssif_info *ssif_info,
				    unsigned char *resp)
{}

/*
 * Global enables we care about.
 */
#define GLOBAL_ENABLES_MASK

static void ssif_remove_dup(struct i2c_client *client)
{}

static int ssif_add_infos(struct i2c_client *client)
{}

/*
 * Prefer ACPI over SMBIOS, if both are available.
 * So if we get an ACPI interface and have already registered a SMBIOS
 * interface at the same address, remove the SMBIOS and add the ACPI one.
 */
static int ssif_check_and_remove(struct i2c_client *client,
			      struct ssif_info *ssif_info)
{}

static int ssif_probe(struct i2c_client *client)
{}

static int new_ssif_client(int addr, char *adapter_name,
			   int debug, int slave_addr,
			   enum ipmi_addr_src addr_src,
			   struct device *dev)
{}

static void free_ssif_clients(void)
{}

static unsigned short *ssif_address_list(void)
{}

#ifdef CONFIG_ACPI
static const struct acpi_device_id ssif_acpi_match[] =;
MODULE_DEVICE_TABLE(acpi, ssif_acpi_match);
#endif

#ifdef CONFIG_DMI
static int dmi_ipmi_probe(struct platform_device *pdev)
{}
#else
static int dmi_ipmi_probe(struct platform_device *pdev)
{
	return -ENODEV;
}
#endif

static const struct i2c_device_id ssif_id[] =;
MODULE_DEVICE_TABLE(i2c, ssif_id);

static struct i2c_driver ssif_i2c_driver =;

static int ssif_platform_probe(struct platform_device *dev)
{}

static void ssif_platform_remove(struct platform_device *dev)
{}

static const struct platform_device_id ssif_plat_ids[] =;
MODULE_DEVICE_TABLE(platform, ssif_plat_ids);

static struct platform_driver ipmi_driver =;

static int __init init_ipmi_ssif(void)
{}
module_init();

static void __exit cleanup_ipmi_ssif(void)
{}
module_exit(cleanup_ipmi_ssif);

MODULE_ALIAS();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();