60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * CDDL HEADER START
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * The contents of this file are subject to the terms of the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Common Development and Distribution License (the "License").
60405de4d8688d96dd05157c28db3ade5c9bc234kz * You may not use this file except in compliance with the License.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
60405de4d8688d96dd05157c28db3ade5c9bc234kz * or http://www.opensolaris.org/os/licensing.
60405de4d8688d96dd05157c28db3ade5c9bc234kz * See the License for the specific language governing permissions
60405de4d8688d96dd05157c28db3ade5c9bc234kz * and limitations under the License.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * When distributing Covered Code, include this CDDL HEADER in each
60405de4d8688d96dd05157c28db3ade5c9bc234kz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
60405de4d8688d96dd05157c28db3ade5c9bc234kz * If applicable, add the following below this CDDL HEADER, with the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * fields enclosed by brackets "[]" replaced with your own identifying
60405de4d8688d96dd05157c28db3ade5c9bc234kz * information: Portions Copyright [yyyy] [name of copyright owner]
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * CDDL HEADER END
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Use is subject to license terms.
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Common misc module interfaces of DRM under Solaris
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * This module calls into gfx and agpmaster misc modules respectively
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * for generic graphics operations and AGP master device support.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "drm_sunmod.h"
60405de4d8688d96dd05157c28db3ade5c9bc234kz#include <sys/modctl.h>
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include <sys/kmem.h>
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include <vm/seg_kmem.h>
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzstatic struct modlmisc modlmisc = {
39b361b2ebefcef5612a54ae5cbd2179e19be296Richard Bean &mod_miscops, "DRM common interfaces"
60405de4d8688d96dd05157c28db3ade5c9bc234kz};
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzstatic struct modlinkage modlinkage = {
60405de4d8688d96dd05157c28db3ade5c9bc234kz MODREV_1, (void *)&modlmisc, NULL
60405de4d8688d96dd05157c28db3ade5c9bc234kz};
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic drm_inst_list_t *drm_inst_head;
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic kmutex_t drm_inst_list_lock;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int drm_sun_open(dev_t *, int, int, cred_t *);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int drm_sun_close(dev_t, int, int, cred_t *);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int drm_sun_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int drm_sun_devmap(dev_t, devmap_cookie_t, offset_t, size_t,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg size_t *, uint_t);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * devmap callbacks for AGP and PCI GART
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int drm_devmap_map(devmap_cookie_t, dev_t,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg uint_t, offset_t, size_t, void **);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int drm_devmap_dup(devmap_cookie_t, void *,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devmap_cookie_t, void **);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic void drm_devmap_unmap(devmap_cookie_t, void *,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg offset_t, size_t, devmap_cookie_t, void **, devmap_cookie_t, void **);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic drm_inst_list_t *drm_supp_alloc_drv_entry(dev_info_t *);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic drm_inst_state_t *drm_sup_devt_to_state(dev_t);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic void drm_supp_free_drv_entry(dev_info_t *);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic struct devmap_callback_ctl drm_devmap_callbacks = {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DEVMAP_OPS_REV, /* devmap_rev */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_devmap_map, /* devmap_map */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg NULL, /* devmap_access */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_devmap_dup, /* devmap_dup */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_devmap_unmap /* devmap_unmap */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg};
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Common device operations structure for all DRM drivers
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstruct cb_ops drm_cb_ops = {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_sun_open, /* cb_open */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_sun_close, /* cb_close */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nodev, /* cb_strategy */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nodev, /* cb_print */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nodev, /* cb_dump */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nodev, /* cb_read */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nodev, /* cb_write */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_sun_ioctl, /* cb_ioctl */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_sun_devmap, /* cb_devmap */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nodev, /* cb_mmap */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg NULL, /* cb_segmap */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nochpoll, /* cb_chpoll */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_prop_op, /* cb_prop_op */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0, /* cb_stream */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg D_NEW | D_MTSAFE |D_DEVMAP /* cb_flag */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg};
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kz_init(void)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int error;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((error = mod_install(&modlinkage)) != 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (error);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* initialize the instance list lock */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_init(&drm_inst_list_lock, NULL, MUTEX_DRIVER, NULL);
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kz_fini(void)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz int err;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if ((err = mod_remove(&modlinkage)) != 0)
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (err);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_destroy(&drm_inst_list_lock);
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kz_info(struct modinfo *modinfop)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (mod_info(&modlinkage, modinfop));
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgvoid *
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_supp_register(dev_info_t *dip, drm_device_t *dp)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int error;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg char buf[80];
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int instance = ddi_get_instance(dip);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_acc_handle_t pci_cfg_handle;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg agp_master_softc_t *agpm;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *entry;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg gfxp_vgatext_softc_ptr_t gfxp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg struct dev_ops *devop;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(dip != NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg entry = drm_supp_alloc_drv_entry(dip);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (entry == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "drm_supp_register: failed to get softstate");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = &entry->disl_state;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * DRM drivers are required to use common cb_ops
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devop = ddi_get_driver(dip);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (devop->devo_cb_ops != &drm_cb_ops) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devop->devo_cb_ops = &drm_cb_ops;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* Generic graphics initialization */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg gfxp = gfxp_vgatext_softc_alloc();
d0538f66491267879b7418b21ad78e3dcc2dcc83cg error = gfxp_vgatext_attach(dip, DDI_ATTACH, gfxp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (error != DDI_SUCCESS) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_supp_regiter: failed to init gfx");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg goto exit1;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* create a minor node for common graphics ops */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (void) sprintf(buf, "%s%d", GFX_NAME, instance);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg error = ddi_create_minor_node(dip, buf, S_IFCHR,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg INST2NODE0(instance), DDI_NT_DISPLAY, NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (error != DDI_SUCCESS) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_supp_regiter: "
d0538f66491267879b7418b21ad78e3dcc2dcc83cg "failed to create minor node for gfx");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg goto exit2;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* setup mapping for later PCI config space access */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg error = pci_config_setup(dip, &pci_cfg_handle);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (error != DDI_SUCCESS) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_supp_regiter: "
d0538f66491267879b7418b21ad78e3dcc2dcc83cg "PCI configuration space setup failed");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg goto exit2;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* AGP master attach */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg agpm = NULL;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (dp->driver->use_agp) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_DEBUG("drm_supp_regiter: driver use AGP\n");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg error = agpmaster_attach(dip, &agpm,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg pci_cfg_handle, INST2NODE1(instance));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((error != DDI_SUCCESS) && (dp->driver->require_agp)) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_supp_regiter: "
d0538f66491267879b7418b21ad78e3dcc2dcc83cg "AGP master support not available");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg goto exit3;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_major = ddi_driver_major(dip);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_dip = dip;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_gfxp = gfxp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_agpm = agpm;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_cfg_hdl = pci_cfg_handle;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_devp = dp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* create minor node for DRM access */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (void) sprintf(buf, "%s%d", DRM_DEVNODE, instance);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ddi_create_minor_node(dip, buf, S_IFCHR,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg INST2NODE2(instance), DDI_NT_DISPLAY_DRM, 0)) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("supp_regiter: faled to create minor node for drm");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg goto exit4;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return ((void *)mstate);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgexit4:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((dp->driver->use_agp) && agpm)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg agpmaster_detach(&agpm);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgexit3:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg pci_config_teardown(&pci_cfg_handle);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgexit2:
c1374a13e412c4ec42cba867e57347a0e049a822Surya Prakki (void) gfxp_vgatext_detach(dip, DDI_DETACH, gfxp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cgexit1:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg gfxp_vgatext_softc_free(gfxp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_supp_free_drv_entry(dip);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_remove_minor_node(dip, NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_supp_unregister(void *handle)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *list;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = (drm_inst_list_t *)handle;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = &list->disl_state;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* AGP master detach */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mstate->mis_agpm != NULL)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg agpmaster_detach(&mstate->mis_agpm);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* free PCI config access handle */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mstate->mis_cfg_hdl)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg pci_config_teardown(&mstate->mis_cfg_hdl);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* graphics misc module detach */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mstate->mis_gfxp) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (void) gfxp_vgatext_detach(mstate->mis_dip, DDI_DETACH,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_gfxp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg gfxp_vgatext_softc_free(mstate->mis_gfxp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_devp = NULL;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* remove all minor nodes */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_remove_minor_node(mstate->mis_dip, NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_supp_free_drv_entry(mstate->mis_dip);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_SUCCESS);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_sun_open(dev_t *devp, int flag, int otyp, cred_t *credp)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg drm_cminor_t *mp, *newp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_device_t *dp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg minor_t minor;
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg int newminor;
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg int instance;
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg int err;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = drm_sup_devt_to_state(*devp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * return ENXIO for deferred attach so that system can
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * attach us again.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mstate == NULL)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ENXIO);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg /*
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * The lest significant 15 bits are used for minor_number, and
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * the mid 3 bits are used for instance number. All minor numbers
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * are used as follows:
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * 0 -- gfx
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * 1 -- agpmaster
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * 2 -- drm
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * (3, MAX_CLONE_MINOR) -- drm minor node for clone open.
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg minor = DEV2MINOR(*devp);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg instance = DEV2INST(*devp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(minor <= MAX_CLONE_MINOR);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg /*
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * No operations for VGA & AGP mater devices, always return OK.
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((minor == GFX_MINOR) || (minor == AGPMASTER_MINOR))
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (0);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * From here, we start to process drm
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dp = mstate->mis_devp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (!dp)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ENXIO);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * Drm driver implements a software lock to serialize access
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * to graphics hardware based on per-process granulation. Before
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * operating graphics hardware, all clients, including kernel
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * and applications, must acquire this lock via DRM_IOCTL_LOCK
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * ioctl, and release it via DRM_IOCTL_UNLOCK after finishing
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * operations. Drm driver will grant r/w permission to the
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * process which acquires this lock (Kernel is assumed to have
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * process ID 0).
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg *
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * A process might be terminated without releasing drm lock, in
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * this case, drm driver is responsible for clearing the holding.
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * To be informed of process exiting, drm driver uses clone open
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * to guarantee that each call to open(9e) have one corresponding
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * call to close(9e). In most cases, a process will close drm
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * during process termination, so that drm driver could have a
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * chance to release drm lock.
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg *
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * In fact, a driver cannot know exactly when a process exits.
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * Clone open doesn't address this issue completely: Because of
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * inheritance, child processes inherit file descriptors from
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * their parent. As a result, if the parent exits before its
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * children, drm close(9e) entrypoint won't be called until all
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * of its children terminate.
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg *
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * Another issue brought up by inhertance is the process PID
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * that calls the drm close() entry point may not be the same
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * as the one who called open(). Per-process struct is allocated
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * when a process first open() drm, and released when the process
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * last close() drm. Since open()/close() may be not the same
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * process, PID cannot be used for key to lookup per-process
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * struct. So, we associate minor number with per-process struct
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * during open()'ing, and find corresponding process struct
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg * via minor number when close() is called.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg newp = kmem_zalloc(sizeof (drm_cminor_t), KM_SLEEP);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&dp->dev_lock);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg for (newminor = DRM_MIN_CLONEMINOR; newminor < MAX_CLONE_MINOR;
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg newminor ++) {
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg TAILQ_FOREACH(mp, &dp->minordevs, link) {
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg if (mp->minor == newminor)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg break;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mp == NULL)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg goto gotminor;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&dp->dev_lock);
194eb4bb9c059fd0abdb05ffbd39c96998f77443tao chen - Sun Microsystems - Beijing China (void) kmem_free(newp, sizeof (drm_cminor_t));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EMFILE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cggotminor:
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg TAILQ_INSERT_TAIL(&dp->minordevs, newp, link);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg newp->minor = newminor;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&dp->dev_lock);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg err = drm_open(dp, newp, flag, otyp, credp);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg if (err) {
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg mutex_enter(&dp->dev_lock);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg TAILQ_REMOVE(&dp->minordevs, newp, link);
194eb4bb9c059fd0abdb05ffbd39c96998f77443tao chen - Sun Microsystems - Beijing China (void) kmem_free(newp, sizeof (drm_cminor_t));
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg mutex_exit(&dp->dev_lock);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg return (err);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg }
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg /* return a clone minor */
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg newminor = newminor | (instance << NBITSMNODE);
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg *devp = makedevice(getmajor(*devp), newminor);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (err);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_sun_close(dev_t dev, int flag, int otyp, cred_t *credp)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_device_t *dp;
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg minor_t minor;
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg int ret;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = drm_sup_devt_to_state(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mstate == NULL)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EBADF);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg minor = DEV2MINOR(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(minor <= MAX_CLONE_MINOR);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((minor == GFX_MINOR) || (minor == AGPMASTER_MINOR))
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (0);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dp = mstate->mis_devp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (dp == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_sun_close: NULL soft state");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ENXIO);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg ret = drm_close(dp, minor, flag, otyp, credp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
fca314aae8ba1403ba891f2b0e7a172bcdc055c8cg return (ret);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_sun_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cred_t *credp, int *rvalp)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg extern drm_ioctl_desc_t drm_ioctls[];
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_device_t *dp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_ioctl_desc_t *ioctl;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_ioctl_t *func;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_file_t *fpriv;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg minor_t minor;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int retval;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int nr;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (cmd == VIS_GETIDENTIFIER) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ddi_copyout(&text_ident, (void *)arg,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg sizeof (struct vis_identifier), mode))
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EFAULT);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = drm_sup_devt_to_state(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mstate == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EIO);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg minor = DEV2MINOR(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(minor <= MAX_CLONE_MINOR);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg switch (minor) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case GFX_MINOR:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg retval = gfxp_vgatext_ioctl(dev, cmd, arg,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mode, credp, rvalp, mstate->mis_gfxp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (retval);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case AGPMASTER_MINOR:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg retval = agpmaster_ioctl(dev, cmd, arg, mode,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg credp, rvalp, mstate->mis_agpm);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (retval);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case DRM_MINOR:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg default: /* DRM cloning minor nodes */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg break;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dp = mstate->mis_devp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(dp != NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nr = DRM_IOCTL_NR(cmd);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ioctl = &drm_ioctls[nr];
d0538f66491267879b7418b21ad78e3dcc2dcc83cg atomic_inc_32(&dp->counts[_DRM_STAT_IOCTLS]);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* It's not a core DRM ioctl, try driver-specific. */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ioctl->func == NULL && nr >= DRM_COMMAND_BASE) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* The array entries begin at DRM_COMMAND_BASE ioctl nr */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nr -= DRM_COMMAND_BASE;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (nr > dp->driver->max_driver_ioctl) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("Bad driver ioctl number, 0x%x (of 0x%x)",
d0538f66491267879b7418b21ad78e3dcc2dcc83cg nr, dp->driver->max_driver_ioctl);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ioctl = &dp->driver->driver_ioctls[nr];
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg func = ioctl->func;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (func == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ENOTSUP);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&dp->dev_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg fpriv = drm_find_file_by_proc(dp, credp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&dp->dev_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (fpriv == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_sun_ioctl : can't find authenticator");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EACCES);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(credp)) ||
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ((ioctl->flags & DRM_AUTH) && !fpriv->authenticated) ||
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ((ioctl->flags & DRM_MASTER) && !fpriv->master))
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EACCES);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China fpriv->dev = dev;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China fpriv->credp = credp;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
d0538f66491267879b7418b21ad78e3dcc2dcc83cg retval = func(dp, arg, fpriv, mode);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (retval);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_sun_devmap(dev_t dev, devmap_cookie_t dhp, offset_t offset,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg size_t len, size_t *maplen, uint_t model)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg extern int drm_get_pci_index_reg(dev_info_t *, uint_t, uint_t, off_t *);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_device_t *dp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_umem_cookie_t cookie;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_local_map_t *map = NULL;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg unsigned long aperbase;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg u_offset_t handle;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg offset_t koff;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg caddr_t kva;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg minor_t minor;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg size_t length;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int ret;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg static ddi_device_acc_attr_t dev_attr = {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_DEVICE_ATTR_V0,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_NEVERSWAP_ACC,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_STRICTORDER_ACC,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg };
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China static ddi_device_acc_attr_t gem_dev_attr = {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_NEVERSWAP_ACC,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_MERGING_OK_ACC
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China };
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = drm_sup_devt_to_state(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (mstate == NULL)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ENXIO);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg minor = DEV2MINOR(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg switch (minor) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case GFX_MINOR:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ret = gfxp_vgatext_devmap(dev, dhp, offset, len, maplen, model,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate->mis_gfxp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ret);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case AGPMASTER_MINOR:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ENOTSUP);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case DRM_MINOR:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg break;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg default:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* DRM cloning nodes */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (minor > MAX_CLONE_MINOR)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EBADF);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg break;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dp = mstate->mis_devp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (dp == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_sun_devmap: NULL soft state");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&dp->dev_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (dp->driver->use_gem == 1) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct idr_list *entry;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_cminor_t *mp;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China mp = drm_find_file_by_minor(dp, minor);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!mp) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China mutex_exit(&dp->dev_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("drm_sun_devmap: can't find authenticator");
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (EACCES);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dp->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China idr_list_for_each(entry, &(mp->fpriv->object_idr)) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if ((uintptr_t)entry->obj == (u_offset_t)offset) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map = entry->obj->map;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto goon;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinagoon:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dp->struct_mutex);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (map == NULL) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * We will solve 32-bit application on 64-bit kernel
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * issue later, now, we just use low 32-bit
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China handle = (u_offset_t)offset;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China handle &= 0xffffffff;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
d0538f66491267879b7418b21ad78e3dcc2dcc83cg TAILQ_FOREACH(map, &dp->maplist, link) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (handle ==
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ((u_offset_t)((uintptr_t)map->handle) & 0xffffffff))
d0538f66491267879b7418b21ad78e3dcc2dcc83cg break;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Temporarily, because offset is phys_addr for register
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * and framebuffer, is kernel virtual_addr for others
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Maybe we will use hash table to solve this issue later.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (map == NULL) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China TAILQ_FOREACH(map, &dp->maplist, link) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (handle == (map->offset & 0xffffffff))
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China break;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (map == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg u_offset_t tmp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&dp->dev_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "Can't find map, offset=0x%llx, len=%x\n",
d0538f66491267879b7418b21ad78e3dcc2dcc83cg offset, (int)len);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "Current mapping:\n");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg TAILQ_FOREACH(map, &dp->maplist, link) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg tmp = (u_offset_t)((uintptr_t)map->handle) & 0xffffffff;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "map(handle=0x%p, size=0x%lx,type=%d,"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg "offset=0x%lx), handle=%llx, tmp=%lld", map->handle,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg map->size, map->type, map->offset, handle, tmp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (-1);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (map->flags & _DRM_RESTRICTED) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&dp->dev_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "restricted map\n");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (-1);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&dp->dev_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg switch (map->type) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case _DRM_FRAME_BUFFER:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case _DRM_REGISTERS:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int regno;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg off_t regoff;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg regno = drm_get_pci_index_reg(dp->dip,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg map->offset, (uint_t)len, &regoff);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (regno < 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("devmap: failed to get register"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg " offset=0x%llx, len=0x%x", handle, len);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ret = devmap_devmem_setup(dhp, dp->dip, NULL,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg regno, (offset_t)regoff, len, PROT_ALL,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0, &dev_attr);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret != 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *maplen = 0;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("devmap: failed, regno=%d,type=%d,"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg " handle=0x%x, offset=0x%llx, len=0x%x",
d0538f66491267879b7418b21ad78e3dcc2dcc83cg regno, map->type, handle, offset, len);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ret);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *maplen = len;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ret);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case _DRM_SHM:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (map->drm_umem_cookie == NULL)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg length = ptob(btopr(map->size));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ret = devmap_umem_setup(dhp, dp->dip, NULL,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg map->drm_umem_cookie, 0, length,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg PROT_ALL, IOMEM_DATA_CACHED, NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret != 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *maplen = 0;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ret);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *maplen = length;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_SUCCESS);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case _DRM_AGP:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (dp->agp == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "drm_sun_devmap: attempted to mmap AGP"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg "memory before AGP support is enabled");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_FAILURE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg aperbase = dp->agp->base;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg koff = map->offset - aperbase;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg length = ptob(btopr(len));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg kva = map->dev_addr;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cookie = gfxp_umem_cookie_init(kva, length);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (cookie == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "devmap:failed to get umem_cookie");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_FAILURE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((ret = devmap_umem_setup(dhp, dp->dip,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg &drm_devmap_callbacks, cookie, 0, length, PROT_ALL,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IOMEM_DATA_UNCACHED | DEVMAP_ALLOW_REMAP, &dev_attr)) < 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg gfxp_umem_cookie_destroy(cookie);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "devmap:failed, retval=%d", ret);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_FAILURE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *maplen = length;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg break;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case _DRM_SCATTER_GATHER:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg koff = map->offset - (unsigned long)(caddr_t)dp->sg->virtual;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg kva = map->dev_addr + koff;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg length = ptob(btopr(len));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (length > map->size) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "offset=0x%lx, virtual=0x%p,"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg "mapsize=0x%lx,len=0x%lx", map->offset,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dp->sg->virtual, map->size, len);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_FAILURE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cookie = gfxp_umem_cookie_init(kva, length);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (cookie == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "devmap:failed to get umem_cookie");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_FAILURE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ret = devmap_umem_setup(dhp, dp->dip,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg &drm_devmap_callbacks, cookie, 0, length, PROT_ALL,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IOMEM_DATA_UNCACHED | DEVMAP_ALLOW_REMAP, &dev_attr);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret != 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "sun_devmap: umem_setup fail");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg gfxp_umem_cookie_destroy(cookie);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_FAILURE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *maplen = length;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg break;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China case _DRM_TTM:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (map->drm_umem_cookie == NULL)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (EINVAL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (gfxp_devmap_umem_setup(dhp, dp->dip,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China NULL, map->drm_umem_cookie, 0, map->size, PROT_ALL,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China IOMEM_DATA_UC_WR_COMBINE | DEVMAP_ALLOW_REMAP,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China &gem_dev_attr)) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China cmn_err(CE_WARN, "devmap:failed, retval=%d", ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *maplen = map->size;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
d0538f66491267879b7418b21ad78e3dcc2dcc83cg default:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_FAILURE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DDI_SUCCESS);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_devmap_map(devmap_cookie_t dhc, dev_t dev, uint_t flags,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg offset_t offset, size_t len, void **new_priv)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devmap_handle_t *dhp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *statep;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg struct ddi_umem_cookie *cp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg statep = drm_sup_devt_to_state(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(statep != NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * This driver only supports MAP_SHARED,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * and doesn't support MAP_PRIVATE
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (flags & MAP_PRIVATE) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "!DRM driver doesn't support MAP_PRIVATE");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&statep->dis_ctxlock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dhp = (devmap_handle_t *)dhc;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cp = (struct ddi_umem_cookie *)dhp->dh_cookie;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cp->cook_refcnt = 1;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&statep->dis_ctxlock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *new_priv = statep;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (0);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic void
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_devmap_unmap(devmap_cookie_t dhc, void *pvtp, offset_t off, size_t len,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devmap_cookie_t new_dhp1, void **new_pvtp1, devmap_cookie_t new_dhp2,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg void **new_pvtp2)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devmap_handle_t *dhp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devmap_handle_t *ndhp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *statep;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg struct ddi_umem_cookie *cp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg struct ddi_umem_cookie *ncp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dhp = (devmap_handle_t *)dhc;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg statep = (drm_inst_state_t *)pvtp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&statep->dis_ctxlock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cp = (struct ddi_umem_cookie *)dhp->dh_cookie;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (new_dhp1 != NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ndhp = (devmap_handle_t *)new_dhp1;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ncp = (struct ddi_umem_cookie *)ndhp->dh_cookie;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ncp->cook_refcnt ++;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *new_pvtp1 = statep;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(ncp == cp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (new_dhp2 != NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ndhp = (devmap_handle_t *)new_dhp2;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ncp = (struct ddi_umem_cookie *)ndhp->dh_cookie;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ncp->cook_refcnt ++;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *new_pvtp2 = statep;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(ncp == cp);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cp->cook_refcnt --;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (cp->cook_refcnt == 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg gfxp_umem_cookie_destroy(dhp->dh_cookie);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dhp->dh_cookie = NULL;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&statep->dis_ctxlock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic int
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_devmap_dup(devmap_cookie_t dhc, void *pvtp, devmap_cookie_t new_dhc,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg void **new_pvtp)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg devmap_handle_t *dhp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *statep;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg struct ddi_umem_cookie *cp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg statep = (drm_inst_state_t *)pvtp;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&statep->dis_ctxlock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dhp = (devmap_handle_t *)dhc;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cp = (struct ddi_umem_cookie *)dhp->dh_cookie;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cp->cook_refcnt ++;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&statep->dis_ctxlock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *new_pvtp = statep;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (0);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_dev_to_instance(dev_t dev)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (DEV2INST(dev));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * drm_supp_alloc_drv_entry()
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Description:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Create a DRM entry and add it into the instance list (drm_inst_head).
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Note that we don't allow a duplicated entry
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic drm_inst_list_t *
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_supp_alloc_drv_entry(dev_info_t *dip)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t **plist;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *list;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *entry;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* protect the driver list */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg plist = &drm_inst_head;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = *plist;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg while (list) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (list->disl_state.mis_dip == dip) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "%s%d already registered",
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_driver_name(dip), ddi_get_instance(dip));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg plist = &list->disl_next;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = list->disl_next;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* "dip" is not registered, create new one and add to list */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg entry = kmem_zalloc(sizeof (*entry), KM_SLEEP);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *plist = entry;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg entry->disl_state.mis_dip = dip;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_init(&entry->disl_state.mis_lock, NULL, MUTEX_DRIVER, NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_init(&entry->disl_state.dis_ctxlock, NULL, MUTEX_DRIVER, NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (entry);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg} /* drm_supp_alloc_drv_entry */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * drm_supp_free_drv_entry()
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic void
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_supp_free_drv_entry(dev_info_t *dip)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *list;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t **plist;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* protect the driver list */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg plist = &drm_inst_head;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = *plist;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg while (list) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (list->disl_state.mis_dip == dip) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *plist = list->disl_next;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = &list->disl_state;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_destroy(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_destroy(&mstate->dis_ctxlock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg kmem_free(list, sizeof (*list));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg plist = &list->disl_next;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = list->disl_next;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg} /* drm_supp_free_drv_entry() */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * drm_sup_devt_to_state()
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * description:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Get the soft state of DRM instance by device number
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic drm_inst_state_t *
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_sup_devt_to_state(dev_t dev)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *list;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg major_t major = getmajor(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int instance = DEV2INST(dev);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = drm_inst_head;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg while (list) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = &list->disl_state;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((mstate->mis_major == major) &&
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (ddi_get_instance(mstate->mis_dip) == instance)) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (mstate);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = list->disl_next;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&mstate->mis_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&drm_inst_list_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg} /* drm_sup_devt_to_state() */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_supp_get_irq(void *handle)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *list;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int irq;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = (drm_inst_list_t *)handle;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = &list->disl_state;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(mstate != NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg irq = pci_config_get8(mstate->mis_cfg_hdl, PCI_CONF_ILINE);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (irq);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_supp_device_capability(void *handle, int capid)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_list_t *list;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_inst_state_t *mstate;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg uint8_t cap = 0;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg uint16_t caps_ptr;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg list = (drm_inst_list_t *)handle;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mstate = &list->disl_state;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(mstate != NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* has capabilities list ? */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((pci_config_get16(mstate->mis_cfg_hdl, PCI_CONF_STAT) &
d0538f66491267879b7418b21ad78e3dcc2dcc83cg PCI_CONF_CAP_MASK) == 0)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg caps_ptr = pci_config_get8(mstate->mis_cfg_hdl, PCI_CONF_CAP_PTR);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg while (caps_ptr != PCI_CAP_NEXT_PTR_NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cap = pci_config_get32(mstate->mis_cfg_hdl, caps_ptr);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((cap & PCI_CONF_CAPID_MASK) == capid)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (cap);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg caps_ptr = pci_config_get8(mstate->mis_cfg_hdl,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg caps_ptr + PCI_CAP_NEXT_PTR);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (0);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}