Merge remote-tracking branch 'asoc/fix/compress' into asoc-linus
[firefly-linux-kernel-4.4.55.git] / drivers / char / ipmi / ipmi_devintf.c
1 /*
2  * ipmi_devintf.c
3  *
4  * Linux device interface for the IPMI message handler.
5  *
6  * Author: MontaVista Software, Inc.
7  *         Corey Minyard <minyard@mvista.com>
8  *         source@mvista.com
9  *
10  * Copyright 2002 MontaVista Software Inc.
11  *
12  *  This program is free software; you can redistribute it and/or modify it
13  *  under the terms of the GNU General Public License as published by the
14  *  Free Software Foundation; either version 2 of the License, or (at your
15  *  option) any later version.
16  *
17  *
18  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *  You should have received a copy of the GNU General Public License along
30  *  with this program; if not, write to the Free Software Foundation, Inc.,
31  *  675 Mass Ave, Cambridge, MA 02139, USA.
32  */
33
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/errno.h>
37 #include <linux/poll.h>
38 #include <linux/sched.h>
39 #include <linux/spinlock.h>
40 #include <linux/slab.h>
41 #include <linux/ipmi.h>
42 #include <linux/mutex.h>
43 #include <linux/init.h>
44 #include <linux/device.h>
45 #include <linux/compat.h>
46
47 struct ipmi_file_private
48 {
49         ipmi_user_t          user;
50         spinlock_t           recv_msg_lock;
51         struct list_head     recv_msgs;
52         struct file          *file;
53         struct fasync_struct *fasync_queue;
54         wait_queue_head_t    wait;
55         struct mutex         recv_mutex;
56         int                  default_retries;
57         unsigned int         default_retry_time_ms;
58 };
59
60 static DEFINE_MUTEX(ipmi_mutex);
61 static void file_receive_handler(struct ipmi_recv_msg *msg,
62                                  void                 *handler_data)
63 {
64         struct ipmi_file_private *priv = handler_data;
65         int                      was_empty;
66         unsigned long            flags;
67
68         spin_lock_irqsave(&(priv->recv_msg_lock), flags);
69
70         was_empty = list_empty(&(priv->recv_msgs));
71         list_add_tail(&(msg->link), &(priv->recv_msgs));
72
73         if (was_empty) {
74                 wake_up_interruptible(&priv->wait);
75                 kill_fasync(&priv->fasync_queue, SIGIO, POLL_IN);
76         }
77
78         spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
79 }
80
81 static 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;
189         msg.data = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
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         {
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 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
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                                            IPMI_CHAN_ALL);
384                 break;
385         }
386
387         case IPMICTL_UNREGISTER_FOR_CMD:
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
401         case IPMICTL_REGISTER_FOR_CMD_CHANS:
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
415         case IPMICTL_UNREGISTER_FOR_CMD_CHANS:
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
429         case IPMICTL_SET_GETS_EVENTS_CMD:
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. */
443         case IPMICTL_SET_MY_ADDRESS_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_address(priv->user, 0, val);
453                 break;
454         }
455
456         case IPMICTL_GET_MY_ADDRESS_CMD:
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
474         case IPMICTL_SET_MY_LUN_CMD:
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
487         case IPMICTL_GET_MY_LUN_CMD:
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
505         case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD:
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
518         case IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD:
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
538         case IPMICTL_SET_MY_CHANNEL_LUN_CMD:
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
551         case IPMICTL_GET_MY_CHANNEL_LUN_CMD:
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
571         case IPMICTL_SET_TIMING_PARMS_CMD:
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
586         case IPMICTL_GET_TIMING_PARMS_CMD:
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
602         case IPMICTL_GET_MAINTENANCE_MODE_CMD:
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
615         case IPMICTL_SET_MAINTENANCE_MODE_CMD:
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;
668         compat_uptr_t   data;
669 };
670
671 struct compat_ipmi_req {
672         compat_uptr_t           addr;
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;
680         compat_uptr_t           addr;
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;
688         compat_int_t            retries;
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 {
698         compat_uptr_t tmp;
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
725         compat_uptr_t   tmp;
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 {
751         compat_uptr_t tmp;
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)
822                                  ? IPMICTL_RECEIVE_MSG
823                                  : IPMICTL_RECEIVE_MSG_TRUNC),
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
841 static long unlocked_compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
842                                        unsigned long arg)
843 {
844         int ret;
845
846         mutex_lock(&ipmi_mutex);
847         ret = compat_ipmi_ioctl(filep, cmd, arg);
848         mutex_unlock(&ipmi_mutex);
849
850         return ret;
851 }
852 #endif
853
854 static const struct file_operations ipmi_fops = {
855         .owner          = THIS_MODULE,
856         .unlocked_ioctl = ipmi_unlocked_ioctl,
857 #ifdef CONFIG_COMPAT
858         .compat_ioctl   = unlocked_compat_ipmi_ioctl,
859 #endif
860         .open           = ipmi_open,
861         .release        = ipmi_release,
862         .fasync         = ipmi_fasync,
863         .poll           = ipmi_poll,
864         .llseek         = noop_llseek,
865 };
866
867 #define DEVICE_NAME     "ipmidev"
868
869 static int ipmi_major;
870 module_param(ipmi_major, int, 0);
871 MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"
872                  " default, or if you set it to zero, it will choose the next"
873                  " available device.  Setting it to -1 will disable the"
874                  " interface.  Other values will set the major device number"
875                  " to that value.");
876
877 /* Keep track of the devices that are registered. */
878 struct ipmi_reg_list {
879         dev_t            dev;
880         struct list_head link;
881 };
882 static LIST_HEAD(reg_list);
883 static DEFINE_MUTEX(reg_list_mutex);
884
885 static struct class *ipmi_class;
886
887 static void ipmi_new_smi(int if_num, struct device *device)
888 {
889         dev_t dev = MKDEV(ipmi_major, if_num);
890         struct ipmi_reg_list *entry;
891
892         entry = kmalloc(sizeof(*entry), GFP_KERNEL);
893         if (!entry) {
894                 printk(KERN_ERR "ipmi_devintf: Unable to create the"
895                        " ipmi class device link\n");
896                 return;
897         }
898         entry->dev = dev;
899
900         mutex_lock(&reg_list_mutex);
901         device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
902         list_add(&entry->link, &reg_list);
903         mutex_unlock(&reg_list_mutex);
904 }
905
906 static void ipmi_smi_gone(int if_num)
907 {
908         dev_t dev = MKDEV(ipmi_major, if_num);
909         struct ipmi_reg_list *entry;
910
911         mutex_lock(&reg_list_mutex);
912         list_for_each_entry(entry, &reg_list, link) {
913                 if (entry->dev == dev) {
914                         list_del(&entry->link);
915                         kfree(entry);
916                         break;
917                 }
918         }
919         device_destroy(ipmi_class, dev);
920         mutex_unlock(&reg_list_mutex);
921 }
922
923 static struct ipmi_smi_watcher smi_watcher =
924 {
925         .owner    = THIS_MODULE,
926         .new_smi  = ipmi_new_smi,
927         .smi_gone = ipmi_smi_gone,
928 };
929
930 static int __init init_ipmi_devintf(void)
931 {
932         int rv;
933
934         if (ipmi_major < 0)
935                 return -EINVAL;
936
937         printk(KERN_INFO "ipmi device interface\n");
938
939         ipmi_class = class_create(THIS_MODULE, "ipmi");
940         if (IS_ERR(ipmi_class)) {
941                 printk(KERN_ERR "ipmi: can't register device class\n");
942                 return PTR_ERR(ipmi_class);
943         }
944
945         rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
946         if (rv < 0) {
947                 class_destroy(ipmi_class);
948                 printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
949                 return rv;
950         }
951
952         if (ipmi_major == 0) {
953                 ipmi_major = rv;
954         }
955
956         rv = ipmi_smi_watcher_register(&smi_watcher);
957         if (rv) {
958                 unregister_chrdev(ipmi_major, DEVICE_NAME);
959                 class_destroy(ipmi_class);
960                 printk(KERN_WARNING "ipmi: can't register smi watcher\n");
961                 return rv;
962         }
963
964         return 0;
965 }
966 module_init(init_ipmi_devintf);
967
968 static void __exit cleanup_ipmi(void)
969 {
970         struct ipmi_reg_list *entry, *entry2;
971         mutex_lock(&reg_list_mutex);
972         list_for_each_entry_safe(entry, entry2, &reg_list, link) {
973                 list_del(&entry->link);
974                 device_destroy(ipmi_class, entry->dev);
975                 kfree(entry);
976         }
977         mutex_unlock(&reg_list_mutex);
978         class_destroy(ipmi_class);
979         ipmi_smi_watcher_unregister(&smi_watcher);
980         unregister_chrdev(ipmi_major, DEVICE_NAME);
981 }
982 module_exit(cleanup_ipmi);
983
984 MODULE_LICENSE("GPL");
985 MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
986 MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
987 MODULE_ALIAS("platform:ipmi_si");