Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ipmi_devintf.c
Go to the documentation of this file.
1 /*
2  * ipmi_devintf.c
3  *
4  * Linux device interface for the IPMI message handler.
5  *
6  * Author: MontaVista Software, Inc.
7  * Corey Minyard <[email protected]>
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 
48 {
52  struct file *file;
55  struct mutex recv_mutex;
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) {
76  }
77 
78  spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
79 }
80 
81 static unsigned int ipmi_poll(struct file *file, poll_table *wait)
82 {
83  struct ipmi_file_private *priv = file->private_data;
84  unsigned int mask = 0;
85  unsigned long flags;
86 
87  poll_wait(file, &priv->wait, wait);
88 
89  spin_lock_irqsave(&priv->recv_msg_lock, flags);
90 
91  if (!list_empty(&(priv->recv_msgs)))
92  mask |= (POLLIN | POLLRDNORM);
93 
94  spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
95 
96  return mask;
97 }
98 
99 static int ipmi_fasync(int fd, struct file *file, int on)
100 {
101  struct ipmi_file_private *priv = file->private_data;
102  int result;
103 
104  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 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 
161  rv = ipmi_destroy_user(priv->user);
162  if (rv)
163  return rv;
164 
165  /* FIXME - free the messages in the list. */
166  kfree(priv);
167 
168  return 0;
169 }
170 
171 static int handle_send_req(ipmi_user_t user,
172  struct ipmi_req *req,
173  int retries,
174  unsigned int retry_time_ms)
175 {
176  int rv;
177  struct ipmi_addr addr;
178  struct kernel_ipmi_msg msg;
179 
180  if (req->addr_len > sizeof(struct ipmi_addr))
181  return -EINVAL;
182 
183  if (copy_from_user(&addr, req->addr, req->addr_len))
184  return -EFAULT;
185 
186  msg.netfn = req->msg.netfn;
187  msg.cmd = req->msg.cmd;
188  msg.data_len = req->msg.data_len;
190  if (!msg.data)
191  return -ENOMEM;
192 
193  /* From here out we cannot return, we must jump to "out" for
194  error exits to free msgdata. */
195 
196  rv = ipmi_validate_addr(&addr, req->addr_len);
197  if (rv)
198  goto out;
199 
200  if (req->msg.data != NULL) {
201  if (req->msg.data_len > IPMI_MAX_MSG_LENGTH) {
202  rv = -EMSGSIZE;
203  goto out;
204  }
205 
206  if (copy_from_user(msg.data,
207  req->msg.data,
208  req->msg.data_len))
209  {
210  rv = -EFAULT;
211  goto out;
212  }
213  } else {
214  msg.data_len = 0;
215  }
216 
217  rv = ipmi_request_settime(user,
218  &addr,
219  req->msgid,
220  &msg,
221  NULL,
222  0,
223  retries,
224  retry_time_ms);
225  out:
226  kfree(msg.data);
227  return rv;
228 }
229 
230 static int ipmi_ioctl(struct 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  {
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 
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:
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 mutex 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 mutex prevents that problem. */
296  mutex_lock(&priv->recv_mutex);
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  mutex_unlock(&priv->recv_mutex);
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  mutex_unlock(&priv->recv_mutex);
366  break;
367 
368  recv_err:
369  mutex_unlock(&priv->recv_mutex);
370  break;
371  }
372 
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  IPMI_CHAN_ALL);
384  break;
385  }
386 
388  {
389  struct ipmi_cmdspec val;
390 
391  if (copy_from_user(&val, arg, sizeof(val))) {
392  rv = -EFAULT;
393  break;
394  }
395 
396  rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
397  IPMI_CHAN_ALL);
398  break;
399  }
400 
402  {
403  struct ipmi_cmdspec_chans val;
404 
405  if (copy_from_user(&val, arg, sizeof(val))) {
406  rv = -EFAULT;
407  break;
408  }
409 
410  rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
411  val.chans);
412  break;
413  }
414 
416  {
417  struct ipmi_cmdspec_chans val;
418 
419  if (copy_from_user(&val, arg, sizeof(val))) {
420  rv = -EFAULT;
421  break;
422  }
423 
424  rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
425  val.chans);
426  break;
427  }
428 
430  {
431  int val;
432 
433  if (copy_from_user(&val, arg, sizeof(val))) {
434  rv = -EFAULT;
435  break;
436  }
437 
438  rv = ipmi_set_gets_events(priv->user, val);
439  break;
440  }
441 
442  /* The next four are legacy, not per-channel. */
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_address(priv->user, 0, val);
453  break;
454  }
455 
457  {
458  unsigned int val;
459  unsigned char rval;
460 
461  rv = ipmi_get_my_address(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 
475  {
476  unsigned int val;
477 
478  if (copy_from_user(&val, arg, sizeof(val))) {
479  rv = -EFAULT;
480  break;
481  }
482 
483  rv = ipmi_set_my_LUN(priv->user, 0, val);
484  break;
485  }
486 
488  {
489  unsigned int val;
490  unsigned char rval;
491 
492  rv = ipmi_get_my_LUN(priv->user, 0, &rval);
493  if (rv)
494  break;
495 
496  val = rval;
497 
498  if (copy_to_user(arg, &val, sizeof(val))) {
499  rv = -EFAULT;
500  break;
501  }
502  break;
503  }
504 
506  {
507  struct ipmi_channel_lun_address_set val;
508 
509  if (copy_from_user(&val, arg, sizeof(val))) {
510  rv = -EFAULT;
511  break;
512  }
513 
514  return ipmi_set_my_address(priv->user, val.channel, val.value);
515  break;
516  }
517 
519  {
520  struct ipmi_channel_lun_address_set val;
521 
522  if (copy_from_user(&val, arg, sizeof(val))) {
523  rv = -EFAULT;
524  break;
525  }
526 
527  rv = ipmi_get_my_address(priv->user, val.channel, &val.value);
528  if (rv)
529  break;
530 
531  if (copy_to_user(arg, &val, sizeof(val))) {
532  rv = -EFAULT;
533  break;
534  }
535  break;
536  }
537 
539  {
540  struct ipmi_channel_lun_address_set val;
541 
542  if (copy_from_user(&val, arg, sizeof(val))) {
543  rv = -EFAULT;
544  break;
545  }
546 
547  rv = ipmi_set_my_LUN(priv->user, val.channel, val.value);
548  break;
549  }
550 
552  {
553  struct ipmi_channel_lun_address_set val;
554 
555  if (copy_from_user(&val, arg, sizeof(val))) {
556  rv = -EFAULT;
557  break;
558  }
559 
560  rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value);
561  if (rv)
562  break;
563 
564  if (copy_to_user(arg, &val, sizeof(val))) {
565  rv = -EFAULT;
566  break;
567  }
568  break;
569  }
570 
572  {
573  struct ipmi_timing_parms parms;
574 
575  if (copy_from_user(&parms, arg, sizeof(parms))) {
576  rv = -EFAULT;
577  break;
578  }
579 
580  priv->default_retries = parms.retries;
581  priv->default_retry_time_ms = parms.retry_time_ms;
582  rv = 0;
583  break;
584  }
585 
587  {
588  struct ipmi_timing_parms parms;
589 
590  parms.retries = priv->default_retries;
591  parms.retry_time_ms = priv->default_retry_time_ms;
592 
593  if (copy_to_user(arg, &parms, sizeof(parms))) {
594  rv = -EFAULT;
595  break;
596  }
597 
598  rv = 0;
599  break;
600  }
601 
603  {
604  int mode;
605 
606  mode = ipmi_get_maintenance_mode(priv->user);
607  if (copy_to_user(arg, &mode, sizeof(mode))) {
608  rv = -EFAULT;
609  break;
610  }
611  rv = 0;
612  break;
613  }
614 
616  {
617  int mode;
618 
619  if (copy_from_user(&mode, arg, sizeof(mode))) {
620  rv = -EFAULT;
621  break;
622  }
623  rv = ipmi_set_maintenance_mode(priv->user, mode);
624  break;
625  }
626  }
627 
628  return rv;
629 }
630 
631 /*
632  * Note: it doesn't make sense to take the BKL here but
633  * not in compat_ipmi_ioctl. -arnd
634  */
635 static long ipmi_unlocked_ioctl(struct file *file,
636  unsigned int cmd,
637  unsigned long data)
638 {
639  int ret;
640 
641  mutex_lock(&ipmi_mutex);
642  ret = ipmi_ioctl(file, cmd, data);
643  mutex_unlock(&ipmi_mutex);
644 
645  return ret;
646 }
647 
648 #ifdef CONFIG_COMPAT
649 
650 /*
651  * The following code contains code for supporting 32-bit compatible
652  * ioctls on 64-bit kernels. This allows running 32-bit apps on the
653  * 64-bit kernel
654  */
655 #define COMPAT_IPMICTL_SEND_COMMAND \
656  _IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
657 #define COMPAT_IPMICTL_SEND_COMMAND_SETTIME \
658  _IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
659 #define COMPAT_IPMICTL_RECEIVE_MSG \
660  _IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
661 #define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC \
662  _IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
663 
664 struct compat_ipmi_msg {
665  u8 netfn;
666  u8 cmd;
667  u16 data_len;
669 };
670 
671 struct compat_ipmi_req {
673  compat_uint_t addr_len;
674  compat_long_t msgid;
675  struct compat_ipmi_msg msg;
676 };
677 
678 struct compat_ipmi_recv {
679  compat_int_t recv_type;
681  compat_uint_t addr_len;
682  compat_long_t msgid;
683  struct compat_ipmi_msg msg;
684 };
685 
686 struct compat_ipmi_req_settime {
687  struct compat_ipmi_req req;
689  compat_uint_t retry_time_ms;
690 };
691 
692 /*
693  * Define some helper functions for copying IPMI data
694  */
695 static long get_compat_ipmi_msg(struct ipmi_msg *p64,
696  struct compat_ipmi_msg __user *p32)
697 {
699 
700  if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
701  __get_user(p64->netfn, &p32->netfn) ||
702  __get_user(p64->cmd, &p32->cmd) ||
703  __get_user(p64->data_len, &p32->data_len) ||
704  __get_user(tmp, &p32->data))
705  return -EFAULT;
706  p64->data = compat_ptr(tmp);
707  return 0;
708 }
709 
710 static long put_compat_ipmi_msg(struct ipmi_msg *p64,
711  struct compat_ipmi_msg __user *p32)
712 {
713  if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
714  __put_user(p64->netfn, &p32->netfn) ||
715  __put_user(p64->cmd, &p32->cmd) ||
716  __put_user(p64->data_len, &p32->data_len))
717  return -EFAULT;
718  return 0;
719 }
720 
721 static long get_compat_ipmi_req(struct ipmi_req *p64,
722  struct compat_ipmi_req __user *p32)
723 {
724 
726 
727  if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
728  __get_user(tmp, &p32->addr) ||
729  __get_user(p64->addr_len, &p32->addr_len) ||
730  __get_user(p64->msgid, &p32->msgid) ||
731  get_compat_ipmi_msg(&p64->msg, &p32->msg))
732  return -EFAULT;
733  p64->addr = compat_ptr(tmp);
734  return 0;
735 }
736 
737 static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
738  struct compat_ipmi_req_settime __user *p32)
739 {
740  if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
741  get_compat_ipmi_req(&p64->req, &p32->req) ||
742  __get_user(p64->retries, &p32->retries) ||
743  __get_user(p64->retry_time_ms, &p32->retry_time_ms))
744  return -EFAULT;
745  return 0;
746 }
747 
748 static long get_compat_ipmi_recv(struct ipmi_recv *p64,
749  struct compat_ipmi_recv __user *p32)
750 {
752 
753  if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
754  __get_user(p64->recv_type, &p32->recv_type) ||
755  __get_user(tmp, &p32->addr) ||
756  __get_user(p64->addr_len, &p32->addr_len) ||
757  __get_user(p64->msgid, &p32->msgid) ||
758  get_compat_ipmi_msg(&p64->msg, &p32->msg))
759  return -EFAULT;
760  p64->addr = compat_ptr(tmp);
761  return 0;
762 }
763 
764 static long put_compat_ipmi_recv(struct ipmi_recv *p64,
765  struct compat_ipmi_recv __user *p32)
766 {
767  if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
768  __put_user(p64->recv_type, &p32->recv_type) ||
769  __put_user(p64->addr_len, &p32->addr_len) ||
770  __put_user(p64->msgid, &p32->msgid) ||
771  put_compat_ipmi_msg(&p64->msg, &p32->msg))
772  return -EFAULT;
773  return 0;
774 }
775 
776 /*
777  * Handle compatibility ioctls
778  */
779 static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
780  unsigned long arg)
781 {
782  int rc;
783  struct ipmi_file_private *priv = filep->private_data;
784 
785  switch(cmd) {
786  case COMPAT_IPMICTL_SEND_COMMAND:
787  {
788  struct ipmi_req rp;
789 
790  if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
791  return -EFAULT;
792 
793  return handle_send_req(priv->user, &rp,
794  priv->default_retries,
795  priv->default_retry_time_ms);
796  }
797  case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
798  {
799  struct ipmi_req_settime sp;
800 
801  if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
802  return -EFAULT;
803 
804  return handle_send_req(priv->user, &sp.req,
805  sp.retries, sp.retry_time_ms);
806  }
807  case COMPAT_IPMICTL_RECEIVE_MSG:
808  case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
809  {
810  struct ipmi_recv __user *precv64;
811  struct ipmi_recv recv64;
812 
813  if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
814  return -EFAULT;
815 
816  precv64 = compat_alloc_user_space(sizeof(recv64));
817  if (copy_to_user(precv64, &recv64, sizeof(recv64)))
818  return -EFAULT;
819 
820  rc = ipmi_ioctl(filep,
821  ((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
824  (unsigned long) precv64);
825  if (rc != 0)
826  return rc;
827 
828  if (copy_from_user(&recv64, precv64, sizeof(recv64)))
829  return -EFAULT;
830 
831  if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
832  return -EFAULT;
833 
834  return rc;
835  }
836  default:
837  return ipmi_ioctl(filep, cmd, arg);
838  }
839 }
840 #endif
841 
842 static const struct file_operations ipmi_fops = {
843  .owner = THIS_MODULE,
844  .unlocked_ioctl = ipmi_unlocked_ioctl,
845 #ifdef CONFIG_COMPAT
846  .compat_ioctl = compat_ipmi_ioctl,
847 #endif
848  .open = ipmi_open,
849  .release = ipmi_release,
850  .fasync = ipmi_fasync,
851  .poll = ipmi_poll,
852  .llseek = noop_llseek,
853 };
854 
855 #define DEVICE_NAME "ipmidev"
856 
857 static int ipmi_major;
858 module_param(ipmi_major, int, 0);
859 MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By"
860  " default, or if you set it to zero, it will choose the next"
861  " available device. Setting it to -1 will disable the"
862  " interface. Other values will set the major device number"
863  " to that value.");
864 
865 /* Keep track of the devices that are registered. */
868  struct list_head link;
869 };
870 static LIST_HEAD(reg_list);
871 static DEFINE_MUTEX(reg_list_mutex);
872 
873 static struct class *ipmi_class;
874 
875 static void ipmi_new_smi(int if_num, struct device *device)
876 {
877  dev_t dev = MKDEV(ipmi_major, if_num);
878  struct ipmi_reg_list *entry;
879 
880  entry = kmalloc(sizeof(*entry), GFP_KERNEL);
881  if (!entry) {
882  printk(KERN_ERR "ipmi_devintf: Unable to create the"
883  " ipmi class device link\n");
884  return;
885  }
886  entry->dev = dev;
887 
888  mutex_lock(&reg_list_mutex);
889  device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
890  list_add(&entry->link, &reg_list);
891  mutex_unlock(&reg_list_mutex);
892 }
893 
894 static void ipmi_smi_gone(int if_num)
895 {
896  dev_t dev = MKDEV(ipmi_major, if_num);
897  struct ipmi_reg_list *entry;
898 
899  mutex_lock(&reg_list_mutex);
900  list_for_each_entry(entry, &reg_list, link) {
901  if (entry->dev == dev) {
902  list_del(&entry->link);
903  kfree(entry);
904  break;
905  }
906  }
907  device_destroy(ipmi_class, dev);
908  mutex_unlock(&reg_list_mutex);
909 }
910 
911 static struct ipmi_smi_watcher smi_watcher =
912 {
913  .owner = THIS_MODULE,
914  .new_smi = ipmi_new_smi,
915  .smi_gone = ipmi_smi_gone,
916 };
917 
918 static int __init init_ipmi_devintf(void)
919 {
920  int rv;
921 
922  if (ipmi_major < 0)
923  return -EINVAL;
924 
925  printk(KERN_INFO "ipmi device interface\n");
926 
927  ipmi_class = class_create(THIS_MODULE, "ipmi");
928  if (IS_ERR(ipmi_class)) {
929  printk(KERN_ERR "ipmi: can't register device class\n");
930  return PTR_ERR(ipmi_class);
931  }
932 
933  rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
934  if (rv < 0) {
935  class_destroy(ipmi_class);
936  printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
937  return rv;
938  }
939 
940  if (ipmi_major == 0) {
941  ipmi_major = rv;
942  }
943 
944  rv = ipmi_smi_watcher_register(&smi_watcher);
945  if (rv) {
946  unregister_chrdev(ipmi_major, DEVICE_NAME);
947  class_destroy(ipmi_class);
948  printk(KERN_WARNING "ipmi: can't register smi watcher\n");
949  return rv;
950  }
951 
952  return 0;
953 }
954 module_init(init_ipmi_devintf);
955 
956 static void __exit cleanup_ipmi(void)
957 {
958  struct ipmi_reg_list *entry, *entry2;
959  mutex_lock(&reg_list_mutex);
960  list_for_each_entry_safe(entry, entry2, &reg_list, link) {
961  list_del(&entry->link);
962  device_destroy(ipmi_class, entry->dev);
963  kfree(entry);
964  }
965  mutex_unlock(&reg_list_mutex);
966  class_destroy(ipmi_class);
967  ipmi_smi_watcher_unregister(&smi_watcher);
968  unregister_chrdev(ipmi_major, DEVICE_NAME);
969 }
970 module_exit(cleanup_ipmi);
971 
972 MODULE_LICENSE("GPL");
973 MODULE_AUTHOR("Corey Minyard <[email protected]>");
974 MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
975 MODULE_ALIAS("platform:ipmi_si");