Commit ee2fae03 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm: Stop defining pci_pretty_name
  drm: r128: comment aligment with drm git
  drm: make kernel context switch same as for drm git tree.
  drm: fixup comment header style
  drm: savage: compat fix from drm git.
  drm: Unify radeon offset checking.
  i915_vblank_tasklet: Try harder to avoid tearing.
  DRM: handle pci_enable_device failure
  drm: fix return value check
parents e4ddc9cc f9841a8d
...@@ -561,8 +561,7 @@ struct drm_driver { ...@@ -561,8 +561,7 @@ struct drm_driver {
int (*context_dtor) (struct drm_device * dev, int context); int (*context_dtor) (struct drm_device * dev, int context);
int (*kernel_context_switch) (struct drm_device * dev, int old, int (*kernel_context_switch) (struct drm_device * dev, int old,
int new); int new);
void (*kernel_context_switch_unlock) (struct drm_device * dev, void (*kernel_context_switch_unlock) (struct drm_device * dev);
drm_lock_t *lock);
int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence); int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence);
int (*dri_library_name) (struct drm_device *dev, char *buf); int (*dri_library_name) (struct drm_device *dev, char *buf);
...@@ -1143,9 +1142,5 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area); ...@@ -1143,9 +1142,5 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area);
extern unsigned long drm_core_get_map_ofs(drm_map_t * map); extern unsigned long drm_core_get_map_ofs(drm_map_t * map);
extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
#ifndef pci_pretty_name
#define pci_pretty_name(dev) ""
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif #endif
...@@ -182,7 +182,7 @@ int drm_unlock(struct inode *inode, struct file *filp, ...@@ -182,7 +182,7 @@ int drm_unlock(struct inode *inode, struct file *filp,
* modules but is required by the Sparc driver. * modules but is required by the Sparc driver.
*/ */
if (dev->driver->kernel_context_switch_unlock) if (dev->driver->kernel_context_switch_unlock)
dev->driver->kernel_context_switch_unlock(dev, &lock); dev->driver->kernel_context_switch_unlock(dev);
else { else {
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT); DRM_KERNEL_CONTEXT);
......
...@@ -211,14 +211,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, ...@@ -211,14 +211,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
pci_enable_device(pdev); ret = pci_enable_device(pdev);
if (ret)
goto err_g1;
if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
goto err_g1; goto err_g2;
} }
if ((ret = drm_get_head(dev, &dev->primary))) if ((ret = drm_get_head(dev, &dev->primary)))
goto err_g1; goto err_g2;
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel, driver->name, driver->major, driver->minor, driver->patchlevel,
...@@ -226,7 +228,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, ...@@ -226,7 +228,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
return 0; return 0;
err_g1: err_g2:
pci_disable_device(pdev);
err_g1:
drm_free(dev, sizeof(*dev), DRM_MEM_STUB); drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
return ret; return ret;
} }
......
...@@ -45,8 +45,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name) ...@@ -45,8 +45,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
int err; int err;
class = class_create(owner, name); class = class_create(owner, name);
if (!class) { if (IS_ERR(class)) {
err = -ENOMEM; err = PTR_ERR(class);
goto err_out; goto err_out;
} }
...@@ -113,8 +113,8 @@ struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) ...@@ -113,8 +113,8 @@ struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
MKDEV(DRM_MAJOR, head->minor), MKDEV(DRM_MAJOR, head->minor),
&(head->dev->pdev)->dev, &(head->dev->pdev)->dev,
"card%d", head->minor); "card%d", head->minor);
if (!class_dev) { if (IS_ERR(class_dev)) {
err = -ENOMEM; err = PTR_ERR(class_dev);
goto err_out; goto err_out;
} }
......
...@@ -46,41 +46,82 @@ static void i915_vblank_tasklet(drm_device_t *dev) ...@@ -46,41 +46,82 @@ static void i915_vblank_tasklet(drm_device_t *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags; unsigned long irqflags;
struct list_head *list, *tmp; struct list_head *list, *tmp, hits, *hit;
int nhits, nrects, slice[2], upper[2], lower[2], i;
unsigned counter[2] = { atomic_read(&dev->vbl_received),
atomic_read(&dev->vbl_received2) };
drm_drawable_info_t *drw;
drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
u32 cpp = dev_priv->cpp;
u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB)
: XY_SRC_COPY_BLT_CMD;
u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
(cpp << 23) | (1 << 24);
RING_LOCALS;
DRM_DEBUG("\n"); DRM_DEBUG("\n");
INIT_LIST_HEAD(&hits);
nhits = nrects = 0;
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
/* Find buffer swaps scheduled for this vertical blank */
list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
drm_i915_vbl_swap_t *vbl_swap = drm_i915_vbl_swap_t *vbl_swap =
list_entry(list, drm_i915_vbl_swap_t, head); list_entry(list, drm_i915_vbl_swap_t, head);
atomic_t *counter = vbl_swap->pipe ? &dev->vbl_received2 :
&dev->vbl_received;
if ((atomic_read(counter) - vbl_swap->sequence) <= (1<<23)) { if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
drm_drawable_info_t *drw; continue;
spin_unlock(&dev_priv->swaps_lock); list_del(list);
dev_priv->swaps_pending--;
spin_unlock(&dev_priv->swaps_lock);
spin_lock(&dev->drw_lock); spin_lock(&dev->drw_lock);
drw = drm_get_drawable_info(dev, vbl_swap->drw_id); drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
if (drw) { if (!drw) {
int i, num_rects = drw->num_rects; spin_unlock(&dev->drw_lock);
drm_clip_rect_t *rect = drw->rects; drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
drm_i915_sarea_t *sarea_priv = spin_lock(&dev_priv->swaps_lock);
dev_priv->sarea_priv; continue;
u32 cpp = dev_priv->cpp; }
u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
XY_SRC_COPY_BLT_WRITE_ALPHA | list_for_each(hit, &hits) {
XY_SRC_COPY_BLT_WRITE_RGB) drm_i915_vbl_swap_t *swap_cmp =
: XY_SRC_COPY_BLT_CMD; list_entry(hit, drm_i915_vbl_swap_t, head);
u32 pitchropcpp = (sarea_priv->pitch * cpp) | drm_drawable_info_t *drw_cmp =
(0xcc << 16) | (cpp << 23) | drm_get_drawable_info(dev, swap_cmp->drw_id);
(1 << 24);
RING_LOCALS; if (drw_cmp &&
drw_cmp->rects[0].y1 > drw->rects[0].y1) {
list_add_tail(list, hit);
break;
}
}
spin_unlock(&dev->drw_lock);
/* List of hits was empty, or we reached the end of it */
if (hit == &hits)
list_add_tail(list, hits.prev);
nhits++;
spin_lock(&dev_priv->swaps_lock);
}
if (nhits == 0) {
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
return;
}
spin_unlock(&dev_priv->swaps_lock);
i915_kernel_lost_context(dev); i915_kernel_lost_context(dev);
...@@ -89,45 +130,83 @@ static void i915_vblank_tasklet(drm_device_t *dev) ...@@ -89,45 +130,83 @@ static void i915_vblank_tasklet(drm_device_t *dev)
OUT_RING(GFX_OP_DRAWRECT_INFO); OUT_RING(GFX_OP_DRAWRECT_INFO);
OUT_RING(0); OUT_RING(0);
OUT_RING(0); OUT_RING(0);
OUT_RING(sarea_priv->width | OUT_RING(sarea_priv->width | sarea_priv->height << 16);
sarea_priv->height << 16); OUT_RING(sarea_priv->width | sarea_priv->height << 16);
OUT_RING(sarea_priv->width |
sarea_priv->height << 16);
OUT_RING(0); OUT_RING(0);
ADVANCE_LP_RING(); ADVANCE_LP_RING();
sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
for (i = 0; i < num_rects; i++, rect++) { upper[0] = upper[1] = 0;
slice[0] = max(sarea_priv->pipeA_h / nhits, 1);
slice[1] = max(sarea_priv->pipeB_h / nhits, 1);
lower[0] = sarea_priv->pipeA_y + slice[0];
lower[1] = sarea_priv->pipeB_y + slice[0];
spin_lock(&dev->drw_lock);
/* Emit blits for buffer swaps, partitioning both outputs into as many
* slices as there are buffer swaps scheduled in order to avoid tearing
* (based on the assumption that a single buffer swap would always
* complete before scanout starts).
*/
for (i = 0; i++ < nhits;
upper[0] = lower[0], lower[0] += slice[0],
upper[1] = lower[1], lower[1] += slice[1]) {
if (i == nhits)
lower[0] = lower[1] = sarea_priv->height;
list_for_each(hit, &hits) {
drm_i915_vbl_swap_t *swap_hit =
list_entry(hit, drm_i915_vbl_swap_t, head);
drm_clip_rect_t *rect;
int num_rects, pipe;
unsigned short top, bottom;
drw = drm_get_drawable_info(dev, swap_hit->drw_id);
if (!drw)
continue;
rect = drw->rects;
pipe = swap_hit->pipe;
top = upper[pipe];
bottom = lower[pipe];
for (num_rects = drw->num_rects; num_rects--; rect++) {
int y1 = max(rect->y1, top);
int y2 = min(rect->y2, bottom);
if (y1 >= y2)
continue;
BEGIN_LP_RING(8); BEGIN_LP_RING(8);
OUT_RING(cmd); OUT_RING(cmd);
OUT_RING(pitchropcpp); OUT_RING(pitchropcpp);
OUT_RING((rect->y1 << 16) | rect->x1); OUT_RING((y1 << 16) | rect->x1);
OUT_RING((rect->y2 << 16) | rect->x2); OUT_RING((y2 << 16) | rect->x2);
OUT_RING(sarea_priv->front_offset); OUT_RING(sarea_priv->front_offset);
OUT_RING((rect->y1 << 16) | rect->x1); OUT_RING((y1 << 16) | rect->x1);
OUT_RING(pitchropcpp & 0xffff); OUT_RING(pitchropcpp & 0xffff);
OUT_RING(sarea_priv->back_offset); OUT_RING(sarea_priv->back_offset);
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
} }
}
spin_unlock(&dev->drw_lock); spin_unlock_irqrestore(&dev->drw_lock, irqflags);
spin_lock(&dev_priv->swaps_lock);
list_del(list); list_for_each_safe(hit, tmp, &hits) {
drm_i915_vbl_swap_t *swap_hit =
list_entry(hit, drm_i915_vbl_swap_t, head);
drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); list_del(hit);
dev_priv->swaps_pending--; drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
} }
}
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
} }
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
......
/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
* Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
*/ */
/* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. /*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved. * All rights reserved.
* *
......
/* r128_drv.h -- Private header for r128 driver -*- linux-c -*- /* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
* Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
*/ */
/* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. /*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved. * All rights reserved.
* *
......
/* r128_state.c -- State support for r128 -*- linux-c -*- /* r128_state.c -- State support for r128 -*- linux-c -*-
* Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
*/ */
/* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. /*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved. * All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
......
...@@ -242,26 +242,6 @@ static __inline__ int r300_check_range(unsigned reg, int count) ...@@ -242,26 +242,6 @@ static __inline__ int r300_check_range(unsigned reg, int count)
return 0; return 0;
} }
/*
* we expect offsets passed to the framebuffer to be either within video
* memory or within AGP space
*/
static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
u32 offset)
{
/* we realy want to check against end of video aperture
but this value is not being kept.
This code is correct for now (does the same thing as the
code that sets MC_FB_LOCATION) in radeon_cp.c */
if (offset >= dev_priv->fb_location &&
offset < (dev_priv->fb_location + dev_priv->fb_size))
return 0;
if (offset >= dev_priv->gart_vm_start &&
offset < (dev_priv->gart_vm_start + dev_priv->gart_size))
return 0;
return 1;
}
static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
dev_priv, dev_priv,
drm_radeon_kcmd_buffer_t drm_radeon_kcmd_buffer_t
...@@ -290,7 +270,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * ...@@ -290,7 +270,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
case MARK_SAFE: case MARK_SAFE:
break; break;
case MARK_CHECK_OFFSET: case MARK_CHECK_OFFSET:
if (r300_check_offset(dev_priv, (u32) values[i])) { if (!radeon_check_offset(dev_priv, (u32) values[i])) {
DRM_ERROR DRM_ERROR
("Offset failed range check (reg=%04x sz=%d)\n", ("Offset failed range check (reg=%04x sz=%d)\n",
reg, sz); reg, sz);
...@@ -452,7 +432,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, ...@@ -452,7 +432,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
i = 1; i = 1;
while ((k < narrays) && (i < (count + 1))) { while ((k < narrays) && (i < (count + 1))) {
i++; /* skip attribute field */ i++; /* skip attribute field */
if (r300_check_offset(dev_priv, payload[i])) { if (!radeon_check_offset(dev_priv, payload[i])) {
DRM_ERROR DRM_ERROR
("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
k, i); k, i);
...@@ -463,7 +443,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, ...@@ -463,7 +443,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
if (k == narrays) if (k == narrays)
break; break;
/* have one more to process, they come in pairs */ /* have one more to process, they come in pairs */
if (r300_check_offset(dev_priv, payload[i])) { if (!radeon_check_offset(dev_priv, payload[i])) {
DRM_ERROR DRM_ERROR
("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
k, i); k, i);
...@@ -508,7 +488,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, ...@@ -508,7 +488,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
| RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
offset = cmd[2] << 10; offset = cmd[2] << 10;
ret = r300_check_offset(dev_priv, offset); ret = !radeon_check_offset(dev_priv, offset);
if (ret) { if (ret) {
DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
...@@ -518,7 +498,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, ...@@ -518,7 +498,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
(cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
offset = cmd[3] << 10; offset = cmd[3] << 10;
ret = r300_check_offset(dev_priv, offset); ret = !radeon_check_offset(dev_priv, offset);
if (ret) { if (ret) {
DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
...@@ -551,7 +531,7 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, ...@@ -551,7 +531,7 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
ret = r300_check_offset(dev_priv, cmd[2]); ret = !radeon_check_offset(dev_priv, cmd[2]);
if (ret) { if (ret) {
DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
......
...@@ -303,6 +303,21 @@ extern int radeon_no_wb; ...@@ -303,6 +303,21 @@ extern int radeon_no_wb;
extern drm_ioctl_desc_t radeon_ioctls[]; extern drm_ioctl_desc_t radeon_ioctls[];
extern int radeon_max_ioctl; extern int radeon_max_ioctl;
/* Check whether the given hardware address is inside the framebuffer or the
* GART area.
*/
static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
u64 off)
{
u32 fb_start = dev_priv->fb_location;
u32 fb_end = fb_start + dev_priv->fb_size - 1;
u32 gart_start = dev_priv->gart_vm_start;
u32 gart_end = gart_start + dev_priv->gart_size - 1;
return ((off >= fb_start && off <= fb_end) ||
(off >= gart_start && off <= gart_end));
}
/* radeon_cp.c */ /* radeon_cp.c */
extern int radeon_cp_init(DRM_IOCTL_ARGS); extern int radeon_cp_init(DRM_IOCTL_ARGS);
extern int radeon_cp_start(DRM_IOCTL_ARGS); extern int radeon_cp_start(DRM_IOCTL_ARGS);
......
/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- /* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */
* /*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
* *
* The Weather Channel (TM) funded Tungsten Graphics to develop the * The Weather Channel (TM) funded Tungsten Graphics to develop the
......
/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- /* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */
* /*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
* *
* The Weather Channel (TM) funded Tungsten Graphics to develop the * The Weather Channel (TM) funded Tungsten Graphics to develop the
......
...@@ -43,10 +43,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * ...@@ -43,10 +43,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
u32 *offset) u32 *offset)
{ {
u64 off = *offset; u64 off = *offset;
u32 fb_start = dev_priv->fb_location; u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
u32 fb_end = fb_start + dev_priv->fb_size - 1;
u32 gart_start = dev_priv->gart_vm_start;
u32 gart_end = gart_start + dev_priv->gart_size - 1;
struct drm_radeon_driver_file_fields *radeon_priv; struct drm_radeon_driver_file_fields *radeon_priv;
/* Hrm ... the story of the offset ... So this function converts /* Hrm ... the story of the offset ... So this function converts
...@@ -66,8 +63,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * ...@@ -66,8 +63,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
/* First, the best case, the offset already lands in either the /* First, the best case, the offset already lands in either the
* framebuffer or the GART mapped space * framebuffer or the GART mapped space
*/ */
if ((off >= fb_start && off <= fb_end) || if (radeon_check_offset(dev_priv, off))
(off >= gart_start && off <= gart_end))
return 0; return 0;
/* Ok, that didn't happen... now check if we have a zero based /* Ok, that didn't happen... now check if we have a zero based
...@@ -81,11 +77,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * ...@@ -81,11 +77,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
/* Finally, assume we aimed at a GART offset if beyond the fb */ /* Finally, assume we aimed at a GART offset if beyond the fb */
if (off > fb_end) if (off > fb_end)
off = off - fb_end - 1 + gart_start; off = off - fb_end - 1 + dev_priv->gart_vm_start;
/* Now recheck and fail if out of bounds */ /* Now recheck and fail if out of bounds */
if ((off >= fb_start && off <= fb_end) || if (radeon_check_offset(dev_priv, off)) {
(off >= gart_start && off <= gart_end)) {
DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
*offset = off; *offset = off;
return 0; return 0;
......
...@@ -963,8 +963,8 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS) ...@@ -963,8 +963,8 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS)
event.count = savage_bci_emit_event(dev_priv, event.flags); event.count = savage_bci_emit_event(dev_priv, event.flags);
event.count |= dev_priv->event_wrap << 16; event.count |= dev_priv->event_wrap << 16;
DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)-> DRM_COPY_TO_USER_IOCTL((drm_savage_event_emit_t __user *) data,
count, event.count, sizeof(event.count)); event, sizeof(event));
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment