Logo Search packages:      
Sourcecode: alsa-driver version File versions

wrappers.c

#define __NO_VERSION__
#include "config.h"

#include <linux/version.h>
#ifdef CONFIG_HAVE_DEPRECATED_CONFIG_H
#include <linux/autoconf.h>
#else
#include <linux/config.h>
#endif
#include <linux/string.h>
#include <linux/sched.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#if defined(CONFIG_MODVERSIONS) && !defined(__GENKSYMS__) && !defined(__DEPEND__)
#include "sndversions.h"
#endif
#endif

#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/devfs_fs_kernel.h>

/* defined in adriver.h but we don't include it... */
#include <linux/compiler.h>
#ifndef __nocast
#define __nocast
#endif

#ifndef CONFIG_HAVE_STRLCPY
#define strlcat snd_compat_strlcat
#ifndef BUG_ON
#define BUG_ON(x) /* nothing */
#endif
size_t snd_compat_strlcat(char *dest, const char *src, size_t count)
{
      size_t dsize = strlen(dest);
      size_t len = strlen(src);
      size_t res = dsize + len;

      /* This would be a bug */
      BUG_ON(dsize >= count);

      dest += dsize;
      count -= dsize;
      if (len >= count)
            len = count-1;
      memcpy(dest, src, len);
      dest[len] = 0;
      return res;
}
EXPORT_SYMBOL(snd_compat_strlcat);
#endif

#ifndef CONFIG_HAVE_VSNPRINTF
#define vsnprintf snd_compat_vsnprintf
int snd_compat_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
#endif

#ifndef CONFIG_HAVE_SSCANF
#include <linux/ctype.h>

/* this function supports any format as long as it's %x  :-) */
int snd_compat_vsscanf(const char *buf, const char *fmt, va_list args)
{
      const char *str = buf;
      char *next;
      int num = 0;
      unsigned int *p;

      while (*fmt && *str) {
            while (isspace(*fmt))
                  ++fmt;

            if (!*fmt)
                  break;

            if (fmt[0] != '%' || fmt[1] != 'x') {
                  printk(KERN_ERR "snd_compat_vsscanf: format isn't %%x\n");
                  return 0;
            }
            fmt += 2;

            while (isspace(*str))
                  ++str;

            if (!*str || !isxdigit(*str))
                  break;

            p = (unsigned int*) va_arg(args, unsigned int*);
            *p = (unsigned int) simple_strtoul(str, &next, 0x10);
            ++num;

            if (!next)
                  break;
            str = next;
      }
      return num;
}
EXPORT_SYMBOL(snd_compat_vsscanf);

int snd_compat_sscanf(const char *buf, const char *fmt, ...)
{
      int res;
      va_list args;

      va_start(args, fmt);
      res = snd_compat_vsscanf(buf, fmt, args);
      va_end(args);
      return res;
}
EXPORT_SYMBOL(snd_compat_sscanf);
#endif

#ifdef CONFIG_HAVE_OLD_REQUEST_MODULE
void snd_compat_request_module(const char *fmt, ...)
{
      char buf[64];
      va_list args;
      int n;

      va_start(args, fmt);
      n = vsnprintf(buf, 64, fmt, args);
      if (n < 64 && buf[0])
            request_module(buf);
      va_end(args);
}
EXPORT_SYMBOL(snd_compat_request_module);
#endif

#if defined(CONFIG_DEVFS_FS)

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 29)

void snd_compat_devfs_remove(const char *fmt, ...)
{
      char buf[64];
      va_list args;
      int n;

      va_start(args, fmt);
      n = vsnprintf(buf, 64, fmt, args);
      if (n < 64 && buf[0]) {
            devfs_handle_t de = devfs_get_handle(NULL, buf, 0, 0, 0, 0);
            devfs_unregister(de);
            devfs_put(de);
      }
      va_end(args);
}
EXPORT_SYMBOL(snd_compat_devfs_remove);

#endif /* 2.5.29 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 67)

int snd_compat_devfs_mk_dir(const char *dir, ...)
{
      char buf[64];
      va_list args;
      int n;

      va_start(args, dir);
      n = vsnprintf(buf, 64, dir, args);
      va_end(args);
      if (n < 64 && buf[0]) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
            return devfs_mk_dir(NULL, buf, strlen(dir), NULL) ? -EIO : 0;
#else
            return devfs_mk_dir(NULL, buf, NULL) ? -EIO : 0;
#endif
      }
      return 0;
}
EXPORT_SYMBOL(snd_compat_devfs_mk_dir);

