Commit be2eca94 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-5.5-1' of git://github.com/cminyard/linux-ipmi

Pull IPMI updates from Corey Minyard:
 "Some small fixes accumulated for IPMI, nothing major"

* tag 'for-linus-5.5-1' of git://github.com/cminyard/linux-ipmi:
  ipmi: fix ipmb_poll()'s return type
  ipmi: kill off 'timespec' usage again
  drivers: ipmi: Support for both IPMB Req and Resp
  ipmi: Fix memory leak in __ipmi_bmc_register
  ipmi: bt-bmc: use devm_platform_ioremap_resource() to simplify code
  ipmi: use %*ph to print small buffer
  ipmi: Don't allow device module unload when in use
parents a11b6969 8e6a5c83
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -444,15 +444,13 @@ static int bt_bmc_probe(struct platform_device *pdev)

	bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
	if (IS_ERR(bt_bmc->map)) {
		struct resource *res;
		void __iomem *base;

		/*
		 * Assume it's not the MFD-based devicetree description, in
		 * which case generate a regmap ourselves
		 */
		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		base = devm_ioremap_resource(&pdev->dev, res);
		base = devm_platform_ioremap_resource(pdev, 0);
		if (IS_ERR(base))
			return PTR_ERR(base);

+12 −25
Original line number Diff line number Diff line
@@ -133,9 +133,6 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf,
	rq_sa = GET_7BIT_ADDR(msg[RQ_SA_8BIT_IDX]);
	netf_rq_lun = msg[NETFN_LUN_IDX];

	if (!(netf_rq_lun & NETFN_RSP_BIT_MASK))
		return -EINVAL;

	/*
	 * subtract rq_sa and netf_rq_lun from the length of the msg passed to
	 * i2c_smbus_xfer
@@ -154,16 +151,16 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf,
	return ret ? : count;
}

static unsigned int ipmb_poll(struct file *file, poll_table *wait)
static __poll_t ipmb_poll(struct file *file, poll_table *wait)
{
	struct ipmb_dev *ipmb_dev = to_ipmb_dev(file);
	unsigned int mask = POLLOUT;
	__poll_t mask = EPOLLOUT;

	mutex_lock(&ipmb_dev->file_mutex);
	poll_wait(file, &ipmb_dev->wait_queue, wait);

	if (atomic_read(&ipmb_dev->request_queue_len))
		mask |= POLLIN;
		mask |= EPOLLIN;
	mutex_unlock(&ipmb_dev->file_mutex);

	return mask;
@@ -203,25 +200,16 @@ static u8 ipmb_verify_checksum1(struct ipmb_dev *ipmb_dev, u8 rs_sa)
		ipmb_dev->request.checksum1);
}

static bool is_ipmb_request(struct ipmb_dev *ipmb_dev, u8 rs_sa)
{
	if (ipmb_dev->msg_idx >= IPMB_REQUEST_LEN_MIN) {
		if (ipmb_verify_checksum1(ipmb_dev, rs_sa))
			return false;

/*
		 * Check whether this is an IPMB request or
		 * response.
		 * The 6 MSB of netfn_rs_lun are dedicated to the netfn
		 * while the remaining bits are dedicated to the lun.
		 * If the LSB of the netfn is cleared, it is associated
		 * with an IPMB request.
		 * If the LSB of the netfn is set, it is associated with
		 * an IPMB response.
 * Verify if message has proper ipmb header with minimum length
 * and correct checksum byte.
 */
		if (!(ipmb_dev->request.netfn_rs_lun & NETFN_RSP_BIT_MASK))
static bool is_ipmb_msg(struct ipmb_dev *ipmb_dev, u8 rs_sa)
{
	if ((ipmb_dev->msg_idx >= IPMB_REQUEST_LEN_MIN) &&
	   (!ipmb_verify_checksum1(ipmb_dev, rs_sa)))
		return true;
	}

	return false;
}

