linux/sound/core/timer_compat.c
<<
>>
Prefs
   1/*
   2 *   32bit -> 64bit ioctl wrapper for timer API
   3 *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
   4 *
   5 *   This program is free software; you can redistribute it and/or modify
   6 *   it under the terms of the GNU General Public License as published by
   7 *   the Free Software Foundation; either version 2 of the License, or
   8 *   (at your option) any later version.
   9 *
  10 *   This program is distributed in the hope that it will be useful,
  11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 *   GNU General Public License for more details.
  14 *
  15 *   You should have received a copy of the GNU General Public License
  16 *   along with this program; if not, write to the Free Software
  17 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18 *
  19 */
  20
  21/* This file included from timer.c */
  22
  23#include <linux/compat.h>
  24
  25struct snd_timer_info32 {
  26        u32 flags;
  27        s32 card;
  28        unsigned char id[64];
  29        unsigned char name[80];
  30        u32 reserved0;
  31        u32 resolution;
  32        unsigned char reserved[64];
  33};
  34
  35static int snd_timer_user_info_compat(struct file *file,
  36                                      struct snd_timer_info32 __user *_info)
  37{
  38        struct snd_timer_user *tu;
  39        struct snd_timer_info32 info;
  40        struct snd_timer *t;
  41
  42        tu = file->private_data;
  43        snd_assert(tu->timeri != NULL, return -ENXIO);
  44        t = tu->timeri->timer;
  45        snd_assert(t != NULL, return -ENXIO);
  46        memset(&info, 0, sizeof(info));
  47        info.card = t->card ? t->card->number : -1;
  48        if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
  49                info.flags |= SNDRV_TIMER_FLG_SLAVE;
  50        strlcpy(info.id, t->id, sizeof(info.id));
  51        strlcpy(info.name, t->name, sizeof(info.name));
  52        info.resolution = t->hw.resolution;
  53        if (copy_to_user(_info, &info, sizeof(*_info)))
  54                return -EFAULT;
  55        return 0;
  56}
  57
  58struct snd_timer_status32 {
  59        struct compat_timespec tstamp;
  60        u32 resolution;
  61        u32 lost;
  62        u32 overrun;
  63        u32 queue;
  64        unsigned char reserved[64];
  65};
  66
  67static int snd_timer_user_status_compat(struct file *file,
  68                                        struct snd_timer_status32 __user *_status)
  69{
  70        struct snd_timer_user *tu;
  71        struct snd_timer_status status;
  72        
  73        tu = file->private_data;
  74        snd_assert(tu->timeri != NULL, return -ENXIO);
  75        memset(&status, 0, sizeof(status));
  76        status.tstamp = tu->tstamp;
  77        status.resolution = snd_timer_resolution(tu->timeri);
  78        status.lost = tu->timeri->lost;
  79        status.overrun = tu->overrun;
  80        spin_lock_irq(&tu->qlock);
  81        status.queue = tu->qused;
  82        spin_unlock_irq(&tu->qlock);
  83        if (copy_to_user(_status, &status, sizeof(status)))
  84                return -EFAULT;
  85        return 0;
  86}
  87
  88/*
  89 */
  90
  91enum {
  92        SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
  93        SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
  94};
  95
  96static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
  97{
  98        void __user *argp = compat_ptr(arg);
  99
 100        switch (cmd) {
 101        case SNDRV_TIMER_IOCTL_PVERSION:
 102        case SNDRV_TIMER_IOCTL_TREAD:
 103        case SNDRV_TIMER_IOCTL_GINFO:
 104        case SNDRV_TIMER_IOCTL_GPARAMS:
 105        case SNDRV_TIMER_IOCTL_GSTATUS:
 106        case SNDRV_TIMER_IOCTL_SELECT:
 107        case SNDRV_TIMER_IOCTL_PARAMS:
 108        case SNDRV_TIMER_IOCTL_START:
 109        case SNDRV_TIMER_IOCTL_START_OLD:
 110        case SNDRV_TIMER_IOCTL_STOP:
 111        case SNDRV_TIMER_IOCTL_STOP_OLD:
 112        case SNDRV_TIMER_IOCTL_CONTINUE:
 113        case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
 114        case SNDRV_TIMER_IOCTL_PAUSE:
 115        case SNDRV_TIMER_IOCTL_PAUSE_OLD:
 116        case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
 117                return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
 118        case SNDRV_TIMER_IOCTL_INFO32:
 119                return snd_timer_user_info_compat(file, argp);
 120        case SNDRV_TIMER_IOCTL_STATUS32:
 121                return snd_timer_user_status_compat(file, argp);
 122        }
 123        return -ENOIOCTLCMD;
 124}
 125