summaryrefslogtreecommitdiff
path: root/kernel/OS/Linux
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/OS/Linux')
-rw-r--r--kernel/OS/Linux/.config1
-rw-r--r--kernel/OS/Linux/os_linux.c1034
-rw-r--r--kernel/OS/Linux/os_linux.h287
-rw-r--r--kernel/OS/Linux/oss_ddi.h46
-rw-r--r--kernel/OS/Linux/wrapper/.nomake0
-rw-r--r--kernel/OS/Linux/wrapper/wrap.h288
6 files changed, 1656 insertions, 0 deletions
diff --git a/kernel/OS/Linux/.config b/kernel/OS/Linux/.config
new file mode 100644
index 0000000..816ac62
--- /dev/null
+++ b/kernel/OS/Linux/.config
@@ -0,0 +1 @@
+mode=kernel
diff --git a/kernel/OS/Linux/os_linux.c b/kernel/OS/Linux/os_linux.c
new file mode 100644
index 0000000..c47f3da
--- /dev/null
+++ b/kernel/OS/Linux/os_linux.c
@@ -0,0 +1,1034 @@
+/*
+ * Purpose: Operating system abstraction functions for Linux
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#include <oss_config.h>
+#include <midi_core.h>
+
+/*
+ * OSS has traditionally used fixed character device number (14). However
+ * current OSS uses fully dynamic major number allocation. The legacy
+ * character device 14 is left for ALSA.
+ */
+static int osscore_major = 0;
+static int oss_expired = 0;
+
+/*
+ * Number of cards supported in the same system. This should be largish
+ * because unplugging/replugging USB cards in wrong way may create
+ * large number of card instances.
+ */
+#define MAX_CARDS 32
+
+static oss_device_t *cards[MAX_CARDS];
+int oss_num_cards = 0;
+
+void
+oss_pci_byteswap (oss_device_t * osdev, int mode)
+{
+ // NOP
+}
+
+int
+oss_pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ return osscore_pci_read_config_byte (osdev->dip, where, val);
+}
+
+int
+oss_pci_read_config_irq (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ return osscore_pci_read_config_irq (osdev->dip, where, val);
+}
+
+int
+oss_pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val)
+{
+ if (osdev == NULL)
+ {
+ cmn_err (CE_CONT, "oss_pci_read_config_word: osdev==NULL\n");
+ return PCIBIOS_FAILED;
+ }
+
+ return osscore_pci_read_config_word (osdev->dip, where, val);
+}
+
+int
+oss_pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val)
+{
+ return osscore_pci_read_config_dword (osdev->dip, where, val);
+}
+
+int
+oss_pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val)
+{
+ return osscore_pci_write_config_byte (osdev->dip, where, val);
+}
+
+int
+oss_pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val)
+{
+ return osscore_pci_write_config_word (osdev->dip, where, val);
+}
+
+int
+oss_pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val)
+{
+ return osscore_pci_write_config_dword (osdev->dip, where, val);
+}
+
+int
+oss_pci_enable_msi (oss_device_t * osdev)
+{
+ return osscore_pci_enable_msi (osdev->dip);
+}
+
+int
+oss_find_minor (int dev_class, int instance)
+{
+ int i;
+
+ for (i = 0; i < oss_num_cdevs; i++)
+ {
+ if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
+ && oss_cdevs[i]->instance == instance)
+ return i;
+ }
+
+ return OSS_ENXIO;
+}
+
+oss_device_t *
+osdev_create (dev_info_t * dip, int dev_type,
+ int instance, const char *nick, const char *handle)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+
+ memset (osdev, 0, sizeof (*osdev));
+
+ sprintf (osdev->nick, "%s%d", nick, instance);
+ osdev->instance = instance;
+ osdev->dip = dip;
+ osdev->available = 1;
+ osdev->first_mixer = -1;
+
+ strcpy (osdev->modname, nick);
+
+ if (handle == NULL)
+ handle = nick;
+
+ if (oss_num_cards >= MAX_CARDS)
+ cmn_err (CE_WARN, "Too many OSS devices. At most %d permitted.\n",
+ MAX_CARDS);
+ else
+ {
+ osdev->cardnum = oss_num_cards;
+ cards[oss_num_cards++] = osdev;
+ }
+/*
+ * Create the device handle
+ */
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ {
+ unsigned int subvendor;
+ char *devpath;
+ devpath = oss_pci_read_devpath (osdev->dip);
+ oss_pci_read_config_dword (osdev, 0x2c, &subvendor);
+
+ sprintf (osdev->handle, "PCI%08x-%s", subvendor, devpath);
+ }
+ break;
+
+ case DRV_USB:
+ // TODO: Get the vendor information
+ sprintf (osdev->handle, "USB-%s%d", handle, instance);
+ break;
+
+ default:
+ sprintf (osdev->handle, "%s%d", handle, instance);
+ }
+
+ return osdev;
+}
+
+oss_device_t *
+osdev_clone (oss_device_t * orig_osdev, int new_instance)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memcpy (osdev, orig_osdev, sizeof (*osdev));
+ osdev->dev_type = DRV_CLONE;
+ osdev->instance = new_instance;
+ sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
+ sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
+
+ return osdev;
+}
+
+void
+osdev_delete (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev == NULL)
+ return;
+
+ osdev->available = 0;
+/*
+ * Mark all minor nodes for this module as invalid.
+ */
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->osdev == osdev)
+ {
+ oss_cdevs[i]->d = NULL;
+ oss_cdevs[i]->osdev = NULL;
+ strcpy (oss_cdevs[i]->name, "Removed device");
+ }
+}
+
+void
+osdev_set_owner (oss_device_t * osdev, struct module *owner)
+{
+ osdev->owner = owner;
+}
+
+void
+osdev_set_major (oss_device_t * osdev, int major)
+{
+ osdev->major = major;
+}
+
+void
+osdev_set_irqparms (oss_device_t * osdev, void *irqparms)
+{
+ osdev->irqparms = irqparms;
+}
+
+void *
+osdev_get_irqparms (oss_device_t * osdev)
+{
+ return osdev->irqparms;
+}
+
+char *
+osdev_get_nick (oss_device_t * osdev)
+{
+ return osdev->nick;
+}
+
+int
+osdev_get_instance (oss_device_t * osdev)
+{
+ return osdev->instance;
+}
+
+void
+oss_inc_intrcount (oss_device_t * osdev, int claimed)
+{
+ osdev->intrcount++;
+
+ if (claimed)
+ osdev->ackcount++;
+}
+
+struct module *
+osdev_get_owner (oss_device_t * osdev)
+{
+ return osdev->owner;
+}
+
+void *
+oss_get_osid (oss_device_t * osdev)
+{
+ return NULL; // TODO
+}
+
+int
+oss_get_procinfo(int what)
+{
+ switch (what)
+ {
+ case OSS_GET_PROCINFO_UID:
+ return oss_get_uid();
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+int
+oss_disable_device (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev->major > 0)
+ oss_unregister_chrdev (osdev->major, osdev->nick);
+ osdev->major = 0;
+
+/*
+ * Now mark all devices unavailable (for the time being)
+ * TODO: Mobe this stuff to some common OSS module (also in Solaris)
+ */
+ if (osdev->refcount > 0)
+ {
+ return OSS_EBUSY;
+ }
+
+ for (i = 0; i < num_mixers; i++)
+ if (mixer_devs[i]->osdev == osdev)
+ {
+ mixer_devs[i]->unloaded = 1;
+ }
+
+ for (i = 0; i < num_mididevs; i++)
+ {
+ if (midi_devs[i]->osdev == osdev)
+ {
+ midi_devs[i]->unloaded = 1;
+ }
+ }
+
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i]->osdev == osdev)
+ {
+ audio_uninit_device (i);
+ }
+
+ return 0;
+}
+
+void
+oss_reserve_device (oss_device_t * osdev)
+{
+ osdev->refcount++;
+}
+
+void
+oss_unreserve_device (oss_device_t * osdev, int decrement)
+{
+ osdev->refcount--;
+ if (osdev->refcount < 0)
+ osdev->refcount = 0;
+}
+
+int
+oss_register_device (oss_device_t * osdev, const char *name)
+{
+ if (name == NULL)
+ {
+ cmn_err (CE_WARN, "oss_register_device: name==NULL\n");
+ osdev->name = "Undefined name";
+ return 0;
+ }
+
+ if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
+ osdev->name = "Unknown device";
+ }
+ strcpy (osdev->name, name);
+ return 0;
+}
+
+void
+oss_unregister_device (oss_device_t * osdev)
+{
+/*
+ * Notice! The driver calling this routine (the owner of the osdev parameter)
+ * has already uninitialized itself. Do not do any actions that may call this
+ * driver directly or indirectly.
+ */
+
+// TODO: Move this to some common OSS module (also under Solaris)
+}
+
+int
+oss_get_cardinfo (int cardnum, oss_card_info * ci)
+{
+/*
+ * Print information about a 'card' in a format suitable for /dev/sndstat
+ */
+
+ if (cardnum < 0 || cardnum >= oss_num_cards)
+ return OSS_ENXIO;
+
+ if (cards[cardnum]->name != NULL)
+ strncpy (ci->longname, cards[cardnum]->name, 128);
+ ci->longname[127] = 0;
+
+ if (cards[cardnum]->nick != NULL)
+ strncpy (ci->shortname, cards[cardnum]->nick, 16);
+ ci->shortname[15] = 0;
+
+ if (cards[cardnum]->hw_info != NULL)
+ strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info));
+ ci->hw_info[sizeof (ci->hw_info) - 1] = 0;
+ ci->intr_count = cards[cardnum]->intrcount;
+ ci->ack_count = cards[cardnum]->ackcount;
+
+ return 0;
+}
+
+int
+__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction)
+{
+ void *buf;
+ int err;
+ oss_native_word phaddr;
+ int size = 64 * 1024;
+ extern int dma_buffsize;
+
+ if (dma_buffsize > 16 && dma_buffsize <= 128)
+ size = dma_buffsize * 1024;
+
+ if (dmap->dmabuf != NULL)
+ return 0; /* Already done */
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: dmap==NULL\n");
+ return OSS_EIO;
+ }
+
+/*
+ * Some applications and virtual drivers need shorter buffer.
+ */
+ if (dmap->flags & DMAP_SMALLBUF)
+ {
+ size = SMALL_DMABUF_SIZE;
+ }
+ else if (dmap->flags & DMAP_MEDIUMBUF)
+ {
+ size = MEDIUM_DMABUF_SIZE;
+ }
+
+ if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
+ size = 32 * 1024;
+
+ dmap->dmabuf = NULL;
+ dmap->buffsize = size;
+
+ err = -1;
+
+ while (err < 0 && dmap->dmabuf == NULL && dmap->buffsize >= 4 * 1024)
+ {
+ if ((buf =
+ oss_contig_malloc (dmap->osdev, dmap->buffsize, maxaddr,
+ &phaddr)) == NULL)
+ {
+ if ((dmap->buffsize = (dmap->buffsize / 2)) < 8 * 1024)
+ return OSS_ENOMEM;
+ cmn_err (CE_CONT, "Dropping DMA buffer size to %d bytes.\n",
+ dmap->buffsize);
+ continue;
+ }
+
+ dmap->dmabuf = buf;
+ dmap->dmabuf_phys = phaddr;
+
+ return 0;
+ }
+
+ return OSS_ENOMEM;
+}
+
+void
+oss_free_dmabuf (int dev, dmap_p dmap)
+{
+ void *buf = dmap->dmabuf;
+
+ if (dmap->dmabuf == NULL)
+ return;
+
+ dmap->dmabuf = NULL;
+ oss_contig_free (NULL, buf, dmap->buffsize);
+ dmap->dmabuf_phys = 0;
+}
+
+static inline int
+cpy_file (oss_file_handle_t * f, struct fileinfo *fi)
+{
+ // TODO: Handle acc_flags properly
+ fi->acc_flags = 0;
+ fi->mode = 0;
+ fi->acc_flags = oss_file_get_flags (f);
+
+ if ((fi->acc_flags & O_ACCMODE) == O_RDWR)
+ fi->mode = OPEN_READWRITE;
+ if ((fi->acc_flags & O_ACCMODE) == O_RDONLY)
+ fi->mode = OPEN_READ;
+ if ((fi->acc_flags & O_ACCMODE) == O_WRONLY)
+ fi->mode = OPEN_WRITE;
+
+ return fi->mode;
+}
+
+static int
+oss_cdev_open (oss_inode_handle_t * inode, oss_file_handle_t * file)
+{
+ int dev = oss_inode_get_minor (inode);
+ oss_native_word d;
+ int tmpdev, dev_class, retval;
+ struct fileinfo fi;
+ oss_cdev_t *cdev;
+
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if (oss_cdevs == NULL)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return OSS_ENXIO;
+
+ DDB (cmn_err
+ (CE_CONT, "oss_cdev_open(%d): %s, class=%d, instance=%d\n", dev,
+ cdev->name, cdev->dev_class, cdev->instance));
+
+ if (cdev->d->open == NULL)
+ {
+ return OSS_ENODEV;
+ }
+
+ dev_class = cdev->dev_class;
+
+ tmpdev = -1;
+ oss_inc_refcounts ();
+ retval =
+ cdev->d->open (cdev->instance, cdev->dev_class, &fi, 0, 0, &tmpdev);
+
+ if (retval < 0)
+ {
+ oss_dec_refcounts ();
+ return retval;
+ }
+
+ if (tmpdev != -1)
+ dev = tmpdev;
+
+ //open_devices++;
+ //open_count[dev]++;
+
+ d = dev;
+ oss_file_set_private (file, (void *) d);
+
+ return 0;
+}
+
+static int
+oss_cdev_release (oss_inode_handle_t * inode, oss_file_handle_t * file)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ struct fileinfo fi;
+ oss_cdev_t *cdev;
+
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return 0;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->close == NULL)
+ {
+ return 0;
+ }
+
+ cdev->d->close (cdev->instance, &fi);
+ oss_dec_refcounts ();
+
+ return 0;
+}
+
+static ssize_t
+oss_cdev_read (oss_file_handle_t * file, char *buf, size_t count,
+ loff_t * offs)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+ uio_t uio;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->read == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if ((err = oss_create_uio (&uio, buf, count, UIO_READ, 0)) < 0)
+ {
+ return err;
+ }
+
+ err = cdev->d->read (cdev->instance, &fi, &uio, count);
+
+ return err;
+}
+
+static ssize_t
+oss_cdev_write (oss_file_handle_t * file, char *buf, size_t count,
+ loff_t * offs)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+ uio_t uio;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->write == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if ((err = oss_create_uio (&uio, buf, count, UIO_WRITE, 0)) < 0)
+ {
+ return err;
+ }
+
+ err = cdev->d->write (cdev->instance, &fi, &uio, count);
+
+ return err;
+}
+
+static int
+oss_cdev_ioctl (oss_inode_handle_t * inode, oss_file_handle_t * file,
+ unsigned int cmd, unsigned long arg)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+ int localbuf[64]; /* 256 bytes is the largest frequently used ioctl size */
+
+ int len = 0;
+ int alloced = 0;
+ int *ptr = (int *) arg;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->ioctl == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if (__SIOC_DIR (cmd) != __SIOC_NONE && __SIOC_DIR (cmd) != 0)
+ {
+ len = __SIOC_SIZE (cmd);
+ if (len < 1 || len > 65536 || arg == 0)
+ {
+ cmn_err (CE_WARN, "Bad ioctl command %x, %d, %x\n", cmd, len, arg);
+ return OSS_EFAULT;
+ }
+
+ /* Use statically allocated buffer for short arguments */
+ if (len > sizeof (localbuf))
+ {
+ ptr = KERNEL_MALLOC (len);
+ alloced = 1;
+ }
+ else
+ ptr = localbuf;
+
+ if (ptr == NULL || arg == 0)
+ {
+ return OSS_EFAULT;
+ }
+
+ if (__SIOC_DIR (cmd) & __SIOC_WRITE)
+ {
+ if (oss_copy_from_user (ptr, (char *) arg, len))
+ {
+ if (alloced)
+ KERNEL_FREE (ptr);
+ return OSS_EFAULT;
+ }
+ }
+ }
+
+ if ((err = cdev->d->ioctl (cdev->instance, &fi, cmd, (ioctl_arg) ptr)) < 0)
+ {
+ if (alloced)
+ KERNEL_FREE (ptr);
+ return err;
+ }
+
+ if (__SIOC_DIR (cmd) & __SIOC_READ)
+ {
+ if (oss_copy_to_user ((char *) arg, ptr, len))
+ {
+ if (alloced)
+ KERNEL_FREE (ptr);
+ return OSS_EFAULT;
+ }
+ }
+
+ /* Free the local buffer unless it was statically allocated */
+ if (ptr != NULL && alloced)
+ if (len > sizeof (localbuf))
+ KERNEL_FREE (ptr);
+
+ return ((err < 0) ? err : 0);
+
+}
+
+/* No BKL if this is used */
+static long
+oss_cdev_unlocked_ioctl (oss_file_handle_t * file, unsigned int cmd,
+ unsigned long arg)
+{
+ return oss_cdev_ioctl (NULL, file, cmd, arg);
+}
+
+/* Used for 32 bit clients on a 64 bit kernel. No BKL here either */
+static long
+oss_cdev_compat_ioctl (oss_file_handle_t * file, unsigned int cmd,
+ unsigned long arg)
+{
+ return oss_cdev_ioctl (NULL, file, cmd, arg);
+}
+
+static unsigned int
+oss_cdev_poll (oss_file_handle_t * file, oss_poll_table_handle_t * wait)
+{
+ oss_poll_event_t ev;
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->chpoll == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ ev.wait = wait;
+ ev.file = file;
+ ev.events = POLLOUT | POLLWRNORM | POLLIN | POLLRDNORM;
+ ev.revents = 0;
+ err = cdev->d->chpoll (cdev->instance, &fi, &ev);
+ if (err < 0)
+ {
+ return err;
+ }
+
+ return ev.revents;
+}
+
+static int
+oss_cdev_mmap (oss_file_handle_t * file, oss_vm_area_handle_t * vma)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ dmap_p dmap = NULL;
+ int err;
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if (cdev->dev_class != OSS_DEV_DSP && cdev->dev_class != OSS_DEV_DSP_ENGINE) /* Only mmap audio devices */
+ {
+ return OSS_ENXIO;
+ }
+
+ dev = cdev->instance;
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ if (audio_engines[dev]->flags & ADEV_NOMMAP)
+ return OSS_EIO;
+
+ if (oss_vma_get_flags (vma) & VM_WRITE) /* Map write and read/write to the output buf */
+ {
+ dmap = audio_engines[dev]->dmap_out;
+ }
+ else if (oss_vma_get_flags (vma) & VM_READ)
+ {
+ dmap = audio_engines[dev]->dmap_in;
+ }
+ else
+ {
+ cmn_err (CE_WARN, "Undefined mmap() access\n");
+ return OSS_EINVAL;
+ }
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "mmap() error. dmap == NULL\n");
+ return OSS_EIO;
+ }
+
+ if (dmap->dmabuf == NULL)
+ {
+ cmn_err (CE_WARN, "mmap() called when raw_buf == NULL\n");
+ return OSS_EIO;
+ }
+
+ if (dmap->dmabuf_phys == 0)
+ {
+ cmn_err (CE_WARN, "mmap() not supported by device /dev/dsp%d.\n", dev);
+ return OSS_EIO;
+ }
+
+ if (dmap->mapping_flags)
+ {
+ cmn_err (CE_WARN, "mmap() called twice for the same DMA buffer\n");
+ return OSS_EIO;
+ }
+
+ if (dmap->flags & DMAP_COOKED)
+ {
+ cmn_err (CE_WARN,
+ "mmap() not possible with currently selected sample format.\n");
+ return OSS_EIO;
+ }
+
+ if ((err = oss_do_mmap (vma, dmap->dmabuf_phys, dmap->bytes_in_use)) < 0)
+ return err;
+
+ dmap->mapping_flags |= DMA_MAP_MAPPED;
+
+ memset (dmap->dmabuf, dmap->neutral_byte, dmap->bytes_in_use);
+ return 0;
+}
+
+oss_file_operation_handle_t oss_fops = {
+ oss_cdev_read,
+ oss_cdev_write,
+ NULL, /* oss_readdir */
+ oss_cdev_poll,
+ oss_cdev_ioctl,
+ oss_cdev_mmap,
+ oss_cdev_open,
+ oss_cdev_release,
+ oss_cdev_compat_ioctl,
+ oss_cdev_unlocked_ioctl
+};
+
+static int
+hookup_cdevsw (oss_device_t * osdev)
+{
+ return oss_register_chrdev (osdev, osscore_major, "osscore", &oss_fops);
+}
+
+int
+oss_request_major (oss_device_t * osdev, int major, char *module)
+{
+ int err;
+
+ err = oss_register_chrdev (osdev, major, module, &oss_fops);
+
+ return err;
+}
+
+static int
+grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int increment)
+{
+ oss_cdev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ new_size += increment;
+
+ if ((new=PMALLOC(osdev, new_size * sizeof (oss_cdev_t *)))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * sizeof(oss_cdev_t *));
+ if (old != NULL)
+ memcpy(new, old, old_size * sizeof(oss_cdev_t *));
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ PMFREE(osdev, old);
+
+ return 1;
+}
+
+void
+oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
+ int instance, oss_cdev_drv_t * drv, int flags)
+{
+/*
+ * oss_install_chrdev creates a character device (minor). However if
+ * name==NULL the device will not be exported (made visible to userland
+ * clients).
+ */
+
+ int num;
+ oss_cdev_t *cdev = NULL;
+
+ if (osdev->major == 0)
+ {
+ cmn_err (CE_WARN, "Module %s major=0\n", osdev->nick);
+ return;
+ }
+
+ if (osdev->major < 0)
+ {
+ cmn_err (CE_WARN, "Failed to allocate major device for %s\n",
+ osdev->nick);
+ }
+
+ if (dev_class != OSS_DEV_STATUS)
+ if (oss_expired && instance > 0)
+ return;
+/*
+ * Find if this dev_class&instance already exists (after previous module
+ * detach).
+ */
+
+ for (num = 0; num < oss_num_cdevs; num++)
+ if (oss_cdevs[num]->d == NULL) /* Unloaded driver */
+ if (oss_cdevs[num]->dev_class == dev_class
+ && oss_cdevs[num]->instance == instance)
+ {
+ cdev = oss_cdevs[num];
+ break;
+ }
+
+ if (cdev == NULL)
+ {
+ if (oss_num_cdevs >= OSS_MAX_CDEVS)
+ {
+ if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, 100))
+ {
+ cmn_err (CE_WARN, "Out of minor numbers.\n");
+ return;
+ }
+ }
+
+ if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
+ return;
+ }
+
+ num = oss_num_cdevs++;
+ }
+
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name));
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+
+/*
+ * Export the device only if name != NULL
+ */
+ if (name != NULL)
+ {
+ strcpy (cdev->name, name);
+ oss_register_minor (osdev->major, num, name);
+ }
+}
+
+int
+oss_init_osscore (oss_device_t * osdev)
+{
+
+#ifdef LICENSED_VERSION
+ if (!oss_license_handle_time (oss_get_time ()))
+ {
+ cmn_err (CE_WARN, "This version of Open Sound System has expired\n");
+ cmn_err (CE_CONT,
+ "Please download the latest version from www.opensound.com\n");
+ oss_expired = 1;
+ }
+#endif
+
+ if ((osscore_major = hookup_cdevsw (osdev)) < 0)
+ {
+ cmn_err (CE_WARN, "Failed to allocate character major number %d\n",
+ osscore_major);
+ return OSS_EBUSY;
+ }
+
+ osdev->major = osscore_major;
+ oss_register_device (osdev, "OSS core services");
+
+ oss_common_init (osdev);
+
+ return 0;
+}
+
+void
+oss_uninit_osscore (oss_device_t * osdev)
+{
+ oss_unload_drivers ();
+
+ // free_all_irqs (); /* If something was left allocated by accident */
+ oss_unregister_chrdev (osscore_major, "osscore");
+}
+
+/*
+ * oss_pmalloc() is only used by usb_wraper.inc.
+ */
+void *
+oss_pmalloc (size_t sz)
+{
+ return oss_memblk_malloc(&oss_global_memblk, sz);
+}
diff --git a/kernel/OS/Linux/os_linux.h b/kernel/OS/Linux/os_linux.h
new file mode 100644
index 0000000..d881859
--- /dev/null
+++ b/kernel/OS/Linux/os_linux.h
@@ -0,0 +1,287 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+/*
+ * Purpose: OS specific definitions for Linux
+ *
+ * Under Linux os.h (this file) defines just the macros, functions and
+ * structures used by the code compiled in the development system. However
+ * there are other Linux specific definitions contained in {!nlink Linux/wrap.h}
+ * that are used both by the code compiled in the devlopment and target systems.
+ * This means that some definitions found in os.h under some other operating
+ * systems may be in wrap.h under Linux.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#define OS_VERSION "2.6.x"
+#define __EXTENDED__
+#define OSS_MAINLINE_BUILD
+
+/*
+ * Debugging and misc settings
+ */
+#undef MUTEX_CHECKS
+#undef MEMDEBUG
+#define VDEV_SUPPORT
+
+#if (!defined(__i386__) && !defined(__x86_64__)) || defined(CONFIG_OSS_FIXDEPOINT)
+// Floating point is not supported or it's disabled
+#undef CONFIG_OSS_VMIX_FLOAT
+#endif
+
+/*
+ * Disable support for per-application features such as /dev/dsp device
+ * selection based on command name. Requires working GET_PROCESS_NAME
+ * macro implementation.
+ */
+
+#undef APPLIST_SUPPORT
+#define USE_DEVICE_SUBDIRS
+#define EXTERN_C
+
+#define __invalid_size_argument_for_IOC 0 /* Dummy define to cure some broken ioctl.h versions */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <oss_errno.h>
+#include <sys/file.h>
+#include "oss_ddi.h"
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <asm/poll.h>
+#include "kernel/OS/Linux/wrapper/wrap.h"
+
+#undef HZ
+extern int oss_hz;
+#define OSS_HZ oss_hz
+
+/* The soundcard.h could be in a nonstandard place so include it here. */
+#include "soundcard.h"
+
+struct _oss_device_t
+{
+ int cardnum;
+ int dev_type;
+ int available;
+ int instance;
+ dev_info_t *dip;
+ void *devc;
+ char *name;
+ char nick[16];
+ char handle[32];
+ int num_audio_engines;
+ int num_audioplay, num_audiorec, num_audioduplex;
+ int num_mididevs;
+ int num_mixerdevs;
+ int num_loopdevs;
+ int first_mixer; /* This must be set to -1 by osdev_create() */
+ int major;
+ struct module *owner; /* Pointer to THISMODULE (needed by osscore.c) */
+ char modname[32];
+ char *hw_info;
+
+ volatile int refcount; /* Nonzero means that the device is needed by some other (virtual) driver. */
+
+/* Interrupts */
+
+ ddi_iblock_cookie_t iblock_cookie; /* Dummy field under Linux */
+ void *irqparms;
+ int intrcount, ackcount;
+
+/* PCI related fields */
+
+#ifdef _KERNEL
+ ddi_acc_handle_t pci_config_handle;
+ ddi_acc_handle_t acc_handle;
+ int swap_mode; /* 0=DDI_STRUCTURE_NEVERSWAP_ACC, 1=DDI_STRUCTURE_LE_ACC */
+#endif
+};
+
+#define ALLOW_BUFFER_MAPPING
+#define ALLOW_SELECT
+#define SEL_IN 0
+#define SEL_OUT 1
+#define SEL_EX 0xffffffff
+
+/* Busy wait routine */
+#define oss_udelay drv_usecwait
+/* System wall timer access */
+#define GET_JIFFIES() oss_get_jiffies()
+
+extern inline unsigned int
+__inb (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "b" " %" "w" "1,%" "b" "0":"=a" (_v):"d" (port),
+ "0" (0));
+ return _v;
+}
+extern inline unsigned int
+__inw (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "w" " %" "w" "1,%" "w" "0":"=a" (_v):"d" (port),
+ "0" (0));
+ return _v;
+}
+extern inline unsigned int
+__inl (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "l" " %" "w" "1,%" "" "0":"=a" (_v):"d" (port));
+ return _v;
+}
+
+extern inline void
+__outb (unsigned char value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "b" " %" "b" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+extern inline void
+__outw (unsigned short value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "w" " %" "w" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+extern inline void
+__outl (unsigned int value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "l" " %" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+
+#define INB(osdev,a) __inb(a)
+#define INW(osdev,a) __inw(a)
+#define INL(osdev,a) __inl(a)
+
+#define OUTB(osdev, d, a) __outb(d, a)
+
+#define OUTW(osdev, d, a) __outw(d, a)
+#define OUTL(osdev, d, a) __outl(d, a)
+
+#define PCI_READL(osdev, p) (*(volatile unsigned int *) (p))
+#define PCI_WRITEL(osdev, addr, data) (*(volatile unsigned int *) (addr) = (data))
+#define PCI_READW(osdev, p) (*(volatile unsigned short *) (p))
+#define PCI_WRITEW(osdev, addr, data) (*(volatile unsigned short *) (addr) = (data))
+#define PCI_READB(osdev, p) (*(volatile unsigned char *) (p))
+#define PCI_WRITEB(osdev, addr, data) (*(volatile unsigned char *) (addr) = (data))
+
+/*
+ KERNEL_MALLOC() allocates requested number of memory and
+ KERNEL_FREE is used to free it.
+ These macros are never called from interrupt, in addition the
+ nbytes will never be more than 4096 bytes. Generally the driver
+ will allocate memory in blocks of 4k. If the kernel has just a
+ page level memory allocation, 4K can be safely used as the size
+ (the nbytes parameter can be ignored).
+*/
+#ifdef MEMDEBUG
+extern void *oss_kmem_alloc (size_t size, char *file, int line);
+extern void oss_kmem_free (void *addr);
+#define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes, __FILE__, __LINE__)
+#define KERNEL_FREE(addr) oss_kmem_free(addr)
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr, char *file,
+ int line);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+extern oss_native_word oss_virt_to_bus (void *addr);
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr, __FILE__, __LINE__)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+#else
+#define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes)
+#define KERNEL_FREE(addr) oss_kmem_free(addr)
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+#endif
+
+/*
+ * Timer macros
+ *
+ * These macros are obsolete and should not be used in any new code.
+ * Use the timeout mechanism (see the timeout(9F) Solaris man page).
+ */
+#define DEFINE_TIMER(name, proc) static timeout_id_t name = 0
+#define REMOVE_TIMER(name, proc) {if (name != 0) oss_untimeout(name);}
+#define INIT_TIMER(name,proc)
+typedef void (*timeout_func_t) (void *);
+#define ACTIVATE_TIMER(name, proc, time) \
+ name=oss_timeout((timeout_func_t)proc, (void*)&name, time)
+
+#endif
+
+#define OSS_OS "Linux"
+#define OSS_OS_LONGNAME "Linux"
+
+#undef DMA_TRY_PSEUDOINIT
+
+int get_dma_residue (int chn);
+void disable_dma (int chn);
+void enable_dma (int chn);
+
+typedef void (*softintr_func_t) (int);
+
+struct oss_softintr
+{
+ int id;
+ softintr_func_t func;
+ volatile int armed, running;
+};
+
+#define MUTEX_INIT(osdev, mutex, hier) mutex=oss_mutex_init()
+#define MUTEX_CLEANUP(mutex) {oss_mutex_cleanup(mutex);mutex=NULL;}
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) flags=0;oss_spin_lock_irqsave(mutex, &flags)
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) oss_spin_unlock_irqrestore(mutex, flags);(flags)++
+#define MUTEX_ENTER(mutex, flags) flags=0;oss_spin_lock(mutex)
+#define MUTEX_EXIT(mutex, flags) oss_spin_unlock(mutex);(flags)++
+
+extern int detect_trace;
+#define DDB(x) if (detect_trace) x
+
+#define MAP_PCI_IOADDR(osdev, nr, io) (oss_native_word)io
+#define MAP_PCI_MEM(osdev, ix, phaddr, size) oss_map_pci_mem(osdev, size, phaddr)
+#define UNMAP_PCI_MEM(osdev, ix, ph, virt, size) oss_unmap_pci_mem(virt)
+#define UNMAP_PCI_IOADDR(osdev, ix) {}
+
+#define GET_PROCESS_PID(x) oss_get_pid()
+#define GET_PROCESS_UID(x) oss_get_uid()
+
+#define GET_PROCESS_NAME(x) oss_get_procname()
+
+#define pci_read_config_irq oss_pci_read_config_irq
+#define pci_read_config_byte oss_pci_read_config_byte
+#define pci_read_config_word oss_pci_read_config_word
+#define pci_read_config_dword oss_pci_read_config_dword
+#define pci_write_config_byte oss_pci_write_config_byte
+#define pci_write_config_word oss_pci_write_config_word
+#define pci_write_config_dword oss_pci_write_config_dword
+#define pci_enable_msi oss_pci_enable_msi
+
+#define VM_READ 0x1
+#define VM_WRITE 0x2
+
+#define FP_SUPPORT
+
+#ifdef FP_SUPPORT
+typedef short fp_env_t[512];
+typedef unsigned int fp_flags_t[4];
+extern int oss_fp_check (void);
+extern void oss_fp_save (short *envbuf, fp_flags_t flags);
+extern void oss_fp_restore (short *envbuf, fp_flags_t flags);
+# define FP_SAVE(envbuf, flags) oss_fp_save(envbuf, flags)
+# define FP_RESTORE(envbuf, flags) oss_fp_restore(envbuf, flags)
+#endif
+
+#include "oss_pci.h"
diff --git a/kernel/OS/Linux/oss_ddi.h b/kernel/OS/Linux/oss_ddi.h
new file mode 100644
index 0000000..36111fe
--- /dev/null
+++ b/kernel/OS/Linux/oss_ddi.h
@@ -0,0 +1,46 @@
+/*
+ * Purpose: Solaris compatible partial DDI interface for OSS/Linux
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+#ifndef NULL
+#define NULL 0
+#endif
+
+typedef int ddi_iblock_cookie_t;
+typedef int kmutex_t;
+typedef int cred_t;
+
+typedef int ddi_acc_handle_t;
+typedef int kcondvar_t;
+typedef int ddi_dma_handle_t;
+typedef int ddi_dma_cookie_t;
+typedef int ddi_dma_win_t;
+typedef int ddi_dma_seg_t;
+typedef int offset_t;
+typedef int ddi_info_cmd_t;
+typedef int ddi_attach_cmd_t;
+typedef int ddi_detach_cmd_t;
+
+#include <stdint.h>
+
+typedef struct _ddi_dma_attr_t
+{
+#define DMA_ATTR_V0 0
+ int a, b, c, d, e, f, g, h, i, j, k, l, m, n;
+} ddi_dma_attr_t;
+
+struct pollhead
+{
+ int dummy;
+};
diff --git a/kernel/OS/Linux/wrapper/.nomake b/kernel/OS/Linux/wrapper/.nomake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/OS/Linux/wrapper/.nomake
diff --git a/kernel/OS/Linux/wrapper/wrap.h b/kernel/OS/Linux/wrapper/wrap.h
new file mode 100644
index 0000000..0a3d3b9
--- /dev/null
+++ b/kernel/OS/Linux/wrapper/wrap.h
@@ -0,0 +1,288 @@
+/*
+ * Purpose: Wrapper routines for Linux kernel services
+ *
+ * The functions and structures declared here are part of the osscore.c
+ * file that is compiled in the target system. This file must not be
+ * modified in the target system because the precompiled binaries included
+ * in the OSS installation package depend on it too.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+/*
+ * Some integer types
+ */
+#if defined(__x86_64__)
+typedef unsigned long long oss_native_word; /* Same as the address and status register size */
+#else
+typedef unsigned long oss_native_word; /* Same as the address and status register size */
+#endif
+typedef long long oss_int64_t; /* Signed 64 bit integer */
+typedef unsigned long long oss_uint64_t; /* Unsigned 64 bit integer */
+
+extern char *oss_strcpy (char *s1, const char *s2);
+extern void *oss_memcpy (void *t_, const void *f_, size_t l);
+extern void *oss_memset (void *t, int val, size_t l);
+extern int oss_strcmp (const char *s1, const char *s2);
+extern size_t oss_strlen (const char *s);
+extern char *oss_strncpy (char *s1, const char *s2, size_t l);
+extern void oss_udelay (unsigned long d);
+
+typedef struct _oss_mutex_t *oss_mutex_t;
+typedef struct _poll_table_handle oss_poll_table_handle_t;
+typedef struct _file_handle_t oss_file_handle_t;
+
+struct _oss_poll_event_t
+{
+ short events, revents;
+ oss_poll_table_handle_t *wait;
+ oss_file_handle_t *file;
+};
+typedef struct _oss_poll_event_t oss_poll_event_t;
+
+extern oss_mutex_t oss_mutex_init (void);
+extern void oss_mutex_cleanup (oss_mutex_t mutex);
+extern void oss_spin_lock_irqsave (oss_mutex_t mutex,
+ oss_native_word * flags);
+extern void oss_spin_unlock_irqrestore (oss_mutex_t mutex,
+ oss_native_word flags);
+extern void oss_spin_lock (oss_mutex_t mutex);
+extern void oss_spin_unlock (oss_mutex_t mutex);
+extern unsigned long long oss_get_jiffies (void);
+extern char *oss_get_procname (void);
+extern int oss_get_pid (void);
+extern int oss_get_uid (void);
+
+struct oss_wait_queue;
+struct module;
+struct _oss_device_t;
+struct pci_dev;
+
+typedef void *oss_dma_handle_t; /* Unused type */
+
+/*
+ * Sleep/wakeup/poll support. These definitions are duplicates from
+ * oss_config.h which is the official place. Both definitions must match.
+ */
+
+extern struct oss_wait_queue *oss_create_wait_queue (oss_device_t * osdev,
+ const char *name);
+extern void oss_reset_wait_queue (struct oss_wait_queue *wq);
+extern void oss_remove_wait_queue (struct oss_wait_queue *wq);
+extern int oss_sleep (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ int ticks, oss_native_word * flags,
+ unsigned int *status);
+extern int oss_register_poll (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev);
+extern void oss_wakeup (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events);
+
+extern void oss_cmn_err (int level, const char *format, ...);
+#define CE_CONT 0
+#define CE_NOTE 1
+#define CE_WARN 2
+#define CE_PANIC 3
+
+typedef int timeout_id_t;
+extern timeout_id_t oss_timeout (void (*func) (void *), void *arg,
+ unsigned long long ticks);
+extern void oss_untimeout (timeout_id_t id);
+
+extern int sprintf (char *buf, const char *s, ...);
+
+typedef enum uio_rw
+{ UIO_READ, UIO_WRITE } uio_rw_t;
+struct uio
+{
+ char *ptr;
+ int resid;
+ int kernel_space; /* Set if this uio points to a kernel space buffer */
+ uio_rw_t rw;
+};
+typedef struct uio uio_t;
+
+extern int oss_uiomove (void *address, size_t nbytes, enum uio_rw rwflag,
+ uio_t * uio_p);
+extern int oss_create_uio (uio_t * uiop, char *buf, size_t count, uio_rw_t rw,
+ int is_kernel);
+extern void *oss_kmem_alloc (size_t size);
+extern void oss_kmem_free (void *addr);
+extern void *oss_pmalloc (size_t sz);
+extern oss_native_word oss_virt_to_bus (void *addr);
+extern void oss_reserve_pages (oss_native_word start_addr,
+ oss_native_word end_addr);
+extern void oss_unreserve_pages (oss_native_word start_addr,
+ oss_native_word end_addr);
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+
+extern time_t oss_get_time (void);
+
+typedef struct _inode_handle_t oss_inode_handle_t;
+typedef struct _vm_aread_handle oss_vm_area_handle_t;
+
+extern int oss_vma_get_flags (oss_vm_area_handle_t *);
+
+typedef struct oss_file_operation_handle
+{
+ ssize_t (*read) (oss_file_handle_t *, char *, size_t, loff_t *);
+ ssize_t (*write) (oss_file_handle_t *, char *, size_t, loff_t *);
+ int (*readdir) (oss_inode_handle_t *, oss_file_handle_t *, void *, int);
+ unsigned int (*poll) (oss_file_handle_t *, oss_poll_table_handle_t *);
+ int (*ioctl) (oss_inode_handle_t *, oss_file_handle_t *, unsigned int,
+ unsigned long);
+ int (*mmap) (oss_file_handle_t *, oss_vm_area_handle_t *);
+ int (*open) (oss_inode_handle_t *, oss_file_handle_t *);
+ int (*release) (oss_inode_handle_t *, oss_file_handle_t *);
+ long (*compat_ioctl) (oss_file_handle_t *, unsigned int, unsigned long);
+ long (*unlocked_ioctl) (oss_file_handle_t *, unsigned int, unsigned long);
+ int (*fsync) (oss_inode_handle_t *, oss_file_handle_t *);
+ int (*fasync) (oss_inode_handle_t *, oss_file_handle_t *, int);
+}
+oss_file_operation_handle_t;
+
+extern int oss_do_mmap (oss_vm_area_handle_t * vma,
+ oss_native_word dmabuf_phys, int bytes_in_use);
+extern int oss_register_chrdev (oss_device_t * osdev, unsigned int major,
+ const char *name,
+ oss_file_operation_handle_t * op);
+extern void oss_register_minor (int major, int minor, char *name);
+extern int oss_unregister_chrdev (unsigned int major, const char *name);
+
+extern int oss_inode_get_minor (oss_inode_handle_t * inode);
+extern int oss_file_get_flags (oss_file_handle_t * file);
+extern void *oss_file_get_private (oss_file_handle_t * file);
+extern void oss_file_set_private (oss_file_handle_t * file, void *v);
+
+extern void oss_inc_refcounts (void);
+extern void oss_dec_refcounts (void);
+
+/*
+ * Redefinitions of some routines defined in oss_config.h
+ * just to ensure they are defined in the same way in both places. The
+ * osscore/wrapper modules only include wrap.h so they can't see the "official"
+ * declarations in oss_config.h.
+ */
+
+typedef struct _dev_info_t dev_info_t;
+extern dev_info_t *oss_create_pcidip (struct pci_dev *pcidev);
+extern oss_device_t *osdev_create (dev_info_t * dip, int dev_type,
+ int instance, const char *nick,
+ const char *handle);
+
+extern void osdev_delete (oss_device_t * osdev);
+
+/*
+ * PCI config space access (in osscore.c)
+ */
+extern char *oss_pci_read_devpath (dev_info_t * dip);
+extern int osscore_pci_read_config_byte (dev_info_t * dip, unsigned int where,
+ unsigned char *val);
+extern int osscore_pci_read_config_irq (dev_info_t * dip, unsigned int where,
+ unsigned char *val);
+extern int osscore_pci_read_config_word (dev_info_t * dip, unsigned int where,
+ unsigned short *val);
+extern int osscore_pci_read_config_dword (dev_info_t * dip,
+ unsigned int where,
+ unsigned int *val);
+extern int osscore_pci_write_config_byte (dev_info_t * dip,
+ unsigned int where,
+ unsigned char val);
+extern int osscore_pci_write_config_word (dev_info_t * dip,
+ unsigned int where,
+ unsigned short val);
+extern int osscore_pci_write_config_dword (dev_info_t * dip,
+ unsigned int where,
+ unsigned int val);
+
+extern int osscore_pci_enable_msi (dev_info_t * dip);
+
+extern void *oss_map_pci_mem (oss_device_t * osdev, int size,
+ unsigned long offset);
+
+extern void oss_unmap_pci_mem (void *addr);
+
+extern int oss_copy_to_user (void *to, const void *from, unsigned long n);
+extern int oss_copy_from_user (void *to, const void *from, unsigned long n);
+
+extern void oss_register_module (struct module *mod);
+extern void oss_unregister_module (struct module *mod);
+
+#ifdef _KERNEL
+extern char *oss_strcpy (char *s1, const char *s2);
+#undef strcpy
+#define strcpy oss_strcpy
+
+extern void *oss_memcpy (void *t_, const void *f_, size_t l);
+#undef memcpy
+#define memcpy oss_memcpy
+
+extern void *oss_memset (void *t, int val, size_t l);
+#undef memset
+#define memset oss_memset
+
+extern int oss_strcmp (const char *s1, const char *s2);
+#undef strcmp
+#define strcmp oss_strcmp
+extern int oss_strncmp (const char *s1, const char *s2, size_t len);
+#undef strncmp
+#define strncmp oss_strncmp
+
+#undef strlen
+#define strlen oss_strlen
+
+#undef strncpy
+#define strncpy oss_strncpy
+#endif // KERNEL
+
+#undef timeout
+#define timeout oss_timeout
+
+#undef untimeout
+#define untimeout oss_untimeout
+
+#define drv_usecwait oss_udelay
+
+#define uiomove oss_uiomove
+
+#define cmn_err oss_cmn_err
+
+struct fileinfo
+{
+ int mode; /* Open mode */
+ int acc_flags;
+};
+#define ISSET_FILE_FLAG(fileinfo, flag) (fileinfo->acc_flags & (flag) ? 1:0)
+
+/*
+ * USB related definitions
+ */
+typedef struct udi_usb_devc udi_usb_devc;
+
+/*
+ * Functions exported by os.c
+ */
+extern int oss_init_osscore (oss_device_t * osdev);
+extern void oss_uninit_osscore (oss_device_t * osdev);
+extern void osdev_set_owner (oss_device_t * osdev, struct module *owner);
+extern void osdev_set_major (oss_device_t * osdev, int major);
+extern void osdev_set_irqparms (oss_device_t * osdev, void *irqparms);
+extern void *osdev_get_irqparms (oss_device_t * osdev);
+extern void oss_inc_intrcount(oss_device_t *osdev, int claimed);
+extern struct module *osdev_get_owner (oss_device_t * osdev);
+extern char *osdev_get_nick (oss_device_t * osdev);
+extern int osdev_get_instance (oss_device_t * osdev);
+extern int oss_request_major (oss_device_t * osdev, int major, char *module);
+extern int oss_register_device (oss_device_t * osdev, const char *name); /* from oss_config.h */
+