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