Some small fixes accumulated for IPMI, nothing major.
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE/Q1c5nzg9ZpmiCaGYfOMkJGb/4EFAl3cCCwACgkQYfOMkJGb /4HjDg//TOaRF7LcF7BYYmqG6wQL+Hi7CvUxG8ifpswr8zzK/TVxQwFS17o91O2g beorNqxl3qx/PgFPoNCtLU7SyNt7YvnTlCW/oBadt8BADln2NseXlOmb/8isy2p+ RvDWVO7Bp+p8TSU3SapZOnqWM8ICBT1vNXUep+TU74FE3unQ4OvqrjgjdlL7FdR2 yz7gD2IwUk8jljaWVEdMy0svH/iWZ2Gbw8HfTZtcmYILn/VtZYTfn2Z59rPV6bAu M3PNGS1T9E3gqROFXoq2mzM6N7DA0JUJvGY9z2l/V1/iHG/5UoQKTXYy2AcrZN+U YL9r9uC9+pLdBGuLvHlB8xQQZYZMO09Rv/yMacUphFbsvRKQ5dElFCMJjTB/dpiQ vxRPGYfr+n5fWhRGT/YR/gheCwZltuJXAu4QOnLPGh1dG9yIS04H/HiKTmoFsbrr 17ur/zxAQqqzKRGKJRVSXrdagunk+WHfBufsPmx8uR9GaiFPG6Vys5/h1oWlozli QA2uU6aQ9CZ9JYBY2ULOWgtFHmuqH/Dctw3vgUQHJy3qHZx1j08f2QY+d2KQQcdU KkSvxvT92G+VK3UjuP4FtWyyRsOfRj0liss5+jdkbIbQswLldxQ5YJo5yWgl+c3K yk9emeujr7fuY2lG/F6TD3UCpbcBlu6lvICRwHhUQPO+YS3AO9E= =uHI2 -----END PGP SIGNATURE----- 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
This commit is contained in:
Коммит
be2eca94d1
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
/*
|
||||
* Verify if message has proper ipmb header with minimum length
|
||||
* and correct checksum byte.
|
||||
*/
|
||||
static bool is_ipmb_msg(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;
|
||||
if ((ipmb_dev->msg_idx >= IPMB_REQUEST_LEN_MIN) &&
|
||||
(!ipmb_verify_checksum1(ipmb_dev, rs_sa)))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (!(ipmb_dev->request.netfn_rs_lun & NETFN_RSP_BIT_MASK))
|
||||
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;
|
||||
|
||||
|
|
|
@ -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,10 +3369,11 @@ 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,
|
||||
void *send_info,
|
||||
struct device *si_dev,
|
||||
unsigned char slave_addr)
|
||||
int ipmi_add_smi(struct module *owner,
|
||||
const struct ipmi_smi_handlers *handlers,
|
||||
void *send_info,
|
||||
struct device *si_dev,
|
||||
unsigned char slave_addr)
|
||||
{
|
||||
int i, j;
|
||||
int rv;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -224,10 +224,14 @@ 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,
|
||||
void *send_info,
|
||||
struct device *dev,
|
||||
unsigned char slave_addr);
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче