Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull IPMI update from Corey Minyard:
"Minor bug fixes for IPMI

I know this is late; I've been travelling and, well, I've been
distracted.

This is just a few bug fixes and adding i2c support to the IPMB
driver, which is something I wanted from the beginning for it"

* tag 'for-linus-5.6-1' of https://github.com/cminyard/linux-ipmi:
drivers: ipmi: fix off-by-one bounds check that leads to a out-of-bounds write
ipmi:ssif: Handle a possible NULL pointer reference
drivers: ipmi: Modify max length of IPMB packet
drivers: ipmi: Support raw i2c packet in IPMB

+42 -5
+4
Documentation/driver-api/ipmb.rst
··· 71 71 ipmb@10 { 72 72 compatible = "ipmb-dev"; 73 73 reg = <0x10>; 74 + i2c-protocol; 74 75 }; 75 76 }; 77 + 78 + If xmit of data to be done using raw i2c block vs smbus 79 + then "i2c-protocol" needs to be defined as above. 76 80 77 81 2) Manually from Linux:: 78 82
+31 -2
drivers/char/ipmi/ipmb_dev_int.c
··· 19 19 #include <linux/spinlock.h> 20 20 #include <linux/wait.h> 21 21 22 - #define MAX_MSG_LEN 128 22 + #define MAX_MSG_LEN 240 23 23 #define IPMB_REQUEST_LEN_MIN 7 24 24 #define NETFN_RSP_BIT_MASK 0x4 25 25 #define REQUEST_QUEUE_MAX_LEN 256 ··· 63 63 spinlock_t lock; 64 64 wait_queue_head_t wait_queue; 65 65 struct mutex file_mutex; 66 + bool is_i2c_protocol; 66 67 }; 67 68 68 69 static inline struct ipmb_dev *to_ipmb_dev(struct file *file) ··· 113 112 return ret < 0 ? ret : count; 114 113 } 115 114 115 + static int ipmb_i2c_write(struct i2c_client *client, u8 *msg, u8 addr) 116 + { 117 + struct i2c_msg i2c_msg; 118 + 119 + /* 120 + * subtract 1 byte (rq_sa) from the length of the msg passed to 121 + * raw i2c_transfer 122 + */ 123 + i2c_msg.len = msg[IPMB_MSG_LEN_IDX] - 1; 124 + 125 + /* Assign message to buffer except first 2 bytes (length and address) */ 126 + i2c_msg.buf = msg + 2; 127 + 128 + i2c_msg.addr = addr; 129 + i2c_msg.flags = client->flags & I2C_CLIENT_PEC; 130 + 131 + return i2c_transfer(client->adapter, &i2c_msg, 1); 132 + } 133 + 116 134 static ssize_t ipmb_write(struct file *file, const char __user *buf, 117 135 size_t count, loff_t *ppos) 118 136 { ··· 152 132 153 133 rq_sa = GET_7BIT_ADDR(msg[RQ_SA_8BIT_IDX]); 154 134 netf_rq_lun = msg[NETFN_LUN_IDX]; 135 + 136 + /* Check i2c block transfer vs smbus */ 137 + if (ipmb_dev->is_i2c_protocol) { 138 + ret = ipmb_i2c_write(ipmb_dev->client, msg, rq_sa); 139 + return (ret == 1) ? count : ret; 140 + } 155 141 156 142 /* 157 143 * subtract rq_sa and netf_rq_lun from the length of the msg passed to ··· 279 253 break; 280 254 281 255 case I2C_SLAVE_WRITE_RECEIVED: 282 - if (ipmb_dev->msg_idx >= sizeof(struct ipmb_msg)) 256 + if (ipmb_dev->msg_idx >= sizeof(struct ipmb_msg) - 1) 283 257 break; 284 258 285 259 buf[++ipmb_dev->msg_idx] = *val; ··· 327 301 ret = misc_register(&ipmb_dev->miscdev); 328 302 if (ret) 329 303 return ret; 304 + 305 + ipmb_dev->is_i2c_protocol 306 + = device_property_read_bool(&client->dev, "i2c-protocol"); 330 307 331 308 ipmb_dev->client = client; 332 309 i2c_set_clientdata(client, ipmb_dev);
+7 -3
drivers/char/ipmi/ipmi_ssif.c
··· 775 775 flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 776 776 msg = ssif_info->curr_msg; 777 777 if (msg) { 778 + if (data) { 779 + if (len > IPMI_MAX_MSG_LENGTH) 780 + len = IPMI_MAX_MSG_LENGTH; 781 + memcpy(msg->rsp, data, len); 782 + } else { 783 + len = 0; 784 + } 778 785 msg->rsp_size = len; 779 - if (msg->rsp_size > IPMI_MAX_MSG_LENGTH) 780 - msg->rsp_size = IPMI_MAX_MSG_LENGTH; 781 - memcpy(msg->rsp, data, msg->rsp_size); 782 786 ssif_info->curr_msg = NULL; 783 787 } 784 788