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