xref: /openbmc/linux/drivers/char/ipmi/ipmi_devintf.c (revision d2574c33)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * ipmi_devintf.c
4  *
5  * Linux device interface for the IPMI message handler.
6  *
7  * Author: MontaVista Software, Inc.
8  *         Corey Minyard <minyard@mvista.com>
9  *         source@mvista.com
10  *
11  * Copyright 2002 MontaVista Software Inc.
12  */
13 
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/errno.h>
17 #include <linux/poll.h>
18 #include <linux/sched.h>
19 #include <linux/spinlock.h>
20 #include <linux/slab.h>
21 #include <linux/ipmi.h>
22 #include <linux/mutex.h>
23 #include <linux/init.h>
24 #include <linux/device.h>
25 #include <linux/compat.h>
26 
27 struct ipmi_file_private
28 {
29 	struct ipmi_user     *user;
30 	spinlock_t           recv_msg_lock;
31 	struct list_head     recv_msgs;
32 	struct file          *file;
33 	struct fasync_struct *fasync_queue;
34 	wait_queue_head_t    wait;
35 	struct mutex	     recv_mutex;
36 	int                  default_retries;
37 	unsigned int         default_retry_time_ms;
38 };
39 
40 static void file_receive_handler(struct ipmi_recv_msg *msg,
41 				 void                 *handler_data)
42 {
43 	struct ipmi_file_private *priv = handler_data;
44 	int                      was_empty;
45 	unsigned long            flags;
46 
47 	spin_lock_irqsave(&priv->recv_msg_lock, flags);
48 	was_empty = list_empty(&priv->recv_msgs);
49 	list_add_tail(&msg->link, &priv->recv_msgs);
50 	spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
51 
52 	if (was_empty) {
53 		wake_up_interruptible(&priv->wait);
54 		kill_fasync(&priv->fasync_queue, SIGIO, POLL_IN);
55 	}
56 }
57 
58 static __poll_t ipmi_poll(struct file *file, poll_table *wait)
59 {
60 	struct ipmi_file_private *priv = file->private_data;
61 	__poll_t             mask = 0;
62 	unsigned long            flags;
63 
64 	poll_wait(file, &priv->wait, wait);
65 
66 	spin_lock_irqsave(&priv->recv_msg_lock, flags);
67 
68 	if (!list_empty(&priv->recv_msgs))
69 		mask |= (EPOLLIN | EPOLLRDNORM);
70 
71 	spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
72 
73 	return mask;
74 }
75 
76 static int ipmi_fasync(int fd, struct file *file, int on)
77 {
78 	struct ipmi_file_private *priv = file->private_data;
79 
80 	return fasync_helper(fd, file, on, &priv->fasync_queue);
81 }
82 
83 static const struct ipmi_user_hndl ipmi_hndlrs =
84 {
85 	.ipmi_recv_hndl	= file_receive_handler,
86 };
87 
88 static int ipmi_open(struct inode *inode, struct file *file)
89 {
90 	int                      if_num = iminor(inode);
91 	int                      rv;
92 	struct ipmi_file_private *priv;
93 
94 	priv = kmalloc(sizeof(*priv), GFP_KERNEL);
95 	if (!priv)
96 		return -ENOMEM;
97 
98 	priv->file = file;
99 
100 	rv = ipmi_create_user(if_num,
101 			      &ipmi_hndlrs,
102 			      priv,
103 			      &priv->user);
104 	if (rv) {
105 		kfree(priv);
106 		goto out;
107 	}
108 
109 	file->private_data = priv;
110 
111 	spin_lock_init(&priv->recv_msg_lock);
112 	INIT_LIST_HEAD(&priv->recv_msgs);
113 	init_waitqueue_head(&priv->wait);
114 	priv->fasync_queue = NULL;
115 	mutex_init(&priv->recv_mutex);
116 
117 	/* Use the low-level defaults. */
118 	priv->default_retries = -1;
119 	priv->default_retry_time_ms = 0;
120 
121 out:
122 	return rv;
123 }
124 
125 static int ipmi_release(struct inode *inode, struct file *file)
126 {
127 	struct ipmi_file_private *priv = file->private_data;
128 	int                      rv;
129 	struct ipmi_recv_msg *msg, *next;
130 
131 	rv = ipmi_destroy_user(priv->user);
132 	if (rv)
133 		return rv;
134 
135 	list_for_each_entry_safe(msg, next, &priv->recv_msgs, link)
136 		ipmi_free_recv_msg(msg);
137 
138 	kfree(priv);
139 
140 	return 0;
141 }
142 
143 static int handle_send_req(struct ipmi_user *user,
144 			   struct ipmi_req *req,
145 			   int             retries,
146 			   unsigned int    retry_time_ms)
147 {
148 	int              rv;
149 	struct ipmi_addr addr;
150 	struct kernel_ipmi_msg msg;
151 
152 	if (req->addr_len > sizeof(struct ipmi_addr))
153 		return -EINVAL;
154 
155 	if (copy_from_user(&addr, req->addr, req->addr_len))
156 		return -EFAULT;
157 
158 	msg.netfn = req->msg.netfn;
159 	msg.cmd = req->msg.cmd;
160 	msg.data_len = req->msg.data_len;
161 	msg.data = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
162 	if (!msg.data)
163 		return -ENOMEM;
164 
165 	/* From here out we cannot return, we must jump to "out" for
166 	   error exits to free msgdata. */
167 
168 	rv = ipmi_validate_addr(&addr, req->addr_len);
169 	if (rv)
170 		goto out;
171 
172 	if (req->msg.data != NULL) {
173 		if (req->msg.data_len > IPMI_MAX_MSG_LENGTH) {
174 			rv = -EMSGSIZE;
175 			goto out;
176 		}
177 
178 		if (copy_from_user(msg.data,
179 				   req->msg.data,
180 				   req->msg.data_len)) {
181 			rv = -EFAULT;
182 			goto out;
183 		}
184 	} else {
185 		msg.data_len = 0;
186 	}
187 
188 	rv = ipmi_request_settime(user,
189 				  &addr,
190 				  req->msgid,
191 				  &msg,
192 				  NULL,
193 				  0,
194 				  retries,
195 				  retry_time_ms);
196  out:
197 	kfree(msg.data);
198 	return rv;
199 }
200 
201 static int handle_recv(struct ipmi_file_private *priv,
202 			bool trunc, struct ipmi_recv *rsp,
203 			int (*copyout)(struct ipmi_recv *, void __user *),
204 			void __user *to)
205 {
206 	int              addr_len;
207 	struct list_head *entry;
208 	struct ipmi_recv_msg  *msg;
209 	unsigned long    flags;
210 	int rv = 0, rv2 = 0;
211 
212 	/* We claim a mutex because we don't want two
213 	   users getting something from the queue at a time.
214 	   Since we have to release the spinlock before we can
215 	   copy the data to the user, it's possible another
216 	   user will grab something from the queue, too.  Then
217 	   the messages might get out of order if something
218 	   fails and the message gets put back onto the
219 	   queue.  This mutex prevents that problem. */
220 	mutex_lock(&priv->recv_mutex);
221 
222 	/* Grab the message off the list. */
223 	spin_lock_irqsave(&priv->recv_msg_lock, flags);
224 	if (list_empty(&(priv->recv_msgs))) {
225 		spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
226 		rv = -EAGAIN;
227 		goto recv_err;
228 	}
229 	entry = priv->recv_msgs.next;
230 	msg = list_entry(entry, struct ipmi_recv_msg, link);
231 	list_del(entry);
232 	spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
233 
234 	addr_len = ipmi_addr_length(msg->addr.addr_type);
235 	if (rsp->addr_len < addr_len) {
236 		rv = -EINVAL;
237 		goto recv_putback_on_err;
238 	}
239 
240 	if (copy_to_user(rsp->addr, &msg->addr, addr_len)) {
241 		rv = -EFAULT;
242 		goto recv_putback_on_err;
243 	}
244 	rsp->addr_len = addr_len;
245 
246 	rsp->recv_type = msg->recv_type;
247 	rsp->msgid = msg->msgid;
248 	rsp->msg.netfn = msg->msg.netfn;
249 	rsp->msg.cmd = msg->msg.cmd;
250 
251 	if (msg->msg.data_len > 0) {
252 		if (rsp->msg.data_len < msg->msg.data_len) {
253 			rv2 = -EMSGSIZE;
254 			if (trunc)
255 				msg->msg.data_len = rsp->msg.data_len;
256 			else
257 				goto recv_putback_on_err;
258 		}
259 
260 		if (copy_to_user(rsp->msg.data,
261 				 msg->msg.data,
262 				 msg->msg.data_len)) {
263 			rv = -EFAULT;
264 			goto recv_putback_on_err;
265 		}
266 		rsp->msg.data_len = msg->msg.data_len;
267 	} else {
268 		rsp->msg.data_len = 0;
269 	}
270 
271 	rv = copyout(rsp, to);
272 	if (rv)
273 		goto recv_putback_on_err;
274 
275 	mutex_unlock(&priv->recv_mutex);
276 	ipmi_free_recv_msg(msg);
277 	return rv2;
278 
279 recv_putback_on_err:
280 	/* If we got an error, put the message back onto
281 	   the head of the queue. */
282 	spin_lock_irqsave(&priv->recv_msg_lock, flags);
283 	list_add(entry, &priv->recv_msgs);
284 	spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
285 recv_err:
286 	mutex_unlock(&priv->recv_mutex);
287 	return rv;
288 }
289 
290 static int copyout_recv(struct ipmi_recv *rsp, void __user *to)
291 {
292 	return copy_to_user(to, rsp, sizeof(struct ipmi_recv)) ? -EFAULT : 0;
293 }
294 
295 static long ipmi_ioctl(struct file   *file,
296 		       unsigned int  cmd,
297 		       unsigned long data)
298 {
299 	int                      rv = -EINVAL;
300 	struct ipmi_file_private *priv = file->private_data;
301 	void __user *arg = (void __user *)data;
302 
303 	switch (cmd)
304 	{
305 	case IPMICTL_SEND_COMMAND:
306 	{
307 		struct ipmi_req req;
308 		int retries;
309 		unsigned int retry_time_ms;
310 
311 		if (copy_from_user(&req, arg, sizeof(req))) {
312 			rv = -EFAULT;
313 			break;
314 		}
315 
316 		mutex_lock(&priv->recv_mutex);
317 		retries = priv->default_retries;
318 		retry_time_ms = priv->default_retry_time_ms;
319 		mutex_unlock(&priv->recv_mutex);
320 
321 		rv = handle_send_req(priv->user, &req, retries, retry_time_ms);
322 		break;
323 	}
324 
325 	case IPMICTL_SEND_COMMAND_SETTIME:
326 	{
327 		struct ipmi_req_settime req;
328 
329 		if (copy_from_user(&req, arg, sizeof(req))) {
330 			rv = -EFAULT;
331 			break;
332 		}
333 
334 		rv = handle_send_req(priv->user,
335 				     &req.req,
336 				     req.retries,
337 				     req.retry_time_ms);
338 		break;
339 	}
340 
341 	case IPMICTL_RECEIVE_MSG:
342 	case IPMICTL_RECEIVE_MSG_TRUNC:
343 	{
344 		struct ipmi_recv      rsp;
345 
346 		if (copy_from_user(&rsp, arg, sizeof(rsp)))
347 			rv = -EFAULT;
348 		else
349 			rv = handle_recv(priv, cmd == IPMICTL_RECEIVE_MSG_TRUNC,
350 					 &rsp, copyout_recv, arg);
351 		break;
352 	}
353 
354 	case IPMICTL_REGISTER_FOR_CMD:
355 	{
356 		struct ipmi_cmdspec val;
357 
358 		if (copy_from_user(&val, arg, sizeof(val))) {
359 			rv = -EFAULT;
360 			break;
361 		}
362 
363 		rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
364 					   IPMI_CHAN_ALL);
365 		break;
366 	}
367 
368 	case IPMICTL_UNREGISTER_FOR_CMD:
369 	{
370 		struct ipmi_cmdspec   val;
371 
372 		if (copy_from_user(&val, arg, sizeof(val))) {
373 			rv = -EFAULT;
374 			break;
375 		}
376 
377 		rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
378 					     IPMI_CHAN_ALL);
379 		break;
380 	}
381 
382 	case IPMICTL_REGISTER_FOR_CMD_CHANS:
383 	{
384 		struct ipmi_cmdspec_chans val;
385 
386 		if (copy_from_user(&val, arg, sizeof(val))) {
387 			rv = -EFAULT;
388 			break;
389 		}
390 
391 		rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
392 					   val.chans);
393 		break;
394 	}
395 
396 	case IPMICTL_UNREGISTER_FOR_CMD_CHANS:
397 	{
398 		struct ipmi_cmdspec_chans val;
399 
400 		if (copy_from_user(&val, arg, sizeof(val))) {
401 			rv = -EFAULT;
402 			break;
403 		}
404 
405 		rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
406 					     val.chans);
407 		break;
408 	}
409 
410 	case IPMICTL_SET_GETS_EVENTS_CMD:
411 	{
412 		int val;
413 
414 		if (copy_from_user(&val, arg, sizeof(val))) {
415 			rv = -EFAULT;
416 			break;
417 		}
418 
419 		rv = ipmi_set_gets_events(priv->user, val);
420 		break;
421 	}
422 
423 	/* The next four are legacy, not per-channel. */
424 	case IPMICTL_SET_MY_ADDRESS_CMD:
425 	{
426 		unsigned int val;
427 
428 		if (copy_from_user(&val, arg, sizeof(val))) {
429 			rv = -EFAULT;
430 			break;
431 		}
432 
433 		rv = ipmi_set_my_address(priv->user, 0, val);
434 		break;
435 	}
436 
437 	case IPMICTL_GET_MY_ADDRESS_CMD:
438 	{
439 		unsigned int  val;
440 		unsigned char rval;
441 
442 		rv = ipmi_get_my_address(priv->user, 0, &rval);
443 		if (rv)
444 			break;
445 
446 		val = rval;
447 
448 		if (copy_to_user(arg, &val, sizeof(val))) {
449 			rv = -EFAULT;
450 			break;
451 		}
452 		break;
453 	}
454 
455 	case IPMICTL_SET_MY_LUN_CMD:
456 	{
457 		unsigned int val;
458 
459 		if (copy_from_user(&val, arg, sizeof(val))) {
460 			rv = -EFAULT;
461 			break;
462 		}
463 
464 		rv = ipmi_set_my_LUN(priv->user, 0, val);
465 		break;
466 	}
467 
468 	case IPMICTL_GET_MY_LUN_CMD:
469 	{
470 		unsigned int  val;
471 		unsigned char rval;
472 
473 		rv = ipmi_get_my_LUN(priv->user, 0, &rval);
474 		if (rv)
475 			break;
476 
477 		val = rval;
478 
479 		if (copy_to_user(arg, &val, sizeof(val))) {
480 			rv = -EFAULT;
481 			break;
482 		}
483 		break;
484 	}
485 
486 	case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD:
487 	{
488 		struct ipmi_channel_lun_address_set val;
489 
490 		if (copy_from_user(&val, arg, sizeof(val))) {
491 			rv = -EFAULT;
492 			break;
493 		}
494 
495 		return ipmi_set_my_address(priv->user, val.channel, val.value);
496 		break;
497 	}
498 
499 	case IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD:
500 	{
501 		struct ipmi_channel_lun_address_set val;
502 
503 		if (copy_from_user(&val, arg, sizeof(val))) {
504 			rv = -EFAULT;
505 			break;
506 		}
507 
508 		rv = ipmi_get_my_address(priv->user, val.channel, &val.value);
509 		if (rv)
510 			break;
511 
512 		if (copy_to_user(arg, &val, sizeof(val))) {
513 			rv = -EFAULT;
514 			break;
515 		}
516 		break;
517 	}
518 
519 	case IPMICTL_SET_MY_CHANNEL_LUN_CMD:
520 	{
521 		struct ipmi_channel_lun_address_set val;
522 
523 		if (copy_from_user(&val, arg, sizeof(val))) {
524 			rv = -EFAULT;
525 			break;
526 		}
527 
528 		rv = ipmi_set_my_LUN(priv->user, val.channel, val.value);
529 		break;
530 	}
531 
532 	case IPMICTL_GET_MY_CHANNEL_LUN_CMD:
533 	{
534 		struct ipmi_channel_lun_address_set val;
535 
536 		if (copy_from_user(&val, arg, sizeof(val))) {
537 			rv = -EFAULT;
538 			break;
539 		}
540 
541 		rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value);
542 		if (rv)
543 			break;
544 
545 		if (copy_to_user(arg, &val, sizeof(val))) {
546 			rv = -EFAULT;
547 			break;
548 		}
549 		break;
550 	}
551 
552 	case IPMICTL_SET_TIMING_PARMS_CMD:
553 	{
554 		struct ipmi_timing_parms parms;
555 
556 		if (copy_from_user(&parms, arg, sizeof(parms))) {
557 			rv = -EFAULT;
558 			break;
559 		}
560 
561 		mutex_lock(&priv->recv_mutex);
562 		priv->default_retries = parms.retries;
563 		priv->default_retry_time_ms = parms.retry_time_ms;
564 		mutex_unlock(&priv->recv_mutex);
565 		rv = 0;
566 		break;
567 	}
568 
569 	case IPMICTL_GET_TIMING_PARMS_CMD:
570 	{
571 		struct ipmi_timing_parms parms;
572 
573 		mutex_lock(&priv->recv_mutex);
574 		parms.retries = priv->default_retries;
575 		parms.retry_time_ms = priv->default_retry_time_ms;
576 		mutex_unlock(&priv->recv_mutex);
577 
578 		if (copy_to_user(arg, &parms, sizeof(parms))) {
579 			rv = -EFAULT;
580 			break;
581 		}
582 
583 		rv = 0;
584 		break;
585 	}
586 
587 	case IPMICTL_GET_MAINTENANCE_MODE_CMD:
588 	{
589 		int mode;
590 
591 		mode = ipmi_get_maintenance_mode(priv->user);
592 		if (copy_to_user(arg, &mode, sizeof(mode))) {
593 			rv = -EFAULT;
594 			break;
595 		}
596 		rv = 0;
597 		break;
598 	}
599 
600 	case IPMICTL_SET_MAINTENANCE_MODE_CMD:
601 	{
602 		int mode;
603 
604 		if (copy_from_user(&mode, arg, sizeof(mode))) {
605 			rv = -EFAULT;
606 			break;
607 		}
608 		rv = ipmi_set_maintenance_mode(priv->user, mode);
609 		break;
610 	}
611 
612 	default:
613 		rv = -ENOTTY;
614 		break;
615 	}
616 
617 	return rv;
618 }
619 
620 #ifdef CONFIG_COMPAT
621 /*
622  * The following code contains code for supporting 32-bit compatible
623  * ioctls on 64-bit kernels.  This allows running 32-bit apps on the
624  * 64-bit kernel
625  */
626 #define COMPAT_IPMICTL_SEND_COMMAND	\
627 	_IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
628 #define COMPAT_IPMICTL_SEND_COMMAND_SETTIME	\
629 	_IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
630 #define COMPAT_IPMICTL_RECEIVE_MSG	\
631 	_IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
632 #define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC	\
633 	_IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
634 
635 struct compat_ipmi_msg {
636 	u8		netfn;
637 	u8		cmd;
638 	u16		data_len;
639 	compat_uptr_t	data;
640 };
641 
642 struct compat_ipmi_req {
643 	compat_uptr_t		addr;
644 	compat_uint_t		addr_len;
645 	compat_long_t		msgid;
646 	struct compat_ipmi_msg	msg;
647 };
648 
649 struct compat_ipmi_recv {
650 	compat_int_t		recv_type;
651 	compat_uptr_t		addr;
652 	compat_uint_t		addr_len;
653 	compat_long_t		msgid;
654 	struct compat_ipmi_msg	msg;
655 };
656 
657 struct compat_ipmi_req_settime {
658 	struct compat_ipmi_req	req;
659 	compat_int_t		retries;
660 	compat_uint_t		retry_time_ms;
661 };
662 
663 /*
664  * Define some helper functions for copying IPMI data
665  */
666 static void get_compat_ipmi_msg(struct ipmi_msg *p64,
667 				struct compat_ipmi_msg *p32)
668 {
669 	p64->netfn = p32->netfn;
670 	p64->cmd = p32->cmd;
671 	p64->data_len = p32->data_len;
672 	p64->data = compat_ptr(p32->data);
673 }
674 
675 static void get_compat_ipmi_req(struct ipmi_req *p64,
676 				struct compat_ipmi_req *p32)
677 {
678 	p64->addr = compat_ptr(p32->addr);
679 	p64->addr_len = p32->addr_len;
680 	p64->msgid = p32->msgid;
681 	get_compat_ipmi_msg(&p64->msg, &p32->msg);
682 }
683 
684 static void get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
685 		struct compat_ipmi_req_settime *p32)
686 {
687 	get_compat_ipmi_req(&p64->req, &p32->req);
688 	p64->retries = p32->retries;
689 	p64->retry_time_ms = p32->retry_time_ms;
690 }
691 
692 static void get_compat_ipmi_recv(struct ipmi_recv *p64,
693 				 struct compat_ipmi_recv *p32)
694 {
695 	memset(p64, 0, sizeof(struct ipmi_recv));
696 	p64->recv_type = p32->recv_type;
697 	p64->addr = compat_ptr(p32->addr);
698 	p64->addr_len = p32->addr_len;
699 	p64->msgid = p32->msgid;
700 	get_compat_ipmi_msg(&p64->msg, &p32->msg);
701 }
702 
703 static int copyout_recv32(struct ipmi_recv *p64, void __user *to)
704 {
705 	struct compat_ipmi_recv v32;
706 	memset(&v32, 0, sizeof(struct compat_ipmi_recv));
707 	v32.recv_type = p64->recv_type;
708 	v32.addr = ptr_to_compat(p64->addr);
709 	v32.addr_len = p64->addr_len;
710 	v32.msgid = p64->msgid;
711 	v32.msg.netfn = p64->msg.netfn;
712 	v32.msg.cmd = p64->msg.cmd;
713 	v32.msg.data_len = p64->msg.data_len;
714 	v32.msg.data = ptr_to_compat(p64->msg.data);
715 	return copy_to_user(to, &v32, sizeof(v32)) ? -EFAULT : 0;
716 }
717 
718 /*
719  * Handle compatibility ioctls
720  */
721 static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
722 			      unsigned long arg)
723 {
724 	struct ipmi_file_private *priv = filep->private_data;
725 
726 	switch(cmd) {
727 	case COMPAT_IPMICTL_SEND_COMMAND:
728 	{
729 		struct ipmi_req	rp;
730 		struct compat_ipmi_req r32;
731 		int retries;
732 		unsigned int retry_time_ms;
733 
734 		if (copy_from_user(&r32, compat_ptr(arg), sizeof(r32)))
735 			return -EFAULT;
736 
737 		get_compat_ipmi_req(&rp, &r32);
738 
739 		mutex_lock(&priv->recv_mutex);
740 		retries = priv->default_retries;
741 		retry_time_ms = priv->default_retry_time_ms;
742 		mutex_unlock(&priv->recv_mutex);
743 
744 		return handle_send_req(priv->user, &rp,
745 				       retries, retry_time_ms);
746 	}
747 	case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
748 	{
749 		struct ipmi_req_settime	sp;
750 		struct compat_ipmi_req_settime sp32;
751 
752 		if (copy_from_user(&sp32, compat_ptr(arg), sizeof(sp32)))
753 			return -EFAULT;
754 
755 		get_compat_ipmi_req_settime(&sp, &sp32);
756 
757 		return handle_send_req(priv->user, &sp.req,
758 				sp.retries, sp.retry_time_ms);
759 	}
760 	case COMPAT_IPMICTL_RECEIVE_MSG:
761 	case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
762 	{
763 		struct ipmi_recv   recv64;
764 		struct compat_ipmi_recv recv32;
765 
766 		if (copy_from_user(&recv32, compat_ptr(arg), sizeof(recv32)))
767 			return -EFAULT;
768 
769 		get_compat_ipmi_recv(&recv64, &recv32);
770 
771 		return handle_recv(priv,
772 				 cmd == COMPAT_IPMICTL_RECEIVE_MSG_TRUNC,
773 				 &recv64, copyout_recv32, compat_ptr(arg));
774 	}
775 	default:
776 		return ipmi_ioctl(filep, cmd, arg);
777 	}
778 }
779 #endif
780 
781 static const struct file_operations ipmi_fops = {
782 	.owner		= THIS_MODULE,
783 	.unlocked_ioctl	= ipmi_ioctl,
784 #ifdef CONFIG_COMPAT
785 	.compat_ioctl   = compat_ipmi_ioctl,
786 #endif
787 	.open		= ipmi_open,
788 	.release	= ipmi_release,
789 	.fasync		= ipmi_fasync,
790 	.poll		= ipmi_poll,
791 	.llseek		= noop_llseek,
792 };
793 
794 #define DEVICE_NAME     "ipmidev"
795 
796 static int ipmi_major;
797 module_param(ipmi_major, int, 0);
798 MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"
799 		 " default, or if you set it to zero, it will choose the next"
800 		 " available device.  Setting it to -1 will disable the"
801 		 " interface.  Other values will set the major device number"
802 		 " to that value.");
803 
804 /* Keep track of the devices that are registered. */
805 struct ipmi_reg_list {
806 	dev_t            dev;
807 	struct list_head link;
808 };
809 static LIST_HEAD(reg_list);
810 static DEFINE_MUTEX(reg_list_mutex);
811 
812 static struct class *ipmi_class;
813 
814 static void ipmi_new_smi(int if_num, struct device *device)
815 {
816 	dev_t dev = MKDEV(ipmi_major, if_num);
817 	struct ipmi_reg_list *entry;
818 
819 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
820 	if (!entry) {
821 		pr_err("ipmi_devintf: Unable to create the ipmi class device link\n");
822 		return;
823 	}
824 	entry->dev = dev;
825 
826 	mutex_lock(&reg_list_mutex);
827 	device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
828 	list_add(&entry->link, &reg_list);
829 	mutex_unlock(&reg_list_mutex);
830 }
831 
832 static void ipmi_smi_gone(int if_num)
833 {
834 	dev_t dev = MKDEV(ipmi_major, if_num);
835 	struct ipmi_reg_list *entry;
836 
837 	mutex_lock(&reg_list_mutex);
838 	list_for_each_entry(entry, &reg_list, link) {
839 		if (entry->dev == dev) {
840 			list_del(&entry->link);
841 			kfree(entry);
842 			break;
843 		}
844 	}
845 	device_destroy(ipmi_class, dev);
846 	mutex_unlock(&reg_list_mutex);
847 }
848 
849 static struct ipmi_smi_watcher smi_watcher =
850 {
851 	.owner    = THIS_MODULE,
852 	.new_smi  = ipmi_new_smi,
853 	.smi_gone = ipmi_smi_gone,
854 };
855 
856 static int __init init_ipmi_devintf(void)
857 {
858 	int rv;
859 
860 	if (ipmi_major < 0)
861 		return -EINVAL;
862 
863 	pr_info("ipmi device interface\n");
864 
865 	ipmi_class = class_create(THIS_MODULE, "ipmi");
866 	if (IS_ERR(ipmi_class)) {
867 		pr_err("ipmi: can't register device class\n");
868 		return PTR_ERR(ipmi_class);
869 	}
870 
871 	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
872 	if (rv < 0) {
873 		class_destroy(ipmi_class);
874 		pr_err("ipmi: can't get major %d\n", ipmi_major);
875 		return rv;
876 	}
877 
878 	if (ipmi_major == 0) {
879 		ipmi_major = rv;
880 	}
881 
882 	rv = ipmi_smi_watcher_register(&smi_watcher);
883 	if (rv) {
884 		unregister_chrdev(ipmi_major, DEVICE_NAME);
885 		class_destroy(ipmi_class);
886 		pr_warn("ipmi: can't register smi watcher\n");
887 		return rv;
888 	}
889 
890 	return 0;
891 }
892 module_init(init_ipmi_devintf);
893 
894 static void __exit cleanup_ipmi(void)
895 {
896 	struct ipmi_reg_list *entry, *entry2;
897 	mutex_lock(&reg_list_mutex);
898 	list_for_each_entry_safe(entry, entry2, &reg_list, link) {
899 		list_del(&entry->link);
900 		device_destroy(ipmi_class, entry->dev);
901 		kfree(entry);
902 	}
903 	mutex_unlock(&reg_list_mutex);
904 	class_destroy(ipmi_class);
905 	ipmi_smi_watcher_unregister(&smi_watcher);
906 	unregister_chrdev(ipmi_major, DEVICE_NAME);
907 }
908 module_exit(cleanup_ipmi);
909 
910 MODULE_LICENSE("GPL");
911 MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
912 MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
913