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