xref: /openbmc/linux/drivers/char/ipmi/ipmi_devintf.c (revision 7fe2f639)
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 
48 struct ipmi_file_private
49 {
50 	ipmi_user_t          user;
51 	spinlock_t           recv_msg_lock;
52 	struct list_head     recv_msgs;
53 	struct file          *file;
54 	struct fasync_struct *fasync_queue;
55 	wait_queue_head_t    wait;
56 	struct mutex	     recv_mutex;
57 	int                  default_retries;
58 	unsigned int         default_retry_time_ms;
59 };
60 
61 static DEFINE_MUTEX(ipmi_mutex);
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 	mutex_lock(&ipmi_mutex); /* could race against open() otherwise */
106 	result = fasync_helper(fd, file, on, &priv->fasync_queue);
107 	mutex_unlock(&ipmi_mutex);
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 	mutex_lock(&ipmi_mutex);
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 	mutex_unlock(&ipmi_mutex);
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 file   *file,
232 		      unsigned int  cmd,
233 		      unsigned long data)
234 {
235 	int                      rv = -EINVAL;
236 	struct ipmi_file_private *priv = file->private_data;
237 	void __user *arg = (void __user *)data;
238 
239 	switch (cmd)
240 	{
241 	case IPMICTL_SEND_COMMAND:
242 	{
243 		struct ipmi_req req;
244 
245 		if (copy_from_user(&req, arg, sizeof(req))) {
246 			rv = -EFAULT;
247 			break;
248 		}
249 
250 		rv = handle_send_req(priv->user,
251 				     &req,
252 				     priv->default_retries,
253 				     priv->default_retry_time_ms);
254 		break;
255 	}
256 
257 	case IPMICTL_SEND_COMMAND_SETTIME:
258 	{
259 		struct ipmi_req_settime req;
260 
261 		if (copy_from_user(&req, arg, sizeof(req))) {
262 			rv = -EFAULT;
263 			break;
264 		}
265 
266 		rv = handle_send_req(priv->user,
267 				     &req.req,
268 				     req.retries,
269 				     req.retry_time_ms);
270 		break;
271 	}
272 
273 	case IPMICTL_RECEIVE_MSG:
274 	case IPMICTL_RECEIVE_MSG_TRUNC:
275 	{
276 		struct ipmi_recv      rsp;
277 		int              addr_len;
278 		struct list_head *entry;
279 		struct ipmi_recv_msg  *msg;
280 		unsigned long    flags;
281 
282 
283 		rv = 0;
284 		if (copy_from_user(&rsp, arg, sizeof(rsp))) {
285 			rv = -EFAULT;
286 			break;
287 		}
288 
289 		/* We claim a mutex because we don't want two
290                    users getting something from the queue at a time.
291                    Since we have to release the spinlock before we can
292                    copy the data to the user, it's possible another
293                    user will grab something from the queue, too.  Then
294                    the messages might get out of order if something
295                    fails and the message gets put back onto the
296                    queue.  This mutex prevents that problem. */
297 		mutex_lock(&priv->recv_mutex);
298 
299 		/* Grab the message off the list. */
300 		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
301 		if (list_empty(&(priv->recv_msgs))) {
302 			spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
303 			rv = -EAGAIN;
304 			goto recv_err;
305 		}
306 		entry = priv->recv_msgs.next;
307 		msg = list_entry(entry, struct ipmi_recv_msg, link);
308 		list_del(entry);
309 		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
310 
311 		addr_len = ipmi_addr_length(msg->addr.addr_type);
312 		if (rsp.addr_len < addr_len)
313 		{
314 			rv = -EINVAL;
315 			goto recv_putback_on_err;
316 		}
317 
318 		if (copy_to_user(rsp.addr, &(msg->addr), addr_len)) {
319 			rv = -EFAULT;
320 			goto recv_putback_on_err;
321 		}
322 		rsp.addr_len = addr_len;
323 
324 		rsp.recv_type = msg->recv_type;
325 		rsp.msgid = msg->msgid;
326 		rsp.msg.netfn = msg->msg.netfn;
327 		rsp.msg.cmd = msg->msg.cmd;
328 
329 		if (msg->msg.data_len > 0) {
330 			if (rsp.msg.data_len < msg->msg.data_len) {
331 				rv = -EMSGSIZE;
332 				if (cmd == IPMICTL_RECEIVE_MSG_TRUNC) {
333 					msg->msg.data_len = rsp.msg.data_len;
334 				} else {
335 					goto recv_putback_on_err;
336 				}
337 			}
338 
339 			if (copy_to_user(rsp.msg.data,
340 					 msg->msg.data,
341 					 msg->msg.data_len))
342 			{
343 				rv = -EFAULT;
344 				goto recv_putback_on_err;
345 			}
346 			rsp.msg.data_len = msg->msg.data_len;
347 		} else {
348 			rsp.msg.data_len = 0;
349 		}
350 
351 		if (copy_to_user(arg, &rsp, sizeof(rsp))) {
352 			rv = -EFAULT;
353 			goto recv_putback_on_err;
354 		}
355 
356 		mutex_unlock(&priv->recv_mutex);
357 		ipmi_free_recv_msg(msg);
358 		break;
359 
360 	recv_putback_on_err:
361 		/* If we got an error, put the message back onto
362 		   the head of the queue. */
363 		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
364 		list_add(entry, &(priv->recv_msgs));
365 		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
366 		mutex_unlock(&priv->recv_mutex);
367 		break;
368 
369 	recv_err:
370 		mutex_unlock(&priv->recv_mutex);
371 		break;
372 	}
373 
374 	case IPMICTL_REGISTER_FOR_CMD:
375 	{
376 		struct ipmi_cmdspec val;
377 
378 		if (copy_from_user(&val, arg, sizeof(val))) {
379 			rv = -EFAULT;
380 			break;
381 		}
382 
383 		rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
384 					   IPMI_CHAN_ALL);
385 		break;
386 	}
387 
388 	case IPMICTL_UNREGISTER_FOR_CMD:
389 	{
390 		struct ipmi_cmdspec   val;
391 
392 		if (copy_from_user(&val, arg, sizeof(val))) {
393 			rv = -EFAULT;
394 			break;
395 		}
396 
397 		rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
398 					     IPMI_CHAN_ALL);
399 		break;
400 	}
401 
402 	case IPMICTL_REGISTER_FOR_CMD_CHANS:
403 	{
404 		struct ipmi_cmdspec_chans val;
405 
406 		if (copy_from_user(&val, arg, sizeof(val))) {
407 			rv = -EFAULT;
408 			break;
409 		}
410 
411 		rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
412 					   val.chans);
413 		break;
414 	}
415 
416 	case IPMICTL_UNREGISTER_FOR_CMD_CHANS:
417 	{
418 		struct ipmi_cmdspec_chans val;
419 
420 		if (copy_from_user(&val, arg, sizeof(val))) {
421 			rv = -EFAULT;
422 			break;
423 		}
424 
425 		rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
426 					     val.chans);
427 		break;
428 	}
429 
430 	case IPMICTL_SET_GETS_EVENTS_CMD:
431 	{
432 		int val;
433 
434 		if (copy_from_user(&val, arg, sizeof(val))) {
435 			rv = -EFAULT;
436 			break;
437 		}
438 
439 		rv = ipmi_set_gets_events(priv->user, val);
440 		break;
441 	}
442 
443 	/* The next four are legacy, not per-channel. */
444 	case IPMICTL_SET_MY_ADDRESS_CMD:
445 	{
446 		unsigned int val;
447 
448 		if (copy_from_user(&val, arg, sizeof(val))) {
449 			rv = -EFAULT;
450 			break;
451 		}
452 
453 		rv = ipmi_set_my_address(priv->user, 0, val);
454 		break;
455 	}
456 
457 	case IPMICTL_GET_MY_ADDRESS_CMD:
458 	{
459 		unsigned int  val;
460 		unsigned char rval;
461 
462 		rv = ipmi_get_my_address(priv->user, 0, &rval);
463 		if (rv)
464 			break;
465 
466 		val = rval;
467 
468 		if (copy_to_user(arg, &val, sizeof(val))) {
469 			rv = -EFAULT;
470 			break;
471 		}
472 		break;
473 	}
474 
475 	case IPMICTL_SET_MY_LUN_CMD:
476 	{
477 		unsigned int val;
478 
479 		if (copy_from_user(&val, arg, sizeof(val))) {
480 			rv = -EFAULT;
481 			break;
482 		}
483 
484 		rv = ipmi_set_my_LUN(priv->user, 0, val);
485 		break;
486 	}
487 
488 	case IPMICTL_GET_MY_LUN_CMD:
489 	{
490 		unsigned int  val;
491 		unsigned char rval;
492 
493 		rv = ipmi_get_my_LUN(priv->user, 0, &rval);
494 		if (rv)
495 			break;
496 
497 		val = rval;
498 
499 		if (copy_to_user(arg, &val, sizeof(val))) {
500 			rv = -EFAULT;
501 			break;
502 		}
503 		break;
504 	}
505 
506 	case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD:
507 	{
508 		struct ipmi_channel_lun_address_set val;
509 
510 		if (copy_from_user(&val, arg, sizeof(val))) {
511 			rv = -EFAULT;
512 			break;
513 		}
514 
515 		return ipmi_set_my_address(priv->user, val.channel, val.value);
516 		break;
517 	}
518 
519 	case IPMICTL_GET_MY_CHANNEL_ADDRESS_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_get_my_address(priv->user, val.channel, &val.value);
529 		if (rv)
530 			break;
531 
532 		if (copy_to_user(arg, &val, sizeof(val))) {
533 			rv = -EFAULT;
534 			break;
535 		}
536 		break;
537 	}
538 
539 	case IPMICTL_SET_MY_CHANNEL_LUN_CMD:
540 	{
541 		struct ipmi_channel_lun_address_set val;
542 
543 		if (copy_from_user(&val, arg, sizeof(val))) {
544 			rv = -EFAULT;
545 			break;
546 		}
547 
548 		rv = ipmi_set_my_LUN(priv->user, val.channel, val.value);
549 		break;
550 	}
551 
552 	case IPMICTL_GET_MY_CHANNEL_LUN_CMD:
553 	{
554 		struct ipmi_channel_lun_address_set val;
555 
556 		if (copy_from_user(&val, arg, sizeof(val))) {
557 			rv = -EFAULT;
558 			break;
559 		}
560 
561 		rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value);
562 		if (rv)
563 			break;
564 
565 		if (copy_to_user(arg, &val, sizeof(val))) {
566 			rv = -EFAULT;
567 			break;
568 		}
569 		break;
570 	}
571 
572 	case IPMICTL_SET_TIMING_PARMS_CMD:
573 	{
574 		struct ipmi_timing_parms parms;
575 
576 		if (copy_from_user(&parms, arg, sizeof(parms))) {
577 			rv = -EFAULT;
578 			break;
579 		}
580 
581 		priv->default_retries = parms.retries;
582 		priv->default_retry_time_ms = parms.retry_time_ms;
583 		rv = 0;
584 		break;
585 	}
586 
587 	case IPMICTL_GET_TIMING_PARMS_CMD:
588 	{
589 		struct ipmi_timing_parms parms;
590 
591 		parms.retries = priv->default_retries;
592 		parms.retry_time_ms = priv->default_retry_time_ms;
593 
594 		if (copy_to_user(arg, &parms, sizeof(parms))) {
595 			rv = -EFAULT;
596 			break;
597 		}
598 
599 		rv = 0;
600 		break;
601 	}
602 
603 	case IPMICTL_GET_MAINTENANCE_MODE_CMD:
604 	{
605 		int mode;
606 
607 		mode = ipmi_get_maintenance_mode(priv->user);
608 		if (copy_to_user(arg, &mode, sizeof(mode))) {
609 			rv = -EFAULT;
610 			break;
611 		}
612 		rv = 0;
613 		break;
614 	}
615 
616 	case IPMICTL_SET_MAINTENANCE_MODE_CMD:
617 	{
618 		int mode;
619 
620 		if (copy_from_user(&mode, arg, sizeof(mode))) {
621 			rv = -EFAULT;
622 			break;
623 		}
624 		rv = ipmi_set_maintenance_mode(priv->user, mode);
625 		break;
626 	}
627 	}
628 
629 	return rv;
630 }
631 
632 /*
633  * Note: it doesn't make sense to take the BKL here but
634  *       not in compat_ipmi_ioctl. -arnd
635  */
636 static long ipmi_unlocked_ioctl(struct file   *file,
637 			        unsigned int  cmd,
638 			        unsigned long data)
639 {
640 	int ret;
641 
642 	mutex_lock(&ipmi_mutex);
643 	ret = ipmi_ioctl(file, cmd, data);
644 	mutex_unlock(&ipmi_mutex);
645 
646 	return ret;
647 }
648 
649 #ifdef CONFIG_COMPAT
650 
651 /*
652  * The following code contains code for supporting 32-bit compatible
653  * ioctls on 64-bit kernels.  This allows running 32-bit apps on the
654  * 64-bit kernel
655  */
656 #define COMPAT_IPMICTL_SEND_COMMAND	\
657 	_IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
658 #define COMPAT_IPMICTL_SEND_COMMAND_SETTIME	\
659 	_IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
660 #define COMPAT_IPMICTL_RECEIVE_MSG	\
661 	_IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
662 #define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC	\
663 	_IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
664 
665 struct compat_ipmi_msg {
666 	u8		netfn;
667 	u8		cmd;
668 	u16		data_len;
669 	compat_uptr_t	data;
670 };
671 
672 struct compat_ipmi_req {
673 	compat_uptr_t		addr;
674 	compat_uint_t		addr_len;
675 	compat_long_t		msgid;
676 	struct compat_ipmi_msg	msg;
677 };
678 
679 struct compat_ipmi_recv {
680 	compat_int_t		recv_type;
681 	compat_uptr_t		addr;
682 	compat_uint_t		addr_len;
683 	compat_long_t		msgid;
684 	struct compat_ipmi_msg	msg;
685 };
686 
687 struct compat_ipmi_req_settime {
688 	struct compat_ipmi_req	req;
689 	compat_int_t		retries;
690 	compat_uint_t		retry_time_ms;
691 };
692 
693 /*
694  * Define some helper functions for copying IPMI data
695  */
696 static long get_compat_ipmi_msg(struct ipmi_msg *p64,
697 				struct compat_ipmi_msg __user *p32)
698 {
699 	compat_uptr_t tmp;
700 
701 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
702 			__get_user(p64->netfn, &p32->netfn) ||
703 			__get_user(p64->cmd, &p32->cmd) ||
704 			__get_user(p64->data_len, &p32->data_len) ||
705 			__get_user(tmp, &p32->data))
706 		return -EFAULT;
707 	p64->data = compat_ptr(tmp);
708 	return 0;
709 }
710 
711 static long put_compat_ipmi_msg(struct ipmi_msg *p64,
712 				struct compat_ipmi_msg __user *p32)
713 {
714 	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
715 			__put_user(p64->netfn, &p32->netfn) ||
716 			__put_user(p64->cmd, &p32->cmd) ||
717 			__put_user(p64->data_len, &p32->data_len))
718 		return -EFAULT;
719 	return 0;
720 }
721 
722 static long get_compat_ipmi_req(struct ipmi_req *p64,
723 				struct compat_ipmi_req __user *p32)
724 {
725 
726 	compat_uptr_t	tmp;
727 
728 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
729 			__get_user(tmp, &p32->addr) ||
730 			__get_user(p64->addr_len, &p32->addr_len) ||
731 			__get_user(p64->msgid, &p32->msgid) ||
732 			get_compat_ipmi_msg(&p64->msg, &p32->msg))
733 		return -EFAULT;
734 	p64->addr = compat_ptr(tmp);
735 	return 0;
736 }
737 
738 static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
739 		struct compat_ipmi_req_settime __user *p32)
740 {
741 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
742 			get_compat_ipmi_req(&p64->req, &p32->req) ||
743 			__get_user(p64->retries, &p32->retries) ||
744 			__get_user(p64->retry_time_ms, &p32->retry_time_ms))
745 		return -EFAULT;
746 	return 0;
747 }
748 
749 static long get_compat_ipmi_recv(struct ipmi_recv *p64,
750 				 struct compat_ipmi_recv __user *p32)
751 {
752 	compat_uptr_t tmp;
753 
754 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
755 			__get_user(p64->recv_type, &p32->recv_type) ||
756 			__get_user(tmp, &p32->addr) ||
757 			__get_user(p64->addr_len, &p32->addr_len) ||
758 			__get_user(p64->msgid, &p32->msgid) ||
759 			get_compat_ipmi_msg(&p64->msg, &p32->msg))
760 		return -EFAULT;
761 	p64->addr = compat_ptr(tmp);
762 	return 0;
763 }
764 
765 static long put_compat_ipmi_recv(struct ipmi_recv *p64,
766 				 struct compat_ipmi_recv __user *p32)
767 {
768 	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
769 			__put_user(p64->recv_type, &p32->recv_type) ||
770 			__put_user(p64->addr_len, &p32->addr_len) ||
771 			__put_user(p64->msgid, &p32->msgid) ||
772 			put_compat_ipmi_msg(&p64->msg, &p32->msg))
773 		return -EFAULT;
774 	return 0;
775 }
776 
777 /*
778  * Handle compatibility ioctls
779  */
780 static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
781 			      unsigned long arg)
782 {
783 	int rc;
784 	struct ipmi_file_private *priv = filep->private_data;
785 
786 	switch(cmd) {
787 	case COMPAT_IPMICTL_SEND_COMMAND:
788 	{
789 		struct ipmi_req	rp;
790 
791 		if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
792 			return -EFAULT;
793 
794 		return handle_send_req(priv->user, &rp,
795 				priv->default_retries,
796 				priv->default_retry_time_ms);
797 	}
798 	case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
799 	{
800 		struct ipmi_req_settime	sp;
801 
802 		if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
803 			return -EFAULT;
804 
805 		return handle_send_req(priv->user, &sp.req,
806 				sp.retries, sp.retry_time_ms);
807 	}
808 	case COMPAT_IPMICTL_RECEIVE_MSG:
809 	case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
810 	{
811 		struct ipmi_recv   __user *precv64;
812 		struct ipmi_recv   recv64;
813 
814 		if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
815 			return -EFAULT;
816 
817 		precv64 = compat_alloc_user_space(sizeof(recv64));
818 		if (copy_to_user(precv64, &recv64, sizeof(recv64)))
819 			return -EFAULT;
820 
821 		rc = ipmi_ioctl(filep,
822 				((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
823 				 ? IPMICTL_RECEIVE_MSG
824 				 : IPMICTL_RECEIVE_MSG_TRUNC),
825 				(unsigned long) precv64);
826 		if (rc != 0)
827 			return rc;
828 
829 		if (copy_from_user(&recv64, precv64, sizeof(recv64)))
830 			return -EFAULT;
831 
832 		if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
833 			return -EFAULT;
834 
835 		return rc;
836 	}
837 	default:
838 		return ipmi_ioctl(filep, cmd, arg);
839 	}
840 }
841 #endif
842 
843 static const struct file_operations ipmi_fops = {
844 	.owner		= THIS_MODULE,
845 	.unlocked_ioctl	= ipmi_unlocked_ioctl,
846 #ifdef CONFIG_COMPAT
847 	.compat_ioctl   = compat_ipmi_ioctl,
848 #endif
849 	.open		= ipmi_open,
850 	.release	= ipmi_release,
851 	.fasync		= ipmi_fasync,
852 	.poll		= ipmi_poll,
853 	.llseek		= noop_llseek,
854 };
855 
856 #define DEVICE_NAME     "ipmidev"
857 
858 static int ipmi_major;
859 module_param(ipmi_major, int, 0);
860 MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"
861 		 " default, or if you set it to zero, it will choose the next"
862 		 " available device.  Setting it to -1 will disable the"
863 		 " interface.  Other values will set the major device number"
864 		 " to that value.");
865 
866 /* Keep track of the devices that are registered. */
867 struct ipmi_reg_list {
868 	dev_t            dev;
869 	struct list_head link;
870 };
871 static LIST_HEAD(reg_list);
872 static DEFINE_MUTEX(reg_list_mutex);
873 
874 static struct class *ipmi_class;
875 
876 static void ipmi_new_smi(int if_num, struct device *device)
877 {
878 	dev_t dev = MKDEV(ipmi_major, if_num);
879 	struct ipmi_reg_list *entry;
880 
881 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
882 	if (!entry) {
883 		printk(KERN_ERR "ipmi_devintf: Unable to create the"
884 		       " ipmi class device link\n");
885 		return;
886 	}
887 	entry->dev = dev;
888 
889 	mutex_lock(&reg_list_mutex);
890 	device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
891 	list_add(&entry->link, &reg_list);
892 	mutex_unlock(&reg_list_mutex);
893 }
894 
895 static void ipmi_smi_gone(int if_num)
896 {
897 	dev_t dev = MKDEV(ipmi_major, if_num);
898 	struct ipmi_reg_list *entry;
899 
900 	mutex_lock(&reg_list_mutex);
901 	list_for_each_entry(entry, &reg_list, link) {
902 		if (entry->dev == dev) {
903 			list_del(&entry->link);
904 			kfree(entry);
905 			break;
906 		}
907 	}
908 	device_destroy(ipmi_class, dev);
909 	mutex_unlock(&reg_list_mutex);
910 }
911 
912 static struct ipmi_smi_watcher smi_watcher =
913 {
914 	.owner    = THIS_MODULE,
915 	.new_smi  = ipmi_new_smi,
916 	.smi_gone = ipmi_smi_gone,
917 };
918 
919 static int __init init_ipmi_devintf(void)
920 {
921 	int rv;
922 
923 	if (ipmi_major < 0)
924 		return -EINVAL;
925 
926 	printk(KERN_INFO "ipmi device interface\n");
927 
928 	ipmi_class = class_create(THIS_MODULE, "ipmi");
929 	if (IS_ERR(ipmi_class)) {
930 		printk(KERN_ERR "ipmi: can't register device class\n");
931 		return PTR_ERR(ipmi_class);
932 	}
933 
934 	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
935 	if (rv < 0) {
936 		class_destroy(ipmi_class);
937 		printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
938 		return rv;
939 	}
940 
941 	if (ipmi_major == 0) {
942 		ipmi_major = rv;
943 	}
944 
945 	rv = ipmi_smi_watcher_register(&smi_watcher);
946 	if (rv) {
947 		unregister_chrdev(ipmi_major, DEVICE_NAME);
948 		class_destroy(ipmi_class);
949 		printk(KERN_WARNING "ipmi: can't register smi watcher\n");
950 		return rv;
951 	}
952 
953 	return 0;
954 }
955 module_init(init_ipmi_devintf);
956 
957 static void __exit cleanup_ipmi(void)
958 {
959 	struct ipmi_reg_list *entry, *entry2;
960 	mutex_lock(&reg_list_mutex);
961 	list_for_each_entry_safe(entry, entry2, &reg_list, link) {
962 		list_del(&entry->link);
963 		device_destroy(ipmi_class, entry->dev);
964 		kfree(entry);
965 	}
966 	mutex_unlock(&reg_list_mutex);
967 	class_destroy(ipmi_class);
968 	ipmi_smi_watcher_unregister(&smi_watcher);
969 	unregister_chrdev(ipmi_major, DEVICE_NAME);
970 }
971 module_exit(cleanup_ipmi);
972 
973 MODULE_LICENSE("GPL");
974 MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
975 MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
976 MODULE_ALIAS("platform:ipmi_si");
977