summaryrefslogtreecommitdiff
path: root/kernel/OS/SunOS/module.inc
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2013-05-03 21:08:42 +0400
committerIgor Pashev <pashev.igor@gmail.com>2013-05-03 21:08:42 +0400
commit1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch)
tree4495d23e7b54ab5700e3839081e797c1eafe0db9 /kernel/OS/SunOS/module.inc
downloadoss4-1058def8e7827e56ce4a70afb4aeacb5dc44148f.tar.gz
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'kernel/OS/SunOS/module.inc')
-rw-r--r--kernel/OS/SunOS/module.inc389
1 files changed, 389 insertions, 0 deletions
diff --git a/kernel/OS/SunOS/module.inc b/kernel/OS/SunOS/module.inc
new file mode 100644
index 0000000..a522492
--- /dev/null
+++ b/kernel/OS/SunOS/module.inc
@@ -0,0 +1,389 @@
+/*
+ * Purpose: OSS module wrapper for Solaris
+ *
+ * This file will be included from the auto-generated drv_cfg.c files. Under
+ * Solaris this file will be compiled in the development system.
+ */
+/*
+ *
+ * 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 <sys/types.h>
+#include <sys/modctl.h>
+#include <sys/kmem.h>
+#include <sys/conf.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+
+static int ossdrv_getinfo (dev_info_t *, ddi_info_cmd_t, void *, void **);
+static int ossdrv_attach (dev_info_t *, ddi_attach_cmd_t);
+static int ossdrv_detach (dev_info_t *, ddi_detach_cmd_t);
+
+#ifdef OSS_POWER_MANAGE
+static int ossdrv_power (dev_info_t *, int component, int level);
+#endif
+
+/* Entry points structure */
+#if DRIVER_TYPE!=DRV_STREAMS
+
+static struct cb_ops ossdrv_cb_ops = {
+ oss_open,
+ oss_close,
+ nodev, /* not a block driver */
+ nodev, /* no print routine */
+ nodev, /* no dump routine */
+ oss_read,
+ oss_write,
+ oss_ioctl,
+#ifdef ALLOW_BUFFER_MAPPING
+ oss_devmap,
+#else
+ nodev, /* no devmap routine */
+#endif
+ nodev,
+ nodev, /* no segmap routine */
+ oss_chpoll, /* no chpoll routine */
+ ddi_prop_op,
+ 0, /* not a STREAMS driver */
+ D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
+ CB_REV
+};
+#else
+extern struct streamtab DRIVER_STR_INFO;
+
+struct cb_ops ossdrv_streams_cb_ops = {
+ nulldev,
+ nulldev,
+ nodev, /* not a block driver */
+ nodev, /* no print routine */
+ nodev, /* no dump routine */
+ nodev,
+ nodev,
+ nodev,
+ nodev, /* no devmap routine */
+ nodev,
+ nodev, /* no segmap routine */
+ nochpoll, /* no chpoll routine */
+ ddi_prop_op,
+ &DRIVER_STR_INFO, /* cb_str */
+ D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
+ CB_REV,
+ nodev, /* cb_aread */
+ nodev, /* cb_awrite */
+};
+#endif
+
+static struct dev_ops ossdrv_dev_ops = {
+ DEVO_REV, /* devo_rev */
+ 0, /* devo_refcnt */
+ ossdrv_getinfo, /* devo_getinfo */
+ nulldev, /* devo_identify - obsolete */
+#if DRIVER_TYPE==DRV_ISA
+ ossdrv_probe,
+#else
+ nulldev, /* devo_probe */
+#endif
+ ossdrv_attach, /* devo_attach */
+ ossdrv_detach, /* devo_detach */
+ nodev, /* devo_reset */
+#if DRIVER_TYPE==DRV_STREAMS
+ &ossdrv_streams_cb_ops, /* devi_cb_ops */
+#else
+ &ossdrv_cb_ops, /* devi_cb_ops */
+#endif
+ NULL, /* devo_bus_ops */
+#ifdef OSS_POWER_MANAGE
+ ossdrv_power
+#else
+ NULL /* devo_power */
+#endif
+};
+
+static struct modldrv ossdrv_modldrv = {
+ &mod_driverops, /* drv_modops */
+ "OSS " OSS_VERSION_STRING,
+ &ossdrv_dev_ops, /* drv_dev_ops */
+};
+
+static struct modlinkage ossdrv_modlinkage = {
+ MODREV_1, /* ml_rev */
+ (void *) &ossdrv_modldrv, /* ml_linkage */
+ NULL /* NULL terminates the list */
+};
+
+/*
+ * _init, _info, and _fini support loading and unloading the driver.
+ */
+int
+_init (void)
+{
+ int error;
+
+ error = mod_install (&ossdrv_modlinkage);
+
+ return error;
+}
+
+int
+_fini (void)
+{
+ int error;
+
+ error = mod_remove (&ossdrv_modlinkage);
+ return error;
+}
+
+int
+_info (struct modinfo *modinfop)
+{
+ int error;
+
+ error = mod_info (&ossdrv_modlinkage, modinfop);
+
+ return error;
+}
+
+/*ARGSUSED*/
+static int
+ossdrv_getinfo (dev_info_t * dontcare_dip, ddi_info_cmd_t cmd, void *arg,
+ void **result)
+{
+ dev_t dev;
+ register int error;
+ int instance;
+ dev_info_t *dip;
+#ifndef SOL9
+ oss_cdev_t *cdev;
+ int minor;
+
+ dev = (dev_t) arg;
+
+ minor = getminor (dev);
+
+ if (minor >= oss_num_cdevs)
+ {
+ *result = NULL;
+ return DDI_FAILURE;
+ }
+
+ if ((cdev = oss_cdevs[minor]) == NULL || cdev->osdev == NULL)
+ {
+ *result = NULL;
+ return DDI_FAILURE;
+ }
+
+ dip = cdev->osdev->dip;
+#else
+ dip = dontcare_dip;
+#endif
+
+ if (dip == NULL)
+ {
+ /* cmn_err (CE_WARN, "ossdrv_getinfo: dip==NULL\n"); */
+ return DDI_FAILURE;
+ }
+
+ instance = ddi_get_instance (dip);
+
+ switch (cmd)
+ {
+ case DDI_INFO_DEVT2DEVINFO:
+ *result = dip;
+ error = DDI_SUCCESS;
+ break;
+ case DDI_INFO_DEVT2INSTANCE:
+ *result = (void *) (long)instance;
+ error = DDI_SUCCESS;
+ break;
+ default:
+ *result = NULL;
+ error = DDI_FAILURE;
+ }
+
+ DDB (cmn_err (CE_CONT,
+ "oss_getinfo: returns %d, result=%lx instance=%d dev=%x\n",
+ error, (unsigned long)*result, instance, (unsigned int)dev));
+ return error;
+}
+
+static int
+ossdrv_attach (dev_info_t * dip, ddi_attach_cmd_t cmd)
+{
+ int instance;
+ oss_device_t *osdev;
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd != DDI_RESUME) /* Allow resume */
+#endif
+ if (cmd != DDI_ATTACH)
+ {
+ cmn_err (CE_WARN, "bad attach cmd %d\n", cmd);
+ return 0;
+ }
+
+ if (dip == NULL)
+ {
+ cmn_err (CE_WARN, "ossdrv_attach: dip==NULL\n");
+ return DDI_FAILURE;
+ }
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd == DDI_RESUME)
+ {
+ if ((osdev = (oss_device_t *) ddi_get_driver_private (dip)) == NULL)
+ {
+ cmn_err (CE_WARN, "ddi_get_driver_private() failed\n");
+ return DDI_SUCCESS;
+ }
+ if (!DRIVER_RESUME(osdev))
+ return DDI_FAILURE;
+
+ return DDI_SUCCESS;
+ }
+#endif
+
+ instance = ddi_get_instance (dip);
+ DDB (cmn_err
+ (CE_CONT, "Attach started " DRIVER_NICK "%d (%s)\n", instance,
+ ddi_get_name (dip)));
+
+ if ((osdev =
+ osdev_create (dip, DRIVER_TYPE, instance, DRIVER_NICK, NULL)) == NULL)
+ {
+ return DDI_FAILURE;
+ }
+
+ oss_load_options (osdev, oss_global_options);
+ oss_load_options (osdev, local_driver_options);
+
+#if DRIVER_TYPE==DRV_PCI || DRIVER_TYPE == DRV_ISA
+ {
+ int err;
+ if ((err =
+ ddi_get_iblock_cookie (dip, 0, &osdev->iblock_cookie)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Cannot get iblock cookie (%d)\n", err);
+ return DDI_FAILURE;
+ }
+ }
+#else
+/* NOTE! The USB driver (actually udi.c) will call usb_get_data() to obtain */
+/* the iblock_cookie. There is no need to do that here. */
+ osdev->iblock_cookie = 0;
+#endif
+
+ if (!DRIVER_ATTACH (osdev))
+ {
+ cmn_err (CE_WARN, "Attach failed\n");
+ osdev_delete (osdev);
+ return DDI_FAILURE;
+ }
+
+ ddi_set_driver_private (dip, (caddr_t) osdev);
+ ddi_report_dev (dip);
+#if DRIVER_TYPE != DRV_USB
+ oss_audio_delayed_attach ();
+#endif
+
+ DDB (cmn_err (CE_CONT, "Attach done " DRIVER_NICK "%d\n", instance));
+
+ return DDI_SUCCESS;
+}
+
+static int
+ossdrv_detach (dev_info_t * dip, ddi_detach_cmd_t cmd)
+{
+ oss_device_t *osdev;
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd != DDI_SUSPEND) /* Allow suspend */
+#endif
+ if (cmd != DDI_DETACH)
+ {
+ cmn_err (CE_WARN, "bad detach cmd %d\n", cmd);
+ return 0;
+ }
+
+ if (dip == NULL)
+ {
+ cmn_err (CE_WARN, "ossdrv_detach: dip==NULL\n");
+ return DDI_FAILURE;
+ }
+//cmn_err(CE_CONT, "Detach started " DRIVER_NICK "\n");
+
+ DDB (cmn_err
+ (CE_CONT, "Detach started " DRIVER_NICK "(%s)\n", ddi_get_name (dip)));
+ if ((osdev = (oss_device_t *) ddi_get_driver_private (dip)) == NULL)
+ {
+ cmn_err (CE_WARN, "ddi_get_driver_private() failed\n");
+ return DDI_SUCCESS;
+ }
+
+ if (osdev==NULL)
+ {
+ cmn_err (CE_WARN, "Driver osdev==NULL - cannot detach\n");
+ return DDI_FAILURE;
+ }
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd == DDI_SUSPEND)
+ {
+ if (!DRIVER_SUSPEND(osdev))
+ return DDI_FAILURE;
+ return DDI_SUCCESS;
+ }
+#endif
+
+ if (DRIVER_DETACH (osdev) <= 0)
+ {
+ cmn_err (CE_WARN, "Driver busy - cannot detach\n");
+ return DDI_FAILURE;
+ }
+
+#if DRIVER_TYPE!=DRV_VMIX
+ osdev_delete (osdev);
+#endif
+
+ DDB (cmn_err (CE_CONT, "Detach done " DRIVER_NICK "\n"));
+ return DDI_SUCCESS;
+}
+
+#ifdef OSS_POWER_MANAGE
+static int
+ossdrv_power (dev_info_t *dip, int component, int level)
+{
+ oss_device_t *osdev;
+
+ if (dip == NULL)
+ {
+ cmn_err (CE_WARN, "ossdrv_detach: dip==NULL\n");
+ return DDI_FAILURE;
+ }
+
+ DDB (cmn_err
+ (CE_CONT, "ossdrv_power " DRIVER_NICK "(%s, %d, %d)\n", ddi_get_name (dip), component, level));
+ if ((osdev = (oss_device_t *) ddi_get_driver_private (dip)) == NULL)
+ {
+ cmn_err (CE_WARN, "ddi_get_driver_private() failed\n");
+ return DDI_SUCCESS;
+ }
+
+ if (osdev==NULL)
+ {
+ cmn_err (CE_WARN, "Driver osdev==NULL - cannot detach\n");
+ return DDI_FAILURE;
+ }
+
+ if (!DRIVER_POWER(osdev, component, level))
+ return DDI_FAILURE;
+
+ return DDI_SUCCESS;
+}
+#endif