ipmb_dev
queue_elem = list_first_entry(&ipmb_dev->request_queue,
atomic_dec(&ipmb_dev->request_queue_len);
spin_unlock_irq(&ipmb_dev->lock);
struct ipmb_dev *ipmb_dev = to_ipmb_dev(file);
if (ipmb_dev->is_i2c_protocol) {
ret = ipmb_i2c_write(ipmb_dev->client, msg, rq_sa);
temp_client = kmemdup(ipmb_dev->client, sizeof(*temp_client), GFP_KERNEL);
struct ipmb_dev *ipmb_dev = to_ipmb_dev(file);
mutex_lock(&ipmb_dev->file_mutex);
poll_wait(file, &ipmb_dev->wait_queue, wait);
if (atomic_read(&ipmb_dev->request_queue_len))
mutex_unlock(&ipmb_dev->file_mutex);
static void ipmb_handle_request(struct ipmb_dev *ipmb_dev)
if (atomic_read(&ipmb_dev->request_queue_len) >=
memcpy(&queue_elem->request, &ipmb_dev->request,
list_add(&queue_elem->list, &ipmb_dev->request_queue);
atomic_inc(&ipmb_dev->request_queue_len);
wake_up_all(&ipmb_dev->wait_queue);
static u8 ipmb_verify_checksum1(struct ipmb_dev *ipmb_dev, u8 rs_sa)
return (rs_sa + ipmb_dev->request.netfn_rs_lun +
ipmb_dev->request.checksum1);
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)))
struct ipmb_dev *ipmb_dev = i2c_get_clientdata(client);
u8 *buf = (u8 *)&ipmb_dev->request;
spin_lock_irqsave(&ipmb_dev->lock, flags);
memset(&ipmb_dev->request, 0, sizeof(ipmb_dev->request));
ipmb_dev->msg_idx = 0;
buf[++ipmb_dev->msg_idx] = GET_8BIT_ADDR(client->addr);
if (ipmb_dev->msg_idx >= sizeof(struct ipmb_msg) - 1)
buf[++ipmb_dev->msg_idx] = *val;
ipmb_dev->request.len = ipmb_dev->msg_idx;
if (is_ipmb_msg(ipmb_dev, GET_8BIT_ADDR(client->addr)))
ipmb_handle_request(ipmb_dev);
spin_unlock_irqrestore(&ipmb_dev->lock, flags);
struct ipmb_dev *ipmb_dev;
ipmb_dev = devm_kzalloc(&client->dev, sizeof(*ipmb_dev),
if (!ipmb_dev)
spin_lock_init(&ipmb_dev->lock);
init_waitqueue_head(&ipmb_dev->wait_queue);
atomic_set(&ipmb_dev->request_queue_len, 0);
INIT_LIST_HEAD(&ipmb_dev->request_queue);
mutex_init(&ipmb_dev->file_mutex);
ipmb_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL,
if (!ipmb_dev->miscdev.name)
ipmb_dev->miscdev.fops = &ipmb_fops;
ipmb_dev->miscdev.parent = &client->dev;
ret = misc_register(&ipmb_dev->miscdev);
ipmb_dev->is_i2c_protocol
ipmb_dev->client = client;
i2c_set_clientdata(client, ipmb_dev);
misc_deregister(&ipmb_dev->miscdev);
struct ipmb_dev *ipmb_dev = i2c_get_clientdata(client);
misc_deregister(&ipmb_dev->miscdev);
static inline struct ipmb_dev *to_ipmb_dev(struct file *file)
return container_of(file->private_data, struct ipmb_dev, miscdev);
struct ipmb_dev *ipmb_dev = to_ipmb_dev(file);
spin_lock_irq(&ipmb_dev->lock);
while (list_empty(&ipmb_dev->request_queue)) {
spin_unlock_irq(&ipmb_dev->lock);
ret = wait_event_interruptible(ipmb_dev->wait_queue,
!list_empty(&ipmb_dev->request_queue));
spin_lock_irq(&ipmb_dev->lock);