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