diff options
Diffstat (limited to 'kernel/OS/Linux')
-rw-r--r-- | kernel/OS/Linux/.config | 1 | ||||
-rw-r--r-- | kernel/OS/Linux/os_linux.c | 1034 | ||||
-rw-r--r-- | kernel/OS/Linux/os_linux.h | 287 | ||||
-rw-r--r-- | kernel/OS/Linux/oss_ddi.h | 46 | ||||
-rw-r--r-- | kernel/OS/Linux/wrapper/.nomake | 0 | ||||
-rw-r--r-- | kernel/OS/Linux/wrapper/wrap.h | 288 |
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 */ + |