extern struct file_operations snd_fops;
int snd_compat_devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
{
      char buf[64];
      va_list args;
      int n;

      va_start(args, fmt);
      n = vsnprintf(buf, 64, fmt, args);
      va_end(args);
      if (n < 64 && buf[0]) {
            devfs_register(NULL, buf, DEVFS_FL_DEFAULT,
                         major(dev), minor(dev), mode,
                         &snd_fops, NULL);
      }
      return 0;
}
EXPORT_SYMBOL(snd_compat_devfs_mk_cdev);

#endif /* 2.5.67 */

#endif /* CONFIG_DEVFS_FS */

#ifndef CONFIG_HAVE_PCI_DEV_PRESENT
#include <linux/pci.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
/* for pci_device_id compatibility layer */
#include "compat_22.h"
#endif
int snd_pci_dev_present(const struct pci_device_id *ids)
{
      while (ids->vendor || ids->subvendor) {
            if (pci_find_device(ids->vendor, ids->subvendor, NULL))
                  return 1;
            ids++;
      }
      return 0;
}
EXPORT_SYMBOL(snd_pci_dev_present);
#endif

/*
 * msleep wrapper
 */
#ifndef CONFIG_HAVE_MSLEEP
#include <linux/delay.h>
void snd_compat_msleep(unsigned int msecs)
{
      unsigned long timeout = ((msecs) * HZ + 999) / 1000;

      while (timeout) {
            set_current_state(TASK_UNINTERRUPTIBLE);
            timeout = schedule_timeout(timeout);
      }
}
EXPORT_SYMBOL(snd_compat_msleep);
#endif

#ifndef CONFIG_HAVE_MSLEEP_INTERRUPTIBLE
#include <linux/delay.h>
unsigned long snd_compat_msleep_interruptible(unsigned int msecs)
{
      unsigned long timeout = ((msecs) * HZ + 999) / 1000;

      while (timeout && !signal_pending(current)) {
            set_current_state(TASK_INTERRUPTIBLE);
            timeout = schedule_timeout(timeout);
      }
      return (timeout * 1000) / HZ;
}
EXPORT_SYMBOL(snd_compat_msleep_interruptible);
#endif /* < 2.6.6 */

/* wrapper for new irq handler type */
#ifndef CONFIG_SND_NEW_IRQ_HANDLER
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/slab.h>
typedef int (*snd_irq_handler_t)(int, void *);
struct irq_list {
      snd_irq_handler_t handler;
      int irq;
      void *data;
      struct list_head list;
};
      
struct pt_regs *snd_irq_regs;
EXPORT_SYMBOL(snd_irq_regs);

#if defined(IRQ_NONE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
static irqreturn_t irq_redirect(int irq, void *data, struct pt_regs *reg)
{
      struct irq_list *list = data;
      irqreturn_t val;
      snd_irq_regs = reg;
      val = list->handler(irq, list->data);
      snd_irq_regs = NULL;
      return val;
}
#else
static void irq_redirect(int irq, void *data, struct pt_regs *reg)
{
      struct irq_list *list = data;
      snd_irq_regs = reg;
      list->handler(irq, list->data);
      snd_irq_regs = NULL;
}
#endif

static LIST_HEAD(irq_list_head);
static DEFINE_MUTEX(irq_list_mutex);

int snd_request_irq(unsigned int irq, snd_irq_handler_t handler,
                unsigned long irq_flags, const char *str, void *data)
{
      struct irq_list *list = kmalloc(sizeof(*list), GFP_KERNEL);
      int err;

      if (!list)
            return -ENOMEM;
      list->handler = handler;
      list->irq = irq;
      list->data = data;
      err = request_irq(irq, irq_redirect, irq_flags, str, list);
      if (err) {
            kfree(list);
            return err;
      }
      mutex_lock(&irq_list_mutex);
      list_add(&list->list, &irq_list_head);
      mutex_unlock(&irq_list_mutex);
      return 0;
}
EXPORT_SYMBOL(snd_request_irq);

void snd_free_irq(unsigned int irq, void *data)
{
      struct list_head *p;

      mutex_lock(&irq_list_mutex);
      list_for_each(p, &irq_list_head) {
            struct irq_list *list = list_entry(p, struct irq_list, list);
            if (list->irq == irq && list->data == data) {
                  free_irq(irq, list);
                  list_del(p);
                  kfree(list);
                  break;
            }
      }
      mutex_unlock(&irq_list_mutex);
}
EXPORT_SYMBOL(snd_free_irq);
#endif /* !CONFIG_SND_NEW_IRQ_HANDLER */


Generated by  Doxygen 1.6.0   Back to index