kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 1 | /* |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 2 | * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 3 | * Use is subject to license terms. |
| 4 | */ |
| 5 | |
| 6 | /* BEGIN CSTYLED */ |
| 7 | /** |
| 8 | * \file drm_pci.h |
| 9 | * \brief PCI consistent, DMA-accessible memory functions. |
| 10 | * |
| 11 | * \author Eric Anholt <anholt@FreeBSD.org> |
| 12 | */ |
| 13 | |
| 14 | /*- |
| 15 | * Copyright 2003 Eric Anholt. |
| 16 | * All Rights Reserved. |
| 17 | * |
| 18 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 19 | * copy of this software and associated documentation files (the "Software"), |
| 20 | * to deal in the Software without restriction, including without limitation |
| 21 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 22 | * and/or sell copies of the Software, and to permit persons to whom the |
| 23 | * Software is furnished to do so, subject to the following conditions: |
| 24 | * |
| 25 | * The above copyright notice and this permission notice (including the next |
| 26 | * paragraph) shall be included in all copies or substantial portions of the |
| 27 | * Software. |
| 28 | * |
| 29 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 30 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 31 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 32 | * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| 33 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| 34 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 35 | */ |
| 36 | |
| 37 | /**********************************************************************/ |
| 38 | /** \name PCI memory */ |
| 39 | /*@{*/ |
| 40 | /* END CSTYLED */ |
| 41 | |
| 42 | #pragma ident "%Z%%M% %I% %E% SMI" |
| 43 | |
| 44 | #include "drmP.h" |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 45 | #include <vm/seg_kmem.h> |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 46 | |
| 47 | #define PCI_DEVICE(x) (((x)>>11) & 0x1f) |
| 48 | #define PCI_FUNCTION(x) (((x) & 0x700) >> 8) |
| 49 | #define PCI_BUS(x) (((x) & 0xff0000) >> 16) |
| 50 | |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 51 | typedef struct drm_pci_resource { |
| 52 | uint_t regnum; |
| 53 | unsigned long offset; |
| 54 | unsigned long size; |
| 55 | } drm_pci_resource_t; |
| 56 | |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 57 | int |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 58 | pci_get_info(drm_device_t *softstate, int *bus, int *slot, int *func) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 59 | { |
| 60 | int *regs_list; |
| 61 | uint_t nregs = 0; |
| 62 | |
| 63 | if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, softstate->dip, |
| 64 | DDI_PROP_DONTPASS, "reg", (int **)®s_list, &nregs) |
| 65 | != DDI_PROP_SUCCESS) { |
| 66 | DRM_ERROR("pci_get_info: get pci function bus device failed"); |
| 67 | goto error; |
| 68 | } |
| 69 | *bus = (int)PCI_BUS(regs_list[0]); |
| 70 | *slot = (int)PCI_DEVICE(regs_list[0]); |
| 71 | *func = (int)PCI_FUNCTION(regs_list[0]); |
| 72 | |
| 73 | if (nregs > 0) { |
| 74 | ddi_prop_free(regs_list); |
| 75 | } |
| 76 | return (DDI_SUCCESS); |
| 77 | error: |
| 78 | if (nregs > 0) { |
| 79 | ddi_prop_free(regs_list); |
| 80 | } |
| 81 | return (DDI_FAILURE); |
| 82 | } |
| 83 | |
| 84 | int |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 85 | pci_get_irq(drm_device_t *statep) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 86 | { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 87 | int irq; |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 88 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 89 | extern int drm_supp_get_irq(void *); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 90 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 91 | irq = ddi_prop_get_int(DDI_DEV_T_ANY, |
| 92 | statep->dip, DDI_PROP_DONTPASS, "interrupts", -1); |
| 93 | |
| 94 | if (irq > 0) { |
| 95 | irq = drm_supp_get_irq(statep->drm_handle); |
| 96 | } |
| 97 | |
| 98 | return (irq); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | int |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 102 | pci_get_vendor(drm_device_t *statep) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 103 | { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 104 | int vendorid; |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 105 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 106 | vendorid = ddi_prop_get_int(DDI_DEV_T_ANY, |
| 107 | statep->dip, DDI_PROP_DONTPASS, "vendor-id", 0); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 108 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 109 | return (vendorid); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | int |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 113 | pci_get_device(drm_device_t *statep) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 114 | { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 115 | int deviceid; |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 116 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 117 | deviceid = ddi_prop_get_int(DDI_DEV_T_ANY, |
| 118 | statep->dip, DDI_PROP_DONTPASS, "device-id", 0); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 119 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 120 | return (deviceid); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | void |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 124 | drm_core_ioremap(struct drm_local_map *map, drm_device_t *dev) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 125 | { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 126 | if ((map->type == _DRM_AGP) && dev->agp) { |
| 127 | /* |
| 128 | * During AGP mapping initialization, we map AGP aperture |
| 129 | * into kernel space. So, when we access the memory which |
| 130 | * managed by agp gart in kernel space, we have to go |
| 131 | * through two-level address translation: kernel virtual |
| 132 | * address --> aperture address --> physical address. For |
| 133 | * improving this, here in opensourced code, agp_remap() |
| 134 | * gets invoking to dispose the mapping between agp aperture |
| 135 | * and kernel space, and directly map the actual physical |
| 136 | * memory which is allocated to agp gart to kernel space. |
| 137 | * After that, access to physical memory managed by agp gart |
| 138 | * hardware in kernel space doesn't go through agp hardware, |
| 139 | * it will be: kernel virtual ---> physical address. |
| 140 | * Obviously, it is more efficient. But in solaris operating |
| 141 | * system, the ioctl AGPIOC_ALLOCATE of apggart driver does |
| 142 | * not return physical address. We are unable to create the |
| 143 | * direct mapping between kernel space and agp memory. So, |
| 144 | * we remove the calling to agp_remap(). |
| 145 | */ |
| 146 | DRM_DEBUG("drm_core_ioremap: skipping agp_remap\n"); |
| 147 | } else { |
| 148 | (void) drm_ioremap(dev, map); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 149 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 150 | } |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 151 | } |
| 152 | |
| 153 | /*ARGSUSED*/ |
| 154 | void |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 155 | drm_core_ioremapfree(struct drm_local_map *map, drm_device_t *dev) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 156 | { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 157 | if (map->type != _DRM_AGP) { |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 158 | if (map->handle && map->size) |
| 159 | drm_ioremapfree(map); |
| 160 | } else { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 161 | /* |
| 162 | * Refer to the comments in drm_core_ioremap() where we removed |
| 163 | * the calling to agp_remap(), correspondingly, we remove the |
| 164 | * calling to agp_remap_free(dev, map); |
| 165 | */ |
| 166 | DRM_DEBUG("drm_core_ioremap: skipping agp_remap_free\n"); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 167 | } |
| 168 | } |
| 169 | |
| 170 | struct drm_local_map * |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 171 | drm_core_findmap(drm_device_t *dev, unsigned long handle) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 172 | { |
| 173 | drm_local_map_t *map; |
| 174 | |
| 175 | DRM_SPINLOCK_ASSERT(&dev->dev_lock); |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 176 | |
| 177 | /* |
| 178 | * For the time being, we compare the low 32 bit only, |
| 179 | * We will hash handle to 32-bit to solve this issue later. |
| 180 | */ |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 181 | TAILQ_FOREACH(map, &dev->maplist, link) { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 182 | if ((((unsigned long)map->handle) & 0x00000000ffffffff) |
| 183 | == (handle & 0x00000000ffffffff)) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 184 | return (map); |
| 185 | } |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 186 | |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 187 | return (NULL); |
| 188 | } |
| 189 | |
| 190 | /* |
| 191 | * pci_alloc_consistent() |
| 192 | */ |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 193 | static ddi_dma_attr_t hw_dma_attr = { |
| 194 | DMA_ATTR_V0, /* version */ |
| 195 | 0, /* addr_lo */ |
| 196 | 0xffffffff, /* addr_hi */ |
| 197 | 0xffffffff, /* count_max */ |
| 198 | 4096, /* alignment */ |
| 199 | 0xfff, /* burstsize */ |
| 200 | 1, /* minxfer */ |
| 201 | 0xffffffff, /* maxxfer */ |
| 202 | 0xffffffff, /* seg */ |
| 203 | 1, /* sgllen */ |
| 204 | 4, /* granular */ |
| 205 | 0 /* flags */ |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 206 | }; |
| 207 | |
| 208 | static ddi_device_acc_attr_t hw_acc_attr = { |
| 209 | DDI_DEVICE_ATTR_V0, |
| 210 | DDI_NEVERSWAP_ACC, |
| 211 | DDI_STRICTORDER_ACC |
| 212 | }; |
| 213 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 214 | |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 215 | void * |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 216 | drm_pci_alloc(drm_device_t *dev, size_t size, |
| 217 | size_t align, dma_addr_t maxaddr, int segments) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 218 | { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 219 | drm_dma_handle_t *dmah; |
| 220 | uint_t count; |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 221 | int ret = DDI_FAILURE; |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 222 | |
| 223 | /* allocat continous physical memory for hw status page */ |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 224 | if (align == 0) |
| 225 | hw_dma_attr.dma_attr_align = 1; |
| 226 | else |
| 227 | hw_dma_attr.dma_attr_align = align; |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 228 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 229 | hw_dma_attr.dma_attr_addr_hi = maxaddr; |
| 230 | hw_dma_attr.dma_attr_sgllen = segments; |
| 231 | |
| 232 | dmah = kmem_zalloc(sizeof (drm_dma_handle_t), KM_SLEEP); |
| 233 | if (ret = ddi_dma_alloc_handle(dev->dip, &hw_dma_attr, |
| 234 | DDI_DMA_SLEEP, NULL, &dmah->dma_hdl)) { |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 235 | DRM_ERROR("drm_pci_alloc:ddi_dma_alloc_handle failed\n"); |
| 236 | goto err3; |
| 237 | } |
| 238 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 239 | if (ret = ddi_dma_mem_alloc(dmah->dma_hdl, size, &hw_acc_attr, |
| 240 | DDI_DMA_CONSISTENT | IOMEM_DATA_UNCACHED, |
| 241 | DDI_DMA_SLEEP, NULL, (caddr_t *)&dmah->vaddr, |
| 242 | &dmah->real_sz, &dmah->acc_hdl)) { |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 243 | DRM_ERROR("drm_pci_alloc: ddi_dma_mem_alloc failed\n"); |
| 244 | goto err2; |
| 245 | } |
| 246 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 247 | ret = ddi_dma_addr_bind_handle(dmah->dma_hdl, NULL, |
| 248 | (caddr_t)dmah->vaddr, dmah->real_sz, |
| 249 | DDI_DMA_RDWR|DDI_DMA_CONSISTENT, |
| 250 | DDI_DMA_SLEEP, NULL, &dmah->cookie, &count); |
| 251 | if (ret != DDI_DMA_MAPPED) { |
| 252 | DRM_ERROR("drm_pci_alloc: alloc phys memory failed"); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 253 | goto err1; |
| 254 | } |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 255 | |
| 256 | if (count > segments) { |
| 257 | (void) ddi_dma_unbind_handle(dmah->dma_hdl); |
| 258 | goto err1; |
| 259 | } |
| 260 | |
| 261 | dmah->cookie_num = count; |
| 262 | if (count == 1) |
| 263 | dmah->paddr = dmah->cookie.dmac_address; |
| 264 | |
| 265 | return (dmah); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 266 | |
| 267 | err1: |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 268 | ddi_dma_mem_free(&dmah->acc_hdl); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 269 | err2: |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 270 | ddi_dma_free_handle(&dmah->dma_hdl); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 271 | err3: |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 272 | kmem_free(dmah, sizeof (*dmah)); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 273 | return (NULL); |
| 274 | } |
| 275 | |
| 276 | /* |
| 277 | * pci_free_consistent() |
| 278 | */ |
| 279 | /*ARGSUSED*/ |
| 280 | void |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 281 | drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 282 | { |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 283 | ASSERT(dmah != NULL); |
| 284 | (void) ddi_dma_unbind_handle(dmah->dma_hdl); |
| 285 | ddi_dma_mem_free(&dmah->acc_hdl); |
| 286 | ddi_dma_free_handle(&dmah->dma_hdl); |
| 287 | kmem_free(dmah, sizeof (drm_dma_handle_t)); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 288 | } |
| 289 | |
| 290 | int |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 291 | do_get_pci_res(drm_device_t *dev, drm_pci_resource_t *resp) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 292 | { |
| 293 | int length; |
| 294 | pci_regspec_t *regs; |
| 295 | |
| 296 | if (ddi_getlongprop( |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 297 | DDI_DEV_T_ANY, dev->dip, DDI_PROP_DONTPASS, |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 298 | "assigned-addresses", (caddr_t)®s, &length) != |
| 299 | DDI_PROP_SUCCESS) { |
| 300 | DRM_ERROR("do_get_pci_res: ddi_getlongprop failed!\n"); |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 301 | return (EFAULT); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 302 | } |
| 303 | resp->offset = |
| 304 | (unsigned long)regs[resp->regnum].pci_phys_low; |
| 305 | resp->size = |
| 306 | (unsigned long)regs[resp->regnum].pci_size_low; |
| 307 | kmem_free(regs, (size_t)length); |
| 308 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 309 | return (0); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 310 | } |
| 311 | |
| 312 | /*ARGSUSED*/ |
| 313 | unsigned long |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 314 | drm_get_resource_start(drm_device_t *softstate, unsigned int regnum) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 315 | { |
| 316 | drm_pci_resource_t res; |
| 317 | int ret; |
| 318 | |
| 319 | res.regnum = regnum; |
| 320 | |
| 321 | ret = do_get_pci_res(softstate, &res); |
| 322 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 323 | if (ret != 0) { |
| 324 | DRM_ERROR("drm_get_resource_start: ioctl failed"); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 325 | return (0); |
| 326 | } |
| 327 | |
| 328 | return (res.offset); |
| 329 | |
| 330 | } |
| 331 | |
| 332 | /*ARGSUSED*/ |
| 333 | unsigned long |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 334 | drm_get_resource_len(drm_device_t *softstate, unsigned int regnum) |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 335 | { |
| 336 | drm_pci_resource_t res; |
| 337 | int ret; |
| 338 | |
| 339 | res.regnum = regnum; |
| 340 | |
| 341 | ret = do_get_pci_res(softstate, &res); |
| 342 | |
cg149915 | d0538f6 | 2008-01-09 19:45:15 -0800 | [diff] [blame] | 343 | if (ret != 0) { |
| 344 | DRM_ERROR("drm_get_resource_len: ioctl failed"); |
kz151634 | 60405de | 2006-09-28 01:41:18 -0700 | [diff] [blame] | 345 | return (0); |
| 346 | } |
| 347 | |
| 348 | return (res.size); |
| 349 | } |