@@ -273,8 +261,7 @@ static int ipmb_slave_cb(struct i2c_client *client,

	case I2C_SLAVE_STOP:
		ipmb_dev->request.len = ipmb_dev->msg_idx;

		if (is_ipmb_request(ipmb_dev, GET_8BIT_ADDR(client->addr)))
		if (is_ipmb_msg(ipmb_dev, GET_8BIT_ADDR(client->addr)))
			ipmb_handle_request(ipmb_dev);
		break;

+24 −31
Original line number Diff line number Diff line
@@ -44,25 +44,6 @@ static void need_waiter(struct ipmi_smi *intf);
static int handle_one_recv_msg(struct ipmi_smi *intf,
			       struct ipmi_smi_msg *msg);

#ifdef DEBUG
static void ipmi_debug_msg(const char *title, unsigned char *data,
			   unsigned int len)
{
	int i, pos;
	char buf[100];

	pos = snprintf(buf, sizeof(buf), "%s: ", title);
	for (i = 0; i < len; i++)
		pos += snprintf(buf + pos, sizeof(buf) - pos,
				" %2.2x", data[i]);
	pr_debug("%s\n", buf);
}
#else
static void ipmi_debug_msg(const char *title, unsigned char *data,
			   unsigned int len)
{ }
#endif

static bool initialized;
static bool drvregistered;

@@ -448,6 +429,8 @@ enum ipmi_stat_indexes {

#define IPMI_IPMB_NUM_SEQ	64
struct ipmi_smi {
	struct module *owner;

	/* What interface number are we? */
	int intf_num;

@@ -1220,6 +1203,11 @@ int ipmi_create_user(unsigned int if_num,
	if (rv)
		goto out_kfree;

	if (!try_module_get(intf->owner)) {
		rv = -ENODEV;
		goto out_kfree;
	}

	/* Note that each existing user holds a refcount to the interface. */
	kref_get(&intf->refcount);

@@ -1349,6 +1337,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
	}

	kref_put(&intf->refcount, intf_free);
	module_put(intf->owner);
}

int ipmi_destroy_user(struct ipmi_user *user)
@@ -2267,7 +2256,7 @@ out_err:
		ipmi_free_smi_msg(smi_msg);
		ipmi_free_recv_msg(recv_msg);
	} else {
		ipmi_debug_msg("Send", smi_msg->data, smi_msg->data_size);
		pr_debug("Send: %*ph\n", smi_msg->data_size, smi_msg->data);

		smi_send(intf, intf->handlers, smi_msg, priority);
	}
@@ -2459,7 +2448,7 @@ static int __get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc)
 * been recently fetched, this will just use the cached data.  Otherwise
 * it will run a new fetch.
 *
 * Except for the first time this is called (in ipmi_register_smi()),
 * Except for the first time this is called (in ipmi_add_smi()),
 * this will always return good data;
 */
static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc,
@@ -3031,8 +3020,11 @@ static int __ipmi_bmc_register(struct ipmi_smi *intf,
		bmc->pdev.name = "ipmi_bmc";

		rv = ida_simple_get(&ipmi_bmc_ida, 0, 0, GFP_KERNEL);
		if (rv < 0)
		if (rv < 0) {
			kfree(bmc);
			goto out;
		}

		bmc->pdev.dev.driver = &ipmidriver.driver;
		bmc->pdev.id = rv;
		bmc->pdev.dev.release = release_bmc_device;
@@ -3377,7 +3369,8 @@ static void redo_bmc_reg(struct work_struct *work)
	kref_put(&intf->refcount, intf_free);
}

int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
int ipmi_add_smi(struct module         *owner,
		 const struct ipmi_smi_handlers *handlers,
		 void		       *send_info,
		 struct device         *si_dev,
		 unsigned char         slave_addr)
@@ -3406,7 +3399,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
		return rv;
	}


	intf->owner = owner;
	intf->bmc = &intf->tmp_bmc;
	INIT_LIST_HEAD(&intf->bmc->intfs);
	mutex_init(&intf->bmc->dyn_mutex);
@@ -3514,7 +3507,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,

	return rv;
}
EXPORT_SYMBOL(ipmi_register_smi);
EXPORT_SYMBOL(ipmi_add_smi);

