xref: /openbmc/linux/drivers/char/ipmi/ipmi_devintf.c (revision 9ac8d3fb)
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/spinlock.h>
40 #include <linux/slab.h>
41 #include <linux/ipmi.h>
42 #include <linux/mutex.h>
43 #include <linux/init.h>
44 #include <linux/device.h>
45 #include <linux/compat.h>
46 #include <linux/smp_lock.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 void file_receive_handler(struct ipmi_recv_msg *msg,
62 				 void                 *handler_data)
63 {
64 	struct ipmi_file_private *priv = handler_data;
65 	int                      was_empty;
66 	unsigned long            flags;
67 
68 	spin_lock_irqsave(&(priv->recv_msg_lock), flags);
69 
70 	was_empty = list_empty(&(priv->recv_msgs));
71 	list_add_tail(&(msg->link), &(priv->recv_msgs));
72 
73 	if (was_empty) {
74 		wake_up_interruptible(&priv->wait);
75 		kill_fasync(&priv->fasync_queue, SIGIO, POLL_IN);
76 	}
77 
78 	spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
79 }
80 
81 static unsigned int ipmi_poll(struct file *file, poll_table *wait)
82 {
83 	struct ipmi_file_private *priv = file->private_data;
84 	unsigned int             mask = 0;
85 	unsigned long            flags;
86 
87 	poll_wait(file, &priv->wait, wait);
88 
89 	spin_lock_irqsave(&priv->recv_msg_lock, flags);
90 
91 	if (!list_empty(&(priv->recv_msgs)))
92 		mask |= (POLLIN | POLLRDNORM);
93 
94 	spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
95 
96 	return mask;
97 }
98 
99 static int ipmi_fasync(int fd, struct file *file, int on)
100 {
101 	struct ipmi_file_private *priv = file->private_data;
102 	int                      result;
103 
104 	lock_kernel(); /* could race against open() otherwise */
105 	result = fasync_helper(fd, file, on, &priv->fasync_queue);
106 	unlock_kernel();
107 
108 	return (result);
109 }
110 
111 static struct ipmi_user_hndl ipmi_hndlrs =
112 {
113 	.ipmi_recv_hndl	= file_receive_handler,
114 };
115 
116 static int ipmi_open(struct inode *inode, struct file *file)
117 {
118 	int                      if_num = iminor(inode);
119 	int                      rv;
120 	struct ipmi_file_private *priv;
121 
122 
123 	priv = kmalloc(sizeof(*priv), GFP_KERNEL);
124 	if (!priv)
125 		return -ENOMEM;
126 
127 	lock_kernel();
128 	priv->file = file;
129 
130 	rv = ipmi_create_user(if_num,
131 			      &ipmi_hndlrs,
132 			      priv,
133 			      &(priv->user));
134 	if (rv) {
135 		kfree(priv);
136 		goto out;
137 	}
138 
139 	file->private_data = priv;
140 
141 	spin_lock_init(&(priv->recv_msg_lock));
142 	INIT_LIST_HEAD(&(priv->recv_msgs));
143 	init_waitqueue_head(&priv->wait);
144 	priv->fasync_queue = NULL;
145 	mutex_init(&priv->recv_mutex);
146 
147 	/* Use the low-level defaults. */
148 	priv->default_retries = -1;
149 	priv->default_retry_time_ms = 0;
150 
151 out:
152 	unlock_kernel();
153 	return rv;
154 }
155 
156 static int ipmi_release(struct inode *inode, struct file *file)
157 {
158 	struct ipmi_file_private *priv = file->private_data;
159 	int                      rv;
160 
161 	rv = ipmi_destroy_user(priv->user);
162 	if (rv)
163 		return rv;
164 
165 	/* FIXME - free the messages in the list. */
166 	kfree(priv);
167 
168 	return 0;
169 }
170 
171 static int handle_send_req(ipmi_user_t     user,
172 			   struct ipmi_req *req,
173 			   int             retries,
174 			   unsigned int    retry_time_ms)
175 {
176 	int              rv;
177 	struct ipmi_addr addr;
178 	struct kernel_ipmi_msg msg;
179 
180 	if (req->addr_len > sizeof(struct ipmi_addr))
181 		return -EINVAL;
182 
183 	if (copy_from_user(&addr, req->addr, req->addr_len))
184 		return -EFAULT;
185 
186 	msg.netfn = req->msg.netfn;
187 	msg.cmd = req->msg.cmd;
188 	msg.data_len = req->msg.data_len;
189 	msg.data = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
190 	if (!msg.data)
191 		return -ENOMEM;
192 
193 	/* From here out we cannot return, we must jump to "out" for
194 	   error exits to free msgdata. */
195 
196 	rv = ipmi_validate_addr(&addr, req->addr_len);
197 	if (rv)
198 		goto out;
199 
200 	if (req->msg.data != NULL) {
201 		if (req->msg.data_len > IPMI_MAX_MSG_LENGTH) {
202 			rv = -EMSGSIZE;
203 			goto out;
204 		}
205 
206 		if (copy_from_user(msg.data,
207 				   req->msg.data,
208 				   req->msg.data_len))
209 		{
210 			rv = -EFAULT;
211 			goto out;
212 		}
213 	} else {
214 		msg.data_len = 0;
215 	}
216 
217 	rv = ipmi_request_settime(user,
218 				  &addr,
219 				  req->msgid,
220 				  &msg,
221 				  NULL,
222 				  0,
223 				  retries,
224 				  retry_time_ms);
225  out:
226 	kfree(msg.data);
227 	return rv;
228 }
229 
230 static int ipmi_ioctl(struct inode  *inode,
231 		      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 #ifdef CONFIG_COMPAT
633 
634 /*
635  * The following code contains code for supporting 32-bit compatible
636  * ioctls on 64-bit kernels.  This allows running 32-bit apps on the
637  * 64-bit kernel
638  */
639 #define COMPAT_IPMICTL_SEND_COMMAND	\
640 	_IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
641 #define COMPAT_IPMICTL_SEND_COMMAND_SETTIME	\
642 	_IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
643 #define COMPAT_IPMICTL_RECEIVE_MSG	\
644 	_IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
645 #define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC	\
646 	_IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
647 
648 struct compat_ipmi_msg {
649 	u8		netfn;
650 	u8		cmd;
651 	u16		data_len;
652 	compat_uptr_t	data;
653 };
654 
655 struct compat_ipmi_req {
656 	compat_uptr_t		addr;
657 	compat_uint_t		addr_len;
658 	compat_long_t		msgid;
659 	struct compat_ipmi_msg	msg;
660 };
661 
662 struct compat_ipmi_recv {
663 	compat_int_t		recv_type;
664 	compat_uptr_t		addr;
665 	compat_uint_t		addr_len;
666 	compat_long_t		msgid;
667 	struct compat_ipmi_msg	msg;
668 };
669 
670 struct compat_ipmi_req_settime {
671 	struct compat_ipmi_req	req;
672 	compat_int_t		retries;
673 	compat_uint_t		retry_time_ms;
674 };
675 
676 /*
677  * Define some helper functions for copying IPMI data
678  */
679 static long get_compat_ipmi_msg(struct ipmi_msg *p64,
680 				struct compat_ipmi_msg __user *p32)
681 {
682 	compat_uptr_t tmp;
683 
684 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
685 			__get_user(p64->netfn, &p32->netfn) ||
686 			__get_user(p64->cmd, &p32->cmd) ||
687 			__get_user(p64->data_len, &p32->data_len) ||
688 			__get_user(tmp, &p32->data))
689 		return -EFAULT;
690 	p64->data = compat_ptr(tmp);
691 	return 0;
692 }
693 
694 static long put_compat_ipmi_msg(struct ipmi_msg *p64,
695 				struct compat_ipmi_msg __user *p32)
696 {
697 	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
698 			__put_user(p64->netfn, &p32->netfn) ||
699 			__put_user(p64->cmd, &p32->cmd) ||
700 			__put_user(p64->data_len, &p32->data_len))
701 		return -EFAULT;
702 	return 0;
703 }
704 
705 static long get_compat_ipmi_req(struct ipmi_req *p64,
706 				struct compat_ipmi_req __user *p32)
707 {
708 
709 	compat_uptr_t	tmp;
710 
711 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
712 			__get_user(tmp, &p32->addr) ||
713 			__get_user(p64->addr_len, &p32->addr_len) ||
714 			__get_user(p64->msgid, &p32->msgid) ||
715 			get_compat_ipmi_msg(&p64->msg, &p32->msg))
716 		return -EFAULT;
717 	p64->addr = compat_ptr(tmp);
718 	return 0;
719 }
720 
721 static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
722 		struct compat_ipmi_req_settime __user *p32)
723 {
724 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
725 			get_compat_ipmi_req(&p64->req, &p32->req) ||
726 			__get_user(p64->retries, &p32->retries) ||
727 			__get_user(p64->retry_time_ms, &p32->retry_time_ms))
728 		return -EFAULT;
729 	return 0;
730 }
731 
732 static long get_compat_ipmi_recv(struct ipmi_recv *p64,
733 				 struct compat_ipmi_recv __user *p32)
734 {
735 	compat_uptr_t tmp;
736 
737 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
738 			__get_user(p64->recv_type, &p32->recv_type) ||
739 			__get_user(tmp, &p32->addr) ||
740 			__get_user(p64->addr_len, &p32->addr_len) ||
741 			__get_user(p64->msgid, &p32->msgid) ||
742 			get_compat_ipmi_msg(&p64->msg, &p32->msg))
743 		return -EFAULT;
744 	p64->addr = compat_ptr(tmp);
745 	return 0;
746 }
747 
748 static long put_compat_ipmi_recv(struct ipmi_recv *p64,
749 				 struct compat_ipmi_recv __user *p32)
750 {
751 	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
752 			__put_user(p64->recv_type, &p32->recv_type) ||
753 			__put_user(p64->addr_len, &p32->addr_len) ||
754 			__put_user(p64->msgid, &p32->msgid) ||
755 			put_compat_ipmi_msg(&p64->msg, &p32->msg))
756 		return -EFAULT;
757 	return 0;
758 }
759 
760 /*
761  * Handle compatibility ioctls
762  */
763 static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
764 			      unsigned long arg)
765 {
766 	int rc;
767 	struct ipmi_file_private *priv = filep->private_data;
768 
769 	switch(cmd) {
770 	case COMPAT_IPMICTL_SEND_COMMAND:
771 	{
772 		struct ipmi_req	rp;
773 
774 		if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
775 			return -EFAULT;
776 
777 		return handle_send_req(priv->user, &rp,
778 				priv->default_retries,
779 				priv->default_retry_time_ms);
780 	}
781 	case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
782 	{
783 		struct ipmi_req_settime	sp;
784 
785 		if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
786 			return -EFAULT;
787 
788 		return handle_send_req(priv->user, &sp.req,
789 				sp.retries, sp.retry_time_ms);
790 	}
791 	case COMPAT_IPMICTL_RECEIVE_MSG:
792 	case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
793 	{
794 		struct ipmi_recv   __user *precv64;
795 		struct ipmi_recv   recv64;
796 
797 		if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
798 			return -EFAULT;
799 
800 		precv64 = compat_alloc_user_space(sizeof(recv64));
801 		if (copy_to_user(precv64, &recv64, sizeof(recv64)))
802 			return -EFAULT;
803 
804 		rc = ipmi_ioctl(filep->f_path.dentry->d_inode, filep,
805 				((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
806 				 ? IPMICTL_RECEIVE_MSG
807 				 : IPMICTL_RECEIVE_MSG_TRUNC),
808 				(unsigned long) precv64);
809 		if (rc != 0)
810 			return rc;
811 
812 		if (copy_from_user(&recv64, precv64, sizeof(recv64)))
813 			return -EFAULT;
814 
815 		if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
816 			return -EFAULT;
817 
818 		return rc;
819 	}
820 	default:
821 		return ipmi_ioctl(filep->f_path.dentry->d_inode, filep, cmd, arg);
822 	}
823 }
824 #endif
825 
826 static const struct file_operations ipmi_fops = {
827 	.owner		= THIS_MODULE,
828 	.ioctl		= ipmi_ioctl,
829 #ifdef CONFIG_COMPAT
830 	.compat_ioctl   = compat_ipmi_ioctl,
831 #endif
832 	.open		= ipmi_open,
833 	.release	= ipmi_release,
834 	.fasync		= ipmi_fasync,
835 	.poll		= ipmi_poll,
836 };
837 
838 #define DEVICE_NAME     "ipmidev"
839 
840 static int ipmi_major;
841 module_param(ipmi_major, int, 0);
842 MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"
843 		 " default, or if you set it to zero, it will choose the next"
844 		 " available device.  Setting it to -1 will disable the"
845 		 " interface.  Other values will set the major device number"
846 		 " to that value.");
847 
848 /* Keep track of the devices that are registered. */
849 struct ipmi_reg_list {
850 	dev_t            dev;
851 	struct list_head link;
852 };
853 static LIST_HEAD(reg_list);
854 static DEFINE_MUTEX(reg_list_mutex);
855 
856 static struct class *ipmi_class;
857 
858 static void ipmi_new_smi(int if_num, struct device *device)
859 {
860 	dev_t dev = MKDEV(ipmi_major, if_num);
861 	struct ipmi_reg_list *entry;
862 
863 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
864 	if (!entry) {
865 		printk(KERN_ERR "ipmi_devintf: Unable to create the"
866 		       " ipmi class device link\n");
867 		return;
868 	}
869 	entry->dev = dev;
870 
871 	mutex_lock(&reg_list_mutex);
872 	device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
873 	list_add(&entry->link, &reg_list);
874 	mutex_unlock(&reg_list_mutex);
875 }
876 
877 static void ipmi_smi_gone(int if_num)
878 {
879 	dev_t dev = MKDEV(ipmi_major, if_num);
880 	struct ipmi_reg_list *entry;
881 
882 	mutex_lock(&reg_list_mutex);
883 	list_for_each_entry(entry, &reg_list, link) {
884 		if (entry->dev == dev) {
885 			list_del(&entry->link);
886 			kfree(entry);
887 			break;
888 		}
889 	}
890 	device_destroy(ipmi_class, dev);
891 	mutex_unlock(&reg_list_mutex);
892 }
893 
894 static struct ipmi_smi_watcher smi_watcher =
895 {
896 	.owner    = THIS_MODULE,
897 	.new_smi  = ipmi_new_smi,
898 	.smi_gone = ipmi_smi_gone,
899 };
900 
901 static __init int init_ipmi_devintf(void)
902 {
903 	int rv;
904 
905 	if (ipmi_major < 0)
906 		return -EINVAL;
907 
908 	printk(KERN_INFO "ipmi device interface\n");
909 
910 	ipmi_class = class_create(THIS_MODULE, "ipmi");
911 	if (IS_ERR(ipmi_class)) {
912 		printk(KERN_ERR "ipmi: can't register device class\n");
913 		return PTR_ERR(ipmi_class);
914 	}
915 
916 	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
917 	if (rv < 0) {
918 		class_destroy(ipmi_class);
919 		printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
920 		return rv;
921 	}
922 
923 	if (ipmi_major == 0) {
924 		ipmi_major = rv;
925 	}
926 
927 	rv = ipmi_smi_watcher_register(&smi_watcher);
928 	if (rv) {
929 		unregister_chrdev(ipmi_major, DEVICE_NAME);
930 		class_destroy(ipmi_class);
931 		printk(KERN_WARNING "ipmi: can't register smi watcher\n");
932 		return rv;
933 	}
934 
935 	return 0;
936 }
937 module_init(init_ipmi_devintf);
938 
939 static __exit void cleanup_ipmi(void)
940 {
941 	struct ipmi_reg_list *entry, *entry2;
942 	mutex_lock(&reg_list_mutex);
943 	list_for_each_entry_safe(entry, entry2, &reg_list, link) {
944 		list_del(&entry->link);
945 		device_destroy(ipmi_class, entry->dev);
946 		kfree(entry);
947 	}
948 	mutex_unlock(&reg_list_mutex);
949 	class_destroy(ipmi_class);
950 	ipmi_smi_watcher_unregister(&smi_watcher);
951 	unregister_chrdev(ipmi_major, DEVICE_NAME);
952 }
953 module_exit(cleanup_ipmi);
954 
955 MODULE_LICENSE("GPL");
956 MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
957 MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
958 MODULE_ALIAS("platform:ipmi_si");
959