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