60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Use is subject to license terms.
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/* BEGIN CSTYLED */
60405de4d8688d96dd05157c28db3ade5c9bc234kz/**
60405de4d8688d96dd05157c28db3ade5c9bc234kz * \file drm_pci.h
60405de4d8688d96dd05157c28db3ade5c9bc234kz * \brief PCI consistent, DMA-accessible memory functions.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * \author Eric Anholt <anholt@FreeBSD.org>
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*-
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Copyright 2003 Eric Anholt.
60405de4d8688d96dd05157c28db3ade5c9bc234kz * All Rights Reserved.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Permission is hereby granted, free of charge, to any person obtaining a
60405de4d8688d96dd05157c28db3ade5c9bc234kz * copy of this software and associated documentation files (the "Software"),
60405de4d8688d96dd05157c28db3ade5c9bc234kz * to deal in the Software without restriction, including without limitation
60405de4d8688d96dd05157c28db3ade5c9bc234kz * the rights to use, copy, modify, merge, publish, distribute, sublicense,
60405de4d8688d96dd05157c28db3ade5c9bc234kz * and/or sell copies of the Software, and to permit persons to whom the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Software is furnished to do so, subject to the following conditions:
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * The above copyright notice and this permission notice (including the next
60405de4d8688d96dd05157c28db3ade5c9bc234kz * paragraph) shall be included in all copies or substantial portions of the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Software.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60405de4d8688d96dd05157c28db3ade5c9bc234kz * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60405de4d8688d96dd05157c28db3ade5c9bc234kz * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
60405de4d8688d96dd05157c28db3ade5c9bc234kz * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
60405de4d8688d96dd05157c28db3ade5c9bc234kz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
60405de4d8688d96dd05157c28db3ade5c9bc234kz * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/**********************************************************************/
60405de4d8688d96dd05157c28db3ade5c9bc234kz/** \name PCI memory */
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*@{*/
60405de4d8688d96dd05157c28db3ade5c9bc234kz/* END CSTYLED */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz#pragma ident "%Z%%M% %I% %E% SMI"
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz#include "drmP.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include <vm/seg_kmem.h>
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz#define PCI_DEVICE(x) (((x)>>11) & 0x1f)
60405de4d8688d96dd05157c28db3ade5c9bc234kz#define PCI_FUNCTION(x) (((x) & 0x700) >> 8)
60405de4d8688d96dd05157c28db3ade5c9bc234kz#define PCI_BUS(x) (((x) & 0xff0000) >> 16)
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kztypedef struct drm_pci_resource {
60405de4d8688d96dd05157c28db3ade5c9bc234kz uint_t regnum;
60405de4d8688d96dd05157c28db3ade5c9bc234kz unsigned long offset;
60405de4d8688d96dd05157c28db3ade5c9bc234kz unsigned long size;
60405de4d8688d96dd05157c28db3ade5c9bc234kz} drm_pci_resource_t;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgpci_get_info(drm_device_t *softstate, int *bus, int *slot, int *func)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz int *regs_list;
60405de4d8688d96dd05157c28db3ade5c9bc234kz uint_t nregs = 0;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, softstate->dip,
60405de4d8688d96dd05157c28db3ade5c9bc234kz DDI_PROP_DONTPASS, "reg", (int **)&regs_list, &nregs)
60405de4d8688d96dd05157c28db3ade5c9bc234kz != DDI_PROP_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("pci_get_info: get pci function bus device failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz goto error;
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz *bus = (int)PCI_BUS(regs_list[0]);
60405de4d8688d96dd05157c28db3ade5c9bc234kz *slot = (int)PCI_DEVICE(regs_list[0]);
60405de4d8688d96dd05157c28db3ade5c9bc234kz *func = (int)PCI_FUNCTION(regs_list[0]);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (nregs > 0) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz ddi_prop_free(regs_list);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_SUCCESS);
60405de4d8688d96dd05157c28db3ade5c9bc234kzerror:
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (nregs > 0) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz ddi_prop_free(regs_list);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgpci_get_irq(drm_device_t *statep)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int irq;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg extern int drm_supp_get_irq(void *);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg irq = ddi_prop_get_int(DDI_DEV_T_ANY,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg statep->dip, DDI_PROP_DONTPASS, "interrupts", -1);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (irq > 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg irq = drm_supp_get_irq(statep->drm_handle);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (irq);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgpci_get_vendor(drm_device_t *statep)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int vendorid;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vendorid = ddi_prop_get_int(DDI_DEV_T_ANY,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg statep->dip, DDI_PROP_DONTPASS, "vendor-id", 0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (vendorid);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cgint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgpci_get_device(drm_device_t *statep)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int deviceid;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg deviceid = ddi_prop_get_int(DDI_DEV_T_ANY,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg statep->dip, DDI_PROP_DONTPASS, "device-id", 0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (deviceid);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzvoid
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_core_ioremap(struct drm_local_map *map, drm_device_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((map->type == _DRM_AGP) && dev->agp) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * During AGP mapping initialization, we map AGP aperture
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * into kernel space. So, when we access the memory which
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * managed by agp gart in kernel space, we have to go
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * through two-level address translation: kernel virtual
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * address --> aperture address --> physical address. For
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * improving this, here in opensourced code, agp_remap()
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * gets invoking to dispose the mapping between agp aperture
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * and kernel space, and directly map the actual physical
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * memory which is allocated to agp gart to kernel space.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * After that, access to physical memory managed by agp gart
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * hardware in kernel space doesn't go through agp hardware,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * it will be: kernel virtual ---> physical address.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Obviously, it is more efficient. But in solaris operating
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * system, the ioctl AGPIOC_ALLOCATE of apggart driver does
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * not return physical address. We are unable to create the
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * direct mapping between kernel space and agp memory. So,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * we remove the calling to agp_remap().
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_DEBUG("drm_core_ioremap: skipping agp_remap\n");
60405de4d8688d96dd05157c28db3ade5c9bc234kz } else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (void) drm_ioremap(dev, map);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzvoid
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_core_ioremapfree(struct drm_local_map *map, drm_device_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (map->type != _DRM_AGP) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (map->handle && map->size)
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_ioremapfree(map);
60405de4d8688d96dd05157c28db3ade5c9bc234kz } else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Refer to the comments in drm_core_ioremap() where we removed
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * the calling to agp_remap(), correspondingly, we remove the
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * calling to agp_remap_free(dev, map);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_DEBUG("drm_core_ioremap: skipping agp_remap_free\n");
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzstruct drm_local_map *
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_core_findmap(drm_device_t *dev, unsigned long handle)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_local_map_t *map;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_SPINLOCK_ASSERT(&dev->dev_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * For the time being, we compare the low 32 bit only,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * We will hash handle to 32-bit to solve this issue later.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
60405de4d8688d96dd05157c28db3ade5c9bc234kz TAILQ_FOREACH(map, &dev->maplist, link) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((((unsigned long)map->handle) & 0x00000000ffffffff)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg == (handle & 0x00000000ffffffff))
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (map);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (NULL);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * pci_alloc_consistent()
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic ddi_dma_attr_t hw_dma_attr = {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DMA_ATTR_V0, /* version */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0, /* addr_lo */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0xffffffff, /* addr_hi */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0xffffffff, /* count_max */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 4096, /* alignment */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0xfff, /* burstsize */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 1, /* minxfer */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0xffffffff, /* maxxfer */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0xffffffff, /* seg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 1, /* sgllen */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 4, /* granular */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 0 /* flags */
60405de4d8688d96dd05157c28db3ade5c9bc234kz};
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzstatic ddi_device_acc_attr_t hw_acc_attr = {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DDI_DEVICE_ATTR_V0,
60405de4d8688d96dd05157c28db3ade5c9bc234kz DDI_NEVERSWAP_ACC,
60405de4d8688d96dd05157c28db3ade5c9bc234kz DDI_STRICTORDER_ACC
60405de4d8688d96dd05157c28db3ade5c9bc234kz};
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
60405de4d8688d96dd05157c28db3ade5c9bc234kzvoid *
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_pci_alloc(drm_device_t *dev, size_t size,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg size_t align, dma_addr_t maxaddr, int segments)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_dma_handle_t *dmah;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg uint_t count;
60405de4d8688d96dd05157c28db3ade5c9bc234kz int ret = DDI_FAILURE;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* allocat continous physical memory for hw status page */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (align == 0)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg hw_dma_attr.dma_attr_align = 1;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg else
d0538f66491267879b7418b21ad78e3dcc2dcc83cg hw_dma_attr.dma_attr_align = align;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg hw_dma_attr.dma_attr_addr_hi = maxaddr;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg hw_dma_attr.dma_attr_sgllen = segments;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dmah = kmem_zalloc(sizeof (drm_dma_handle_t), KM_SLEEP);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret = ddi_dma_alloc_handle(dev->dip, &hw_dma_attr,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_DMA_SLEEP, NULL, &dmah->dma_hdl)) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_pci_alloc:ddi_dma_alloc_handle failed\n");
60405de4d8688d96dd05157c28db3ade5c9bc234kz goto err3;
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret = ddi_dma_mem_alloc(dmah->dma_hdl, size, &hw_acc_attr,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_DMA_CONSISTENT | IOMEM_DATA_UNCACHED,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_DMA_SLEEP, NULL, (caddr_t *)&dmah->vaddr,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg &dmah->real_sz, &dmah->acc_hdl)) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_pci_alloc: ddi_dma_mem_alloc failed\n");
60405de4d8688d96dd05157c28db3ade5c9bc234kz goto err2;
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ret = ddi_dma_addr_bind_handle(dmah->dma_hdl, NULL,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (caddr_t)dmah->vaddr, dmah->real_sz,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_DMA_SLEEP, NULL, &dmah->cookie, &count);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret != DDI_DMA_MAPPED) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_pci_alloc: alloc phys memory failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz goto err1;
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (count > segments) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (void) ddi_dma_unbind_handle(dmah->dma_hdl);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg goto err1;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dmah->cookie_num = count;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (count == 1)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dmah->paddr = dmah->cookie.dmac_address;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (dmah);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzerr1:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_dma_mem_free(&dmah->acc_hdl);
60405de4d8688d96dd05157c28db3ade5c9bc234kzerr2:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_dma_free_handle(&dmah->dma_hdl);
60405de4d8688d96dd05157c28db3ade5c9bc234kzerr3:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg kmem_free(dmah, sizeof (*dmah));
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (NULL);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * pci_free_consistent()
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzvoid
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ASSERT(dmah != NULL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (void) ddi_dma_unbind_handle(dmah->dma_hdl);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_dma_mem_free(&dmah->acc_hdl);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ddi_dma_free_handle(&dmah->dma_hdl);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg kmem_free(dmah, sizeof (drm_dma_handle_t));
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdo_get_pci_res(drm_device_t *dev, drm_pci_resource_t *resp)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz int length;
60405de4d8688d96dd05157c28db3ade5c9bc234kz pci_regspec_t *regs;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_getlongprop(
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DDI_DEV_T_ANY, dev->dip, DDI_PROP_DONTPASS,
60405de4d8688d96dd05157c28db3ade5c9bc234kz "assigned-addresses", (caddr_t)&regs, &length) !=
60405de4d8688d96dd05157c28db3ade5c9bc234kz DDI_PROP_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("do_get_pci_res: ddi_getlongprop failed!\n");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EFAULT);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz resp->offset =
60405de4d8688d96dd05157c28db3ade5c9bc234kz (unsigned long)regs[resp->regnum].pci_phys_low;
60405de4d8688d96dd05157c28db3ade5c9bc234kz resp->size =
60405de4d8688d96dd05157c28db3ade5c9bc234kz (unsigned long)regs[resp->regnum].pci_size_low;
60405de4d8688d96dd05157c28db3ade5c9bc234kz kmem_free(regs, (size_t)length);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzunsigned long
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_get_resource_start(drm_device_t *softstate, unsigned int regnum)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_pci_resource_t res;
60405de4d8688d96dd05157c28db3ade5c9bc234kz int ret;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz res.regnum = regnum;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz ret = do_get_pci_res(softstate, &res);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret != 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_get_resource_start: ioctl failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (res.offset);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzunsigned long
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_get_resource_len(drm_device_t *softstate, unsigned int regnum)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_pci_resource_t res;
60405de4d8688d96dd05157c28db3ade5c9bc234kz int ret;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz res.regnum = regnum;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz ret = do_get_pci_res(softstate, &res);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ret != 0) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_ERROR("drm_get_resource_len: ioctl failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (res.size);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}