return (!GAMMA_READ(GAMMA_DMACOUNT));
}
-irqreturn_t gamma_dma_service( DRM_IRQ_ARGS )
+irqreturn_t gamma_driver_irq_handler( DRM_IRQ_ARGS )
{
drm_device_t *dev = (drm_device_t *)arg;
drm_device_dma_t *dma = dev->dma;
gamma_dma_schedule((drm_device_t *)dev, 0);
}
-void gamma_dma_immediate_bh(void *dev)
+void gamma_irq_immediate_bh(void *dev)
{
gamma_dma_schedule(dev, 0);
}
drm_buf_t *buf;
drm_buf_t *last_buf = NULL;
drm_device_dma_t *dma = dev->dma;
+ int *send_indices = NULL;
+ int *send_sizes = NULL;
+
DECLARE_WAITQUEUE(entry, current);
/* Turn off interrupt handling */
++must_free;
}
+ send_indices = DRM(alloc)(d->send_count * sizeof(*send_indices),
+ DRM_MEM_DRIVER);
+ if (send_indices == NULL)
+ return -ENOMEM;
+ if (copy_from_user(send_indices, d->send_indices,
+ d->send_count * sizeof(*send_indices))) {
+ retcode = -EFAULT;
+ goto cleanup;
+ }
+
+ send_sizes = DRM(alloc)(d->send_count * sizeof(*send_sizes),
+ DRM_MEM_DRIVER);
+ if (send_sizes == NULL)
+ return -ENOMEM;
+ if (copy_from_user(send_sizes, d->send_sizes,
+ d->send_count * sizeof(*send_sizes))) {
+ retcode = -EFAULT;
+ goto cleanup;
+ }
+
for (i = 0; i < d->send_count; i++) {
- idx = d->send_indices[i];
+ idx = send_indices[i];
if (idx < 0 || idx >= dma->buf_count) {
DRM_ERROR("Index %d (of %d max)\n",
- d->send_indices[i], dma->buf_count - 1);
+ send_indices[i], dma->buf_count - 1);
continue;
}
buf = dma->buflist[ idx ];
process closes the /dev/drm? handle, so
it can't also be doing DMA. */
buf->list = DRM_LIST_PRIO;
- buf->used = d->send_sizes[i];
+ buf->used = send_sizes[i];
buf->context = d->context;
buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED;
address = (unsigned long)buf->address;
if (buf->pending) {
DRM_ERROR("Sending pending buffer:"
" buffer %d, offset %d\n",
- d->send_indices[i], i);
+ send_indices[i], i);
retcode = -EINVAL;
goto cleanup;
}
if (buf->waiting) {
DRM_ERROR("Sending waiting buffer:"
" buffer %d, offset %d\n",
- d->send_indices[i], i);
+ send_indices[i], i);
retcode = -EINVAL;
goto cleanup;
}
gamma_dma_ready(dev);
gamma_free_buffer(dev, last_buf);
}
+ if (send_indices)
+ DRM(free)(send_indices, d->send_count * sizeof(*send_indices),
+ DRM_MEM_DRIVER);
+ if (send_sizes)
+ DRM(free)(send_sizes, d->send_count * sizeof(*send_sizes),
+ DRM_MEM_DRIVER);
if (must_free && !dev->context_flag) {
if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
drm_buf_t *last_buf = NULL;
int retcode = 0;
drm_device_dma_t *dma = dev->dma;
+ int send_index;
+
+ if (get_user(send_index, &d->send_indices[d->send_count-1]))
+ return -EFAULT;
if (d->flags & _DRM_DMA_BLOCK) {
- last_buf = dma->buflist[d->send_indices[d->send_count-1]];
+ last_buf = dma->buflist[send_index];
add_wait_queue(&last_buf->dma_wait, &entry);
}
drm_device_t *dev = priv->dev;
drm_device_dma_t *dma = dev->dma;
int retcode = 0;
+ drm_dma_t __user *argp = (void __user *)arg;
drm_dma_t d;
- if (copy_from_user(&d, (drm_dma_t *)arg, sizeof(d)))
+ if (copy_from_user(&d, argp, sizeof(d)))
return -EFAULT;
if (d.send_count < 0 || d.send_count > dma->buf_count) {
DRM_DEBUG("%d returning, granted = %d\n",
current->pid, d.granted_count);
- if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))
+ if (copy_to_user(argp, &d, sizeof(d)))
return -EFAULT;
return retcode;
break;
}
}
-
- DRM_FIND_MAP( dev_priv->mmio0, init->mmio0 );
- DRM_FIND_MAP( dev_priv->mmio1, init->mmio1 );
- DRM_FIND_MAP( dev_priv->mmio2, init->mmio2 );
- DRM_FIND_MAP( dev_priv->mmio3, init->mmio3 );
-
+
+ dev_priv->mmio0 = drm_core_findmap(dev, init->mmio0);
+ dev_priv->mmio1 = drm_core_findmap(dev, init->mmio1);
+ dev_priv->mmio2 = drm_core_findmap(dev, init->mmio2);
+ dev_priv->mmio3 = drm_core_findmap(dev, init->mmio3);
+
dev_priv->sarea_priv = (drm_gamma_sarea_t *)
((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
buf = dma->buflist[GLINT_DRI_BUF_COUNT];
} else {
- DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
-
- DRM_IOREMAP( dev_priv->buffers, dev );
+ dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ drm_core_ioremap( dev->agp_buffer_map, dev);
buf = dma->buflist[GLINT_DRI_BUF_COUNT];
pgt = buf->address;
{
DRM_DEBUG( "%s\n", __FUNCTION__ );
-#if _HAVE_DMA_IRQ
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
- if ( dev->irq ) DRM(irq_uninstall)(dev);
-#endif
+ if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+ if ( dev->irq_enabled )
+ DRM(irq_uninstall)(dev);
if ( dev->dev_private ) {
- drm_gamma_private_t *dev_priv = dev->dev_private;
- if ( dev_priv->buffers != NULL )
- DRM_IOREMAPFREE( dev_priv->buffers, dev );
+ if ( dev->agp_buffer_map != NULL )
+ drm_core_ioremapfree( dev->agp_buffer_map, dev );
DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t),
DRM_MEM_DRIVER );
LOCK_TEST_WITH_RETURN( dev, filp );
- if ( copy_from_user( &init, (drm_gamma_init_t *)arg, sizeof(init) ) )
+ if ( copy_from_user( &init, (drm_gamma_init_t __user *)arg, sizeof(init) ) )
return -EFAULT;
switch ( init.func ) {
drm_device_t *dev = priv->dev;
drm_gamma_copy_t copy;
- if ( copy_from_user( ©, (drm_gamma_copy_t *)arg, sizeof(copy) ) )
+ if ( copy_from_user( ©, (drm_gamma_copy_t __user *)arg, sizeof(copy) ) )
return -EFAULT;
return gamma_do_copy_dma( dev, © );
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
+ drm_ctx_priv_map_t __user *argp = (void __user *)arg;
drm_ctx_priv_map_t request;
drm_map_t *map;
- if (copy_from_user(&request,
- (drm_ctx_priv_map_t *)arg,
- sizeof(request)))
+ if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
down(&dev->struct_sem);
up(&dev->struct_sem);
request.handle = map->handle;
- if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request)))
+ if (copy_to_user(argp, &request, sizeof(request)))
return -EFAULT;
return 0;
}
struct list_head *list;
if (copy_from_user(&request,
- (drm_ctx_priv_map_t *)arg,
+ (drm_ctx_priv_map_t __user *)arg,
sizeof(request)))
return -EFAULT;
return 0;
}
-void DRM(driver_irq_preinstall)( drm_device_t *dev ) {
+void gamma_driver_irq_preinstall( drm_device_t *dev ) {
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );
}
-void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
+void gamma_driver_irq_postinstall( drm_device_t *dev ) {
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 );
}
-void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
+void gamma_driver_irq_uninstall( drm_device_t *dev ) {
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
if (!dev_priv)
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 );
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 );
}
+
+extern drm_ioctl_desc_t DRM(ioctls)[];
+
+static int gamma_driver_preinit(drm_device_t *dev)
+{
+ /* reset the finish ioctl */
+ DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_FINISH)].func = DRM(finish);
+ return 0;
+}
+
+static void gamma_driver_pretakedown(drm_device_t *dev)
+{
+ gamma_do_cleanup_dma(dev);
+}
+
+static void gamma_driver_dma_ready(drm_device_t *dev)
+{
+ gamma_dma_ready(dev);
+}
+
+static int gamma_driver_dma_quiescent(drm_device_t *dev)
+{
+ drm_gamma_private_t *dev_priv = (
+ drm_gamma_private_t *)dev->dev_private;
+ if (dev_priv->num_rast == 2)
+ gamma_dma_quiescent_dual(dev);
+ else gamma_dma_quiescent_single(dev);
+ return 0;
+}
+
+void gamma_driver_register_fns(drm_device_t *dev)
+{
+ dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
+ DRM(fops).read = gamma_fops_read;
+ DRM(fops).poll = gamma_fops_poll;
+ dev->fn_tbl.preinit = gamma_driver_preinit;
+ dev->fn_tbl.pretakedown = gamma_driver_pretakedown;
+ dev->fn_tbl.dma_ready = gamma_driver_dma_ready;
+ dev->fn_tbl.dma_quiescent = gamma_driver_dma_quiescent;
+ dev->fn_tbl.dma_flush_block_and_flush = gamma_flush_block_and_flush;
+ dev->fn_tbl.dma_flush_unblock = gamma_flush_unblock;
+}