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        if (snd_BUG_ON(!tu->timeri))
  44                return -ENXIO;
  45        t = tu->timeri->timer;
  46        if (snd_BUG_ON(!t))
  47                return -ENXIO;
  48        memset(&info, 0, sizeof(info));
  49        info.card = t->card ? t->card->number : -1;
  50        if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
  51                info.flags |= SNDRV_TIMER_FLG_SLAVE;
  52        strlcpy(info.id, t->id, sizeof(info.id));
  53        strlcpy(info.name, t->name, sizeof(info.name));
  54        info.resolution = t->hw.resolution;
  55        if (copy_to_user(_info, &info, sizeof(*_info)))
  56                return -EFAULT;
  57        return 0;
  58}
  59
  60struct snd_timer_status32 {
  61        struct compat_timespec tstamp;
  62        u32 resolution;
  63        u32 lost;
  64        u32 overrun;
  65        u32 queue;
  66        unsigned char reserved[64];
  67};
  68
  69static int snd_timer_user_status_compat(struct file *file,
  70                                        struct snd_timer_status32 __user *_status)
  71{
  72        struct snd_timer_user *tu;
  73        struct snd_timer_status status;
  74        
  75        tu = file->private_data;
  76        if (snd_BUG_ON(!tu->timeri))
  77                return -ENXIO;
  78        memset(&status, 0, sizeof(status));
  79        status.tstamp = tu->tstamp;
  80        status.resolution = snd_timer_resolution(tu->timeri);
  81        status.lost = tu->timeri->lost;
  82        status.overrun = tu->overrun;
  83        spin_lock_irq(&tu->qlock);
  84        status.queue = tu->qused;
  85        spin_unlock_irq(&tu->qlock);
  86        if (copy_to_user(_status, &status, sizeof(status)))
  87                return -EFAULT;
  88        return 0;
  89}
  90
  91/*
  92 */
  93
  94enum {
  95        SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
  96        SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
  97};
  98
  99static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 100{
 101        void __user *argp = compat_ptr(arg);
 102
 103        switch (cmd) {
 104        case SNDRV_TIMER_IOCTL_PVERSION:
 105        case SNDRV_TIMER_IOCTL_TREAD:
 106        case SNDRV_TIMER_IOCTL_GINFO:
 107        case SNDRV_TIMER_IOCTL_GPARAMS:
 108        case SNDRV_TIMER_IOCTL_GSTATUS:
 109        case SNDRV_TIMER_IOCTL_SELECT:
 110        case SNDRV_TIMER_IOCTL_PARAMS:
 111        case SNDRV_TIMER_IOCTL_START:
 112        case SNDRV_TIMER_IOCTL_START_OLD:
 113        case SNDRV_TIMER_IOCTL_STOP:
 114        case SNDRV_TIMER_IOCTL_STOP_OLD:
 115        case SNDRV_TIMER_IOCTL_CONTINUE:
 116        case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
 117        case SNDRV_TIMER_IOCTL_PAUSE:
 118        case SNDRV_TIMER_IOCTL_PAUSE_OLD:
 119        case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
 120                return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
 121        case SNDRV_TIMER_IOCTL_INFO32:
 122                return snd_timer_user_info_compat(file, argp);
 123        case SNDRV_TIMER_IOCTL_STATUS32:
 124                return snd_timer_user_status_compat(file, argp);
 125        }
 126        return -ENOIOCTLCMD;
 127}
 128