static void deliver_smi_err_response(struct ipmi_smi *intf,
				     struct ipmi_smi_msg *msg,
@@ -3730,7 +3723,7 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
		msg->data[10] = ipmb_checksum(&msg->data[6], 4);
		msg->data_size = 11;

		ipmi_debug_msg("Invalid command:", msg->data, msg->data_size);
		pr_debug("Invalid command: %*ph\n", msg->data_size, msg->data);

		rcu_read_lock();
		if (!intf->in_shutdown) {
@@ -4217,7 +4210,7 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
	int requeue;
	int chan;

	ipmi_debug_msg("Recv:", msg->rsp, msg->rsp_size);
	pr_debug("Recv: %*ph\n", msg->rsp_size, msg->rsp);

	if ((msg->data_size >= 2)
	    && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
@@ -4576,7 +4569,7 @@ smi_from_recv_msg(struct ipmi_smi *intf, struct ipmi_recv_msg *recv_msg,
	smi_msg->data_size = recv_msg->msg.data_len;
	smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid);

	ipmi_debug_msg("Resend: ", smi_msg->data, smi_msg->data_size);
	pr_debug("Resend: %*ph\n", smi_msg->data_size, smi_msg->data);

	return smi_msg;
}
+13 −27
Original line number Diff line number Diff line
@@ -265,10 +265,10 @@ static void cleanup_ipmi_si(void);
#ifdef DEBUG_TIMING
void debug_timestamp(char *msg)
{
	struct timespec t;
	struct timespec64 t;

	ktime_get_ts(&t);
	pr_debug("**%s: %ld.%9.9ld\n", msg, (long) t.tv_sec, t.tv_nsec);
	ktime_get_ts64(&t);
	pr_debug("**%s: %lld.%9.9ld\n", msg, t.tv_sec, t.tv_nsec);
}
#else
#define debug_timestamp(x)
@@ -935,38 +935,25 @@ static void set_run_to_completion(void *send_info, bool i_run_to_completion)
}

/*
 * Use -1 in the nsec value of the busy waiting timespec to tell that
 * we are spinning in kipmid looking for something and not delaying
 * between checks
 * Use -1 as a special constant to tell that we are spinning in kipmid
 * looking for something and not delaying between checks
 */
static inline void ipmi_si_set_not_busy(struct timespec *ts)
{
	ts->tv_nsec = -1;
}
static inline int ipmi_si_is_busy(struct timespec *ts)
{
	return ts->tv_nsec != -1;
}

#define IPMI_TIME_NOT_BUSY ns_to_ktime(-1ull)
static inline bool ipmi_thread_busy_wait(enum si_sm_result smi_result,
					 const struct smi_info *smi_info,
					 struct timespec *busy_until)
					 ktime_t *busy_until)
{
	unsigned int max_busy_us = 0;

	if (smi_info->si_num < num_max_busy_us)
		max_busy_us = kipmid_max_busy_us[smi_info->si_num];
	if (max_busy_us == 0 || smi_result != SI_SM_CALL_WITH_DELAY)
		ipmi_si_set_not_busy(busy_until);
	else if (!ipmi_si_is_busy(busy_until)) {
		ktime_get_ts(busy_until);
		timespec_add_ns(busy_until, max_busy_us * NSEC_PER_USEC);
		*busy_until = IPMI_TIME_NOT_BUSY;
	else if (*busy_until == IPMI_TIME_NOT_BUSY) {
		*busy_until = ktime_get() + max_busy_us * NSEC_PER_USEC;
	} else {
		struct timespec now;

		ktime_get_ts(&now);
		if (unlikely(timespec_compare(&now, busy_until) > 0)) {
			ipmi_si_set_not_busy(busy_until);
		if (unlikely(ktime_get() > *busy_until)) {
			*busy_until = IPMI_TIME_NOT_BUSY;
			return false;
		}
	}
@@ -988,9 +975,8 @@ static int ipmi_thread(void *data)
	struct smi_info *smi_info = data;
	unsigned long flags;
	enum si_sm_result smi_result;
	struct timespec busy_until = { 0, 0 };
	ktime_t busy_until = IPMI_TIME_NOT_BUSY;

	ipmi_si_set_not_busy(&busy_until);
	set_user_nice(current, MAX_NICE);
	while (!kthread_should_stop()) {
		int busy_wait;
+8 −4
Original line number Diff line number Diff line
@@ -224,11 +224,15 @@ static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd,
 * is called, and the lower layer must get the interface from that
 * call.
 */
int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
int ipmi_add_smi(struct module            *owner,
		 const struct ipmi_smi_handlers *handlers,
		 void                     *send_info,
		 struct device            *dev,
		 unsigned char            slave_addr);

#define ipmi_register_smi(handlers, send_info, dev, slave_addr) \
	ipmi_add_smi(THIS_MODULE, handlers, send_info, dev, 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.