Lines Matching +full:ipmi +full:- +full:bt

1 // SPDX-License-Identifier: GPL-2.0
8 * This was inspired by Brendan Higgins' ipmi-bmc-bt-i2c driver.
34 #define IPMB_MSG_PAYLOAD_LEN_MAX (MAX_MSG_LEN - IPMB_REQUEST_LEN_MIN - 1)
71 return container_of(file->private_data, struct ipmb_dev, miscdev); in to_ipmb_dev()
84 spin_lock_irq(&ipmb_dev->lock); in ipmb_read()
86 while (list_empty(&ipmb_dev->request_queue)) { in ipmb_read()
87 spin_unlock_irq(&ipmb_dev->lock); in ipmb_read()
89 if (file->f_flags & O_NONBLOCK) in ipmb_read()
90 return -EAGAIN; in ipmb_read()
92 ret = wait_event_interruptible(ipmb_dev->wait_queue, in ipmb_read()
93 !list_empty(&ipmb_dev->request_queue)); in ipmb_read()
97 spin_lock_irq(&ipmb_dev->lock); in ipmb_read()
100 queue_elem = list_first_entry(&ipmb_dev->request_queue, in ipmb_read()
102 memcpy(&msg, &queue_elem->request, sizeof(msg)); in ipmb_read()
103 list_del(&queue_elem->list); in ipmb_read()
105 atomic_dec(&ipmb_dev->request_queue_len); in ipmb_read()
107 spin_unlock_irq(&ipmb_dev->lock); in ipmb_read()
111 ret = -EFAULT; in ipmb_read()
124 i2c_msg.len = msg[IPMB_MSG_LEN_IDX] - 1; in ipmb_i2c_write()
130 i2c_msg.flags = client->flags & I2C_CLIENT_PEC; in ipmb_i2c_write()
132 return i2c_transfer(client->adapter, &i2c_msg, 1); in ipmb_i2c_write()
145 return -EINVAL; in ipmb_write()
148 return -EFAULT; in ipmb_write()
151 return -EINVAL; in ipmb_write()
157 if (ipmb_dev->is_i2c_protocol) { in ipmb_write()
158 ret = ipmb_i2c_write(ipmb_dev->client, msg, rq_sa); in ipmb_write()
164 * temporary client. Note that its use is an exception for IPMI. in ipmb_write()
166 msg_len = msg[IPMB_MSG_LEN_IDX] - SMBUS_MSG_HEADER_LENGTH; in ipmb_write()
167 temp_client = kmemdup(ipmb_dev->client, sizeof(*temp_client), GFP_KERNEL); in ipmb_write()
169 return -ENOMEM; in ipmb_write()
171 temp_client->addr = rq_sa; in ipmb_write()
185 mutex_lock(&ipmb_dev->file_mutex); in ipmb_poll()
186 poll_wait(file, &ipmb_dev->wait_queue, wait); in ipmb_poll()
188 if (atomic_read(&ipmb_dev->request_queue_len)) in ipmb_poll()
190 mutex_unlock(&ipmb_dev->file_mutex); in ipmb_poll()
202 /* Called with ipmb_dev->lock held. */
207 if (atomic_read(&ipmb_dev->request_queue_len) >= in ipmb_handle_request()
215 memcpy(&queue_elem->request, &ipmb_dev->request, in ipmb_handle_request()
217 list_add(&queue_elem->list, &ipmb_dev->request_queue); in ipmb_handle_request()
218 atomic_inc(&ipmb_dev->request_queue_len); in ipmb_handle_request()
219 wake_up_all(&ipmb_dev->wait_queue); in ipmb_handle_request()
225 return (rs_sa + ipmb_dev->request.netfn_rs_lun + in ipmb_verify_checksum1()
226 ipmb_dev->request.checksum1); in ipmb_verify_checksum1()
235 if ((ipmb_dev->msg_idx >= IPMB_REQUEST_LEN_MIN) && in is_ipmb_msg()
253 u8 *buf = (u8 *)&ipmb_dev->request; in ipmb_slave_cb()
256 spin_lock_irqsave(&ipmb_dev->lock, flags); in ipmb_slave_cb()
259 memset(&ipmb_dev->request, 0, sizeof(ipmb_dev->request)); in ipmb_slave_cb()
260 ipmb_dev->msg_idx = 0; in ipmb_slave_cb()
278 buf[++ipmb_dev->msg_idx] = GET_8BIT_ADDR(client->addr); in ipmb_slave_cb()
282 if (ipmb_dev->msg_idx >= sizeof(struct ipmb_msg) - 1) in ipmb_slave_cb()
285 buf[++ipmb_dev->msg_idx] = *val; in ipmb_slave_cb()
289 ipmb_dev->request.len = ipmb_dev->msg_idx; in ipmb_slave_cb()
290 if (is_ipmb_msg(ipmb_dev, GET_8BIT_ADDR(client->addr))) in ipmb_slave_cb()
297 spin_unlock_irqrestore(&ipmb_dev->lock, flags); in ipmb_slave_cb()
307 ipmb_dev = devm_kzalloc(&client->dev, sizeof(*ipmb_dev), in ipmb_probe()
310 return -ENOMEM; in ipmb_probe()
312 spin_lock_init(&ipmb_dev->lock); in ipmb_probe()
313 init_waitqueue_head(&ipmb_dev->wait_queue); in ipmb_probe()
314 atomic_set(&ipmb_dev->request_queue_len, 0); in ipmb_probe()
315 INIT_LIST_HEAD(&ipmb_dev->request_queue); in ipmb_probe()
317 mutex_init(&ipmb_dev->file_mutex); in ipmb_probe()
319 ipmb_dev->miscdev.minor = MISC_DYNAMIC_MINOR; in ipmb_probe()
321 ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL, in ipmb_probe()
322 "%s%d", "ipmb-", in ipmb_probe()
323 client->adapter->nr); in ipmb_probe()
324 if (!ipmb_dev->miscdev.name) in ipmb_probe()
325 return -ENOMEM; in ipmb_probe()
327 ipmb_dev->miscdev.fops = &ipmb_fops; in ipmb_probe()
328 ipmb_dev->miscdev.parent = &client->dev; in ipmb_probe()
329 ret = misc_register(&ipmb_dev->miscdev); in ipmb_probe()
333 ipmb_dev->is_i2c_protocol in ipmb_probe()
334 = device_property_read_bool(&client->dev, "i2c-protocol"); in ipmb_probe()
336 ipmb_dev->client = client; in ipmb_probe()
340 misc_deregister(&ipmb_dev->miscdev); in ipmb_probe()
352 misc_deregister(&ipmb_dev->miscdev); in ipmb_remove()
356 { "ipmb-dev" },
371 .name = "ipmb-dev",