diff --git a/[refs] b/[refs] index c07cf14deb1e..cc7f6854f160 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 58cba4650a7a414eabd2b40cc9d8e45fcdf192d9 +refs/heads/master: ac7c66698a2c51e4c6a34b84621c79e7cb89e07d diff --git a/trunk/drivers/char/drm/Makefile b/trunk/drivers/char/drm/Makefile index 9d180c42816c..e41060c76226 100644 --- a/trunk/drivers/char/drm/Makefile +++ b/trunk/drivers/char/drm/Makefile @@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ - drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \ + drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ drm_sysfs.o @@ -18,7 +18,7 @@ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o ffb-objs := ffb_drv.o ffb_context.o sis-objs := sis_drv.o sis_ds.o sis_mm.o savage-objs := savage_drv.o savage_bci.o savage_state.o -via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o +via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o ifeq ($(CONFIG_COMPAT),y) drm-objs += drm_ioc32.o diff --git a/trunk/drivers/char/drm/ati_pcigart.c b/trunk/drivers/char/drm/ati_pcigart.c index 5485382cadec..efff0eec618c 100644 --- a/trunk/drivers/char/drm/ati_pcigart.c +++ b/trunk/drivers/char/drm/ati_pcigart.c @@ -52,7 +52,7 @@ # define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ -static void *drm_ati_alloc_pcigart_table(void) +static unsigned long drm_ati_alloc_pcigart_table(void) { unsigned long address; struct page *page; @@ -72,26 +72,27 @@ static void *drm_ati_alloc_pcigart_table(void) } DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); - return (void *)address; + return address; } -static void drm_ati_free_pcigart_table(void *address) +static void drm_ati_free_pcigart_table(unsigned long address) { struct page *page; int i; DRM_DEBUG("%s\n", __FUNCTION__); - page = virt_to_page((unsigned long)address); + page = virt_to_page(address); for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { __put_page(page); ClearPageReserved(page); } - free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); + free_pages(address, ATI_PCIGART_TABLE_ORDER); } -int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) +int drm_ati_pcigart_cleanup(drm_device_t * dev, + drm_ati_pcigart_info * gart_info) { drm_sg_mem_t *entry = dev->sg; unsigned long pages; @@ -135,10 +136,10 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) EXPORT_SYMBOL(drm_ati_pcigart_cleanup); -int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) +int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) { drm_sg_mem_t *entry = dev->sg; - void *address = NULL; + unsigned long address = 0; unsigned long pages; u32 *pci_gart, page_base, bus_address = 0; int i, j, ret = 0; @@ -162,7 +163,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) goto done; } - bus_address = pci_map_single(dev->pdev, address, + bus_address = pci_map_single(dev->pdev, (void *)address, ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, PCI_DMA_TODEVICE); if (bus_address == 0) { @@ -175,7 +176,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) address = gart_info->addr; bus_address = gart_info->bus_addr; DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", - bus_address, (unsigned long)address); + bus_address, address); } pci_gart = (u32 *) address; @@ -194,7 +195,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) if (entry->busaddr[i] == 0) { DRM_ERROR("unable to map PCIGART pages!\n"); drm_ati_pcigart_cleanup(dev, gart_info); - address = NULL; + address = 0; bus_address = 0; goto done; } diff --git a/trunk/drivers/char/drm/drm.h b/trunk/drivers/char/drm/drm.h index 9da0ddb892b5..64d6237fdd0b 100644 --- a/trunk/drivers/char/drm/drm.h +++ b/trunk/drivers/char/drm/drm.h @@ -90,8 +90,8 @@ #define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ #define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ -#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ -#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ +#define _DRM_LOCK_HELD 0x80000000 /**< Hardware lock is held */ +#define _DRM_LOCK_CONT 0x40000000 /**< Hardware lock is contended */ #define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) #define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) diff --git a/trunk/drivers/char/drm/drmP.h b/trunk/drivers/char/drm/drmP.h index 54b561e69486..3dc3c9d79ae4 100644 --- a/trunk/drivers/char/drm/drmP.h +++ b/trunk/drivers/char/drm/drmP.h @@ -144,6 +144,20 @@ /** \name Backward compatibility section */ /*@{*/ +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + +#ifndef preempt_disable +#define preempt_disable() +#define preempt_enable() +#endif + +#ifndef pte_offset_map +#define pte_offset_map pte_offset +#define pte_unmap(pte) +#endif + #define DRM_RPR_ARG(vma) vma, #define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) @@ -272,13 +286,10 @@ typedef int drm_ioctl_t(struct inode *inode, struct file *filp, typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg); -#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 - typedef struct drm_ioctl_desc { drm_ioctl_t *func; - int flags; + int auth_needed; + int root_only; } drm_ioctl_desc_t; typedef struct drm_devstate { @@ -373,7 +384,6 @@ typedef struct drm_buf_entry { /** File private data */ typedef struct drm_file { int authenticated; - int master; int minor; pid_t pid; uid_t uid; @@ -522,9 +532,8 @@ typedef struct drm_vbl_sig { typedef struct ati_pcigart_info { int gart_table_location; int is_pcie; - void *addr; + unsigned long addr; dma_addr_t bus_addr; - drm_local_map_t mapping; } drm_ati_pcigart_info; /** @@ -535,14 +544,16 @@ typedef struct ati_pcigart_info { struct drm_device; struct drm_driver { - int (*load) (struct drm_device *, unsigned long flags); - int (*firstopen) (struct drm_device *); - int (*open) (struct drm_device *, drm_file_t *); - void (*preclose) (struct drm_device *, struct file * filp); - void (*postclose) (struct drm_device *, drm_file_t *); - void (*lastclose) (struct drm_device *); - int (*unload) (struct drm_device *); + int (*preinit) (struct drm_device *, unsigned long flags); + void (*prerelease) (struct drm_device *, struct file * filp); + void (*pretakedown) (struct drm_device *); + int (*postcleanup) (struct drm_device *); + int (*presetup) (struct drm_device *); + int (*postsetup) (struct drm_device *); int (*dma_ioctl) (DRM_IOCTL_ARGS); + int (*open_helper) (struct drm_device *, drm_file_t *); + void (*free_filp_priv) (struct drm_device *, drm_file_t *); + void (*release) (struct drm_device *, struct file * filp); void (*dma_ready) (struct drm_device *); int (*dma_quiescent) (struct drm_device *); int (*context_ctor) (struct drm_device * dev, int context); @@ -550,9 +561,8 @@ struct drm_driver { int (*kernel_context_switch) (struct drm_device * dev, int old, int new); void (*kernel_context_switch_unlock) (struct drm_device * dev, - drm_lock_t *lock); + drm_lock_t * lock); int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); - int (*dri_library_name) (struct drm_device *dev, char *buf); /** * Called by \c drm_device_is_agp. Typically used to determine if a @@ -569,24 +579,16 @@ struct drm_driver { /* these have to be filled in */ - irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); + int (*postinit) (struct drm_device *, unsigned long flags); + irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); void (*irq_preinstall) (struct drm_device * dev); void (*irq_postinstall) (struct drm_device * dev); void (*irq_uninstall) (struct drm_device * dev); void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); - void (*reclaim_buffers_locked) (struct drm_device *dev, - struct file *filp); unsigned long (*get_map_ofs) (drm_map_t * map); unsigned long (*get_reg_ofs) (struct drm_device * dev); void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); - - int major; - int minor; - int patchlevel; - char *name; - char *desc; - char *date; - + int (*version) (drm_version_t * version); u32 driver_features; int dev_priv_size; drm_ioctl_desc_t *ioctls; @@ -750,43 +752,19 @@ static inline int drm_core_has_MTRR(struct drm_device *dev) { return drm_core_check_feature(dev, DRIVER_USE_MTRR); } - -#define DRM_MTRR_WC MTRR_TYPE_WRCOMB - -static inline int drm_mtrr_add(unsigned long offset, unsigned long size, - unsigned int flags) -{ - return mtrr_add(offset, size, flags, 1); -} - -static inline int drm_mtrr_del(int handle, unsigned long offset, - unsigned long size, unsigned int flags) -{ - return mtrr_del(handle, offset, size); -} - #else #define drm_core_has_MTRR(dev) (0) - -#define DRM_MTRR_WC 0 - -static inline int drm_mtrr_add(unsigned long offset, unsigned long size, - unsigned int flags) -{ - return 0; -} - -static inline int drm_mtrr_del(int handle, unsigned long offset, - unsigned long size, unsigned int flags) -{ - return 0; -} #endif /******************************************************************/ /** \name Internal function definitions */ /*@{*/ + /* Misc. support (drm_init.h) */ +extern int drm_flags; +extern void drm_parse_options(char *s); +extern int drm_cpu_valid(void); + /* Driver support (drm_drv.h) */ extern int drm_init(struct drm_driver *driver); extern void drm_exit(struct drm_driver *driver); @@ -794,11 +772,12 @@ extern int drm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_lastclose(drm_device_t *dev); +extern int drm_takedown(drm_device_t * dev); /* Device support (drm_fops.h) */ extern int drm_open(struct inode *inode, struct file *filp); extern int drm_stub_open(struct inode *inode, struct file *filp); +extern int drm_flush(struct file *filp); extern int drm_fasync(int fd, struct file *filp, int on); extern int drm_release(struct inode *inode, struct file *filp); @@ -840,8 +819,6 @@ extern int drm_getstats(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_setversion(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_noop(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); /* Context IOCTL support (drm_context.h) */ extern int drm_resctx(struct inode *inode, struct file *filp, @@ -880,6 +857,10 @@ extern int drm_getmagic(struct inode *inode, struct file *filp, extern int drm_authmagic(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + /* Placeholder for ioctls past */ +extern int drm_noop(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + /* Locking IOCTL support (drm_lock.h) */ extern int drm_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -892,7 +873,6 @@ extern int drm_lock_free(drm_device_t * dev, /* Buffer management support (drm_bufs.h) */ extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); -extern int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request); extern int drm_addmap(drm_device_t * dev, unsigned int offset, unsigned int size, drm_map_type_t type, drm_map_flags_t flags, drm_local_map_t ** map_ptr); @@ -928,8 +908,8 @@ extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp); /* IRQ support (drm_irq.h) */ extern int drm_control(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); extern int drm_irq_uninstall(drm_device_t * dev); +extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); extern void drm_driver_irq_preinstall(drm_device_t * dev); extern void drm_driver_irq_postinstall(drm_device_t * dev); extern void drm_driver_irq_uninstall(drm_device_t * dev); @@ -953,17 +933,13 @@ extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info); extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request); -extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp, +extern int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request); -extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp, +extern int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request); -extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp, +extern int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request); -extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp, +extern int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type); @@ -1015,8 +991,10 @@ extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name); extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, - drm_head_t *head); -extern void drm_sysfs_device_remove(struct class_device *class_dev); + dev_t dev, + struct device *device, + const char *fmt, ...); +extern void drm_sysfs_device_remove(dev_t dev); /* Inline replacements for DRM_IOREMAP macros */ static __inline__ void drm_core_ioremap(struct drm_map *map, diff --git a/trunk/drivers/char/drm/drm_agpsupport.c b/trunk/drivers/char/drm/drm_agpsupport.c index fabc930c67a2..2b6453a9ffce 100644 --- a/trunk/drivers/char/drm/drm_agpsupport.c +++ b/trunk/drivers/char/drm/drm_agpsupport.c @@ -1,5 +1,5 @@ /** - * \file drm_agpsupport.c + * \file drm_agpsupport.h * DRM support for AGP/GART backend * * \author Rickard E. (Rik) Faith @@ -91,7 +91,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp, /** * Acquire the AGP device. * - * \param dev DRM device that is to acquire AGP. + * \param dev DRM device that is to acquire AGP * \return zero on success or a negative number on failure. * * Verifies the AGP device hasn't been acquired before and calls @@ -134,7 +134,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp, /** * Release the AGP device. * - * \param dev DRM device that is to release AGP. + * \param dev DRM device that is to release AGP * \return zero on success or a negative number on failure. * * Verifies the AGP device has been acquired and calls \c agp_backend_release. @@ -147,6 +147,7 @@ int drm_agp_release(drm_device_t * dev) dev->agp->acquired = 0; return 0; } + EXPORT_SYMBOL(drm_agp_release); int drm_agp_release_ioctl(struct inode *inode, struct file *filp, @@ -207,22 +208,30 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, * Verifies the AGP device is present and has been acquired, allocates the * memory via alloc_agp() and creates a drm_agp_mem entry for it. */ -int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request) +int drm_agp_alloc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_agp_buffer_t request; drm_agp_mem_t *entry; DRM_AGP_MEM *memory; unsigned long pages; u32 type; + drm_agp_buffer_t __user *argp = (void __user *)arg; if (!dev->agp || !dev->agp->acquired) return -EINVAL; + if (copy_from_user(&request, argp, sizeof(request))) + return -EFAULT; if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) return -ENOMEM; memset(entry, 0, sizeof(*entry)); - pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; - type = (u32) request->type; + pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; + type = (u32) request.type; + if (!(memory = drm_alloc_agp(dev, pages, type))) { drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -ENOMEM; @@ -238,39 +247,16 @@ int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request) dev->agp->memory->prev = entry; dev->agp->memory = entry; - request->handle = entry->handle; - request->physical = memory->physical; - - return 0; -} -EXPORT_SYMBOL(drm_agp_alloc); - -int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_agp_buffer_t request; - drm_agp_buffer_t __user *argp = (void __user *)arg; - int err; - - if (copy_from_user(&request, argp, sizeof(request))) - return -EFAULT; - - err = drm_agp_alloc(dev, &request); - if (err) - return err; + request.handle = entry->handle; + request.physical = memory->physical; if (copy_to_user(argp, &request, sizeof(request))) { - drm_agp_mem_t *entry = dev->agp->memory; - dev->agp->memory = entry->next; dev->agp->memory->prev = NULL; - drm_free_agp(entry->memory, entry->pages); + drm_free_agp(memory, pages); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -EFAULT; } - return 0; } @@ -307,14 +293,21 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev, * Verifies the AGP device is present and acquired, looks-up the AGP memory * entry and passes it to the unbind_agp() function. */ -int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request) +int drm_agp_unbind(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_agp_binding_t request; drm_agp_mem_t *entry; int ret; if (!dev->agp || !dev->agp->acquired) return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) + if (copy_from_user + (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) + return -EFAULT; + if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (!entry->bound) return -EINVAL; @@ -323,21 +316,6 @@ int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request) entry->bound = 0; return ret; } -EXPORT_SYMBOL(drm_agp_unbind); - -int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_agp_binding_t request; - - if (copy_from_user - (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) - return -EFAULT; - - return drm_agp_unbind(dev, &request); -} /** * Bind AGP memory into the GATT (ioctl) @@ -352,19 +330,26 @@ int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp, * is currently bound into the GATT. Looks-up the AGP memory entry and passes * it to bind_agp() function. */ -int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request) +int drm_agp_bind(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_agp_binding_t request; drm_agp_mem_t *entry; int retcode; int page; if (!dev->agp || !dev->agp->acquired) return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) + if (copy_from_user + (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) + return -EFAULT; + if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (entry->bound) return -EINVAL; - page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; + page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; if ((retcode = drm_bind_agp(entry->memory, page))) return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); @@ -372,21 +357,6 @@ int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request) dev->agp->base, entry->bound); return 0; } -EXPORT_SYMBOL(drm_agp_bind); - -int drm_agp_bind_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_agp_binding_t request; - - if (copy_from_user - (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) - return -EFAULT; - - return drm_agp_bind(dev, &request); -} /** * Free AGP memory (ioctl). @@ -402,13 +372,20 @@ int drm_agp_bind_ioctl(struct inode *inode, struct file *filp, * unbind_agp(). Frees it via free_agp() as well as the entry itself * and unlinks from the doubly linked list it's inserted in. */ -int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request) +int drm_agp_free(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_agp_buffer_t request; drm_agp_mem_t *entry; if (!dev->agp || !dev->agp->acquired) return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) + if (copy_from_user + (&request, (drm_agp_buffer_t __user *) arg, sizeof(request))) + return -EFAULT; + if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (entry->bound) drm_unbind_agp(entry->memory); @@ -425,30 +402,12 @@ int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request) drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; } -EXPORT_SYMBOL(drm_agp_free); - -int drm_agp_free_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_agp_buffer_t request; - - if (copy_from_user - (&request, (drm_agp_buffer_t __user *) arg, sizeof(request))) - return -EFAULT; - - return drm_agp_free(dev, &request); -} /** * Initialize the AGP resources. * * \return pointer to a drm_agp_head structure. * - * Gets the drm_agp_t structure which is made available by the agpgart module - * via the inter_module_* functions. Creates and initializes a drm_agp_head - * structure. */ drm_agp_head_t *drm_agp_init(drm_device_t * dev) { diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index 1db12dcb6802..319bdea8de8a 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -36,21 +36,22 @@ #include #include "drmP.h" -unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) +unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource) { return pci_resource_start(dev->pdev, resource); } + EXPORT_SYMBOL(drm_get_resource_start); -unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) +unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource) { return pci_resource_len(dev->pdev, resource); } EXPORT_SYMBOL(drm_get_resource_len); -static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, - drm_local_map_t *map) +static drm_map_list_t *drm_find_matching_map(drm_device_t * dev, + drm_local_map_t * map) { struct list_head *list; @@ -73,7 +74,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, #ifdef _LP64 static __inline__ unsigned int HandleID(unsigned long lhandle, - drm_device_t *dev) + drm_device_t * dev) { static unsigned int map32_handle = START_RANGE; unsigned int hash; @@ -154,7 +155,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) - if (map->offset + (map->size-1) < map->offset || + if (map->offset + map->size < map->offset || map->offset < virt_to_phys(high_memory)) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; @@ -300,9 +301,6 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, return -EFAULT; } - if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP)) - return -EPERM; - err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags, &maplist); @@ -334,7 +332,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, * * \sa drm_addmap */ -int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) +int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map) { struct list_head *list; drm_map_list_t *r_list = NULL; @@ -386,9 +384,10 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) return 0; } + EXPORT_SYMBOL(drm_rmmap_locked); -int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) +int drm_rmmap(drm_device_t * dev, drm_local_map_t * map) { int ret; @@ -398,6 +397,7 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) return ret; } + EXPORT_SYMBOL(drm_rmmap); /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on @@ -548,7 +548,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) DRM_DEBUG("count: %d\n", count); DRM_DEBUG("order: %d\n", order); DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %lx\n", agp_offset); + DRM_DEBUG("agp_offset: %lu\n", agp_offset); DRM_DEBUG("alignment: %d\n", alignment); DRM_DEBUG("page_order: %d\n", page_order); DRM_DEBUG("total: %d\n", total); @@ -649,8 +649,6 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) } dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; dma->byte_count += byte_count; DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); @@ -666,6 +664,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) atomic_dec(&dev->buf_alloc); return 0; } + EXPORT_SYMBOL(drm_addbufs_agp); #endif /* __OS_HAS_AGP */ @@ -690,13 +689,9 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL; - if (!dma) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - count = request->count; order = drm_order(request->size); size = 1 << order; @@ -887,6 +882,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) return 0; } + EXPORT_SYMBOL(drm_addbufs_pci); static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) @@ -912,9 +908,6 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) if (!dma) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - count = request->count; order = drm_order(request->size); size = 1 << order; @@ -1033,8 +1026,6 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) } dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; dma->byte_count += byte_count; DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); @@ -1051,7 +1042,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) return 0; } -int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) +static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; @@ -1074,9 +1065,6 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) if (!dma) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - count = request->count; order = drm_order(request->size); size = 1 << order; @@ -1193,8 +1181,6 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) } dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; dma->byte_count += byte_count; DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); @@ -1210,8 +1196,6 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) atomic_dec(&dev->buf_alloc); return 0; } -EXPORT_SYMBOL(drm_addbufs_fb); - /** * Add buffers for DMA transfers (ioctl). @@ -1593,6 +1577,5 @@ int drm_order(unsigned long size) return order; } -EXPORT_SYMBOL(drm_order); - +EXPORT_SYMBOL(drm_order); diff --git a/trunk/drivers/char/drm/drm_context.c b/trunk/drivers/char/drm/drm_context.c index f84254526949..bd958d69a2ac 100644 --- a/trunk/drivers/char/drm/drm_context.c +++ b/trunk/drivers/char/drm/drm_context.c @@ -433,7 +433,7 @@ int drm_addctx(struct inode *inode, struct file *filp, if (ctx.handle != DRM_KERNEL_CONTEXT) { if (dev->driver->context_ctor) if (!dev->driver->context_ctor(dev, ctx.handle)) { - DRM_DEBUG("Running out of ctxs or memory.\n"); + DRM_DEBUG( "Running out of ctxs or memory.\n"); return -ENOMEM; } } diff --git a/trunk/drivers/char/drm/drm_core.h b/trunk/drivers/char/drm/drm_core.h index f4f9db6c7ed4..cc97bb906dda 100644 --- a/trunk/drivers/char/drm/drm_core.h +++ b/trunk/drivers/char/drm/drm_core.h @@ -24,11 +24,11 @@ #define CORE_NAME "drm" #define CORE_DESC "DRM shared core routines" -#define CORE_DATE "20051102" +#define CORE_DATE "20040925" #define DRM_IF_MAJOR 1 #define DRM_IF_MINOR 2 #define CORE_MAJOR 1 #define CORE_MINOR 0 -#define CORE_PATCHLEVEL 1 +#define CORE_PATCHLEVEL 0 diff --git a/trunk/drivers/char/drm/drm_drv.c b/trunk/drivers/char/drm/drm_drv.c index c4fa5a29582b..4dff7554eb08 100644 --- a/trunk/drivers/char/drm/drm_drv.c +++ b/trunk/drivers/char/drm/drm_drv.c @@ -56,66 +56,66 @@ static int drm_version(struct inode *inode, struct file *filp, /** Ioctl table */ static drm_ioctl_desc_t drm_ioctls[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0}, - [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, DRM_AUTH}, - - [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH}, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, DRM_AUTH}, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - - [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, DRM_AUTH}, - - [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, DRM_AUTH}, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1}, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1}, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0}, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0}, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0}, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1}, + + [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0}, + + [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0}, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0}, /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = {NULL, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1}, #if __OS_HAS_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1}, #endif - [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1}, - [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0}, + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0}, }; #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) @@ -129,7 +129,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { * * \sa drm_device */ -int drm_lastclose(drm_device_t * dev) +int drm_takedown(drm_device_t * dev) { drm_magic_entry_t *pt, *next; drm_map_list_t *r_list; @@ -138,9 +138,9 @@ int drm_lastclose(drm_device_t * dev) DRM_DEBUG("\n"); - if (dev->driver->lastclose) - dev->driver->lastclose(dev); - DRM_DEBUG("driver lastclose completed\n"); + if (dev->driver->pretakedown) + dev->driver->pretakedown(dev); + DRM_DEBUG("driver pretakedown completed\n"); if (dev->unique) { drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); @@ -233,7 +233,7 @@ int drm_lastclose(drm_device_t * dev) } up(&dev->struct_sem); - DRM_DEBUG("lastclose completed\n"); + DRM_DEBUG("takedown completed\n"); return 0; } @@ -281,7 +281,7 @@ EXPORT_SYMBOL(drm_init); /** * Called via cleanup_module() at module unload time. * - * Cleans up all DRM device, calling drm_lastclose(). + * Cleans up all DRM device, calling takedown(). * * \sa drm_init */ @@ -294,7 +294,7 @@ static void drm_cleanup(drm_device_t * dev) return; } - drm_lastclose(dev); + drm_takedown(dev); if (dev->maplist) { drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); @@ -317,8 +317,8 @@ static void drm_cleanup(drm_device_t * dev) dev->agp = NULL; } - if (dev->driver->unload) - dev->driver->unload(dev); + if (dev->driver->postcleanup) + dev->driver->postcleanup(dev); drm_put_head(&dev->primary); if (drm_put_dev(dev)) @@ -342,12 +342,12 @@ void drm_exit(struct drm_driver *driver) if (head->dev->driver != driver) continue; dev = head->dev; - if (dev) { - /* release the pci driver */ - if (dev->pdev) - pci_dev_put(dev->pdev); - drm_cleanup(dev); - } + } + if (dev) { + /* release the pci driver */ + if (dev->pdev) + pci_dev_put(dev->pdev); + drm_cleanup(dev); } DRM_INFO("Module unloaded\n"); } @@ -432,17 +432,14 @@ static int drm_version(struct inode *inode, struct file *filp, drm_device_t *dev = priv->head->dev; drm_version_t __user *argp = (void __user *)arg; drm_version_t version; - int len; + int ret; if (copy_from_user(&version, argp, sizeof(version))) return -EFAULT; - version.version_major = dev->driver->major; - version.version_minor = dev->driver->minor; - version.version_patchlevel = dev->driver->patchlevel; - DRM_COPY(version.name, dev->driver->name); - DRM_COPY(version.date, dev->driver->date); - DRM_COPY(version.desc, dev->driver->desc); + /* version is a required function to return the personality module version */ + if ((ret = dev->driver->version(&version))) + return ret; if (copy_to_user(argp, &version, sizeof(version))) return -EFAULT; @@ -496,9 +493,8 @@ int drm_ioctl(struct inode *inode, struct file *filp, if (!func) { DRM_DEBUG("no function\n"); retcode = -EINVAL; - } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || - ((ioctl->flags & DRM_AUTH) && !priv->authenticated) || - ((ioctl->flags & DRM_MASTER) && !priv->master)) { + } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) || + (ioctl->auth_needed && !priv->authenticated)) { retcode = -EACCES; } else { retcode = func(inode, filp, cmd, arg); diff --git a/trunk/drivers/char/drm/drm_fops.c b/trunk/drivers/char/drm/drm_fops.c index 403f44a1bf01..bf0a740122bf 100644 --- a/trunk/drivers/char/drm/drm_fops.c +++ b/trunk/drivers/char/drm/drm_fops.c @@ -35,7 +35,6 @@ */ #include "drmP.h" -#include "drm_sarea.h" #include static int drm_open_helper(struct inode *inode, struct file *filp, @@ -43,21 +42,15 @@ static int drm_open_helper(struct inode *inode, struct file *filp, static int drm_setup(drm_device_t * dev) { - drm_local_map_t *map; int i; int ret; - if (dev->driver->firstopen) { - ret = dev->driver->firstopen(dev); + if (dev->driver->presetup) { + ret = dev->driver->presetup(dev); if (ret != 0) return ret; } - /* prebuild the SAREA */ - i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); - if (i != 0) - return i; - atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -116,6 +109,8 @@ static int drm_setup(drm_device_t * dev) * drm_select_queue fails between the time the interrupt is * initialized and the time the queues are initialized. */ + if (dev->driver->postsetup) + dev->driver->postsetup(dev); return 0; } @@ -159,166 +154,8 @@ int drm_open(struct inode *inode, struct file *filp) return retcode; } -EXPORT_SYMBOL(drm_open); - -/** - * File \c open operation. - * - * \param inode device inode. - * \param filp file pointer. - * - * Puts the dev->fops corresponding to the device minor number into - * \p filp, call the \c open method, and restore the file operations. - */ -int drm_stub_open(struct inode *inode, struct file *filp) -{ - drm_device_t *dev = NULL; - int minor = iminor(inode); - int err = -ENODEV; - struct file_operations *old_fops; - - DRM_DEBUG("\n"); - - if (!((minor >= 0) && (minor < drm_cards_limit))) - return -ENODEV; - - if (!drm_heads[minor]) - return -ENODEV; - - if (!(dev = drm_heads[minor]->dev)) - return -ENODEV; - - old_fops = filp->f_op; - filp->f_op = fops_get(&dev->driver->fops); - if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { - fops_put(filp->f_op); - filp->f_op = fops_get(old_fops); - } - fops_put(old_fops); - - return err; -} - -/** - * Check whether DRI will run on this CPU. - * - * \return non-zero if the DRI will run on this CPU, or zero otherwise. - */ -static int drm_cpu_valid(void) -{ -#if defined(__i386__) - if (boot_cpu_data.x86 == 3) - return 0; /* No cmpxchg on a 386 */ -#endif -#if defined(__sparc__) && !defined(__sparc_v9__) - return 0; /* No cmpxchg before v9 sparc. */ -#endif - return 1; -} - -/** - * Called whenever a process opens /dev/drm. - * - * \param inode device inode. - * \param filp file pointer. - * \param dev device. - * \return zero on success or a negative number on failure. - * - * Creates and initializes a drm_file structure for the file private data in \p - * filp and add it into the double linked list in \p dev. - */ -static int drm_open_helper(struct inode *inode, struct file *filp, - drm_device_t * dev) -{ - int minor = iminor(inode); - drm_file_t *priv; - int ret; - - if (filp->f_flags & O_EXCL) - return -EBUSY; /* No exclusive opens */ - if (!drm_cpu_valid()) - return -EINVAL; - - DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); - - priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); - if (!priv) - return -ENOMEM; - - memset(priv, 0, sizeof(*priv)); - filp->private_data = priv; - priv->uid = current->euid; - priv->pid = current->pid; - priv->minor = minor; - priv->head = drm_heads[minor]; - priv->ioctl_count = 0; - /* for compatibility root is always authenticated */ - priv->authenticated = capable(CAP_SYS_ADMIN); - priv->lock_count = 0; - - if (dev->driver->open) { - ret = dev->driver->open(dev, priv); - if (ret < 0) - goto out_free; - } - - down(&dev->struct_sem); - if (!dev->file_last) { - priv->next = NULL; - priv->prev = NULL; - dev->file_first = priv; - dev->file_last = priv; - /* first opener automatically becomes master */ - priv->master = 1; - } else { - priv->next = NULL; - priv->prev = dev->file_last; - dev->file_last->next = priv; - dev->file_last = priv; - } - up(&dev->struct_sem); - -#ifdef __alpha__ - /* - * Default the hose - */ - if (!dev->hose) { - struct pci_dev *pci_dev; - pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); - if (pci_dev) { - dev->hose = pci_dev->sysdata; - pci_dev_put(pci_dev); - } - if (!dev->hose) { - struct pci_bus *b = pci_bus_b(pci_root_buses.next); - if (b) - dev->hose = b->sysdata; - } - } -#endif - - return 0; - out_free: - drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - filp->private_data = NULL; - return ret; -} - -/** No-op. */ -int drm_fasync(int fd, struct file *filp, int on) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - int retcode; - DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, - (long)old_encode_dev(priv->head->device)); - retcode = fasync_helper(fd, filp, on, &dev->buf_async); - if (retcode < 0) - return retcode; - return 0; -} -EXPORT_SYMBOL(drm_fasync); +EXPORT_SYMBOL(drm_open); /** * Release file. @@ -330,7 +167,7 @@ EXPORT_SYMBOL(drm_fasync); * If the hardware lock is held then free it, and take it again for the kernel * context since it's necessary to reclaim buffers. Unlink the file private * data from its list and free it. Decreases the open count and if it reaches - * zero calls drm_lastclose(). + * zero calls takedown(). */ int drm_release(struct inode *inode, struct file *filp) { @@ -343,8 +180,8 @@ int drm_release(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); - if (dev->driver->preclose) - dev->driver->preclose(dev, filp); + if (dev->driver->prerelease) + dev->driver->prerelease(dev, filp); /* ======================================================== * Begin inline drm_release @@ -360,8 +197,8 @@ int drm_release(struct inode *inode, struct file *filp) DRM_DEBUG("File %p released, freeing lock for context %d\n", filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - if (dev->driver->reclaim_buffers_locked) - dev->driver->reclaim_buffers_locked(dev, filp); + if (dev->driver->release) + dev->driver->release(dev, filp); drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); @@ -370,7 +207,7 @@ int drm_release(struct inode *inode, struct file *filp) hardware at this point, possibly processed via a callback to the X server. */ - } else if (dev->driver->reclaim_buffers_locked && priv->lock_count + } else if (dev->driver->release && priv->lock_count && dev->lock.hw_lock) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE(entry, current); @@ -400,14 +237,15 @@ int drm_release(struct inode *inode, struct file *filp) __set_current_state(TASK_RUNNING); remove_wait_queue(&dev->lock.lock_queue, &entry); if (!retcode) { - dev->driver->reclaim_buffers_locked(dev, filp); + if (dev->driver->release) + dev->driver->release(dev, filp); drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); } } - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && - !dev->driver->reclaim_buffers_locked) { + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) + && !dev->driver->release) { dev->driver->reclaim_buffers(dev, filp); } @@ -454,8 +292,9 @@ int drm_release(struct inode *inode, struct file *filp) } up(&dev->struct_sem); - if (dev->driver->postclose) - dev->driver->postclose(dev, priv); + if (dev->driver->free_filp_priv) + dev->driver->free_filp_priv(dev, priv); + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); /* ======================================================== @@ -474,7 +313,7 @@ int drm_release(struct inode *inode, struct file *filp) } spin_unlock(&dev->count_lock); unlock_kernel(); - return drm_lastclose(dev); + return drm_takedown(dev); } spin_unlock(&dev->count_lock); @@ -482,11 +321,129 @@ int drm_release(struct inode *inode, struct file *filp) return retcode; } + EXPORT_SYMBOL(drm_release); +/** + * Called whenever a process opens /dev/drm. + * + * \param inode device inode. + * \param filp file pointer. + * \param dev device. + * \return zero on success or a negative number on failure. + * + * Creates and initializes a drm_file structure for the file private data in \p + * filp and add it into the double linked list in \p dev. + */ +static int drm_open_helper(struct inode *inode, struct file *filp, + drm_device_t * dev) +{ + int minor = iminor(inode); + drm_file_t *priv; + int ret; + + if (filp->f_flags & O_EXCL) + return -EBUSY; /* No exclusive opens */ + if (!drm_cpu_valid()) + return -EINVAL; + + DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); + + priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); + if (!priv) + return -ENOMEM; + + memset(priv, 0, sizeof(*priv)); + filp->private_data = priv; + priv->uid = current->euid; + priv->pid = current->pid; + priv->minor = minor; + priv->head = drm_heads[minor]; + priv->ioctl_count = 0; + priv->authenticated = capable(CAP_SYS_ADMIN); + priv->lock_count = 0; + + if (dev->driver->open_helper) { + ret = dev->driver->open_helper(dev, priv); + if (ret < 0) + goto out_free; + } + + down(&dev->struct_sem); + if (!dev->file_last) { + priv->next = NULL; + priv->prev = NULL; + dev->file_first = priv; + dev->file_last = priv; + } else { + priv->next = NULL; + priv->prev = dev->file_last; + dev->file_last->next = priv; + dev->file_last = priv; + } + up(&dev->struct_sem); + +#ifdef __alpha__ + /* + * Default the hose + */ + if (!dev->hose) { + struct pci_dev *pci_dev; + pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); + if (pci_dev) { + dev->hose = pci_dev->sysdata; + pci_dev_put(pci_dev); + } + if (!dev->hose) { + struct pci_bus *b = pci_bus_b(pci_root_buses.next); + if (b) + dev->hose = b->sysdata; + } + } +#endif + + return 0; + out_free: + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); + filp->private_data = NULL; + return ret; +} + +/** No-op. */ +int drm_flush(struct file *filp) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)old_encode_dev(priv->head->device), + dev->open_count); + return 0; +} + +EXPORT_SYMBOL(drm_flush); + +/** No-op. */ +int drm_fasync(int fd, struct file *filp, int on) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + int retcode; + + DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, + (long)old_encode_dev(priv->head->device)); + retcode = fasync_helper(fd, filp, on, &dev->buf_async); + if (retcode < 0) + return retcode; + return 0; +} + +EXPORT_SYMBOL(drm_fasync); + /** No-op. */ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) { return 0; } + EXPORT_SYMBOL(drm_poll); diff --git a/trunk/drivers/char/drm/drm_init.c b/trunk/drivers/char/drm/drm_init.c new file mode 100644 index 000000000000..754b934715c4 --- /dev/null +++ b/trunk/drivers/char/drm/drm_init.c @@ -0,0 +1,53 @@ +/** + * \file drm_init.c + * Setup/Cleanup for DRM + * + * \author Rickard E. (Rik) Faith + * \author Gareth Hughes + */ + +/* + * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "drmP.h" + +/** + * Check whether DRI will run on this CPU. + * + * \return non-zero if the DRI will run on this CPU, or zero otherwise. + */ +int drm_cpu_valid(void) +{ +#if defined(__i386__) + if (boot_cpu_data.x86 == 3) + return 0; /* No cmpxchg on a 386 */ +#endif +#if defined(__sparc__) && !defined(__sparc_v9__) + return 0; /* No cmpxchg before v9 sparc. */ +#endif + return 1; +} diff --git a/trunk/drivers/char/drm/drm_ioctl.c b/trunk/drivers/char/drm/drm_ioctl.c index bcd4e604d3ec..9b0feba6b063 100644 --- a/trunk/drivers/char/drm/drm_ioctl.c +++ b/trunk/drivers/char/drm/drm_ioctl.c @@ -137,22 +137,17 @@ int drm_setunique(struct inode *inode, struct file *filp, static int drm_set_busid(drm_device_t * dev) { - int len; - if (dev->unique != NULL) return EBUSY; - dev->unique_len = 40; + dev->unique_len = 20; dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); if (dev->unique == NULL) return ENOMEM; - len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", + snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); - if (len > dev->unique_len) - DRM_ERROR("Unique buffer overflowed\n"); - dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2, DRM_MEM_DRIVER); @@ -244,7 +239,7 @@ int drm_getclient(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_client_t __user *argp = (drm_client_t __user *)arg; + drm_client_t __user *argp = (void __user *)arg; drm_client_t client; drm_file_t *pt; int idx; @@ -267,7 +262,7 @@ int drm_getclient(struct inode *inode, struct file *filp, client.iocs = pt->ioctl_count; up(&dev->struct_sem); - if (copy_to_user(argp, &client, sizeof(client))) + if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client))) return -EFAULT; return 0; } @@ -330,13 +325,17 @@ int drm_setversion(DRM_IOCTL_ARGS) drm_set_version_t retv; int if_version; drm_set_version_t __user *argp = (void __user *)data; + drm_version_t version; DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); + memset(&version, 0, sizeof(version)); + + dev->driver->version(&version); retv.drm_di_major = DRM_IF_MAJOR; retv.drm_di_minor = DRM_IF_MINOR; - retv.drm_dd_major = dev->driver->major; - retv.drm_dd_minor = dev->driver->minor; + retv.drm_dd_major = version.version_major; + retv.drm_dd_minor = version.version_minor; DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); @@ -344,7 +343,7 @@ int drm_setversion(DRM_IOCTL_ARGS) if (sv.drm_di_major != DRM_IF_MAJOR || sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR) return EINVAL; - if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor); + if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor); dev->if_version = DRM_MAX(if_version, dev->if_version); if (sv.drm_di_minor >= 1) { /* @@ -355,9 +354,9 @@ int drm_setversion(DRM_IOCTL_ARGS) } if (sv.drm_dd_major != -1) { - if (sv.drm_dd_major != dev->driver->major || + if (sv.drm_dd_major != version.version_major || sv.drm_dd_minor < 0 - || sv.drm_dd_minor > dev->driver->minor) + || sv.drm_dd_minor > version.version_minor) return EINVAL; if (dev->driver->set_version) diff --git a/trunk/drivers/char/drm/drm_lock.c b/trunk/drivers/char/drm/drm_lock.c index f9e45303498d..b48a595d54ec 100644 --- a/trunk/drivers/char/drm/drm_lock.c +++ b/trunk/drivers/char/drm/drm_lock.c @@ -130,6 +130,7 @@ int drm_lock(struct inode *inode, struct file *filp, /* dev->driver->kernel_context_switch isn't used by any of the x86 * drivers but is used by the Sparc driver. */ + if (dev->driver->kernel_context_switch && dev->last_context != lock.context) { dev->driver->kernel_context_switch(dev, dev->last_context, diff --git a/trunk/drivers/char/drm/drm_memory.c b/trunk/drivers/char/drm/drm_memory.c index 8074771e348f..abef2acf99f5 100644 --- a/trunk/drivers/char/drm/drm_memory.c +++ b/trunk/drivers/char/drm/drm_memory.c @@ -145,22 +145,30 @@ DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) return drm_agp_allocate_memory(dev->agp->bridge, pages, type); } +EXPORT_SYMBOL(drm_alloc_agp); + /** Wrapper around agp_free_memory() */ int drm_free_agp(DRM_AGP_MEM * handle, int pages) { return drm_agp_free_memory(handle) ? 0 : -EINVAL; } +EXPORT_SYMBOL(drm_free_agp); + /** Wrapper around agp_bind_memory() */ int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) { return drm_agp_bind_memory(handle, start); } +EXPORT_SYMBOL(drm_bind_agp); + /** Wrapper around agp_unbind_memory() */ int drm_unbind_agp(DRM_AGP_MEM * handle) { return drm_agp_unbind_memory(handle); } + +EXPORT_SYMBOL(drm_unbind_agp); #endif /* agp */ #endif /* debug_memory */ diff --git a/trunk/drivers/char/drm/drm_memory_debug.h b/trunk/drivers/char/drm/drm_memory_debug.h index e84605fc54af..b370aca718d2 100644 --- a/trunk/drivers/char/drm/drm_memory_debug.h +++ b/trunk/drivers/char/drm/drm_memory_debug.h @@ -1,5 +1,5 @@ /** - * \file drm_memory_debug.h + * \file drm_memory.h * Memory management wrappers for DRM. * * \author Rickard E. (Rik) Faith @@ -43,41 +43,42 @@ typedef struct drm_mem_stats { unsigned long bytes_freed; } drm_mem_stats_t; -static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED; -static unsigned long drm_ram_available = 0; /* In pages */ -static unsigned long drm_ram_used = 0; -static drm_mem_stats_t drm_mem_stats[] = +static DEFINE_SPINLOCK(DRM(mem_lock)); +static unsigned long DRM(ram_available) = 0; /* In pages */ +static unsigned long DRM(ram_used) = 0; +static drm_mem_stats_t DRM(mem_stats)[] = { - [DRM_MEM_DMA] = {"dmabufs"}, - [DRM_MEM_SAREA] = {"sareas"}, - [DRM_MEM_DRIVER] = {"driver"}, - [DRM_MEM_MAGIC] = {"magic"}, - [DRM_MEM_IOCTLS] = {"ioctltab"}, - [DRM_MEM_MAPS] = {"maplist"}, - [DRM_MEM_VMAS] = {"vmalist"}, - [DRM_MEM_BUFS] = {"buflist"}, - [DRM_MEM_SEGS] = {"seglist"}, - [DRM_MEM_PAGES] = {"pagelist"}, - [DRM_MEM_FILES] = {"files"}, - [DRM_MEM_QUEUES] = {"queues"}, - [DRM_MEM_CMDS] = {"commands"}, - [DRM_MEM_MAPPINGS] = {"mappings"}, - [DRM_MEM_BUFLISTS] = {"buflists"}, - [DRM_MEM_AGPLISTS] = {"agplist"}, - [DRM_MEM_SGLISTS] = {"sglist"}, - [DRM_MEM_TOTALAGP] = {"totalagp"}, - [DRM_MEM_BOUNDAGP] = {"boundagp"}, - [DRM_MEM_CTXBITMAP] = {"ctxbitmap"}, - [DRM_MEM_CTXLIST] = {"ctxlist"}, - [DRM_MEM_STUB] = {"stub"}, - {NULL, 0,} /* Last entry must be null */ + [DRM_MEM_DMA] = { + "dmabufs"},[DRM_MEM_SAREA] = { + "sareas"},[DRM_MEM_DRIVER] = { + "driver"},[DRM_MEM_MAGIC] = { + "magic"},[DRM_MEM_IOCTLS] = { + "ioctltab"},[DRM_MEM_MAPS] = { + "maplist"},[DRM_MEM_VMAS] = { + "vmalist"},[DRM_MEM_BUFS] = { + "buflist"},[DRM_MEM_SEGS] = { + "seglist"},[DRM_MEM_PAGES] = { + "pagelist"},[DRM_MEM_FILES] = { + "files"},[DRM_MEM_QUEUES] = { + "queues"},[DRM_MEM_CMDS] = { + "commands"},[DRM_MEM_MAPPINGS] = { + "mappings"},[DRM_MEM_BUFLISTS] = { + "buflists"},[DRM_MEM_AGPLISTS] = { + "agplist"},[DRM_MEM_SGLISTS] = { + "sglist"},[DRM_MEM_TOTALAGP] = { + "totalagp"},[DRM_MEM_BOUNDAGP] = { + "boundagp"},[DRM_MEM_CTXBITMAP] = { + "ctxbitmap"},[DRM_MEM_CTXLIST] = { + "ctxlist"},[DRM_MEM_STUB] = { + "stub"}, { + NULL, 0,} /* Last entry must be null */ }; -void drm_mem_init (void) { +void DRM(mem_init) (void) { drm_mem_stats_t *mem; struct sysinfo si; - for (mem = drm_mem_stats; mem->name; ++mem) { + for (mem = DRM(mem_stats); mem->name; ++mem) { mem->succeed_count = 0; mem->free_count = 0; mem->fail_count = 0; @@ -86,13 +87,13 @@ void drm_mem_init (void) { } si_meminfo(&si); - drm_ram_available = si.totalram; - drm_ram_used = 0; + DRM(ram_available) = si.totalram; + DRM(ram_used) = 0; } /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ -static int drm__mem_info (char *buf, char **start, off_t offset, +static int DRM(_mem_info) (char *buf, char **start, off_t offset, int request, int *eof, void *data) { drm_mem_stats_t *pt; int len = 0; @@ -111,11 +112,11 @@ static int drm__mem_info (char *buf, char **start, off_t offset, " | allocs bytes\n\n"); DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", "system", 0, 0, 0, - drm_ram_available << (PAGE_SHIFT - 10)); + DRM(ram_available) << (PAGE_SHIFT - 10)); DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", - "locked", 0, 0, 0, drm_ram_used >> 10); + "locked", 0, 0, 0, DRM(ram_used) >> 10); DRM_PROC_PRINT("\n"); - for (pt = drm_mem_stats; pt->name; pt++) { + for (pt = DRM(mem_stats); pt->name; pt++) { DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", pt->name, pt->succeed_count, @@ -134,17 +135,17 @@ static int drm__mem_info (char *buf, char **start, off_t offset, return len - offset; } -int drm_mem_info (char *buf, char **start, off_t offset, +int DRM(mem_info) (char *buf, char **start, off_t offset, int len, int *eof, void *data) { int ret; - spin_lock(&drm_mem_lock); - ret = drm__mem_info (buf, start, offset, len, eof, data); - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ret = DRM(_mem_info) (buf, start, offset, len, eof, data); + spin_unlock(&DRM(mem_lock)); return ret; } -void *drm_alloc (size_t size, int area) { +void *DRM(alloc) (size_t size, int area) { void *pt; if (!size) { @@ -153,41 +154,41 @@ void *drm_alloc (size_t size, int area) { } if (!(pt = kmalloc(size, GFP_KERNEL))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].fail_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[area].fail_count; + spin_unlock(&DRM(mem_lock)); return NULL; } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].succeed_count; - drm_mem_stats[area].bytes_allocated += size; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[area].succeed_count; + DRM(mem_stats)[area].bytes_allocated += size; + spin_unlock(&DRM(mem_lock)); return pt; } -void *drm_calloc (size_t nmemb, size_t size, int area) { +void *DRM(calloc) (size_t nmemb, size_t size, int area) { void *addr; - addr = drm_alloc (nmemb * size, area); + addr = DRM(alloc) (nmemb * size, area); if (addr != NULL) memset((void *)addr, 0, size * nmemb); return addr; } -void *drm_realloc (void *oldpt, size_t oldsize, size_t size, int area) { +void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) { void *pt; - if (!(pt = drm_alloc (size, area))) + if (!(pt = DRM(alloc) (size, area))) return NULL; if (oldpt && oldsize) { memcpy(pt, oldpt, oldsize); - drm_free (oldpt, oldsize, area); + DRM(free) (oldpt, oldsize, area); } return pt; } -void drm_free (void *pt, size_t size, int area) { +void DRM(free) (void *pt, size_t size, int area) { int alloc_count; int free_count; @@ -195,43 +196,43 @@ void drm_free (void *pt, size_t size, int area) { DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); else kfree(pt); - spin_lock(&drm_mem_lock); - drm_mem_stats[area].bytes_freed += size; - free_count = ++drm_mem_stats[area].free_count; - alloc_count = drm_mem_stats[area].succeed_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + DRM(mem_stats)[area].bytes_freed += size; + free_count = ++DRM(mem_stats)[area].free_count; + alloc_count = DRM(mem_stats)[area].succeed_count; + spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", free_count, alloc_count); } } -unsigned long drm_alloc_pages (int order, int area) { +unsigned long DRM(alloc_pages) (int order, int area) { unsigned long address; unsigned long bytes = PAGE_SIZE << order; unsigned long addr; unsigned int sz; - spin_lock(&drm_mem_lock); - if ((drm_ram_used >> PAGE_SHIFT) - > (DRM_RAM_PERCENT * drm_ram_available) / 100) { - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + if ((DRM(ram_used) >> PAGE_SHIFT) + > (DRM_RAM_PERCENT * DRM(ram_available)) / 100) { + spin_unlock(&DRM(mem_lock)); return 0; } - spin_unlock(&drm_mem_lock); + spin_unlock(&DRM(mem_lock)); address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); if (!address) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].fail_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[area].fail_count; + spin_unlock(&DRM(mem_lock)); return 0; } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].succeed_count; - drm_mem_stats[area].bytes_allocated += bytes; - drm_ram_used += bytes; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[area].succeed_count; + DRM(mem_stats)[area].bytes_allocated += bytes; + DRM(ram_used) += bytes; + spin_unlock(&DRM(mem_lock)); /* Zero outside the lock */ memset((void *)address, 0, bytes); @@ -245,7 +246,7 @@ unsigned long drm_alloc_pages (int order, int area) { return address; } -void drm_free_pages (unsigned long address, int order, int area) { +void DRM(free_pages) (unsigned long address, int order, int area) { unsigned long bytes = PAGE_SIZE << order; int alloc_count; int free_count; @@ -263,12 +264,12 @@ void drm_free_pages (unsigned long address, int order, int area) { free_pages(address, order); } - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[area].free_count; - alloc_count = drm_mem_stats[area].succeed_count; - drm_mem_stats[area].bytes_freed += bytes; - drm_ram_used -= bytes; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + free_count = ++DRM(mem_stats)[area].free_count; + alloc_count = DRM(mem_stats)[area].succeed_count; + DRM(mem_stats)[area].bytes_freed += bytes; + DRM(ram_used) -= bytes; + spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", @@ -276,7 +277,7 @@ void drm_free_pages (unsigned long address, int order, int area) { } } -void *drm_ioremap (unsigned long offset, unsigned long size, +void *DRM(ioremap) (unsigned long offset, unsigned long size, drm_device_t * dev) { void *pt; @@ -287,19 +288,19 @@ void *drm_ioremap (unsigned long offset, unsigned long size, } if (!(pt = drm_ioremap(offset, size, dev))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; + spin_unlock(&DRM(mem_lock)); return NULL; } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; - drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; + spin_unlock(&DRM(mem_lock)); return pt; } -void *drm_ioremap_nocache (unsigned long offset, unsigned long size, +void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size, drm_device_t * dev) { void *pt; @@ -310,19 +311,19 @@ void *drm_ioremap_nocache (unsigned long offset, unsigned long size, } if (!(pt = drm_ioremap_nocache(offset, size, dev))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; + spin_unlock(&DRM(mem_lock)); return NULL; } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; - drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; + spin_unlock(&DRM(mem_lock)); return pt; } -void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { +void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) { int alloc_count; int free_count; @@ -332,11 +333,11 @@ void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { else drm_ioremapfree(pt, size, dev); - spin_lock(&drm_mem_lock); - drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size; - free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count; - alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; + free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; + alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; + spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Excess frees: %d frees, %d allocs\n", @@ -346,7 +347,7 @@ void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { #if __OS_HAS_AGP -DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { +DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) { DRM_AGP_MEM *handle; if (!pages) { @@ -354,21 +355,21 @@ DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { return NULL; } - if ((handle = drm_agp_allocate_memory (pages, type))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; - drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated + if ((handle = DRM(agp_allocate_memory) (pages, type))) { + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; + DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated += pages << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); + spin_unlock(&DRM(mem_lock)); return handle; } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count; + spin_unlock(&DRM(mem_lock)); return NULL; } -int drm_free_agp (DRM_AGP_MEM * handle, int pages) { +int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) { int alloc_count; int free_count; int retval = -EINVAL; @@ -379,13 +380,13 @@ int drm_free_agp (DRM_AGP_MEM * handle, int pages) { return retval; } - if (drm_agp_free_memory (handle)) { - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count; - alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; - drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed + if (DRM(agp_free_memory) (handle)) { + spin_lock(&DRM(mem_lock)); + free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; + alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; + DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed += pages << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); + spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Excess frees: %d frees, %d allocs\n", @@ -396,7 +397,7 @@ int drm_free_agp (DRM_AGP_MEM * handle, int pages) { return retval; } -int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) { +int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) { int retcode = -EINVAL; if (!handle) { @@ -405,21 +406,21 @@ int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) { return retcode; } - if (!(retcode = drm_agp_bind_memory (handle, start))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated + if (!(retcode = DRM(agp_bind_memory) (handle, start))) { + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; + DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated += handle->page_count << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); + spin_unlock(&DRM(mem_lock)); return retcode; } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count; - spin_unlock(&drm_mem_lock); + spin_lock(&DRM(mem_lock)); + ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count; + spin_unlock(&DRM(mem_lock)); return retcode; } -int drm_unbind_agp (DRM_AGP_MEM * handle) { +int DRM(unbind_agp) (DRM_AGP_MEM * handle) { int alloc_count; int free_count; int retcode = -EINVAL; @@ -430,14 +431,14 @@ int drm_unbind_agp (DRM_AGP_MEM * handle) { return retcode; } - if ((retcode = drm_agp_unbind_memory (handle))) + if ((retcode = DRM(agp_unbind_memory) (handle))) return retcode; - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; - alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed + spin_lock(&DRM(mem_lock)); + free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; + alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; + DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed += handle->page_count << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); + spin_unlock(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Excess frees: %d frees, %d allocs\n", diff --git a/trunk/drivers/char/drm/drm_os_linux.h b/trunk/drivers/char/drm/drm_os_linux.h index 695115d70382..d51aeb4966f4 100644 --- a/trunk/drivers/char/drm/drm_os_linux.h +++ b/trunk/drivers/char/drm/drm_os_linux.h @@ -13,7 +13,6 @@ #define DRM_ERR(d) -(d) /** Current process ID */ #define DRM_CURRENTPID current->pid -#define DRM_SUSER(p) capable(CAP_SYS_ADMIN) #define DRM_UDELAY(d) udelay(d) /** Read a byte from a MMIO region */ #define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset)) diff --git a/trunk/drivers/char/drm/drm_pciids.h b/trunk/drivers/char/drm/drm_pciids.h index 5b1d3a04458d..d66dc55e29a0 100644 --- a/trunk/drivers/char/drm/drm_pciids.h +++ b/trunk/drivers/char/drm/drm_pciids.h @@ -46,7 +46,6 @@ {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ @@ -70,7 +69,6 @@ {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ @@ -84,13 +82,10 @@ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ {0, 0, 0} #define r128_PCI_IDS \ @@ -181,7 +176,7 @@ #define viadrv_PCI_IDS \ {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ + {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ @@ -201,10 +196,6 @@ {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} -#define gamma_PCI_IDS \ - {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} - #define savage_PCI_IDS \ {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ @@ -243,4 +234,3 @@ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} - diff --git a/trunk/drivers/char/drm/drm_proc.c b/trunk/drivers/char/drm/drm_proc.c index 6f943e3309ef..3f452f763f0f 100644 --- a/trunk/drivers/char/drm/drm_proc.c +++ b/trunk/drivers/char/drm/drm_proc.c @@ -61,14 +61,16 @@ static struct drm_proc_list { const char *name; /**< file name */ int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ } drm_proc_list[] = { - {"name", drm_name_info}, - {"mem", drm_mem_info}, - {"vm", drm_vm_info}, - {"clients", drm_clients_info}, - {"queues", drm_queues_info}, - {"bufs", drm_bufs_info}, + { + "name", drm_name_info}, { + "mem", drm_mem_info}, { + "vm", drm_vm_info}, { + "clients", drm_clients_info}, { + "queues", drm_queues_info}, { + "bufs", drm_bufs_info}, #if DRM_DEBUG_CODE - {"vma", drm_vma_info}, + { + "vma", drm_vma_info}, #endif }; diff --git a/trunk/drivers/char/drm/drm_stub.c b/trunk/drivers/char/drm/drm_stub.c index 42d766359caa..60b6f8e8bf69 100644 --- a/trunk/drivers/char/drm/drm_stub.c +++ b/trunk/drivers/char/drm/drm_stub.c @@ -93,8 +93,8 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, dev->driver = driver; - if (dev->driver->load) - if ((retcode = dev->driver->load(dev, ent->driver_data))) + if (dev->driver->preinit) + if ((retcode = dev->driver->preinit(dev, ent->driver_data))) goto error_out_unreg; if (drm_core_has_AGP(dev)) { @@ -124,10 +124,47 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, return 0; error_out_unreg: - drm_lastclose(dev); + drm_takedown(dev); return retcode; } +/** + * File \c open operation. + * + * \param inode device inode. + * \param filp file pointer. + * + * Puts the dev->fops corresponding to the device minor number into + * \p filp, call the \c open method, and restore the file operations. + */ +int drm_stub_open(struct inode *inode, struct file *filp) +{ + drm_device_t *dev = NULL; + int minor = iminor(inode); + int err = -ENODEV; + struct file_operations *old_fops; + + DRM_DEBUG("\n"); + + if (!((minor >= 0) && (minor < drm_cards_limit))) + return -ENODEV; + + if (!drm_heads[minor]) + return -ENODEV; + + if (!(dev = drm_heads[minor]->dev)) + return -ENODEV; + + old_fops = filp->f_op; + filp->f_op = fops_get(&dev->driver->fops); + if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { + fops_put(filp->f_op); + filp->f_op = fops_get(old_fops); + } + fops_put(old_fops); + + return err; +} /** * Get a secondary minor number. @@ -163,7 +200,11 @@ static int drm_get_head(drm_device_t * dev, drm_head_t * head) goto err_g1; } - head->dev_class = drm_sysfs_device_add(drm_class, head); + head->dev_class = drm_sysfs_device_add(drm_class, + MKDEV(DRM_MAJOR, + minor), + &dev->pdev->dev, + "card%d", minor); if (IS_ERR(head->dev_class)) { printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); @@ -217,10 +258,11 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, } if ((ret = drm_get_head(dev, &dev->primary))) goto err_g1; - - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary.minor); + + /* postinit is a required function to display the signon banner */ + /* drivers add secondary heads here if needed */ + if ((ret = dev->driver->postinit(dev, ent->driver_data))) + goto err_g1; return 0; @@ -276,9 +318,10 @@ int drm_put_head(drm_head_t * head) DRM_DEBUG("release secondary minor %d\n", minor); drm_proc_cleanup(minor, drm_proc_root, head->dev_root); - drm_sysfs_device_remove(head->dev_class); + drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor)); - *head = (drm_head_t) {.dev = NULL}; + *head = (drm_head_t) { + .dev = NULL}; drm_heads[minor] = NULL; diff --git a/trunk/drivers/char/drm/drm_sysfs.c b/trunk/drivers/char/drm/drm_sysfs.c index 68e43ddc16ae..6d3449761914 100644 --- a/trunk/drivers/char/drm/drm_sysfs.c +++ b/trunk/drivers/char/drm/drm_sysfs.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "drm_core.h" #include "drmP.h" @@ -26,11 +28,15 @@ struct drm_sysfs_class { #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) struct simple_dev { + struct list_head node; dev_t dev; struct class_device class_dev; }; #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) +static LIST_HEAD(simple_dev_list); +static DEFINE_SPINLOCK(simple_dev_list_lock); + static void release_simple_dev(struct class_device *class_dev) { struct simple_dev *s_dev = to_simple_dev(class_dev); @@ -118,18 +124,6 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs) class_unregister(&cs->class); } -static ssize_t show_dri(struct class_device *class_device, char *buf) -{ - drm_device_t * dev = ((drm_head_t *)class_get_devdata(class_device))->dev; - if (dev->driver->dri_library_name) - return dev->driver->dri_library_name(dev, buf); - return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); -} - -static struct class_device_attribute class_device_attrs[] = { - __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), -}; - /** * drm_sysfs_device_add - adds a class device to sysfs for a character driver * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. @@ -144,11 +138,13 @@ static struct class_device_attribute class_device_attrs[] = { * Note: the struct drm_sysfs_class passed to this function must have previously been * created with a call to drm_sysfs_create(). */ -struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, - drm_head_t *head) +struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, + struct device *device, + const char *fmt, ...) { + va_list args; struct simple_dev *s_dev = NULL; - int i, retval; + int retval; if ((cs == NULL) || (IS_ERR(cs))) { retval = -ENODEV; @@ -162,23 +158,26 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, } memset(s_dev, 0x00, sizeof(*s_dev)); - s_dev->dev = MKDEV(DRM_MAJOR, head->minor); - s_dev->class_dev.dev = &(head->dev->pdev)->dev; + s_dev->dev = dev; + s_dev->class_dev.dev = device; s_dev->class_dev.class = &cs->class; - snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); + va_start(args, fmt); + vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args); + va_end(args); retval = class_device_register(&s_dev->class_dev); if (retval) goto error; class_device_create_file(&s_dev->class_dev, &cs->attr); - class_set_devdata(&s_dev->class_dev, head); - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); + spin_lock(&simple_dev_list_lock); + list_add(&s_dev->node, &simple_dev_list); + spin_unlock(&simple_dev_list_lock); + return &s_dev->class_dev; -error: + error: kfree(s_dev); return ERR_PTR(retval); } @@ -190,12 +189,23 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, * This call unregisters and cleans up a class device that was created with a * call to drm_sysfs_device_add() */ -void drm_sysfs_device_remove(struct class_device *class_dev) +void drm_sysfs_device_remove(dev_t dev) { - struct simple_dev *s_dev = to_simple_dev(class_dev); - int i; - - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); - class_device_unregister(&s_dev->class_dev); + struct simple_dev *s_dev = NULL; + int found = 0; + + spin_lock(&simple_dev_list_lock); + list_for_each_entry(s_dev, &simple_dev_list, node) { + if (s_dev->dev == dev) { + found = 1; + break; + } + } + if (found) { + list_del(&s_dev->node); + spin_unlock(&simple_dev_list_lock); + class_device_unregister(&s_dev->class_dev); + } else { + spin_unlock(&simple_dev_list_lock); + } } diff --git a/trunk/drivers/char/drm/i810_dma.c b/trunk/drivers/char/drm/i810_dma.c index cc1b89086876..dba502373da1 100644 --- a/trunk/drivers/char/drm/i810_dma.c +++ b/trunk/drivers/char/drm/i810_dma.c @@ -114,6 +114,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) static struct file_operations i810_buffer_fops = { .open = drm_open, + .flush = drm_flush, .release = drm_release, .ioctl = drm_ioctl, .mmap = i810_mmap_buffers, @@ -1318,24 +1319,12 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp, return 0; } -int i810_driver_load(drm_device_t *dev, unsigned long flags) -{ - /* i810 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - return 0; -} - -void i810_driver_lastclose(drm_device_t * dev) +void i810_driver_pretakedown(drm_device_t * dev) { i810_dma_cleanup(dev); } -void i810_driver_preclose(drm_device_t * dev, DRMFILE filp) +void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_i810_private_t *dev_priv = dev->dev_private; @@ -1345,7 +1334,7 @@ void i810_driver_preclose(drm_device_t * dev, DRMFILE filp) } } -void i810_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp) +void i810_driver_release(drm_device_t * dev, struct file *filp) { i810_reclaim_buffers(dev, filp); } @@ -1357,21 +1346,21 @@ int i810_driver_dma_quiescent(drm_device_t * dev) } drm_ioctl_desc_t i810_ioctls[] = { - [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, DRM_AUTH} + [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1}, + [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0}, + [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0} }; int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); diff --git a/trunk/drivers/char/drm/i810_drv.c b/trunk/drivers/char/drm/i810_drv.c index dfe6ad2b6a6e..070cef6c2b46 100644 --- a/trunk/drivers/char/drm/i810_drv.c +++ b/trunk/drivers/char/drm/i810_drv.c @@ -38,6 +38,38 @@ #include "drm_pciids.h" +static int postinit(struct drm_device *dev, unsigned long flags) +{ + /* i810 has 4 more counters */ + dev->counters += 4; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + dev->types[9] = _DRM_STAT_DMA; + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} + static struct pci_device_id pciidlist[] = { i810_PCI_IDS }; @@ -47,14 +79,16 @@ static struct drm_driver driver = { DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, .dev_priv_size = sizeof(drm_i810_buf_priv_t), - .load = i810_driver_load, - .lastclose = i810_driver_lastclose, - .preclose = i810_driver_preclose, + .pretakedown = i810_driver_pretakedown, + .prerelease = i810_driver_prerelease, .device_is_agp = i810_driver_device_is_agp, - .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, + .release = i810_driver_release, .dma_quiescent = i810_driver_dma_quiescent, + .reclaim_buffers = i810_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .postinit = postinit, + .version = version, .ioctls = i810_ioctls, .fops = { .owner = THIS_MODULE, @@ -64,19 +98,13 @@ static struct drm_driver driver = { .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, - }, - + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } + , }; static int __init i810_init(void) diff --git a/trunk/drivers/char/drm/i810_drv.h b/trunk/drivers/char/drm/i810_drv.h index a18b80d91920..c78f36aaa2f0 100644 --- a/trunk/drivers/char/drm/i810_drv.h +++ b/trunk/drivers/char/drm/i810_drv.h @@ -116,13 +116,9 @@ typedef struct drm_i810_private { extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp); extern int i810_driver_dma_quiescent(drm_device_t * dev); -extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev, - struct file *filp); -extern int i810_driver_load(struct drm_device *, unsigned long flags); -extern void i810_driver_lastclose(drm_device_t * dev); -extern void i810_driver_preclose(drm_device_t * dev, DRMFILE filp); -extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev, - struct file *filp); +extern void i810_driver_release(drm_device_t * dev, struct file *filp); +extern void i810_driver_pretakedown(drm_device_t * dev); +extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern int i810_driver_device_is_agp(drm_device_t * dev); extern drm_ioctl_desc_t i810_ioctls[]; diff --git a/trunk/drivers/char/drm/i830_dma.c b/trunk/drivers/char/drm/i830_dma.c index 4fea32aed6d2..dc94f1914425 100644 --- a/trunk/drivers/char/drm/i830_dma.c +++ b/trunk/drivers/char/drm/i830_dma.c @@ -116,6 +116,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) static struct file_operations i830_buffer_fops = { .open = drm_open, + .flush = drm_flush, .release = drm_release, .ioctl = drm_ioctl, .mmap = i830_mmap_buffers, @@ -1516,24 +1517,12 @@ static int i830_setparam(struct inode *inode, struct file *filp, return 0; } -int i830_driver_load(drm_device_t *dev, unsigned long flags) -{ - /* i830 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - return 0; -} - -void i830_driver_lastclose(drm_device_t * dev) +void i830_driver_pretakedown(drm_device_t * dev) { i830_dma_cleanup(dev); } -void i830_driver_preclose(drm_device_t * dev, DRMFILE filp) +void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -1543,7 +1532,7 @@ void i830_driver_preclose(drm_device_t * dev, DRMFILE filp) } } -void i830_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp) +void i830_driver_release(drm_device_t * dev, struct file *filp) { i830_reclaim_buffers(dev, filp); } @@ -1555,20 +1544,20 @@ int i830_driver_dma_quiescent(drm_device_t * dev) } drm_ioctl_desc_t i830_ioctls[] = { - [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, DRM_AUTH} + [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0}, + [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0} }; int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); diff --git a/trunk/drivers/char/drm/i830_drv.c b/trunk/drivers/char/drm/i830_drv.c index 722658188f5f..acd821e8fe4d 100644 --- a/trunk/drivers/char/drm/i830_drv.c +++ b/trunk/drivers/char/drm/i830_drv.c @@ -40,6 +40,37 @@ #include "drm_pciids.h" +static int postinit(struct drm_device *dev, unsigned long flags) +{ + dev->counters += 4; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + dev->types[9] = _DRM_STAT_DMA; + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} + static struct pci_device_id pciidlist[] = { i830_PCI_IDS }; @@ -52,12 +83,12 @@ static struct drm_driver driver = { .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ, #endif .dev_priv_size = sizeof(drm_i830_buf_priv_t), - .load = i830_driver_load, - .lastclose = i830_driver_lastclose, - .preclose = i830_driver_preclose, + .pretakedown = i830_driver_pretakedown, + .prerelease = i830_driver_prerelease, .device_is_agp = i830_driver_device_is_agp, - .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked, + .release = i830_driver_release, .dma_quiescent = i830_driver_dma_quiescent, + .reclaim_buffers = i830_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, #if USE_IRQS @@ -66,6 +97,8 @@ static struct drm_driver driver = { .irq_uninstall = i830_driver_irq_uninstall, .irq_handler = i830_driver_irq_handler, #endif + .postinit = postinit, + .version = version, .ioctls = i830_ioctls, .fops = { .owner = THIS_MODULE, @@ -75,19 +108,13 @@ static struct drm_driver driver = { .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, - }, - + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, + .name = DRIVER_NAME, + .id_table = pciidlist, + } - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, }; static int __init i830_init(void) diff --git a/trunk/drivers/char/drm/i830_drv.h b/trunk/drivers/char/drm/i830_drv.h index bf9075b576bd..bc4bd49fb0cc 100644 --- a/trunk/drivers/char/drm/i830_drv.h +++ b/trunk/drivers/char/drm/i830_drv.h @@ -136,12 +136,10 @@ extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS); extern void i830_driver_irq_preinstall(drm_device_t * dev); extern void i830_driver_irq_postinstall(drm_device_t * dev); extern void i830_driver_irq_uninstall(drm_device_t * dev); -extern int i830_driver_load(struct drm_device *, unsigned long flags); -extern void i830_driver_preclose(drm_device_t * dev, DRMFILE filp); -extern void i830_driver_lastclose(drm_device_t * dev); -extern void i830_driver_reclaim_buffers_locked(drm_device_t * dev, - struct file *filp); +extern void i830_driver_pretakedown(drm_device_t * dev); +extern void i830_driver_release(drm_device_t * dev, struct file *filp); extern int i830_driver_dma_quiescent(drm_device_t * dev); +extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern int i830_driver_device_is_agp(drm_device_t * dev); #define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) diff --git a/trunk/drivers/char/drm/i915_dma.c b/trunk/drivers/char/drm/i915_dma.c index 9140703da1ba..f3aa0c370127 100644 --- a/trunk/drivers/char/drm/i915_dma.c +++ b/trunk/drivers/char/drm/i915_dma.c @@ -1,6 +1,7 @@ /* i915_dma.c -- DMA support for the I915 -*- linux-c -*- */ -/* +/************************************************************************** + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * @@ -24,7 +25,7 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - */ + **************************************************************************/ #include "drmP.h" #include "drm.h" @@ -195,7 +196,7 @@ static int i915_initialize(drm_device_t * dev, return 0; } -static int i915_dma_resume(drm_device_t * dev) +static int i915_resume(drm_device_t * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -252,7 +253,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) retcode = i915_dma_cleanup(dev); break; case I915_RESUME_DMA: - retcode = i915_dma_resume(dev); + retcode = i915_resume(dev); break; default: retcode = -EINVAL; @@ -653,9 +654,6 @@ static int i915_getparam(DRM_IOCTL_ARGS) case I915_PARAM_ALLOW_BATCHBUFFER: value = dev_priv->allow_batchbuffer ? 1 : 0; break; - case I915_PARAM_LAST_DISPATCH: - value = READ_BREADCRUMB(dev_priv); - break; default: DRM_ERROR("Unkown parameter %d\n", param.param); return DRM_ERR(EINVAL); @@ -701,19 +699,7 @@ static int i915_setparam(DRM_IOCTL_ARGS) return 0; } -int i915_driver_load(drm_device_t *dev, unsigned long flags) -{ - /* i915 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - return 0; -} - -void i915_driver_lastclose(drm_device_t * dev) +void i915_driver_pretakedown(drm_device_t * dev) { if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -722,7 +708,7 @@ void i915_driver_lastclose(drm_device_t * dev) i915_dma_cleanup(dev); } -void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) +void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -731,18 +717,18 @@ void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) } drm_ioctl_desc_t i915_ioctls[] = { - [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH} + [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1}, + [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0}, + [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1}, + [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0} }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/trunk/drivers/char/drm/i915_drm.h b/trunk/drivers/char/drm/i915_drm.h index 77412ddac007..23e027d29080 100644 --- a/trunk/drivers/char/drm/i915_drm.h +++ b/trunk/drivers/char/drm/i915_drm.h @@ -1,4 +1,5 @@ -/* +/************************************************************************** + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * @@ -22,7 +23,7 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - */ + **************************************************************************/ #ifndef _I915_DRM_H_ #define _I915_DRM_H_ @@ -151,7 +152,6 @@ typedef struct drm_i915_irq_wait { */ #define I915_PARAM_IRQ_ACTIVE 1 #define I915_PARAM_ALLOW_BATCHBUFFER 2 -#define I915_PARAM_LAST_DISPATCH 3 typedef struct drm_i915_getparam { int param; diff --git a/trunk/drivers/char/drm/i915_drv.c b/trunk/drivers/char/drm/i915_drv.c index 8e2e6095c4b3..0508240f4e3b 100644 --- a/trunk/drivers/char/drm/i915_drv.c +++ b/trunk/drivers/char/drm/i915_drv.c @@ -1,6 +1,6 @@ /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- */ -/* +/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -25,7 +25,7 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - */ + **************************************************************************/ #include "drmP.h" #include "drm.h" @@ -34,22 +34,48 @@ #include "drm_pciids.h" +static int postinit(struct drm_device *dev, unsigned long flags) +{ + dev->counters += 4; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + dev->types[9] = _DRM_STAT_DMA; + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} + static struct pci_device_id pciidlist[] = { i915_PCI_IDS }; static struct drm_driver driver = { - /* don't use mtrr's here, the Xserver or user space app should - * deal with them for intel hardware. - */ .driver_features = - DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, - .load = i915_driver_load, - .lastclose = i915_driver_lastclose, - .preclose = i915_driver_preclose, + DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + .pretakedown = i915_driver_pretakedown, + .prerelease = i915_driver_prerelease, .device_is_agp = i915_driver_device_is_agp, - .vblank_wait = i915_driver_vblank_wait, .irq_preinstall = i915_driver_irq_preinstall, .irq_postinstall = i915_driver_irq_postinstall, .irq_uninstall = i915_driver_irq_uninstall, @@ -57,6 +83,8 @@ static struct drm_driver driver = { .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .postinit = postinit, + .version = version, .ioctls = i915_ioctls, .fops = { .owner = THIS_MODULE, @@ -69,19 +97,11 @@ static struct drm_driver driver = { #ifdef CONFIG_COMPAT .compat_ioctl = i915_compat_ioctl, #endif - }, - + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init i915_init(void) diff --git a/trunk/drivers/char/drm/i915_drv.h b/trunk/drivers/char/drm/i915_drv.h index c6c71b45f101..17e457c73dc7 100644 --- a/trunk/drivers/char/drm/i915_drv.h +++ b/trunk/drivers/char/drm/i915_drv.h @@ -1,6 +1,6 @@ /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- */ -/* +/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -25,7 +25,7 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - */ + **************************************************************************/ #ifndef _I915_DRV_H_ #define _I915_DRV_H_ @@ -37,18 +37,21 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20051209" +#define DRIVER_DATE "20040405" /* Interface history: * * 1.1: Original. - * 1.2: Add Power Management - * 1.3: Add vblank support */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 +#define DRIVER_MINOR 1 #define DRIVER_PATCHLEVEL 0 +/* We use our own dma mechanisms, not the drm template code. However, + * the shared IRQ code is useful to us: + */ +#define __HAVE_PM 1 + typedef struct _drm_i915_ring_buffer { int tail_mask; unsigned long Start; @@ -94,7 +97,6 @@ typedef struct drm_i915_private { int tex_lru_log_granularity; int allow_batchbuffer; struct mem_block *agp_heap; - unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; } drm_i915_private_t; extern drm_ioctl_desc_t i915_ioctls[]; @@ -102,18 +104,14 @@ extern int i915_max_ioctl; /* i915_dma.c */ extern void i915_kernel_lost_context(drm_device_t * dev); -extern int i915_driver_load(struct drm_device *, unsigned long flags); -extern void i915_driver_lastclose(drm_device_t * dev); -extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp); +extern void i915_driver_pretakedown(drm_device_t * dev); +extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern int i915_driver_device_is_agp(drm_device_t * dev); -extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); /* i915_irq.c */ extern int i915_irq_emit(DRM_IOCTL_ARGS); extern int i915_irq_wait(DRM_IOCTL_ARGS); -extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(drm_device_t * dev); extern void i915_driver_irq_postinstall(drm_device_t * dev); @@ -127,10 +125,13 @@ extern void i915_mem_takedown(struct mem_block **heap); extern void i915_mem_release(drm_device_t * dev, DRMFILE filp, struct mem_block *heap); -#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg)) -#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val)) -#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg)) -#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) +extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); + +#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) +#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val) +#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) +#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val) #define I915_VERBOSE 0 @@ -194,13 +195,6 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define PPCR 0x61204 #define PPCR_ON (1<<0) -#define DVOB 0x61140 -#define DVOB_ON (1<<31) -#define DVOC 0x61160 -#define DVOC_ON (1<<31) -#define LVDS 0x61180 -#define LVDS_ON (1<<31) - #define ADPA 0x61100 #define ADPA_DPMS_MASK (~(3<<10)) #define ADPA_DPMS_ON (0<<10) @@ -264,6 +258,4 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) -#define READ_BREADCRUMB(dev_priv) (((u32 *)(dev_priv->hw_status_page))[5]) - #endif diff --git a/trunk/drivers/char/drm/i915_irq.c b/trunk/drivers/char/drm/i915_irq.c index a1381c61aa63..4fa448ee846b 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -1,6 +1,7 @@ -/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*- +/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- */ -/* +/************************************************************************** + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * @@ -24,18 +25,16 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - */ + **************************************************************************/ #include "drmP.h" #include "drm.h" #include "i915_drm.h" #include "i915_drv.h" -#define USER_INT_FLAG (1<<1) -#define VSYNC_PIPEB_FLAG (1<<5) -#define VSYNC_PIPEA_FLAG (1<<7) - +#define USER_INT_FLAG 0x2 #define MAX_NOPID ((u32)~0) +#define READ_BREADCRUMB(dev_priv) (((u32*)(dev_priv->hw_status_page))[5]) irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { @@ -44,7 +43,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) u16 temp; temp = I915_READ16(I915REG_INT_IDENTITY_R); - temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG); + temp &= USER_INT_FLAG; DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); @@ -52,15 +51,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_NONE; I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - - if (temp & USER_INT_FLAG) - DRM_WAKEUP(&dev_priv->irq_queue); - - if (temp & VSYNC_PIPEA_FLAG) { - atomic_inc(&dev->vbl_received); - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); - } + DRM_WAKEUP(&dev_priv->irq_queue); return IRQ_HANDLED; } @@ -111,27 +102,6 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) return ret; } -int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - unsigned int cur_vblank; - int ret = 0; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); - } - - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(&dev->vbl_received)) - - *sequence) <= (1<<23))); - - *sequence = cur_vblank; - - return ret; -} - - /* Needs the lock as it touches the ring. */ int i915_irq_emit(DRM_IOCTL_ARGS) @@ -195,7 +165,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG); + I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG); DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); } diff --git a/trunk/drivers/char/drm/i915_mem.c b/trunk/drivers/char/drm/i915_mem.c index ba87ff17ff64..13176d136a99 100644 --- a/trunk/drivers/char/drm/i915_mem.c +++ b/trunk/drivers/char/drm/i915_mem.c @@ -1,6 +1,7 @@ /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- */ -/* +/************************************************************************** + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * @@ -24,7 +25,7 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - */ + **************************************************************************/ #include "drmP.h" #include "drm.h" diff --git a/trunk/drivers/char/drm/mga_dma.c b/trunk/drivers/char/drm/mga_dma.c index c2a4bac14521..70dc7f64b7b9 100644 --- a/trunk/drivers/char/drm/mga_dma.c +++ b/trunk/drivers/char/drm/mga_dma.c @@ -44,9 +44,7 @@ #define MGA_DEFAULT_USEC_TIMEOUT 10000 #define MGA_FREELIST_DEBUG 0 -#define MINIMAL_CLEANUP 0 -#define FULL_CLEANUP 1 -static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup); +static int mga_do_cleanup_dma(drm_device_t * dev); /* ================================================================ * Engine control @@ -393,7 +391,7 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf) * DMA initialization, cleanup */ -int mga_driver_load(drm_device_t * dev, unsigned long flags) +int mga_driver_preinit(drm_device_t * dev, unsigned long flags) { drm_mga_private_t *dev_priv; @@ -407,14 +405,6 @@ int mga_driver_load(drm_device_t * dev, unsigned long flags) dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; dev_priv->chipset = flags; - dev_priv->mmio_base = drm_get_resource_start(dev, 1); - dev_priv->mmio_size = drm_get_resource_len(dev, 1); - - dev->counters += 3; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - return 0; } @@ -448,19 +438,17 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, drm_buf_desc_t req; drm_agp_mode_t mode; drm_agp_info_t info; - drm_agp_buffer_t agp_req; - drm_agp_binding_t bind_req; /* Acquire AGP. */ err = drm_agp_acquire(dev); if (err) { - DRM_ERROR("Unable to acquire AGP: %d\n", err); + DRM_ERROR("Unable to acquire AGP\n"); return err; } err = drm_agp_info(dev, &info); if (err) { - DRM_ERROR("Unable to get AGP info: %d\n", err); + DRM_ERROR("Unable to get AGP info\n"); return err; } @@ -484,24 +472,18 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, } /* Allocate and bind AGP memory. */ - agp_req.size = agp_size; - agp_req.type = 0; - err = drm_agp_alloc(dev, &agp_req); - if (err) { - dev_priv->agp_size = 0; + dev_priv->agp_pages = agp_size / PAGE_SIZE; + dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0); + if (dev_priv->agp_mem == NULL) { + dev_priv->agp_pages = 0; DRM_ERROR("Unable to allocate %uMB AGP memory\n", dma_bs->agp_size); - return err; + return DRM_ERR(ENOMEM); } - - dev_priv->agp_size = agp_size; - dev_priv->agp_handle = agp_req.handle; - bind_req.handle = agp_req.handle; - bind_req.offset = 0; - err = drm_agp_bind(dev, &bind_req); + err = drm_bind_agp(dev_priv->agp_mem, 0); if (err) { - DRM_ERROR("Unable to bind AGP memory: %d\n", err); + DRM_ERROR("Unable to bind AGP memory\n"); return err; } @@ -515,7 +497,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, err = drm_addmap(dev, offset, warp_size, _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); if (err) { - DRM_ERROR("Unable to map WARP microcode: %d\n", err); + DRM_ERROR("Unable to map WARP microcode\n"); return err; } @@ -523,7 +505,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, err = drm_addmap(dev, offset, dma_bs->primary_size, _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); if (err) { - DRM_ERROR("Unable to map primary DMA region: %d\n", err); + DRM_ERROR("Unable to map primary DMA region\n"); return err; } @@ -531,7 +513,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, err = drm_addmap(dev, offset, secondary_size, _DRM_AGP, 0, &dev->agp_buffer_map); if (err) { - DRM_ERROR("Unable to map secondary DMA region: %d\n", err); + DRM_ERROR("Unable to map secondary DMA region\n"); return err; } @@ -543,29 +525,15 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, err = drm_addbufs_agp(dev, &req); if (err) { - DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); + DRM_ERROR("Unable to add secondary DMA buffers\n"); return err; } - { - drm_map_list_t *_entry; - unsigned long agp_token = 0; - - list_for_each_entry(_entry, &dev->maplist->head, head) { - if (_entry->map == dev->agp_buffer_map) - agp_token = _entry->user_token; - } - if (!agp_token) - return -EFAULT; - - dev->agp_buffer_token = agp_token; - } - offset += secondary_size; err = drm_addmap(dev, offset, agp_size - offset, _DRM_AGP, 0, &dev_priv->agp_textures); if (err) { - DRM_ERROR("Unable to map AGP texture region %d\n", err); + DRM_ERROR("Unable to map AGP texture region\n"); return err; } @@ -635,8 +603,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, _DRM_READ_ONLY, &dev_priv->warp); if (err != 0) { - DRM_ERROR("Unable to create mapping for WARP microcode: %d\n", - err); + DRM_ERROR("Unable to create mapping for WARP microcode\n"); return err; } @@ -655,7 +622,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, } if (err != 0) { - DRM_ERROR("Unable to allocate primary DMA region: %d\n", err); + DRM_ERROR("Unable to allocate primary DMA region\n"); return DRM_ERR(ENOMEM); } @@ -679,7 +646,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, } if (bin_count == 0) { - DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); + DRM_ERROR("Unable to add secondary DMA buffers\n"); return err; } @@ -715,7 +682,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); if (err) { - DRM_ERROR("Unable to map MMIO region: %d\n", err); + DRM_ERROR("Unable to map MMIO region\n"); return err; } @@ -723,7 +690,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, &dev_priv->status); if (err) { - DRM_ERROR("Unable to map status region: %d\n", err); + DRM_ERROR("Unable to map status region\n"); return err; } @@ -741,7 +708,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, */ if (err) { - mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); + mga_do_cleanup_dma(dev); } /* Not only do we want to try and initialized PCI cards for PCI DMA, @@ -764,32 +731,35 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS) DRM_DEVICE; drm_mga_dma_bootstrap_t bootstrap; int err; - static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; - const drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; DRM_COPY_FROM_USER_IOCTL(bootstrap, (drm_mga_dma_bootstrap_t __user *) data, sizeof(bootstrap)); err = mga_do_dma_bootstrap(dev, &bootstrap); - if (err) { - mga_do_cleanup_dma(dev, FULL_CLEANUP); - return err; - } + if (!err) { + static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; + const drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; + + if (dev_priv->agp_textures != NULL) { + bootstrap.texture_handle = + dev_priv->agp_textures->offset; + bootstrap.texture_size = dev_priv->agp_textures->size; + } else { + bootstrap.texture_handle = 0; + bootstrap.texture_size = 0; + } - if (dev_priv->agp_textures != NULL) { - bootstrap.texture_handle = dev_priv->agp_textures->offset; - bootstrap.texture_size = dev_priv->agp_textures->size; + bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; + if (DRM_COPY_TO_USER((void __user *)data, &bootstrap, + sizeof(bootstrap))) { + err = DRM_ERR(EFAULT); + } } else { - bootstrap.texture_handle = 0; - bootstrap.texture_size = 0; + mga_do_cleanup_dma(dev); } - bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; - DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data, - bootstrap, sizeof(bootstrap)); - return err; } @@ -883,13 +853,13 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) ret = mga_warp_install_microcode(dev_priv); if (ret < 0) { - DRM_ERROR("failed to install WARP ucode!: %d\n", ret); + DRM_ERROR("failed to install WARP ucode!\n"); return ret; } ret = mga_warp_init(dev_priv); if (ret < 0) { - DRM_ERROR("failed to init WARP engine!: %d\n", ret); + DRM_ERROR("failed to init WARP engine!\n"); return ret; } @@ -934,7 +904,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) return 0; } -static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup) +static int mga_do_cleanup_dma(drm_device_t * dev) { int err = 0; DRM_DEBUG("\n"); @@ -962,39 +932,31 @@ static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup) if (dev_priv->used_new_dma_init) { #if __OS_HAS_AGP - if (dev_priv->agp_handle != 0) { - drm_agp_binding_t unbind_req; - drm_agp_buffer_t free_req; - - unbind_req.handle = dev_priv->agp_handle; - drm_agp_unbind(dev, &unbind_req); - - free_req.handle = dev_priv->agp_handle; - drm_agp_free(dev, &free_req); - + if (dev_priv->agp_mem != NULL) { dev_priv->agp_textures = NULL; - dev_priv->agp_size = 0; - dev_priv->agp_handle = 0; + drm_unbind_agp(dev_priv->agp_mem); + + drm_free_agp(dev_priv->agp_mem, + dev_priv->agp_pages); + dev_priv->agp_pages = 0; + dev_priv->agp_mem = NULL; } if ((dev->agp != NULL) && dev->agp->acquired) { err = drm_agp_release(dev); } #endif + dev_priv->used_new_dma_init = 0; } dev_priv->warp = NULL; dev_priv->primary = NULL; + dev_priv->mmio = NULL; + dev_priv->status = NULL; dev_priv->sarea = NULL; dev_priv->sarea_priv = NULL; dev->agp_buffer_map = NULL; - if (full_cleanup) { - dev_priv->mmio = NULL; - dev_priv->status = NULL; - dev_priv->used_new_dma_init = 0; - } - memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); dev_priv->warp_pipe = 0; memset(dev_priv->warp_pipe_phys, 0, @@ -1005,7 +967,7 @@ static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup) } } - return 0; + return err; } int mga_dma_init(DRM_IOCTL_ARGS) @@ -1023,11 +985,11 @@ int mga_dma_init(DRM_IOCTL_ARGS) case MGA_INIT_DMA: err = mga_do_init_dma(dev, &init); if (err) { - (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); + (void)mga_do_cleanup_dma(dev); } return err; case MGA_CLEANUP_DMA: - return mga_do_cleanup_dma(dev, FULL_CLEANUP); + return mga_do_cleanup_dma(dev); } return DRM_ERR(EINVAL); @@ -1156,7 +1118,7 @@ int mga_dma_buffers(DRM_IOCTL_ARGS) /** * Called just before the module is unloaded. */ -int mga_driver_unload(drm_device_t * dev) +int mga_driver_postcleanup(drm_device_t * dev) { drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -1167,9 +1129,9 @@ int mga_driver_unload(drm_device_t * dev) /** * Called when the last opener of the device is closed. */ -void mga_driver_lastclose(drm_device_t * dev) +void mga_driver_pretakedown(drm_device_t * dev) { - mga_do_cleanup_dma(dev, FULL_CLEANUP); + mga_do_cleanup_dma(dev); } int mga_driver_dma_quiescent(drm_device_t * dev) diff --git a/trunk/drivers/char/drm/mga_drv.c b/trunk/drivers/char/drm/mga_drv.c index 9f7ed0e0351b..1713451a5cc6 100644 --- a/trunk/drivers/char/drm/mga_drv.c +++ b/trunk/drivers/char/drm/mga_drv.c @@ -38,6 +38,41 @@ #include "drm_pciids.h" static int mga_driver_device_is_agp(drm_device_t * dev); +static int postinit(struct drm_device *dev, unsigned long flags) +{ + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; + + dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); + dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); + + dev->counters += 3; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} static struct pci_device_id pciidlist[] = { mga_PCI_IDS @@ -45,12 +80,12 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | + DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, - .load = mga_driver_load, - .unload = mga_driver_unload, - .lastclose = mga_driver_lastclose, + .preinit = mga_driver_preinit, + .postcleanup = mga_driver_postcleanup, + .pretakedown = mga_driver_pretakedown, .dma_quiescent = mga_driver_dma_quiescent, .device_is_agp = mga_driver_device_is_agp, .vblank_wait = mga_driver_vblank_wait, @@ -61,6 +96,8 @@ static struct drm_driver driver = { .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .postinit = postinit, + .version = version, .ioctls = mga_ioctls, .dma_ioctl = mga_dma_buffers, .fops = { @@ -76,16 +113,9 @@ static struct drm_driver driver = { #endif }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init mga_init(void) diff --git a/trunk/drivers/char/drm/mga_drv.h b/trunk/drivers/char/drm/mga_drv.h index 6b0c53193506..461728e6a58a 100644 --- a/trunk/drivers/char/drm/mga_drv.h +++ b/trunk/drivers/char/drm/mga_drv.h @@ -38,11 +38,11 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20051102" +#define DRIVER_DATE "20050607" #define DRIVER_MAJOR 3 #define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 +#define DRIVER_PATCHLEVEL 0 typedef struct drm_mga_primary_buffer { u8 *start; @@ -144,22 +144,22 @@ typedef struct drm_mga_private { drm_local_map_t *primary; drm_local_map_t *agp_textures; - unsigned long agp_handle; - unsigned int agp_size; + DRM_AGP_MEM *agp_mem; + unsigned int agp_pages; } drm_mga_private_t; extern drm_ioctl_desc_t mga_ioctls[]; extern int mga_max_ioctl; /* mga_dma.c */ +extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags); extern int mga_dma_bootstrap(DRM_IOCTL_ARGS); extern int mga_dma_init(DRM_IOCTL_ARGS); extern int mga_dma_flush(DRM_IOCTL_ARGS); extern int mga_dma_reset(DRM_IOCTL_ARGS); extern int mga_dma_buffers(DRM_IOCTL_ARGS); -extern int mga_driver_load(drm_device_t *dev, unsigned long flags); -extern int mga_driver_unload(drm_device_t * dev); -extern void mga_driver_lastclose(drm_device_t * dev); +extern int mga_driver_postcleanup(drm_device_t * dev); +extern void mga_driver_pretakedown(drm_device_t * dev); extern int mga_driver_dma_quiescent(drm_device_t * dev); extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); diff --git a/trunk/drivers/char/drm/mga_state.c b/trunk/drivers/char/drm/mga_state.c index 2837e669183a..47f54b5ae956 100644 --- a/trunk/drivers/char/drm/mga_state.c +++ b/trunk/drivers/char/drm/mga_state.c @@ -1127,19 +1127,19 @@ static int mga_wait_fence(DRM_IOCTL_ARGS) } drm_ioctl_desc_t mga_ioctls[] = { - [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1}, + [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0}, + [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1}, }; int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); diff --git a/trunk/drivers/char/drm/r128_cce.c b/trunk/drivers/char/drm/r128_cce.c index db5a60450e68..7452753d4d01 100644 --- a/trunk/drivers/char/drm/r128_cce.c +++ b/trunk/drivers/char/drm/r128_cce.c @@ -1,7 +1,6 @@ -/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- +/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com - */ -/* + * * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -560,8 +559,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) if (dev_priv->is_pci) { #endif dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; - dev_priv->gart_info.addr = NULL; - dev_priv->gart_info.bus_addr = 0; + dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0; dev_priv->gart_info.is_pcie = 0; if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); @@ -603,16 +601,15 @@ int r128_do_cleanup_cce(drm_device_t * dev) drm_core_ioremapfree(dev_priv->cce_ring, dev); if (dev_priv->ring_rptr != NULL) drm_core_ioremapfree(dev_priv->ring_rptr, dev); - if (dev->agp_buffer_map != NULL) { + if (dev->agp_buffer_map != NULL) drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } } else #endif { if (dev_priv->gart_info.bus_addr) if (!drm_ati_pcigart_cleanup(dev, - &dev_priv->gart_info)) + &dev_priv-> + gart_info)) DRM_ERROR ("failed to cleanup PCI GART!\n"); } diff --git a/trunk/drivers/char/drm/r128_drm.h b/trunk/drivers/char/drm/r128_drm.h index 5d835b006f55..5ddc03202411 100644 --- a/trunk/drivers/char/drm/r128_drm.h +++ b/trunk/drivers/char/drm/r128_drm.h @@ -1,7 +1,7 @@ /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- * 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. * All rights reserved. * diff --git a/trunk/drivers/char/drm/r128_drv.c b/trunk/drivers/char/drm/r128_drv.c index e20450ae220e..1661e7351402 100644 --- a/trunk/drivers/char/drm/r128_drv.c +++ b/trunk/drivers/char/drm/r128_drv.c @@ -37,6 +37,31 @@ #include "drm_pciids.h" +static int postinit(struct drm_device *dev, unsigned long flags) +{ + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} + static struct pci_device_id pciidlist[] = { r128_PCI_IDS }; @@ -47,8 +72,8 @@ static struct drm_driver driver = { DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_r128_buf_priv_t), - .preclose = r128_driver_preclose, - .lastclose = r128_driver_lastclose, + .prerelease = r128_driver_prerelease, + .pretakedown = r128_driver_pretakedown, .vblank_wait = r128_driver_vblank_wait, .irq_preinstall = r128_driver_irq_preinstall, .irq_postinstall = r128_driver_irq_postinstall, @@ -57,6 +82,8 @@ static struct drm_driver driver = { .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .postinit = postinit, + .version = version, .ioctls = r128_ioctls, .dma_ioctl = r128_cce_buffers, .fops = { @@ -70,19 +97,12 @@ static struct drm_driver driver = { #ifdef CONFIG_COMPAT .compat_ioctl = r128_compat_ioctl, #endif - }, - + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init r128_init(void) diff --git a/trunk/drivers/char/drm/r128_drv.h b/trunk/drivers/char/drm/r128_drv.h index 94abffb2cca5..5c79e40eb88f 100644 --- a/trunk/drivers/char/drm/r128_drv.h +++ b/trunk/drivers/char/drm/r128_drv.h @@ -1,7 +1,7 @@ /* r128_drv.h -- Private header for r128 driver -*- linux-c -*- * 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. * All rights reserved. * @@ -154,8 +154,8 @@ extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); extern void r128_driver_irq_preinstall(drm_device_t * dev); extern void r128_driver_irq_postinstall(drm_device_t * dev); extern void r128_driver_irq_uninstall(drm_device_t * dev); -extern void r128_driver_lastclose(drm_device_t * dev); -extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp); +extern void r128_driver_pretakedown(drm_device_t * dev); +extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp); extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/trunk/drivers/char/drm/r128_irq.c b/trunk/drivers/char/drm/r128_irq.c index 87f8ca2b0685..27eb0e31bd3b 100644 --- a/trunk/drivers/char/drm/r128_irq.c +++ b/trunk/drivers/char/drm/r128_irq.c @@ -1,5 +1,5 @@ -/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */ -/* +/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- + * * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * * The Weather Channel (TM) funded Tungsten Graphics to develop the diff --git a/trunk/drivers/char/drm/r128_state.c b/trunk/drivers/char/drm/r128_state.c index caeecc2c36da..14479cc08a57 100644 --- a/trunk/drivers/char/drm/r128_state.c +++ b/trunk/drivers/char/drm/r128_state.c @@ -1,7 +1,7 @@ /* r128_state.c -- State support for r128 -*- linux-c -*- * 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. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -1674,7 +1674,7 @@ static int r128_getparam(DRM_IOCTL_ARGS) return 0; } -void r128_driver_preclose(drm_device_t * dev, DRMFILE filp) +void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -1684,29 +1684,29 @@ void r128_driver_preclose(drm_device_t * dev, DRMFILE filp) } } -void r128_driver_lastclose(drm_device_t * dev) +void r128_driver_pretakedown(drm_device_t * dev) { r128_do_cleanup_cce(dev); } drm_ioctl_desc_t r128_ioctls[] = { - [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, 1, 0}, + [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, 1, 1}, + [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, 1, 0}, }; int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); diff --git a/trunk/drivers/char/drm/r300_cmdbuf.c b/trunk/drivers/char/drm/r300_cmdbuf.c index 291dbf4c8186..3a1ac5f78b43 100644 --- a/trunk/drivers/char/drm/r300_cmdbuf.c +++ b/trunk/drivers/char/drm/r300_cmdbuf.c @@ -52,8 +52,8 @@ static const int r300_cliprect_cntl[4] = { * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command * buffer, starting with index n. */ -static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, int n) +static int r300_emit_cliprects(drm_radeon_private_t * dev_priv, + drm_radeon_kcmd_buffer_t * cmdbuf, int n) { drm_clip_rect_t box; int nr; @@ -216,7 +216,6 @@ void r300_init_reg_flags(void) ADD_RANGE(R300_TX_UNK1_0, 16); ADD_RANGE(R300_TX_SIZE_0, 16); ADD_RANGE(R300_TX_FORMAT_0, 16); - ADD_RANGE(R300_TX_PITCH_0, 16); /* Texture offset is dangerous and needs more checking */ ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); ADD_RANGE(R300_TX_UNK4_0, 16); @@ -243,7 +242,7 @@ static __inline__ int r300_check_range(unsigned reg, int count) /* 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, +static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv, u32 offset) { /* we realy want to check against end of video aperture @@ -318,8 +317,8 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * * * Note that checks are performed on contents and addresses of the registers */ -static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, +static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, + drm_radeon_kcmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int reg; @@ -364,8 +363,8 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv, * the graphics card. * Called by r300_do_cp_cmdbuf. */ -static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, +static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, + drm_radeon_kcmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int sz; @@ -401,8 +400,8 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv, * Emit a clear packet from userspace. * Called by r300_emit_packet3. */ -static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) +static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, + drm_radeon_kcmd_buffer_t * cmdbuf) { RING_LOCALS; @@ -422,8 +421,8 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv, return 0; } -static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, +static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv, + drm_radeon_kcmd_buffer_t * cmdbuf, u32 header) { int count, i, k; @@ -490,8 +489,8 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, return 0; } -static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) +static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, + drm_radeon_kcmd_buffer_t * cmdbuf) { u32 header; int count; @@ -555,8 +554,8 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, * Emit a rendering packet3 from userspace. * Called by r300_do_cp_cmdbuf. */ -static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, +static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv, + drm_radeon_kcmd_buffer_t * cmdbuf, drm_r300_cmd_header_t header) { int n; @@ -624,7 +623,7 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv, /** * Emit the sequence to pacify R300. */ -static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) +static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv) { RING_LOCALS; @@ -658,10 +657,9 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf) * commands on the DMA ring buffer. * Called by the ioctl handler function radeon_cp_cmdbuf. */ -int r300_do_cp_cmdbuf(drm_device_t *dev, +int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, - drm_file_t *filp_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) + drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; diff --git a/trunk/drivers/char/drm/r300_reg.h b/trunk/drivers/char/drm/r300_reg.h index a0ed20e25221..e5b73c002394 100644 --- a/trunk/drivers/char/drm/r300_reg.h +++ b/trunk/drivers/char/drm/r300_reg.h @@ -797,7 +797,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_FORMAT_YUV_MODE 0x00800000 -#define R300_TX_PITCH_0 0x4500 #define R300_TX_OFFSET_0 0x4540 /* BEGIN: Guess from R200 */ # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) diff --git a/trunk/drivers/char/drm/radeon_cp.c b/trunk/drivers/char/drm/radeon_cp.c index 915665c7fe7c..342302d46743 100644 --- a/trunk/drivers/char/drm/radeon_cp.c +++ b/trunk/drivers/char/drm/radeon_cp.c @@ -1,5 +1,5 @@ -/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */ -/* +/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- + * * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Fremont, California. * All Rights Reserved. @@ -824,7 +824,7 @@ static int RADEON_READ_PLL(drm_device_t * dev, int addr) return RADEON_READ(RADEON_CLOCK_CNTL_DATA); } -static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) +static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr) { RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); return RADEON_READ(RADEON_PCIE_DATA); @@ -1125,7 +1125,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | (dev_priv->fb_location >> 16)); #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { + if (!dev_priv->is_pci) { RADEON_WRITE(RADEON_MC_AGP_LOCATION, (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 0xffff0000) | @@ -1152,7 +1152,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, dev_priv->ring.tail = cur_read_ptr; #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { + if (!dev_priv->is_pci) { /* set RADEON_AGP_BASE here instead of relying on X from user space */ RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, @@ -1278,15 +1278,13 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) /* Enable or disable PCI GART on the chip */ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { - u32 tmp; + u32 tmp = RADEON_READ(RADEON_AIC_CNTL); if (dev_priv->flags & CHIP_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; } - tmp = RADEON_READ(RADEON_AIC_CNTL); - if (on) { RADEON_WRITE(RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN); @@ -1314,17 +1312,13 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) - { - DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~CHIP_IS_AGP; - } + dev_priv->is_pci = init->is_pci; - if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) { + if (dev_priv->is_pci && !dev->sg) { DRM_ERROR("PCI GART memory not allocated!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } @@ -1333,11 +1327,12 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if (dev_priv->usec_timeout < 1 || dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { DRM_DEBUG("TIMEOUT problem!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } - switch(init->func) { + switch (init->func) { case RADEON_INIT_R200_CP: dev_priv->microcode_version = UCODE_R200; break; @@ -1358,6 +1353,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } @@ -1420,6 +1416,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) DRM_GETSAREA(); + dev_priv->fb_offset = init->fb_offset; + dev_priv->mmio_offset = init->mmio_offset; dev_priv->ring_offset = init->ring_offset; dev_priv->ring_rptr_offset = init->ring_rptr_offset; dev_priv->buffers_offset = init->buffers_offset; @@ -1427,19 +1425,29 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if (!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } + dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); + if (!dev_priv->mmio) { + DRM_ERROR("could not find mmio region!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); if (!dev_priv->cp_ring) { DRM_ERROR("could not find cp ring region!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); if (!dev_priv->ring_rptr) { DRM_ERROR("could not find ring read pointer!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } @@ -1447,6 +1455,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { DRM_ERROR("could not find dma buffer region!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } @@ -1456,6 +1465,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) drm_core_findmap(dev, init->gart_textures_offset); if (!dev_priv->gart_textures) { DRM_ERROR("could not find GART texture region!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } @@ -1466,7 +1476,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) init->sarea_priv_offset); #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { + if (!dev_priv->is_pci) { drm_core_ioremap(dev_priv->cp_ring, dev); drm_core_ioremap(dev_priv->ring_rptr, dev); drm_core_ioremap(dev->agp_buffer_map, dev); @@ -1474,6 +1484,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) !dev_priv->ring_rptr->handle || !dev->agp_buffer_map->handle) { DRM_ERROR("could not find ioremap agp regions!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } @@ -1514,7 +1525,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) + RADEON_READ(RADEON_CONFIG_APER_SIZE); #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) + if (!dev_priv->is_pci) dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1540,7 +1551,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { + if (!dev_priv->is_pci) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -1550,28 +1561,25 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if (dev_priv->pcigart_offset) { dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.mapping.offset = - dev_priv->gart_info.bus_addr; - dev_priv->gart_info.mapping.size = - RADEON_PCIGART_TABLE_SIZE; - - drm_core_ioremap(&dev_priv->gart_info.mapping, dev); dev_priv->gart_info.addr = - dev_priv->gart_info.mapping.handle; + (unsigned long)drm_ioremap(dev_priv->gart_info. + bus_addr, + RADEON_PCIGART_TABLE_SIZE, + dev); dev_priv->gart_info.is_pcie = !!(dev_priv->flags & CHIP_IS_PCIE); dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; - DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", + DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", dev_priv->gart_info.addr, dev_priv->pcigart_offset); } else { dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; - dev_priv->gart_info.addr = NULL; - dev_priv->gart_info.bus_addr = 0; + dev_priv->gart_info.addr = + dev_priv->gart_info.bus_addr = 0; if (dev_priv->flags & CHIP_IS_PCIE) { DRM_ERROR ("Cannot use PCI Express without GART in FB memory\n"); @@ -1582,6 +1590,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); + dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); return DRM_ERR(ENOMEM); } @@ -1595,6 +1604,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->last_buf = 0; + dev->dev_private = (void *)dev_priv; + radeon_do_engine_reset(dev); return 0; @@ -1613,15 +1624,11 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) drm_irq_uninstall(dev); #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { - if (dev_priv->cp_ring != NULL) { + if (!dev_priv->is_pci) { + if (dev_priv->cp_ring != NULL) drm_core_ioremapfree(dev_priv->cp_ring, dev); - dev_priv->cp_ring = NULL; - } - if (dev_priv->ring_rptr != NULL) { + if (dev_priv->ring_rptr != NULL) drm_core_ioremapfree(dev_priv->ring_rptr, dev); - dev_priv->ring_rptr = NULL; - } if (dev->agp_buffer_map != NULL) { drm_core_ioremapfree(dev->agp_buffer_map, dev); dev->agp_buffer_map = NULL; @@ -1629,20 +1636,17 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) } else #endif { - - if (dev_priv->gart_info.bus_addr) { - /* Turn off PCI GART */ - radeon_set_pcigart(dev_priv, 0); + if (dev_priv->gart_info.bus_addr) if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) DRM_ERROR("failed to cleanup PCI GART!\n"); - } - if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) - { - drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); + if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { + drm_ioremapfree((void *)dev_priv->gart_info.addr, + RADEON_PCIGART_TABLE_SIZE, dev); dev_priv->gart_info.addr = 0; } } + /* only clear to the start of flags */ memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); @@ -1668,7 +1672,7 @@ static int radeon_do_resume_cp(drm_device_t * dev) DRM_DEBUG("Starting radeon_do_resume_cp()\n"); #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { + if (!dev_priv->is_pci) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -2099,7 +2103,7 @@ int radeon_cp_buffers(DRM_IOCTL_ARGS) return ret; } -int radeon_driver_load(struct drm_device *dev, unsigned long flags) +int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) { drm_radeon_private_t *dev_priv; int ret = 0; @@ -2132,14 +2136,11 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->flags |= CHIP_IS_PCIE; DRM_DEBUG("%s card detected\n", - ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI")))); + ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); return ret; } -/* Create mappings for registers and framebuffer so userland doesn't necessarily - * have to find them. - */ -int radeon_driver_firstopen(struct drm_device *dev) +int radeon_presetup(struct drm_device *dev) { int ret; drm_local_map_t *map; @@ -2160,11 +2161,12 @@ int radeon_driver_firstopen(struct drm_device *dev) return 0; } -int radeon_driver_unload(struct drm_device *dev) +int radeon_driver_postcleanup(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; diff --git a/trunk/drivers/char/drm/radeon_drm.h b/trunk/drivers/char/drm/radeon_drm.h index 9c177a6b2a4c..1cd81a671a36 100644 --- a/trunk/drivers/char/drm/radeon_drm.h +++ b/trunk/drivers/char/drm/radeon_drm.h @@ -624,11 +624,6 @@ typedef struct drm_radeon_indirect { int discard; } drm_radeon_indirect_t; -/* enum for card type parameters */ -#define RADEON_CARD_PCI 0 -#define RADEON_CARD_AGP 1 -#define RADEON_CARD_PCIE 2 - /* 1.3: An ioctl to get parameters that aren't available to the 3d * client any other way. */ @@ -645,7 +640,6 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_SAREA_HANDLE 9 #define RADEON_PARAM_GART_TEX_HANDLE 10 #define RADEON_PARAM_SCRATCH_OFFSET 11 -#define RADEON_PARAM_CARD_TYPE 12 typedef struct drm_radeon_getparam { int param; diff --git a/trunk/drivers/char/drm/radeon_drv.c b/trunk/drivers/char/drm/radeon_drv.c index b04ed1b562b9..ee49670d8162 100644 --- a/trunk/drivers/char/drm/radeon_drv.c +++ b/trunk/drivers/char/drm/radeon_drv.c @@ -42,15 +42,29 @@ int radeon_no_wb; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); module_param_named(no_wb, radeon_no_wb, int, 0444); -static int dri_library_name(struct drm_device *dev, char *buf) +static int postinit(struct drm_device *dev, unsigned long flags) { - drm_radeon_private_t *dev_priv = dev->dev_private; - int family = dev_priv->flags & CHIP_FAMILY_MASK; + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; - return snprintf(buf, PAGE_SIZE, "%s\n", - (family < CHIP_R200) ? "radeon" : - ((family < CHIP_R300) ? "r200" : - "r300")); + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; } static struct pci_device_id pciidlist[] = { @@ -63,22 +77,23 @@ static struct drm_driver driver = { DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_radeon_buf_priv_t), - .load = radeon_driver_load, - .firstopen = radeon_driver_firstopen, - .open = radeon_driver_open, - .preclose = radeon_driver_preclose, - .postclose = radeon_driver_postclose, - .lastclose = radeon_driver_lastclose, - .unload = radeon_driver_unload, + .preinit = radeon_driver_preinit, + .presetup = radeon_presetup, + .postcleanup = radeon_driver_postcleanup, + .prerelease = radeon_driver_prerelease, + .pretakedown = radeon_driver_pretakedown, + .open_helper = radeon_driver_open_helper, .vblank_wait = radeon_driver_vblank_wait, - .dri_library_name = dri_library_name, .irq_preinstall = radeon_driver_irq_preinstall, .irq_postinstall = radeon_driver_irq_postinstall, .irq_uninstall = radeon_driver_irq_uninstall, .irq_handler = radeon_driver_irq_handler, + .free_filp_priv = radeon_driver_free_filp_priv, .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .postinit = postinit, + .version = version, .ioctls = radeon_ioctls, .dma_ioctl = radeon_cp_buffers, .fops = { @@ -92,19 +107,12 @@ static struct drm_driver driver = { #ifdef CONFIG_COMPAT .compat_ioctl = radeon_compat_ioctl, #endif - }, - + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init radeon_init(void) diff --git a/trunk/drivers/char/drm/radeon_drv.h b/trunk/drivers/char/drm/radeon_drv.h index 498b19b1d641..d92ccee3e54c 100644 --- a/trunk/drivers/char/drm/radeon_drv.h +++ b/trunk/drivers/char/drm/radeon_drv.h @@ -38,7 +38,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20051229" +#define DRIVER_DATE "20050911" /* Interface history: * @@ -73,7 +73,7 @@ * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color * and GL_EXT_blend_[func|equation]_separate on r200 * 1.12- Add R300 CP microcode support - this just loads the CP on r300 - * (No 3D support yet - just microcode loading). + * (No 3D support yet - just microcode loading) * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters * - Add hyperz support, add hyperz flags to clear ioctl. * 1.14- Add support for color tiling @@ -88,13 +88,14 @@ * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) * 1.19- Add support for gart table in FB memory and PCIE r300 - * 1.20- Add support for r300 texrect - * 1.21- Add support for card type getparam */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 21 +#define DRIVER_MINOR 19 #define DRIVER_PATCHLEVEL 0 +#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) +#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) + /* * Radeon chip families */ @@ -102,8 +103,8 @@ enum radeon_family { CHIP_R100, CHIP_RS100, CHIP_RV100, - CHIP_RV200, CHIP_R200, + CHIP_RV200, CHIP_RS200, CHIP_R250, CHIP_RS250, @@ -137,9 +138,6 @@ enum radeon_chip_flags { CHIP_IS_PCIE = 0x00200000UL, }; -#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) -#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) - typedef struct drm_radeon_freelist { unsigned int age; drm_buf_t *buf; @@ -247,6 +245,8 @@ typedef struct drm_radeon_private { drm_radeon_depth_clear_t depth_clear; + unsigned long fb_offset; + unsigned long mmio_offset; unsigned long ring_offset; unsigned long ring_rptr_offset; unsigned long buffers_offset; @@ -273,6 +273,7 @@ typedef struct drm_radeon_private { /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ + int is_pci; } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -329,14 +330,17 @@ extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern void radeon_driver_irq_preinstall(drm_device_t * dev); extern void radeon_driver_irq_postinstall(drm_device_t * dev); extern void radeon_driver_irq_uninstall(drm_device_t * dev); +extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp); +extern void radeon_driver_pretakedown(drm_device_t * dev); +extern int radeon_driver_open_helper(drm_device_t * dev, + drm_file_t * filp_priv); +extern void radeon_driver_free_filp_priv(drm_device_t * dev, + drm_file_t * filp_priv); + +extern int radeon_preinit(struct drm_device *dev, unsigned long flags); +extern int radeon_postinit(struct drm_device *dev, unsigned long flags); +extern int radeon_postcleanup(struct drm_device *dev); -extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); -extern int radeon_driver_unload(struct drm_device *dev); -extern int radeon_driver_firstopen(struct drm_device *dev); -extern void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp); -extern void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp); -extern void radeon_driver_lastclose(drm_device_t * dev); -extern int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv); extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); @@ -360,8 +364,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, */ #define RADEON_AGP_COMMAND 0x0f60 -#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ -# define RADEON_AGP_ENABLE (1<<8) #define RADEON_AUX_SCISSOR_CNTL 0x26f0 # define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) # define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) @@ -649,8 +651,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_WAIT_UNTIL 0x1720 # define RADEON_WAIT_CRTC_PFLIP (1 << 0) -# define RADEON_WAIT_2D_IDLE (1 << 14) -# define RADEON_WAIT_3D_IDLE (1 << 15) # define RADEON_WAIT_2D_IDLECLEAN (1 << 16) # define RADEON_WAIT_3D_IDLECLEAN (1 << 17) # define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) @@ -1105,6 +1105,7 @@ do { \ write = 0; \ _tab += _i; \ } \ + \ while (_size > 0) { \ *(ring + write) = *_tab++; \ write++; \ diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index 7bc27516d425..231ac1438c69 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -1,5 +1,5 @@ -/* radeon_state.c -- State support for Radeon -*- linux-c -*- */ -/* +/* radeon_state.c -- State support for Radeon -*- linux-c -*- + * * Copyright 2000 VA Linux Systems, Inc., Fremont, California. * All Rights Reserved. * @@ -72,7 +72,10 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case RADEON_EMIT_PP_MISC: if (radeon_check_and_fixup_offset(dev_priv, filp_priv, - &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) { + &data[(RADEON_RB3D_DEPTHOFFSET + - + RADEON_PP_MISC) / + 4])) { DRM_ERROR("Invalid depth buffer offset\n"); return DRM_ERR(EINVAL); } @@ -80,7 +83,10 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case RADEON_EMIT_PP_CNTL: if (radeon_check_and_fixup_offset(dev_priv, filp_priv, - &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) { + &data[(RADEON_RB3D_COLOROFFSET + - + RADEON_PP_CNTL) / + 4])) { DRM_ERROR("Invalid colour buffer offset\n"); return DRM_ERR(EINVAL); } @@ -103,7 +109,10 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case RADEON_EMIT_PP_TXFILTER_1: case RADEON_EMIT_PP_TXFILTER_2: if (radeon_check_and_fixup_offset(dev_priv, filp_priv, - &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) { + &data[(RADEON_PP_TXOFFSET_0 + - + RADEON_PP_TXFILTER_0) / + 4])) { DRM_ERROR("Invalid R100 texture offset\n"); return DRM_ERR(EINVAL); } @@ -117,9 +126,8 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case R200_EMIT_PP_CUBIC_OFFSETS_5:{ int i; for (i = 0; i < 5; i++) { - if (radeon_check_and_fixup_offset(dev_priv, - filp_priv, - &data[i])) { + if (radeon_check_and_fixup_offset + (dev_priv, filp_priv, &data[i])) { DRM_ERROR ("Invalid R200 cubic texture offset\n"); return DRM_ERR(EINVAL); @@ -231,9 +239,8 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * dev_priv, - drm_file_t *filp_priv, - drm_radeon_kcmd_buffer_t * - cmdbuf, + drm_file_t * filp_priv, + drm_radeon_kcmd_buffer_t *cmdbuf, unsigned int *cmdsz) { u32 *cmd = (u32 *) cmdbuf->buf; @@ -548,8 +555,7 @@ static struct { {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, - {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, - "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, + {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, @@ -563,7 +569,7 @@ static struct { {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ - {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ + {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, @@ -586,7 +592,7 @@ static struct { {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, - {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ + {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, @@ -979,8 +985,8 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, * rendering a quad into just those buffers. Thus, we have to * make sure the 3D engine is configured correctly. */ - else if ((dev_priv->microcode_version == UCODE_R200) && - (flags & (RADEON_DEPTH | RADEON_STENCIL))) { + if ((dev_priv->microcode_version == UCODE_R200) && + (flags & (RADEON_DEPTH | RADEON_STENCIL))) { int tempPP_CNTL; int tempRE_CNTL; @@ -1631,14 +1637,6 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); dwords = size / 4; -#define RADEON_COPY_MT(_buf, _data, _width) \ - do { \ - if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\ - DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \ - return DRM_ERR(EFAULT); \ - } \ - } while(0) - if (microtile) { /* texture micro tiling in use, minimum texture width is thus 16 bytes. however, we cannot use blitter directly for texture width < 64 bytes, @@ -1650,19 +1648,46 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, from user space. */ if (tex->height == 1) { if (tex_width >= 64 || tex_width <= 16) { - RADEON_COPY_MT(buffer, data, - (int)(tex_width * sizeof(u32))); + if (DRM_COPY_FROM_USER(buffer, data, + tex_width * + sizeof(u32))) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } } else if (tex_width == 32) { - RADEON_COPY_MT(buffer, data, 16); - RADEON_COPY_MT(buffer + 8, - data + 16, 16); + if (DRM_COPY_FROM_USER + (buffer, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } + if (DRM_COPY_FROM_USER + (buffer + 8, data + 16, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } } } else if (tex_width >= 64 || tex_width == 16) { - RADEON_COPY_MT(buffer, data, - (int)(dwords * sizeof(u32))); + if (DRM_COPY_FROM_USER(buffer, data, + dwords * sizeof(u32))) { + DRM_ERROR("EFAULT on data, %d dwords\n", + dwords); + return DRM_ERR(EFAULT); + } } else if (tex_width < 16) { for (i = 0; i < tex->height; i++) { - RADEON_COPY_MT(buffer, data, tex_width); + if (DRM_COPY_FROM_USER + (buffer, data, tex_width)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } buffer += 4; data += tex_width; } @@ -1670,13 +1695,37 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, /* TODO: make sure this works when not fitting in one buffer (i.e. 32bytes x 2048...) */ for (i = 0; i < tex->height; i += 2) { - RADEON_COPY_MT(buffer, data, 16); + if (DRM_COPY_FROM_USER + (buffer, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } data += 16; - RADEON_COPY_MT(buffer + 8, data, 16); + if (DRM_COPY_FROM_USER + (buffer + 8, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } data += 16; - RADEON_COPY_MT(buffer + 4, data, 16); + if (DRM_COPY_FROM_USER + (buffer + 4, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } data += 16; - RADEON_COPY_MT(buffer + 12, data, 16); + if (DRM_COPY_FROM_USER + (buffer + 12, data, 16)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } data += 16; buffer += 16; } @@ -1686,22 +1735,31 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, /* Texture image width is larger than the minimum, so we * can upload it directly. */ - RADEON_COPY_MT(buffer, data, - (int)(dwords * sizeof(u32))); + if (DRM_COPY_FROM_USER(buffer, data, + dwords * sizeof(u32))) { + DRM_ERROR("EFAULT on data, %d dwords\n", + dwords); + return DRM_ERR(EFAULT); + } } else { /* Texture image width is less than the minimum, so we * need to pad out each image scanline to the minimum * width. */ for (i = 0; i < tex->height; i++) { - RADEON_COPY_MT(buffer, data, tex_width); + if (DRM_COPY_FROM_USER + (buffer, data, tex_width)) { + DRM_ERROR + ("EFAULT on pad, %d bytes\n", + tex_width); + return DRM_ERR(EFAULT); + } buffer += 8; data += tex_width; } } } -#undef RADEON_COPY_MT buf->filp = filp; buf->used = size; offset = dev_priv->gart_buffers_offset + buf->offset; @@ -1763,7 +1821,7 @@ static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple) } static void radeon_apply_surface_regs(int surf_index, - drm_radeon_private_t *dev_priv) + drm_radeon_private_t * dev_priv) { if (!dev_priv->mmio) return; @@ -1789,8 +1847,8 @@ static void radeon_apply_surface_regs(int surf_index, * freed, we suddenly need two surfaces to store A and C, which might * not always be available. */ -static int alloc_surface(drm_radeon_surface_alloc_t *new, - drm_radeon_private_t *dev_priv, DRMFILE filp) +static int alloc_surface(drm_radeon_surface_alloc_t * new, + drm_radeon_private_t * dev_priv, DRMFILE filp) { struct radeon_virt_surface *s; int i; @@ -2100,11 +2158,6 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); - } - DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, @@ -2543,9 +2596,9 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv, return 0; } -static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv, +static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv, drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { int sz = header.scalars.count; int start = header.scalars.offset; @@ -2565,9 +2618,9 @@ static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv, /* God this is ugly */ -static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv, +static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv, drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { int sz = header.scalars.count; int start = ((unsigned int)header.scalars.offset) + 0x100; @@ -2585,9 +2638,9 @@ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv, return 0; } -static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv, +static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv, drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) + drm_radeon_kcmd_buffer_t * cmdbuf) { int sz = header.vectors.count; int start = header.vectors.offset; @@ -2632,8 +2685,8 @@ static int radeon_emit_packet3(drm_device_t * dev, return 0; } -static int radeon_emit_packet3_cliprect(drm_device_t *dev, - drm_file_t *filp_priv, +static int radeon_emit_packet3_cliprect(drm_device_t * dev, + drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t *cmdbuf, int orig_nbox) { @@ -2765,8 +2818,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER); if (kbuf == NULL) return DRM_ERR(ENOMEM); - if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, - cmdbuf.bufsz)) { + if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) { drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); return DRM_ERR(EFAULT); } @@ -2929,7 +2981,7 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) value = dev_priv->gart_vm_start; break; case RADEON_PARAM_REGISTER_HANDLE: - value = dev_priv->mmio->offset; + value = dev_priv->mmio_offset; break; case RADEON_PARAM_STATUS_HANDLE: value = dev_priv->ring_rptr_offset; @@ -2952,15 +3004,6 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) case RADEON_PARAM_GART_TEX_HANDLE: value = dev_priv->gart_textures_offset; break; - - case RADEON_PARAM_CARD_TYPE: - if (dev_priv->flags & CHIP_IS_PCIE) - value = RADEON_CARD_PCIE; - else if (dev_priv->flags & CHIP_IS_AGP) - value = RADEON_CARD_AGP; - else - value = RADEON_CARD_PCI; - break; default: return DRM_ERR(EINVAL); } @@ -3023,11 +3066,10 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) /* When a client dies: * - Check for and clean up flipped page state * - Free any alloced GART memory. - * - Free any alloced radeon surfaces. * * DRM infrastructure takes care of reclaiming dma buffers. */ -void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) +void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -3040,17 +3082,16 @@ void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) } } -void radeon_driver_lastclose(drm_device_t * dev) +void radeon_driver_pretakedown(drm_device_t * dev) { radeon_do_release(dev); } -int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) +int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; struct drm_radeon_driver_file_fields *radeon_priv; - DRM_DEBUG("\n"); radeon_priv = (struct drm_radeon_driver_file_fields *) drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); @@ -3059,7 +3100,6 @@ int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) return -ENOMEM; filp_priv->driver_priv = radeon_priv; - if (dev_priv) radeon_priv->radeon_fb_delta = dev_priv->fb_location; else @@ -3067,7 +3107,7 @@ int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) return 0; } -void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv) +void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv) { struct drm_radeon_driver_file_fields *radeon_priv = filp_priv->driver_priv; @@ -3076,33 +3116,33 @@ void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv) } drm_ioctl_desc_t radeon_ioctls[] = { - [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, DRM_AUTH} + [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1}, + [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0} }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); diff --git a/trunk/drivers/char/drm/savage_bci.c b/trunk/drivers/char/drm/savage_bci.c index 0d426deeefec..6d10515795cc 100644 --- a/trunk/drivers/char/drm/savage_bci.c +++ b/trunk/drivers/char/drm/savage_bci.c @@ -533,32 +533,16 @@ static void savage_fake_dma_flush(drm_savage_private_t * dev_priv) dev_priv->first_dma_page = dev_priv->current_dma_page = 0; } -int savage_driver_load(drm_device_t *dev, unsigned long chipset) -{ - drm_savage_private_t *dev_priv; - - dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return DRM_ERR(ENOMEM); - - memset(dev_priv, 0, sizeof(drm_savage_private_t)); - dev->dev_private = (void *)dev_priv; - - dev_priv->chipset = (enum savage_family)chipset; - - return 0; -} - - /* * Initalize mappings. On Savage4 and SavageIX the alignment * and size of the aperture is not suitable for automatic MTRR setup - * in drm_addmap. Therefore we add them manually before the maps are - * initialized, and tear them down on last close. + * in drm_addmap. Therefore we do it manually before the maps are + * initialized. We also need to take care of deleting the MTRRs in + * postcleanup. */ -int savage_driver_firstopen(drm_device_t *dev) +int savage_preinit(drm_device_t * dev, unsigned long chipset) { - drm_savage_private_t *dev_priv = dev->dev_private; + drm_savage_private_t *dev_priv; unsigned long mmio_base, fb_base, fb_size, aperture_base; /* fb_rsrc and aper_rsrc aren't really used currently, but still exist * in case we decide we need information on the BAR for BSD in the @@ -567,6 +551,14 @@ int savage_driver_firstopen(drm_device_t *dev) unsigned int fb_rsrc, aper_rsrc; int ret = 0; + dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return DRM_ERR(ENOMEM); + + memset(dev_priv, 0, sizeof(drm_savage_private_t)); + dev->dev_private = (void *)dev_priv; + dev_priv->chipset = (enum savage_family)chipset; + dev_priv->mtrr[0].handle = -1; dev_priv->mtrr[1].handle = -1; dev_priv->mtrr[2].handle = -1; @@ -584,24 +576,26 @@ int savage_driver_firstopen(drm_device_t *dev) dev_priv->mtrr[0].base = fb_base; dev_priv->mtrr[0].size = 0x01000000; dev_priv->mtrr[0].handle = - drm_mtrr_add(dev_priv->mtrr[0].base, - dev_priv->mtrr[0].size, DRM_MTRR_WC); + mtrr_add(dev_priv->mtrr[0].base, + dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, + 1); dev_priv->mtrr[1].base = fb_base + 0x02000000; dev_priv->mtrr[1].size = 0x02000000; dev_priv->mtrr[1].handle = - drm_mtrr_add(dev_priv->mtrr[1].base, - dev_priv->mtrr[1].size, DRM_MTRR_WC); + mtrr_add(dev_priv->mtrr[1].base, + dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB, + 1); dev_priv->mtrr[2].base = fb_base + 0x04000000; dev_priv->mtrr[2].size = 0x04000000; dev_priv->mtrr[2].handle = - drm_mtrr_add(dev_priv->mtrr[2].base, - dev_priv->mtrr[2].size, DRM_MTRR_WC); + mtrr_add(dev_priv->mtrr[2].base, + dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB, + 1); } else { DRM_ERROR("strange pci_resource_len %08lx\n", drm_get_resource_len(dev, 0)); } - } else if (dev_priv->chipset != S3_SUPERSAVAGE && - dev_priv->chipset != S3_SAVAGE2000) { + } else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) { mmio_base = drm_get_resource_start(dev, 0); fb_rsrc = 1; fb_base = drm_get_resource_start(dev, 1); @@ -615,8 +609,9 @@ int savage_driver_firstopen(drm_device_t *dev) dev_priv->mtrr[0].base = fb_base; dev_priv->mtrr[0].size = 0x08000000; dev_priv->mtrr[0].handle = - drm_mtrr_add(dev_priv->mtrr[0].base, - dev_priv->mtrr[0].size, DRM_MTRR_WC); + mtrr_add(dev_priv->mtrr[0].base, + dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, + 1); } else { DRM_ERROR("strange pci_resource_len %08lx\n", drm_get_resource_len(dev, 1)); @@ -653,21 +648,16 @@ int savage_driver_firstopen(drm_device_t *dev) /* * Delete MTRRs and free device-private data. */ -void savage_driver_lastclose(drm_device_t *dev) +int savage_postcleanup(drm_device_t * dev) { drm_savage_private_t *dev_priv = dev->dev_private; int i; for (i = 0; i < 3; ++i) if (dev_priv->mtrr[i].handle >= 0) - drm_mtrr_del(dev_priv->mtrr[i].handle, + mtrr_del(dev_priv->mtrr[i].handle, dev_priv->mtrr[i].base, - dev_priv->mtrr[i].size, DRM_MTRR_WC); -} - -int savage_driver_unload(drm_device_t *dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; + dev_priv->mtrr[i].size); drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); @@ -1004,7 +994,8 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) * DMA buffer management */ -static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d) +static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev, + drm_dma_t * d) { drm_buf_t *buf; int i; @@ -1066,7 +1057,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS) return ret; } -void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) +void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp) { drm_device_dma_t *dma = dev->dma; drm_savage_private_t *dev_priv = dev->dev_private; @@ -1099,10 +1090,10 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) } drm_ioctl_desc_t savage_ioctls[] = { - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0}, }; int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); diff --git a/trunk/drivers/char/drm/savage_drv.c b/trunk/drivers/char/drm/savage_drv.c index aa6c0d1a82f8..22d799cde41c 100644 --- a/trunk/drivers/char/drm/savage_drv.c +++ b/trunk/drivers/char/drm/savage_drv.c @@ -30,6 +30,31 @@ #include "drm_pciids.h" +static int postinit(struct drm_device *dev, unsigned long flags) +{ + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} + static struct pci_device_id pciidlist[] = { savage_PCI_IDS }; @@ -38,13 +63,13 @@ static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, .dev_priv_size = sizeof(drm_savage_buf_priv_t), - .load = savage_driver_load, - .firstopen = savage_driver_firstopen, - .lastclose = savage_driver_lastclose, - .unload = savage_driver_unload, + .preinit = savage_preinit, + .postinit = postinit, + .postcleanup = savage_postcleanup, .reclaim_buffers = savage_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .version = version, .ioctls = savage_ioctls, .dma_ioctl = savage_bci_buffers, .fops = { @@ -55,19 +80,12 @@ static struct drm_driver driver = { .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, - }, - + } + , .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init savage_init(void) diff --git a/trunk/drivers/char/drm/savage_drv.h b/trunk/drivers/char/drm/savage_drv.h index dd46cb85439c..a4b0fa998a95 100644 --- a/trunk/drivers/char/drm/savage_drv.h +++ b/trunk/drivers/char/drm/savage_drv.h @@ -1,5 +1,5 @@ -/* savage_drv.h -- Private header for the savage driver */ -/* +/* savage_drv.h -- Private header for the savage driver + * * Copyright 2004 Felix Kuehling * All Rights Reserved. * @@ -192,7 +192,7 @@ typedef struct drm_savage_private { /* Err, there is a macro wait_event in include/linux/wait.h. * Avoid unwanted macro expansion. */ void (*emit_clip_rect) (struct drm_savage_private * dev_priv, - const drm_clip_rect_t * pbox); + drm_clip_rect_t * pbox); void (*dma_flush) (struct drm_savage_private * dev_priv); } drm_savage_private_t; @@ -208,18 +208,16 @@ extern void savage_dma_reset(drm_savage_private_t * dev_priv); extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page); extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n); -extern int savage_driver_load(drm_device_t *dev, unsigned long chipset); -extern int savage_driver_firstopen(drm_device_t *dev); -extern void savage_driver_lastclose(drm_device_t *dev); -extern int savage_driver_unload(drm_device_t *dev); +extern int savage_preinit(drm_device_t * dev, unsigned long chipset); +extern int savage_postcleanup(drm_device_t * dev); extern int savage_do_cleanup_bci(drm_device_t * dev); extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp); /* state functions */ extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, - const drm_clip_rect_t * pbox); + drm_clip_rect_t * pbox); extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, - const drm_clip_rect_t * pbox); + drm_clip_rect_t * pbox); #define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ #define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ @@ -502,6 +500,15 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, #define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val) +#define BCI_COPY_FROM_USER(src,n) do { \ + unsigned int i; \ + for (i = 0; i < n; ++i) { \ + uint32_t val; \ + DRM_GET_USER_UNCHECKED(val, &((uint32_t*)(src))[i]); \ + BCI_WRITE(val); \ + } \ +} while(0) + /* * command DMA support */ @@ -527,8 +534,8 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, #define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val) -#define DMA_COPY(src, n) do { \ - memcpy(dma_ptr, (src), (n)*4); \ +#define DMA_COPY_FROM_USER(src,n) do { \ + DRM_COPY_FROM_USER_UNCHECKED(dma_ptr, (src), (n)*4); \ dma_ptr += n; \ } while(0) diff --git a/trunk/drivers/char/drm/savage_state.c b/trunk/drivers/char/drm/savage_state.c index ef2581d16146..e87a5d59b99c 100644 --- a/trunk/drivers/char/drm/savage_state.c +++ b/trunk/drivers/char/drm/savage_state.c @@ -27,7 +27,7 @@ #include "savage_drv.h" void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, - const drm_clip_rect_t * pbox) + drm_clip_rect_t * pbox) { uint32_t scstart = dev_priv->state.s3d.new_scstart; uint32_t scend = dev_priv->state.s3d.new_scend; @@ -53,7 +53,7 @@ void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, } void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, - const drm_clip_rect_t * pbox) + drm_clip_rect_t * pbox) { uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; @@ -115,19 +115,18 @@ static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit, #define SAVE_STATE(reg,where) \ if(start <= reg && start+count > reg) \ - dev_priv->state.where = regs[reg - start] + DRM_GET_USER_UNCHECKED(dev_priv->state.where, ®s[reg-start]) #define SAVE_STATE_MASK(reg,where,mask) do { \ if(start <= reg && start+count > reg) { \ uint32_t tmp; \ - tmp = regs[reg - start]; \ + DRM_GET_USER_UNCHECKED(tmp, ®s[reg-start]); \ dev_priv->state.where = (tmp & (mask)) | \ (dev_priv->state.where & ~(mask)); \ } \ } while (0) - static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, unsigned int start, unsigned int count, - const uint32_t *regs) + const uint32_t __user * regs) { if (start < SAVAGE_TEXPALADDR_S3D || start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { @@ -149,7 +148,8 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr); if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK) return savage_verify_texaddr(dev_priv, 0, - dev_priv->state.s3d.texaddr); + dev_priv->state.s3d. + texaddr); } return 0; @@ -157,7 +157,7 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, static int savage_verify_state_s4(drm_savage_private_t * dev_priv, unsigned int start, unsigned int count, - const uint32_t *regs) + const uint32_t __user * regs) { int ret = 0; @@ -174,18 +174,19 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv, ~SAVAGE_SCISSOR_MASK_S4); /* if any texture regs were changed ... */ - if (start <= SAVAGE_TEXDESCR_S4 && - start + count > SAVAGE_TEXPALADDR_S4) { + if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) { /* ... check texture state */ SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr); SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0); SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1); if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK) - ret |= savage_verify_texaddr(dev_priv, 0, - dev_priv->state.s4.texaddr0); + ret |= + savage_verify_texaddr(dev_priv, 0, + dev_priv->state.s4.texaddr0); if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK) - ret |= savage_verify_texaddr(dev_priv, 1, - dev_priv->state.s4.texaddr1); + ret |= + savage_verify_texaddr(dev_priv, 1, + dev_priv->state.s4.texaddr1); } return ret; @@ -196,7 +197,7 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv, static int savage_dispatch_state(drm_savage_private_t * dev_priv, const drm_savage_cmd_header_t * cmd_header, - const uint32_t *regs) + const uint32_t __user * regs) { unsigned int count = cmd_header->state.count; unsigned int start = cmd_header->state.start; @@ -208,6 +209,9 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv, if (!count) return 0; + if (DRM_VERIFYAREA_READ(regs, count * 4)) + return DRM_ERR(EFAULT); + if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { ret = savage_verify_state_s3d(dev_priv, start, count, regs); if (ret != 0) @@ -232,8 +236,8 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv, /* scissor regs are emitted in savage_dispatch_draw */ if (start < SAVAGE_DRAWCTRL0_S4) { if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) - count2 = count - - (SAVAGE_DRAWCTRL1_S4 + 1 - start); + count2 = + count - (SAVAGE_DRAWCTRL1_S4 + 1 - start); if (start + count > SAVAGE_DRAWCTRL0_S4) count = SAVAGE_DRAWCTRL0_S4 - start; } else if (start <= SAVAGE_DRAWCTRL1_S4) { @@ -259,7 +263,7 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv, while (count > 0) { unsigned int n = count < 255 ? count : 255; DMA_SET_REGISTERS(start, n); - DMA_COPY(regs, n); + DMA_COPY_FROM_USER(regs, n); count -= n; start += n; regs += n; @@ -417,8 +421,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv, static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, const drm_savage_cmd_header_t * cmd_header, - const uint32_t *vtxbuf, unsigned int vb_size, - unsigned int vb_stride) + const uint32_t __user * vtxbuf, + unsigned int vb_size, unsigned int vb_stride) { unsigned char reorder = 0; unsigned int prim = cmd_header->prim.prim; @@ -503,7 +507,8 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, for (i = start; i < start + count; ++i) { unsigned int j = i + reorder[i % 3]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], + vtx_size); } DMA_COMMIT(); @@ -512,12 +517,13 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, DMA_DRAW_PRIMITIVE(count, prim, skip); if (vb_stride == vtx_size) { - DMA_COPY(&vtxbuf[vb_stride * start], - vtx_size * count); + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start], + vtx_size * count); } else { for (i = start; i < start + count; ++i) { - DMA_COPY(&vtxbuf [vb_stride * i], - vtx_size); + DMA_COPY_FROM_USER(&vtxbuf + [vb_stride * i], + vtx_size); } } @@ -535,7 +541,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, const drm_savage_cmd_header_t * cmd_header, - const uint16_t *idx, + const uint16_t __user * usr_idx, const drm_buf_t * dmabuf) { unsigned char reorder = 0; @@ -622,8 +628,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, while (n != 0) { /* Can emit up to 255 indices (85 triangles) at once. */ unsigned int count = n > 255 ? 255 : n; + /* Is it ok to allocate 510 bytes on the stack in an ioctl? */ + uint16_t idx[255]; - /* check indices */ + /* Copy and check indices */ + DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2); for (i = 0; i < count; ++i) { if (idx[i] > dmabuf->total / 32) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", @@ -643,8 +652,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, for (i = 1; i + 1 < count; i += 2) BCI_WRITE(idx[i + reorder[i % 3]] | - (idx[i + 1 + - reorder[(i + 1) % 3]] << 16)); + (idx[i + 1 + reorder[(i + 1) % 3]] << + 16)); if (i < count) BCI_WRITE(idx[i + reorder[i % 3]]); } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { @@ -665,7 +674,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, BCI_WRITE(idx[i]); } - idx += count; + usr_idx += count; n -= count; prim |= BCI_CMD_DRAW_CONT; @@ -676,8 +685,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, const drm_savage_cmd_header_t * cmd_header, - const uint16_t *idx, - const uint32_t *vtxbuf, + const uint16_t __user * usr_idx, + const uint32_t __user * vtxbuf, unsigned int vb_size, unsigned int vb_stride) { unsigned char reorder = 0; @@ -742,8 +751,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, while (n != 0) { /* Can emit up to 255 vertices (85 triangles) at once. */ unsigned int count = n > 255 ? 255 : n; - - /* Check indices */ + /* Is it ok to allocate 510 bytes on the stack in an ioctl? */ + uint16_t idx[255]; + + /* Copy and check indices */ + DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2); for (i = 0; i < count; ++i) { if (idx[i] > vb_size / (vb_stride * 4)) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", @@ -763,7 +775,8 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, for (i = 0; i < count; ++i) { unsigned int j = idx[i + reorder[i % 3]]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], + vtx_size); } DMA_COMMIT(); @@ -773,13 +786,14 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, for (i = 0; i < count; ++i) { unsigned int j = idx[i]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); + DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], + vtx_size); } DMA_COMMIT(); } - idx += count; + usr_idx += count; n -= count; prim |= BCI_CMD_DRAW_CONT; @@ -790,11 +804,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, static int savage_dispatch_clear(drm_savage_private_t * dev_priv, const drm_savage_cmd_header_t * cmd_header, - const drm_savage_cmd_header_t *data, + const drm_savage_cmd_header_t __user * data, unsigned int nbox, - const drm_clip_rect_t *boxes) + const drm_clip_rect_t __user * usr_boxes) { - unsigned int flags = cmd_header->clear0.flags; + unsigned int flags = cmd_header->clear0.flags, mask, value; unsigned int clear_cmd; unsigned int i, nbufs; DMA_LOCALS; @@ -802,6 +816,9 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, if (nbox == 0) return 0; + DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask); + DRM_GET_USER_UNCHECKED(value, &data->clear1.value); + clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; BCI_CMD_SET_ROP(clear_cmd, 0xCC); @@ -811,19 +828,21 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, if (nbufs == 0) return 0; - if (data->clear1.mask != 0xffffffff) { + if (mask != 0xffffffff) { /* set mask */ BEGIN_DMA(2); DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); - DMA_WRITE(data->clear1.mask); + DMA_WRITE(mask); DMA_COMMIT(); } for (i = 0; i < nbox; ++i) { + drm_clip_rect_t box; unsigned int x, y, w, h; unsigned int buf; - x = boxes[i].x1, y = boxes[i].y1; - w = boxes[i].x2 - boxes[i].x1; - h = boxes[i].y2 - boxes[i].y1; + DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); + x = box.x1, y = box.y1; + w = box.x2 - box.x1; + h = box.y2 - box.y1; BEGIN_DMA(nbufs * 6); for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { if (!(flags & buf)) @@ -843,13 +862,13 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, DMA_WRITE(dev_priv->depth_bd); break; } - DMA_WRITE(data->clear1.value); + DMA_WRITE(value); DMA_WRITE(BCI_X_Y(x, y)); DMA_WRITE(BCI_W_H(w, h)); } DMA_COMMIT(); } - if (data->clear1.mask != 0xffffffff) { + if (mask != 0xffffffff) { /* reset mask */ BEGIN_DMA(2); DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); @@ -861,7 +880,8 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv, } static int savage_dispatch_swap(drm_savage_private_t * dev_priv, - unsigned int nbox, const drm_clip_rect_t *boxes) + unsigned int nbox, + const drm_clip_rect_t __user * usr_boxes) { unsigned int swap_cmd; unsigned int i; @@ -875,14 +895,16 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv, BCI_CMD_SET_ROP(swap_cmd, 0xCC); for (i = 0; i < nbox; ++i) { + drm_clip_rect_t box; + DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); + BEGIN_DMA(6); DMA_WRITE(swap_cmd); DMA_WRITE(dev_priv->back_offset); DMA_WRITE(dev_priv->back_bd); - DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); - DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); - DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1, - boxes[i].y2 - boxes[i].y1)); + DMA_WRITE(BCI_X_Y(box.x1, box.y1)); + DMA_WRITE(BCI_X_Y(box.x1, box.y1)); + DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1)); DMA_COMMIT(); } @@ -890,52 +912,68 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv, } static int savage_dispatch_draw(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t *start, - const drm_savage_cmd_header_t *end, + const drm_savage_cmd_header_t __user * start, + const drm_savage_cmd_header_t __user * end, const drm_buf_t * dmabuf, - const unsigned int *vtxbuf, + const unsigned int __user * usr_vtxbuf, unsigned int vb_size, unsigned int vb_stride, unsigned int nbox, - const drm_clip_rect_t *boxes) + const drm_clip_rect_t __user * usr_boxes) { unsigned int i, j; int ret; for (i = 0; i < nbox; ++i) { - const drm_savage_cmd_header_t *cmdbuf; - dev_priv->emit_clip_rect(dev_priv, &boxes[i]); + drm_clip_rect_t box; + const drm_savage_cmd_header_t __user *usr_cmdbuf; + DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); + dev_priv->emit_clip_rect(dev_priv, &box); - cmdbuf = start; - while (cmdbuf < end) { + usr_cmdbuf = start; + while (usr_cmdbuf < end) { drm_savage_cmd_header_t cmd_header; - cmd_header = *cmdbuf; - cmdbuf++; + DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, + sizeof(cmd_header)); + usr_cmdbuf++; switch (cmd_header.cmd.cmd) { case SAVAGE_CMD_DMA_PRIM: - ret = savage_dispatch_dma_prim( - dev_priv, &cmd_header, dmabuf); + ret = + savage_dispatch_dma_prim(dev_priv, + &cmd_header, + dmabuf); break; case SAVAGE_CMD_VB_PRIM: - ret = savage_dispatch_vb_prim( - dev_priv, &cmd_header, - vtxbuf, vb_size, vb_stride); + ret = + savage_dispatch_vb_prim(dev_priv, + &cmd_header, + (const uint32_t + __user *) + usr_vtxbuf, vb_size, + vb_stride); break; case SAVAGE_CMD_DMA_IDX: j = (cmd_header.idx.count + 3) / 4; /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_dma_idx(dev_priv, - &cmd_header, (const uint16_t *)cmdbuf, - dmabuf); - cmdbuf += j; + ret = + savage_dispatch_dma_idx(dev_priv, + &cmd_header, + (const uint16_t + __user *) + usr_cmdbuf, dmabuf); + usr_cmdbuf += j; break; case SAVAGE_CMD_VB_IDX: j = (cmd_header.idx.count + 3) / 4; /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_vb_idx(dev_priv, - &cmd_header, (const uint16_t *)cmdbuf, - (const uint32_t *)vtxbuf, vb_size, - vb_stride); - cmdbuf += j; + ret = + savage_dispatch_vb_idx(dev_priv, + &cmd_header, + (const uint16_t + __user *)usr_cmdbuf, + (const uint32_t + __user *)usr_vtxbuf, + vb_size, vb_stride); + usr_cmdbuf += j; break; default: /* What's the best return code? EFAULT? */ @@ -960,10 +998,10 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) drm_device_dma_t *dma = dev->dma; drm_buf_t *dmabuf; drm_savage_cmdbuf_t cmdbuf; - drm_savage_cmd_header_t *kcmd_addr = NULL; - drm_savage_cmd_header_t *first_draw_cmd; - unsigned int *kvb_addr = NULL; - drm_clip_rect_t *kbox_addr = NULL; + drm_savage_cmd_header_t __user *usr_cmdbuf; + drm_savage_cmd_header_t __user *first_draw_cmd; + unsigned int __user *usr_vtxbuf; + drm_clip_rect_t __user *usr_boxes; unsigned int i, j; int ret = 0; @@ -986,53 +1024,15 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) dmabuf = NULL; } - /* Copy the user buffers into kernel temporary areas. This hasn't been - * a performance loss compared to VERIFYAREA_READ/ - * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct - * for locking on FreeBSD. - */ - if (cmdbuf.size) { - kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); - if (kcmd_addr == NULL) - return ENOMEM; - - if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, - cmdbuf.size * 8)) - { - drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); - return DRM_ERR(EFAULT); - } - cmdbuf.cmd_addr = kcmd_addr; - } - if (cmdbuf.vb_size) { - kvb_addr = drm_alloc(cmdbuf.vb_size, DRM_MEM_DRIVER); - if (kvb_addr == NULL) { - ret = DRM_ERR(ENOMEM); - goto done; - } - - if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf.vb_addr, - cmdbuf.vb_size)) { - ret = DRM_ERR(EFAULT); - goto done; - } - cmdbuf.vb_addr = kvb_addr; - } - if (cmdbuf.nbox) { - kbox_addr = drm_alloc(cmdbuf.nbox * sizeof(drm_clip_rect_t), - DRM_MEM_DRIVER); - if (kbox_addr == NULL) { - ret = DRM_ERR(ENOMEM); - goto done; - } - - if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf.box_addr, - cmdbuf.nbox * sizeof(drm_clip_rect_t))) { - ret = DRM_ERR(EFAULT); - goto done; - } - cmdbuf.box_addr = kbox_addr; - } + usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr; + usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr; + usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr; + if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) || + (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size)) + || (cmdbuf.nbox + && DRM_VERIFYAREA_READ(usr_boxes, + cmdbuf.nbox * sizeof(drm_clip_rect_t)))) + return DRM_ERR(EFAULT); /* Make sure writes to DMA buffers are finished before sending * DMA commands to the graphics hardware. */ @@ -1046,8 +1046,9 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) first_draw_cmd = NULL; while (i < cmdbuf.size) { drm_savage_cmd_header_t cmd_header; - cmd_header = *(drm_savage_cmd_header_t *)cmdbuf.cmd_addr; - cmdbuf.cmd_addr++; + DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, + sizeof(cmd_header)); + usr_cmdbuf++; i++; /* Group drawing commands with same state to minimize @@ -1067,18 +1068,21 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) case SAVAGE_CMD_DMA_PRIM: case SAVAGE_CMD_VB_PRIM: if (!first_draw_cmd) - first_draw_cmd = cmdbuf.cmd_addr - 1; - cmdbuf.cmd_addr += j; + first_draw_cmd = usr_cmdbuf - 1; + usr_cmdbuf += j; i += j; break; default: if (first_draw_cmd) { - ret = savage_dispatch_draw( - dev_priv, first_draw_cmd, - cmdbuf.cmd_addr - 1, - dmabuf, cmdbuf.vb_addr, cmdbuf.vb_size, - cmdbuf.vb_stride, - cmdbuf.nbox, cmdbuf.box_addr); + ret = + savage_dispatch_draw(dev_priv, + first_draw_cmd, + usr_cmdbuf - 1, dmabuf, + usr_vtxbuf, + cmdbuf.vb_size, + cmdbuf.vb_stride, + cmdbuf.nbox, + usr_boxes); if (ret != 0) return ret; first_draw_cmd = NULL; @@ -1094,12 +1098,12 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) DRM_ERROR("command SAVAGE_CMD_STATE extends " "beyond end of command buffer\n"); DMA_FLUSH(); - ret = DRM_ERR(EINVAL); - goto done; + return DRM_ERR(EINVAL); } ret = savage_dispatch_state(dev_priv, &cmd_header, - (const uint32_t *)cmdbuf.cmd_addr); - cmdbuf.cmd_addr += j; + (uint32_t __user *) + usr_cmdbuf); + usr_cmdbuf += j; i += j; break; case SAVAGE_CMD_CLEAR: @@ -1107,40 +1111,39 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) DRM_ERROR("command SAVAGE_CMD_CLEAR extends " "beyond end of command buffer\n"); DMA_FLUSH(); - ret = DRM_ERR(EINVAL); - goto done; + return DRM_ERR(EINVAL); } ret = savage_dispatch_clear(dev_priv, &cmd_header, - cmdbuf.cmd_addr, - cmdbuf.nbox, cmdbuf.box_addr); - cmdbuf.cmd_addr++; + usr_cmdbuf, + cmdbuf.nbox, usr_boxes); + usr_cmdbuf++; i++; break; case SAVAGE_CMD_SWAP: - ret = savage_dispatch_swap(dev_priv, cmdbuf.nbox, - cmdbuf.box_addr); + ret = savage_dispatch_swap(dev_priv, + cmdbuf.nbox, usr_boxes); break; default: DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd); DMA_FLUSH(); - ret = DRM_ERR(EINVAL); - goto done; + return DRM_ERR(EINVAL); } if (ret != 0) { DMA_FLUSH(); - goto done; + return ret; } } if (first_draw_cmd) { - ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, cmdbuf.cmd_addr, dmabuf, - cmdbuf.vb_addr, cmdbuf.vb_size, cmdbuf.vb_stride, - cmdbuf.nbox, cmdbuf.box_addr); + ret = + savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf, + dmabuf, usr_vtxbuf, cmdbuf.vb_size, + cmdbuf.vb_stride, cmdbuf.nbox, + usr_boxes); if (ret != 0) { DMA_FLUSH(); - goto done; + return ret; } } @@ -1154,12 +1157,5 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) savage_freelist_put(dev, dmabuf); } -done: - /* If we didn't need to allocate them, these'll be NULL */ - drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); - drm_free(kvb_addr, cmdbuf.vb_size, DRM_MEM_DRIVER); - drm_free(kbox_addr, cmdbuf.nbox * sizeof(drm_clip_rect_t), - DRM_MEM_DRIVER); - - return ret; + return 0; } diff --git a/trunk/drivers/char/drm/sis_drm.h b/trunk/drivers/char/drm/sis_drm.h index 30f7b3827466..8f273da76ddb 100644 --- a/trunk/drivers/char/drm/sis_drm.h +++ b/trunk/drivers/char/drm/sis_drm.h @@ -1,28 +1,3 @@ -/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */ -/* - * Copyright 2005 Eric Anholt - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ #ifndef __SIS_DRM_H__ #define __SIS_DRM_H__ diff --git a/trunk/drivers/char/drm/sis_drv.c b/trunk/drivers/char/drm/sis_drv.c index 6f6d7d613ede..3cef10643a8f 100644 --- a/trunk/drivers/char/drm/sis_drv.c +++ b/trunk/drivers/char/drm/sis_drv.c @@ -32,6 +32,31 @@ #include "drm_pciids.h" +static int postinit(struct drm_device *dev, unsigned long flags) +{ + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} + static struct pci_device_id pciidlist[] = { sisdrv_PCI_IDS }; @@ -43,6 +68,8 @@ static struct drm_driver driver = { .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .postinit = postinit, + .version = version, .ioctls = sis_ioctls, .fops = { .owner = THIS_MODULE, @@ -52,18 +79,11 @@ static struct drm_driver driver = { .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, - }, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init sis_init(void) diff --git a/trunk/drivers/char/drm/sis_drv.h b/trunk/drivers/char/drm/sis_drv.h index e218e5269503..b1fddad83a93 100644 --- a/trunk/drivers/char/drm/sis_drv.h +++ b/trunk/drivers/char/drm/sis_drv.h @@ -1,5 +1,5 @@ -/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */ -/* +/* sis_drv.h -- Private header for sis driver -*- linux-c -*- + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All rights reserved. diff --git a/trunk/drivers/char/drm/sis_ds.h b/trunk/drivers/char/drm/sis_ds.h index 94f2b4728b63..da850b4f5440 100644 --- a/trunk/drivers/char/drm/sis_ds.h +++ b/trunk/drivers/char/drm/sis_ds.h @@ -1,7 +1,6 @@ -/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- +/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw - */ -/* + * * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. * All rights reserved. * @@ -36,7 +35,7 @@ #define SET_SIZE 5000 -typedef unsigned long ITEM_TYPE; +typedef unsigned int ITEM_TYPE; typedef struct { ITEM_TYPE val; diff --git a/trunk/drivers/char/drm/sis_mm.c b/trunk/drivers/char/drm/sis_mm.c index 6774d2fe3452..a8529728fa63 100644 --- a/trunk/drivers/char/drm/sis_mm.c +++ b/trunk/drivers/char/drm/sis_mm.c @@ -86,7 +86,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) { drm_sis_mem_t fb; struct sis_memreq req; - drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; + drm_sis_mem_t __user *argp = (void __user *)data; int retval = 0; DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb)); @@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); - DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); + DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset); return retval; } @@ -127,9 +127,9 @@ static int sis_fb_free(DRM_IOCTL_ARGS) if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) retval = DRM_ERR(EINVAL); - sis_free(fb.free); + sis_free((u32) fb.free); - DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free); + DRM_DEBUG("free fb, offset = %lu\n", fb.free); return retval; } @@ -176,7 +176,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; + drm_sis_mem_t __user *argp = (void __user *)data; drm_sis_mem_t fb; PMemBlock block; int retval = 0; @@ -267,7 +267,7 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; + drm_sis_mem_t __user *argp = (void __user *)data; drm_sis_mem_t agp; PMemBlock block; int retval = 0; @@ -367,7 +367,7 @@ int sis_final_context(struct drm_device *dev, int context) if (i < MAX_CONTEXT) { set_t *set; - ITEM_TYPE item; + unsigned int item; int retval; DRM_DEBUG("find socket %d, context = %d\n", i, context); @@ -376,7 +376,7 @@ int sis_final_context(struct drm_device *dev, int context) set = global_ppriv[i].sets[0]; retval = setFirst(set, &item); while (retval) { - DRM_DEBUG("free video memory 0x%lx\n", item); + DRM_DEBUG("free video memory 0x%x\n", item); #if defined(__linux__) && defined(CONFIG_FB_SIS) sis_free(item); #else @@ -390,7 +390,7 @@ int sis_final_context(struct drm_device *dev, int context) set = global_ppriv[i].sets[1]; retval = setFirst(set, &item); while (retval) { - DRM_DEBUG("free agp memory 0x%lx\n", item); + DRM_DEBUG("free agp memory 0x%x\n", item); mmFreeMem((PMemBlock) item); retval = setNext(set, &item); } @@ -403,12 +403,12 @@ int sis_final_context(struct drm_device *dev, int context) } drm_ioctl_desc_t sis_ioctls[] = { - [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY} + [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0}, + [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1}, + [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0}, + [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1} }; int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); diff --git a/trunk/drivers/char/drm/tdfx_drv.c b/trunk/drivers/char/drm/tdfx_drv.c index baa4416032a8..c275cbb6e9ce 100644 --- a/trunk/drivers/char/drm/tdfx_drv.c +++ b/trunk/drivers/char/drm/tdfx_drv.c @@ -36,6 +36,31 @@ #include "drm_pciids.h" +static int postinit(struct drm_device *dev, unsigned long flags) +{ + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; +} + static struct pci_device_id pciidlist[] = { tdfx_PCI_IDS }; @@ -45,6 +70,8 @@ static struct drm_driver driver = { .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, + .postinit = postinit, + .version = version, .fops = { .owner = THIS_MODULE, .open = drm_open, @@ -53,18 +80,11 @@ static struct drm_driver driver = { .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, - }, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init tdfx_init(void) diff --git a/trunk/drivers/char/drm/tdfx_drv.h b/trunk/drivers/char/drm/tdfx_drv.h index 84204ec1b046..a582a3db4c75 100644 --- a/trunk/drivers/char/drm/tdfx_drv.h +++ b/trunk/drivers/char/drm/tdfx_drv.h @@ -1,7 +1,6 @@ /* tdfx.h -- 3dfx DRM template customization -*- linux-c -*- * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com - */ -/* + * * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * @@ -31,6 +30,10 @@ #ifndef __TDFX_H__ #define __TDFX_H__ +/* This remains constant for all DRM template files. + */ +#define DRM(x) tdfx_##x + /* General customization: */ diff --git a/trunk/drivers/char/drm/via_dma.c b/trunk/drivers/char/drm/via_dma.c index 593c0b8f650a..d4b1766608b0 100644 --- a/trunk/drivers/char/drm/via_dma.c +++ b/trunk/drivers/char/drm/via_dma.c @@ -213,9 +213,7 @@ static int via_initialize(drm_device_t * dev, dev_priv->dma_wrap = init->size; dev_priv->dma_offset = init->offset; dev_priv->last_pause_ptr = NULL; - dev_priv->hw_addr_ptr = - (volatile uint32_t *)((char *)dev_priv->mmio->handle + - init->reg_pause_addr); + dev_priv->hw_addr_ptr = dev_priv->mmio->handle + init->reg_pause_addr; via_cmdbuf_start(dev_priv); @@ -234,13 +232,13 @@ int via_dma_init(DRM_IOCTL_ARGS) switch (init.func) { case VIA_INIT_DMA: - if (!DRM_SUSER(DRM_CURPROC)) + if (!capable(CAP_SYS_ADMIN)) retcode = DRM_ERR(EPERM); else retcode = via_initialize(dev, dev_priv, &init); break; case VIA_CLEANUP_DMA: - if (!DRM_SUSER(DRM_CURPROC)) + if (!capable(CAP_SYS_ADMIN)) retcode = DRM_ERR(EPERM); else retcode = via_dma_cleanup(dev); @@ -351,6 +349,9 @@ int via_cmdbuffer(DRM_IOCTL_ARGS) return 0; } +extern int +via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, + unsigned int size); static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) { @@ -449,9 +450,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv, if ((count <= 8) && (count >= 0)) { uint32_t rgtr, ptr; rgtr = *(dev_priv->hw_addr_ptr); - ptr = ((volatile char *)dev_priv->last_pause_ptr - - dev_priv->dma_ptr) + dev_priv->dma_offset + - (uint32_t) dev_priv->agpAddr + 4 - CMDBUF_ALIGNMENT_SIZE; + ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + + dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - + CMDBUF_ALIGNMENT_SIZE; if (rgtr <= ptr) { DRM_ERROR ("Command regulator\npaused at count %d, address %x, " @@ -471,7 +472,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv, && count--) ; rgtr = *(dev_priv->hw_addr_ptr); - ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + + ptr = ((char *)paused_at - dev_priv->dma_ptr) + dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ? @@ -723,22 +724,3 @@ int via_cmdbuf_size(DRM_IOCTL_ARGS) sizeof(d_siz)); return ret; } - -drm_ioctl_desc_t via_ioctls[] = { - [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, DRM_AUTH|DRM_MASTER}, - [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, DRM_AUTH|DRM_MASTER}, - [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, DRM_AUTH|DRM_MASTER}, - [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_DMA_BLIT)] = {via_dma_blit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_BLIT_SYNC)] = {via_dma_blit_sync, DRM_AUTH} -}; - -int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); diff --git a/trunk/drivers/char/drm/via_dmablit.c b/trunk/drivers/char/drm/via_dmablit.c deleted file mode 100644 index 9d5e027dae0e..000000000000 --- a/trunk/drivers/char/drm/via_dmablit.c +++ /dev/null @@ -1,805 +0,0 @@ -/* via_dmablit.c -- PCI DMA BitBlt support for the VIA Unichrome/Pro - * - * Copyright (C) 2005 Thomas Hellstrom, All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Thomas Hellstrom. - * Partially based on code obtained from Digeo Inc. - */ - - -/* - * Unmaps the DMA mappings. - * FIXME: Is this a NoOp on x86? Also - * FIXME: What happens if this one is called and a pending blit has previously done - * the same DMA mappings? - */ - -#include "drmP.h" -#include "via_drm.h" -#include "via_drv.h" -#include "via_dmablit.h" - -#include - -#define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK) -#define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK) -#define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT) - -typedef struct _drm_via_descriptor { - uint32_t mem_addr; - uint32_t dev_addr; - uint32_t size; - uint32_t next; -} drm_via_descriptor_t; - - -/* - * Unmap a DMA mapping. - */ - - - -static void -via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg) -{ - int num_desc = vsg->num_desc; - unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page; - unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page; - drm_via_descriptor_t *desc_ptr = vsg->desc_pages[cur_descriptor_page] + - descriptor_this_page; - dma_addr_t next = vsg->chain_start; - - while(num_desc--) { - if (descriptor_this_page-- == 0) { - cur_descriptor_page--; - descriptor_this_page = vsg->descriptors_per_page - 1; - desc_ptr = vsg->desc_pages[cur_descriptor_page] + - descriptor_this_page; - } - dma_unmap_single(&pdev->dev, next, sizeof(*desc_ptr), DMA_TO_DEVICE); - dma_unmap_page(&pdev->dev, desc_ptr->mem_addr, desc_ptr->size, vsg->direction); - next = (dma_addr_t) desc_ptr->next; - desc_ptr--; - } -} - -/* - * If mode = 0, count how many descriptors are needed. - * If mode = 1, Map the DMA pages for the device, put together and map also the descriptors. - * Descriptors are run in reverse order by the hardware because we are not allowed to update the - * 'next' field without syncing calls when the descriptor is already mapped. - */ - -static void -via_map_blit_for_device(struct pci_dev *pdev, - const drm_via_dmablit_t *xfer, - drm_via_sg_info_t *vsg, - int mode) -{ - unsigned cur_descriptor_page = 0; - unsigned num_descriptors_this_page = 0; - unsigned char *mem_addr = xfer->mem_addr; - unsigned char *cur_mem; - unsigned char *first_addr = (unsigned char *)VIA_PGDN(mem_addr); - uint32_t fb_addr = xfer->fb_addr; - uint32_t cur_fb; - unsigned long line_len; - unsigned remaining_len; - int num_desc = 0; - int cur_line; - dma_addr_t next = 0 | VIA_DMA_DPR_EC; - drm_via_descriptor_t *desc_ptr = 0; - - if (mode == 1) - desc_ptr = vsg->desc_pages[cur_descriptor_page]; - - for (cur_line = 0; cur_line < xfer->num_lines; ++cur_line) { - - line_len = xfer->line_length; - cur_fb = fb_addr; - cur_mem = mem_addr; - - while (line_len > 0) { - - remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len); - line_len -= remaining_len; - - if (mode == 1) { - desc_ptr->mem_addr = - dma_map_page(&pdev->dev, - vsg->pages[VIA_PFN(cur_mem) - - VIA_PFN(first_addr)], - VIA_PGOFF(cur_mem), remaining_len, - vsg->direction); - desc_ptr->dev_addr = cur_fb; - - desc_ptr->size = remaining_len; - desc_ptr->next = (uint32_t) next; - next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr), - DMA_TO_DEVICE); - desc_ptr++; - if (++num_descriptors_this_page >= vsg->descriptors_per_page) { - num_descriptors_this_page = 0; - desc_ptr = vsg->desc_pages[++cur_descriptor_page]; - } - } - - num_desc++; - cur_mem += remaining_len; - cur_fb += remaining_len; - } - - mem_addr += xfer->mem_stride; - fb_addr += xfer->fb_stride; - } - - if (mode == 1) { - vsg->chain_start = next; - vsg->state = dr_via_device_mapped; - } - vsg->num_desc = num_desc; -} - -/* - * Function that frees up all resources for a blit. It is usable even if the - * blit info has only be partially built as long as the status enum is consistent - * with the actual status of the used resources. - */ - - -void -via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) -{ - struct page *page; - int i; - - switch(vsg->state) { - case dr_via_device_mapped: - via_unmap_blit_from_device(pdev, vsg); - case dr_via_desc_pages_alloc: - for (i=0; inum_desc_pages; ++i) { - if (vsg->desc_pages[i] != NULL) - free_page((unsigned long)vsg->desc_pages[i]); - } - kfree(vsg->desc_pages); - case dr_via_pages_locked: - for (i=0; inum_pages; ++i) { - if ( NULL != (page = vsg->pages[i])) { - if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) - SetPageDirty(page); - page_cache_release(page); - } - } - case dr_via_pages_alloc: - vfree(vsg->pages); - default: - vsg->state = dr_via_sg_init; - } - if (vsg->bounce_buffer) { - vfree(vsg->bounce_buffer); - vsg->bounce_buffer = NULL; - } - vsg->free_on_sequence = 0; -} - -/* - * Fire a blit engine. - */ - -static void -via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine) -{ - drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; - - VIA_WRITE(VIA_PCI_DMA_MAR0 + engine*0x10, 0); - VIA_WRITE(VIA_PCI_DMA_DAR0 + engine*0x10, 0); - VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DD | VIA_DMA_CSR_TD | - VIA_DMA_CSR_DE); - VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); - VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0); - VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start); - VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); -} - -/* - * Obtain a page pointer array and lock all pages into system memory. A segmentation violation will - * occur here if the calling user does not have access to the submitted address. - */ - -static int -via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) -{ - int ret; - unsigned long first_pfn = VIA_PFN(xfer->mem_addr); - vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) - - first_pfn + 1; - - if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) - return DRM_ERR(ENOMEM); - memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages); - down_read(¤t->mm->mmap_sem); - ret = get_user_pages(current, current->mm, (unsigned long) xfer->mem_addr, - vsg->num_pages, vsg->direction, 0, vsg->pages, NULL); - - up_read(¤t->mm->mmap_sem); - if (ret != vsg->num_pages) { - if (ret < 0) - return ret; - vsg->state = dr_via_pages_locked; - return DRM_ERR(EINVAL); - } - vsg->state = dr_via_pages_locked; - DRM_DEBUG("DMA pages locked\n"); - return 0; -} - -/* - * Allocate DMA capable memory for the blit descriptor chain, and an array that keeps track of the - * pages we allocate. We don't want to use kmalloc for the descriptor chain because it may be - * quite large for some blits, and pages don't need to be contingous. - */ - -static int -via_alloc_desc_pages(drm_via_sg_info_t *vsg) -{ - int i; - - vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t); - vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) / - vsg->descriptors_per_page; - - if (NULL == (vsg->desc_pages = kmalloc(sizeof(void *) * vsg->num_desc_pages, GFP_KERNEL))) - return DRM_ERR(ENOMEM); - - memset(vsg->desc_pages, 0, sizeof(void *) * vsg->num_desc_pages); - vsg->state = dr_via_desc_pages_alloc; - for (i=0; inum_desc_pages; ++i) { - if (NULL == (vsg->desc_pages[i] = - (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL))) - return DRM_ERR(ENOMEM); - } - DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages, - vsg->num_desc); - return 0; -} - -static void -via_abort_dmablit(drm_device_t *dev, int engine) -{ - drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; - - VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TA); -} - -static void -via_dmablit_engine_off(drm_device_t *dev, int engine) -{ - drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; - - VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD | VIA_DMA_CSR_DD); -} - - - -/* - * The dmablit part of the IRQ handler. Trying to do only reasonably fast things here. - * The rest, like unmapping and freeing memory for done blits is done in a separate workqueue - * task. Basically the task of the interrupt handler is to submit a new blit to the engine, while - * the workqueue task takes care of processing associated with the old blit. - */ - -void -via_dmablit_handler(drm_device_t *dev, int engine, int from_irq) -{ - drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; - drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; - int cur; - int done_transfer; - unsigned long irqsave=0; - uint32_t status = 0; - - DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n", - engine, from_irq, (unsigned long) blitq); - - if (from_irq) { - spin_lock(&blitq->blit_lock); - } else { - spin_lock_irqsave(&blitq->blit_lock, irqsave); - } - - done_transfer = blitq->is_active && - (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD); - done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE)); - - cur = blitq->cur; - if (done_transfer) { - - blitq->blits[cur]->aborted = blitq->aborting; - blitq->done_blit_handle++; - DRM_WAKEUP(blitq->blit_queue + cur); - - cur++; - if (cur >= VIA_NUM_BLIT_SLOTS) - cur = 0; - blitq->cur = cur; - - /* - * Clear transfer done flag. - */ - - VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD); - - blitq->is_active = 0; - blitq->aborting = 0; - schedule_work(&blitq->wq); - - } else if (blitq->is_active && time_after_eq(jiffies, blitq->end)) { - - /* - * Abort transfer after one second. - */ - - via_abort_dmablit(dev, engine); - blitq->aborting = 1; - blitq->end = jiffies + DRM_HZ; - } - - if (!blitq->is_active) { - if (blitq->num_outstanding) { - via_fire_dmablit(dev, blitq->blits[cur], engine); - blitq->is_active = 1; - blitq->cur = cur; - blitq->num_outstanding--; - blitq->end = jiffies + DRM_HZ; - if (!timer_pending(&blitq->poll_timer)) { - blitq->poll_timer.expires = jiffies+1; - add_timer(&blitq->poll_timer); - } - } else { - if (timer_pending(&blitq->poll_timer)) { - del_timer(&blitq->poll_timer); - } - via_dmablit_engine_off(dev, engine); - } - } - - if (from_irq) { - spin_unlock(&blitq->blit_lock); - } else { - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - } -} - - - -/* - * Check whether this blit is still active, performing necessary locking. - */ - -static int -via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue) -{ - unsigned long irqsave; - uint32_t slot; - int active; - - spin_lock_irqsave(&blitq->blit_lock, irqsave); - - /* - * Allow for handle wraparounds. - */ - - active = ((blitq->done_blit_handle - handle) > (1 << 23)) && - ((blitq->cur_blit_handle - handle) <= (1 << 23)); - - if (queue && active) { - slot = handle - blitq->done_blit_handle + blitq->cur -1; - if (slot >= VIA_NUM_BLIT_SLOTS) { - slot -= VIA_NUM_BLIT_SLOTS; - } - *queue = blitq->blit_queue + slot; - } - - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - - return active; -} - -/* - * Sync. Wait for at least three seconds for the blit to be performed. - */ - -static int -via_dmablit_sync(drm_device_t *dev, uint32_t handle, int engine) -{ - - drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; - drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; - wait_queue_head_t *queue; - int ret = 0; - - if (via_dmablit_active(blitq, engine, handle, &queue)) { - DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ, - !via_dmablit_active(blitq, engine, handle, NULL)); - } - DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n", - handle, engine, ret); - - return ret; -} - - -/* - * A timer that regularly polls the blit engine in cases where we don't have interrupts: - * a) Broken hardware (typically those that don't have any video capture facility). - * b) Blit abort. The hardware doesn't send an interrupt when a blit is aborted. - * The timer and hardware IRQ's can and do work in parallel. If the hardware has - * irqs, it will shorten the latency somewhat. - */ - - - -static void -via_dmablit_timer(unsigned long data) -{ - drm_via_blitq_t *blitq = (drm_via_blitq_t *) data; - drm_device_t *dev = blitq->dev; - int engine = (int) - (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues); - - DRM_DEBUG("Polling timer called for engine %d, jiffies %lu\n", engine, - (unsigned long) jiffies); - - via_dmablit_handler(dev, engine, 0); - - if (!timer_pending(&blitq->poll_timer)) { - blitq->poll_timer.expires = jiffies+1; - add_timer(&blitq->poll_timer); - } - via_dmablit_handler(dev, engine, 0); - -} - - - - -/* - * Workqueue task that frees data and mappings associated with a blit. - * Also wakes up waiting processes. Each of these tasks handles one - * blit engine only and may not be called on each interrupt. - */ - - -static void -via_dmablit_workqueue(void *data) -{ - drm_via_blitq_t *blitq = (drm_via_blitq_t *) data; - drm_device_t *dev = blitq->dev; - unsigned long irqsave; - drm_via_sg_info_t *cur_sg; - int cur_released; - - - DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long) - (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues)); - - spin_lock_irqsave(&blitq->blit_lock, irqsave); - - while(blitq->serviced != blitq->cur) { - - cur_released = blitq->serviced++; - - DRM_DEBUG("Releasing blit slot %d\n", cur_released); - - if (blitq->serviced >= VIA_NUM_BLIT_SLOTS) - blitq->serviced = 0; - - cur_sg = blitq->blits[cur_released]; - blitq->num_free++; - - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - - DRM_WAKEUP(&blitq->busy_queue); - - via_free_sg_info(dev->pdev, cur_sg); - kfree(cur_sg); - - spin_lock_irqsave(&blitq->blit_lock, irqsave); - } - - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); -} - - -/* - * Init all blit engines. Currently we use two, but some hardware have 4. - */ - - -void -via_init_dmablit(drm_device_t *dev) -{ - int i,j; - drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; - drm_via_blitq_t *blitq; - - pci_set_master(dev->pdev); - - for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) { - blitq = dev_priv->blit_queues + i; - blitq->dev = dev; - blitq->cur_blit_handle = 0; - blitq->done_blit_handle = 0; - blitq->head = 0; - blitq->cur = 0; - blitq->serviced = 0; - blitq->num_free = VIA_NUM_BLIT_SLOTS; - blitq->num_outstanding = 0; - blitq->is_active = 0; - blitq->aborting = 0; - blitq->blit_lock = SPIN_LOCK_UNLOCKED; - for (j=0; jblit_queue + j); - } - DRM_INIT_WAITQUEUE(&blitq->busy_queue); - INIT_WORK(&blitq->wq, via_dmablit_workqueue, blitq); - init_timer(&blitq->poll_timer); - blitq->poll_timer.function = &via_dmablit_timer; - blitq->poll_timer.data = (unsigned long) blitq; - } -} - -/* - * Build all info and do all mappings required for a blit. - */ - - -static int -via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) -{ - int draw = xfer->to_fb; - int ret = 0; - - vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; - vsg->bounce_buffer = 0; - - vsg->state = dr_via_sg_init; - - if (xfer->num_lines <= 0 || xfer->line_length <= 0) { - DRM_ERROR("Zero size bitblt.\n"); - return DRM_ERR(EINVAL); - } - - /* - * Below check is a driver limitation, not a hardware one. We - * don't want to lock unused pages, and don't want to incoporate the - * extra logic of avoiding them. Make sure there are no. - * (Not a big limitation anyway.) - */ - - if (((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) || - (xfer->mem_stride > 2048*4)) { - DRM_ERROR("Too large system memory stride. Stride: %d, " - "Length: %d\n", xfer->mem_stride, xfer->line_length); - return DRM_ERR(EINVAL); - } - - if (xfer->num_lines > 2048) { - DRM_ERROR("Too many PCI DMA bitblt lines.\n"); - return DRM_ERR(EINVAL); - } - - /* - * we allow a negative fb stride to allow flipping of images in - * transfer. - */ - - if (xfer->mem_stride < xfer->line_length || - abs(xfer->fb_stride) < xfer->line_length) { - DRM_ERROR("Invalid frame-buffer / memory stride.\n"); - return DRM_ERR(EINVAL); - } - - /* - * A hardware bug seems to be worked around if system memory addresses start on - * 16 byte boundaries. This seems a bit restrictive however. VIA is contacted - * about this. Meanwhile, impose the following restrictions: - */ - -#ifdef VIA_BUGFREE - if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) || - ((xfer->mem_stride & 3) != (xfer->fb_stride & 3))) { - DRM_ERROR("Invalid DRM bitblt alignment.\n"); - return DRM_ERR(EINVAL); - } -#else - if ((((unsigned long)xfer->mem_addr & 15) || - ((unsigned long)xfer->fb_addr & 3)) || (xfer->mem_stride & 15) || - (xfer->fb_stride & 3)) { - DRM_ERROR("Invalid DRM bitblt alignment.\n"); - return DRM_ERR(EINVAL); - } -#endif - - if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) { - DRM_ERROR("Could not lock DMA pages.\n"); - via_free_sg_info(dev->pdev, vsg); - return ret; - } - - via_map_blit_for_device(dev->pdev, xfer, vsg, 0); - if (0 != (ret = via_alloc_desc_pages(vsg))) { - DRM_ERROR("Could not allocate DMA descriptor pages.\n"); - via_free_sg_info(dev->pdev, vsg); - return ret; - } - via_map_blit_for_device(dev->pdev, xfer, vsg, 1); - - return 0; -} - - -/* - * Reserve one free slot in the blit queue. Will wait for one second for one - * to become available. Otherwise -EBUSY is returned. - */ - -static int -via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) -{ - int ret=0; - unsigned long irqsave; - - DRM_DEBUG("Num free is %d\n", blitq->num_free); - spin_lock_irqsave(&blitq->blit_lock, irqsave); - while(blitq->num_free == 0) { - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - - DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); - if (ret) { - return (DRM_ERR(EINTR) == ret) ? DRM_ERR(EAGAIN) : ret; - } - - spin_lock_irqsave(&blitq->blit_lock, irqsave); - } - - blitq->num_free--; - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - - return 0; -} - -/* - * Hand back a free slot if we changed our mind. - */ - -static void -via_dmablit_release_slot(drm_via_blitq_t *blitq) -{ - unsigned long irqsave; - - spin_lock_irqsave(&blitq->blit_lock, irqsave); - blitq->num_free++; - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - DRM_WAKEUP( &blitq->busy_queue ); -} - -/* - * Grab a free slot. Build blit info and queue a blit. - */ - - -static int -via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer) -{ - drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; - drm_via_sg_info_t *vsg; - drm_via_blitq_t *blitq; - int ret; - int engine; - unsigned long irqsave; - - if (dev_priv == NULL) { - DRM_ERROR("Called without initialization.\n"); - return DRM_ERR(EINVAL); - } - - engine = (xfer->to_fb) ? 0 : 1; - blitq = dev_priv->blit_queues + engine; - if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) { - return ret; - } - if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) { - via_dmablit_release_slot(blitq); - return DRM_ERR(ENOMEM); - } - if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) { - via_dmablit_release_slot(blitq); - kfree(vsg); - return ret; - } - spin_lock_irqsave(&blitq->blit_lock, irqsave); - - blitq->blits[blitq->head++] = vsg; - if (blitq->head >= VIA_NUM_BLIT_SLOTS) - blitq->head = 0; - blitq->num_outstanding++; - xfer->sync.sync_handle = ++blitq->cur_blit_handle; - - spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - xfer->sync.engine = engine; - - via_dmablit_handler(dev, engine, 0); - - return 0; -} - -/* - * Sync on a previously submitted blit. Note that the X server use signals extensively, and - * that there is a very big proability that this IOCTL will be interrupted by a signal. In that - * case it returns with -EAGAIN for the signal to be delivered. - * The caller should then reissue the IOCTL. This is similar to what is being done for drmGetLock(). - */ - -int -via_dma_blit_sync( DRM_IOCTL_ARGS ) -{ - drm_via_blitsync_t sync; - int err; - DRM_DEVICE; - - DRM_COPY_FROM_USER_IOCTL(sync, (drm_via_blitsync_t *)data, sizeof(sync)); - - if (sync.engine >= VIA_NUM_BLIT_ENGINES) - return DRM_ERR(EINVAL); - - err = via_dmablit_sync(dev, sync.sync_handle, sync.engine); - - if (DRM_ERR(EINTR) == err) - err = DRM_ERR(EAGAIN); - - return err; -} - - -/* - * Queue a blit and hand back a handle to be used for sync. This IOCTL may be interrupted by a signal - * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should - * be reissued. See the above IOCTL code. - */ - -int -via_dma_blit( DRM_IOCTL_ARGS ) -{ - drm_via_dmablit_t xfer; - int err; - DRM_DEVICE; - - DRM_COPY_FROM_USER_IOCTL(xfer, (drm_via_dmablit_t __user *)data, sizeof(xfer)); - - err = via_dmablit(dev, &xfer); - - DRM_COPY_TO_USER_IOCTL((void __user *)data, xfer, sizeof(xfer)); - - return err; -} diff --git a/trunk/drivers/char/drm/via_dmablit.h b/trunk/drivers/char/drm/via_dmablit.h deleted file mode 100644 index f4036cd5d0e0..000000000000 --- a/trunk/drivers/char/drm/via_dmablit.h +++ /dev/null @@ -1,140 +0,0 @@ -/* via_dmablit.h -- PCI DMA BitBlt support for the VIA Unichrome/Pro - * - * Copyright 2005 Thomas Hellstrom. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Thomas Hellstrom. - * Register info from Digeo Inc. - */ - -#ifndef _VIA_DMABLIT_H -#define _VIA_DMABLIT_H - -#include - -#define VIA_NUM_BLIT_ENGINES 2 -#define VIA_NUM_BLIT_SLOTS 8 - -struct _drm_via_descriptor; - -typedef struct _drm_via_sg_info { - struct page **pages; - unsigned long num_pages; - struct _drm_via_descriptor **desc_pages; - int num_desc_pages; - int num_desc; - enum dma_data_direction direction; - unsigned char *bounce_buffer; - dma_addr_t chain_start; - uint32_t free_on_sequence; - unsigned int descriptors_per_page; - int aborted; - enum { - dr_via_device_mapped, - dr_via_desc_pages_alloc, - dr_via_pages_locked, - dr_via_pages_alloc, - dr_via_sg_init - } state; -} drm_via_sg_info_t; - -typedef struct _drm_via_blitq { - drm_device_t *dev; - uint32_t cur_blit_handle; - uint32_t done_blit_handle; - unsigned serviced; - unsigned head; - unsigned cur; - unsigned num_free; - unsigned num_outstanding; - unsigned long end; - int aborting; - int is_active; - drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS]; - spinlock_t blit_lock; - wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS]; - wait_queue_head_t busy_queue; - struct work_struct wq; - struct timer_list poll_timer; -} drm_via_blitq_t; - - -/* - * PCI DMA Registers - * Channels 2 & 3 don't seem to be implemented in hardware. - */ - -#define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */ -#define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */ -#define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */ -#define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */ - -#define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */ -#define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */ -#define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */ -#define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */ - -#define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */ -#define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */ -#define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */ -#define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */ - -#define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */ -#define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */ -#define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */ -#define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */ - -#define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */ -#define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */ -#define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */ -#define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */ - -#define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */ -#define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */ -#define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */ -#define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */ - -#define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */ - -/* Define for DMA engine */ -/* DPR */ -#define VIA_DMA_DPR_EC (1<<1) /* end of chain */ -#define VIA_DMA_DPR_DDIE (1<<2) /* descriptor done interrupt enable */ -#define VIA_DMA_DPR_DT (1<<3) /* direction of transfer (RO) */ - -/* MR */ -#define VIA_DMA_MR_CM (1<<0) /* chaining mode */ -#define VIA_DMA_MR_TDIE (1<<1) /* transfer done interrupt enable */ -#define VIA_DMA_MR_HENDMACMD (1<<7) /* ? */ - -/* CSR */ -#define VIA_DMA_CSR_DE (1<<0) /* DMA enable */ -#define VIA_DMA_CSR_TS (1<<1) /* transfer start */ -#define VIA_DMA_CSR_TA (1<<2) /* transfer abort */ -#define VIA_DMA_CSR_TD (1<<3) /* transfer done */ -#define VIA_DMA_CSR_DD (1<<4) /* descriptor done */ -#define VIA_DMA_DPR_EC (1<<1) /* end of chain */ - - - -#endif diff --git a/trunk/drivers/char/drm/via_drm.h b/trunk/drivers/char/drm/via_drm.h index 47f0b5b26379..ebde9206115e 100644 --- a/trunk/drivers/char/drm/via_drm.h +++ b/trunk/drivers/char/drm/via_drm.h @@ -75,8 +75,6 @@ #define DRM_VIA_CMDBUF_SIZE 0x0b #define NOT_USED #define DRM_VIA_WAIT_IRQ 0x0d -#define DRM_VIA_DMA_BLIT 0x0e -#define DRM_VIA_BLIT_SYNC 0x0f #define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t) #define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t) @@ -91,8 +89,6 @@ #define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \ drm_via_cmdbuf_size_t) #define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t) -#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t) -#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t) /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, @@ -107,12 +103,8 @@ #define VIA_BACK 0x2 #define VIA_DEPTH 0x4 #define VIA_STENCIL 0x8 -#define VIA_MEM_VIDEO 0 /* matches drm constant */ -#define VIA_MEM_AGP 1 /* matches drm constant */ -#define VIA_MEM_SYSTEM 2 -#define VIA_MEM_MIXED 3 -#define VIA_MEM_UNKNOWN 4 - +#define VIDEO 0 +#define AGP 1 typedef struct { uint32_t offset; uint32_t size; @@ -200,9 +192,6 @@ typedef struct _drm_via_sarea { unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS]; unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */ - /* Used by the 3d driver only at this point, for pageflipping: - */ - unsigned int pfCurrentOffset; } drm_via_sarea_t; typedef struct _drm_via_cmdbuf_size { @@ -223,16 +212,6 @@ typedef enum { #define VIA_IRQ_FLAGS_MASK 0xF0000000 -enum drm_via_irqs { - drm_via_irq_hqv0 = 0, - drm_via_irq_hqv1, - drm_via_irq_dma0_dd, - drm_via_irq_dma0_td, - drm_via_irq_dma1_dd, - drm_via_irq_dma1_td, - drm_via_irq_num -}; - struct drm_via_wait_irq_request { unsigned irq; via_irq_seq_type_t type; @@ -245,25 +224,20 @@ typedef union drm_via_irqwait { struct drm_wait_vblank_reply reply; } drm_via_irqwait_t; -typedef struct drm_via_blitsync { - uint32_t sync_handle; - unsigned engine; -} drm_via_blitsync_t; - -typedef struct drm_via_dmablit { - uint32_t num_lines; - uint32_t line_length; - - uint32_t fb_addr; - uint32_t fb_stride; - - unsigned char *mem_addr; - uint32_t mem_stride; - - int bounce_buffer; - int to_fb; - - drm_via_blitsync_t sync; -} drm_via_dmablit_t; +#ifdef __KERNEL__ + +int via_fb_init(DRM_IOCTL_ARGS); +int via_mem_alloc(DRM_IOCTL_ARGS); +int via_mem_free(DRM_IOCTL_ARGS); +int via_agp_init(DRM_IOCTL_ARGS); +int via_map_init(DRM_IOCTL_ARGS); +int via_decoder_futex(DRM_IOCTL_ARGS); +int via_dma_init(DRM_IOCTL_ARGS); +int via_cmdbuffer(DRM_IOCTL_ARGS); +int via_flush_ioctl(DRM_IOCTL_ARGS); +int via_pci_cmdbuffer(DRM_IOCTL_ARGS); +int via_cmdbuf_size(DRM_IOCTL_ARGS); +int via_wait_irq(DRM_IOCTL_ARGS); +#endif #endif /* _VIA_DRM_H_ */ diff --git a/trunk/drivers/char/drm/via_drv.c b/trunk/drivers/char/drm/via_drv.c index 3f012255d315..016665e0c69f 100644 --- a/trunk/drivers/char/drm/via_drv.c +++ b/trunk/drivers/char/drm/via_drv.c @@ -29,21 +29,54 @@ #include "drm_pciids.h" -static int dri_library_name(struct drm_device *dev, char *buf) +static int postinit(struct drm_device *dev, unsigned long flags) { - return snprintf(buf, PAGE_SIZE, "unichrome"); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev) + ); + return 0; +} + +static int version(drm_version_t * version) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY(version->name, DRIVER_NAME); + DRM_COPY(version->date, DRIVER_DATE); + DRM_COPY(version->desc, DRIVER_DESC); + return 0; } static struct pci_device_id pciidlist[] = { viadrv_PCI_IDS }; +static drm_ioctl_desc_t ioctls[] = { + [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, 1, 0}, + [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, 1, 0} +}; + static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, - .load = via_driver_load, - .unload = via_driver_unload, .context_ctor = via_init_context, .context_dtor = via_final_context, .vblank_wait = via_driver_vblank_wait, @@ -52,11 +85,13 @@ static struct drm_driver driver = { .irq_uninstall = via_driver_irq_uninstall, .irq_handler = via_driver_irq_handler, .dma_quiescent = via_driver_dma_quiescent, - .dri_library_name = dri_library_name, .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = via_ioctls, + .postinit = postinit, + .version = version, + .ioctls = ioctls, + .num_ioctls = DRM_ARRAY_SIZE(ioctls), .fops = { .owner = THIS_MODULE, .open = drm_open, @@ -65,23 +100,15 @@ static struct drm_driver driver = { .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, - }, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .id_table = pciidlist, + } }; static int __init via_init(void) { - driver.num_ioctls = via_max_ioctl; via_init_command_verifier(); return drm_init(&driver); } diff --git a/trunk/drivers/char/drm/via_drv.h b/trunk/drivers/char/drm/via_drv.h index aad4f99f5405..7d5daf43797e 100644 --- a/trunk/drivers/char/drm/via_drv.h +++ b/trunk/drivers/char/drm/via_drv.h @@ -24,26 +24,24 @@ #ifndef _VIA_DRV_H_ #define _VIA_DRV_H_ -#define DRIVER_AUTHOR "Various" +#define DRIVER_AUTHOR "VIA" #define DRIVER_NAME "via" #define DRIVER_DESC "VIA Unichrome / Pro" -#define DRIVER_DATE "20051116" +#define DRIVER_DATE "20050523" #define DRIVER_MAJOR 2 -#define DRIVER_MINOR 7 -#define DRIVER_PATCHLEVEL 4 +#define DRIVER_MINOR 6 +#define DRIVER_PATCHLEVEL 3 #include "via_verifier.h" -#include "via_dmablit.h" - #define VIA_PCI_BUF_SIZE 60000 #define VIA_FIRE_BUF_SIZE 1024 -#define VIA_NUM_IRQS 4 +#define VIA_NUM_IRQS 2 typedef struct drm_via_ring_buffer { - drm_local_map_t map; + drm_map_t map; char *virtual_start; } drm_via_ring_buffer_t; @@ -58,9 +56,9 @@ typedef struct drm_via_irq { typedef struct drm_via_private { drm_via_sarea_t *sarea_priv; - drm_local_map_t *sarea; - drm_local_map_t *fb; - drm_local_map_t *mmio; + drm_map_t *sarea; + drm_map_t *fb; + drm_map_t *mmio; unsigned long agpAddr; wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS]; char *dma_ptr; @@ -84,15 +82,8 @@ typedef struct drm_via_private { maskarray_t *irq_masks; uint32_t irq_enable_mask; uint32_t irq_pending_mask; - int *irq_map; - drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; } drm_via_private_t; -enum via_family { - VIA_OTHER = 0, - VIA_PRO_GROUP_A, -}; - /* VIA MMIO register access */ #define VIA_BASE ((dev_priv->mmio)) @@ -101,31 +92,12 @@ enum via_family { #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) #define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) -extern drm_ioctl_desc_t via_ioctls[]; -extern int via_max_ioctl; - -extern int via_fb_init(DRM_IOCTL_ARGS); -extern int via_mem_alloc(DRM_IOCTL_ARGS); -extern int via_mem_free(DRM_IOCTL_ARGS); -extern int via_agp_init(DRM_IOCTL_ARGS); -extern int via_map_init(DRM_IOCTL_ARGS); -extern int via_decoder_futex(DRM_IOCTL_ARGS); -extern int via_dma_init(DRM_IOCTL_ARGS); -extern int via_cmdbuffer(DRM_IOCTL_ARGS); -extern int via_flush_ioctl(DRM_IOCTL_ARGS); -extern int via_pci_cmdbuffer(DRM_IOCTL_ARGS); -extern int via_cmdbuf_size(DRM_IOCTL_ARGS); -extern int via_wait_irq(DRM_IOCTL_ARGS); -extern int via_dma_blit_sync( DRM_IOCTL_ARGS ); -extern int via_dma_blit( DRM_IOCTL_ARGS ); - -extern int via_driver_load(drm_device_t *dev, unsigned long chipset); -extern int via_driver_unload(drm_device_t *dev); - extern int via_init_context(drm_device_t * dev, int context); extern int via_final_context(drm_device_t * dev, int context); extern int via_do_cleanup_map(drm_device_t * dev); +extern int via_map_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); @@ -139,10 +111,8 @@ extern int via_driver_dma_quiescent(drm_device_t * dev); extern void via_init_futex(drm_via_private_t * dev_priv); extern void via_cleanup_futex(drm_via_private_t * dev_priv); extern void via_release_futex(drm_via_private_t * dev_priv, int context); -extern int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, - int force_sequence, unsigned int *sequence); -extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq); -extern void via_init_dmablit(drm_device_t *dev); +extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, + unsigned int size); #endif diff --git a/trunk/drivers/char/drm/via_ds.c b/trunk/drivers/char/drm/via_ds.c index 9429736b3b96..5c71e089246c 100644 --- a/trunk/drivers/char/drm/via_ds.c +++ b/trunk/drivers/char/drm/via_ds.c @@ -22,7 +22,14 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ -#include "drmP.h" +#include +#include +#include +#include +#include +#include +#include +#include #include "via_ds.h" extern unsigned int VIA_DEBUG; diff --git a/trunk/drivers/char/drm/via_irq.c b/trunk/drivers/char/drm/via_irq.c index 56d7e3daea12..d023add1929b 100644 --- a/trunk/drivers/char/drm/via_irq.c +++ b/trunk/drivers/char/drm/via_irq.c @@ -50,15 +50,6 @@ #define VIA_IRQ_HQV1_ENABLE (1 << 25) #define VIA_IRQ_HQV0_PENDING (1 << 9) #define VIA_IRQ_HQV1_PENDING (1 << 10) -#define VIA_IRQ_DMA0_DD_ENABLE (1 << 20) -#define VIA_IRQ_DMA0_TD_ENABLE (1 << 21) -#define VIA_IRQ_DMA1_DD_ENABLE (1 << 22) -#define VIA_IRQ_DMA1_TD_ENABLE (1 << 23) -#define VIA_IRQ_DMA0_DD_PENDING (1 << 4) -#define VIA_IRQ_DMA0_TD_PENDING (1 << 5) -#define VIA_IRQ_DMA1_DD_PENDING (1 << 6) -#define VIA_IRQ_DMA1_TD_PENDING (1 << 7) - /* * Device-specific IRQs go here. This type might need to be extended with @@ -70,24 +61,13 @@ static maskarray_t via_pro_group_a_irqs[] = { {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000}, {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, - 0x00000000}, - {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, - VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, - {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, - VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, + 0x00000000} }; static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t); -static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3}; -static maskarray_t via_unichrome_irqs[] = { - {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, - VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, - {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, - VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} -}; +static maskarray_t via_unichrome_irqs[] = { }; static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); -static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; static unsigned time_diff(struct timeval *now, struct timeval *then) { @@ -133,11 +113,6 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) atomic_inc(&cur_irq->irq_received); DRM_WAKEUP(&cur_irq->irq_queue); handled = 1; - if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) { - via_dmablit_handler(dev, 0, 1); - } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) { - via_dmablit_handler(dev, 1, 1); - } } cur_irq++; } @@ -190,7 +165,7 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) return ret; } -int +static int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, unsigned int *sequence) { @@ -199,7 +174,6 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, drm_via_irq_t *cur_irq = dev_priv->via_irqs; int ret = 0; maskarray_t *masks = dev_priv->irq_masks; - int real_irq; DRM_DEBUG("%s\n", __FUNCTION__); @@ -208,23 +182,15 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, return DRM_ERR(EINVAL); } - if (irq >= drm_via_irq_num) { + if (irq >= dev_priv->num_irqs) { DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq); return DRM_ERR(EINVAL); } - real_irq = dev_priv->irq_map[irq]; - - if (real_irq < 0) { - DRM_ERROR("%s Video IRQ %d not available on this hardware.\n", - __FUNCTION__, irq); - return DRM_ERR(EINVAL); - } - - cur_irq += real_irq; + cur_irq += irq; - if (masks[real_irq][2] && !force_sequence) { + if (masks[irq][2] && !force_sequence) { DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, ((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4])); @@ -260,8 +226,6 @@ void via_driver_irq_preinstall(drm_device_t * dev) via_pro_group_a_irqs : via_unichrome_irqs; dev_priv->num_irqs = (dev_priv->pro_group_a) ? via_num_pro_group_a : via_num_unichrome; - dev_priv->irq_map = (dev_priv->pro_group_a) ? - via_irqmap_pro_group_a : via_irqmap_unichrome; for (i = 0; i < dev_priv->num_irqs; ++i) { atomic_set(&cur_irq->irq_received, 0); @@ -277,7 +241,7 @@ void via_driver_irq_preinstall(drm_device_t * dev) dev_priv->last_vblank_valid = 0; - /* Clear VSync interrupt regs */ + // Clear VSync interrupt regs status = VIA_READ(VIA_REG_INTERRUPT); VIA_WRITE(VIA_REG_INTERRUPT, status & ~(dev_priv->irq_enable_mask)); @@ -327,7 +291,8 @@ void via_driver_irq_uninstall(drm_device_t * dev) int via_wait_irq(DRM_IOCTL_ARGS) { - DRM_DEVICE; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; drm_via_irqwait_t __user *argp = (void __user *)data; drm_via_irqwait_t irqwait; struct timeval now; diff --git a/trunk/drivers/char/drm/via_map.c b/trunk/drivers/char/drm/via_map.c index c6a08e96285b..6bd6ac52ad1b 100644 --- a/trunk/drivers/char/drm/via_map.c +++ b/trunk/drivers/char/drm/via_map.c @@ -27,10 +27,16 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) { - drm_via_private_t *dev_priv = dev->dev_private; + drm_via_private_t *dev_priv; DRM_DEBUG("%s\n", __FUNCTION__); + dev_priv = drm_alloc(sizeof(drm_via_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + + memset(dev_priv, 0, sizeof(drm_via_private_t)); + DRM_GETSAREA(); if (!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); @@ -61,8 +67,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) dev_priv->agpAddr = init->agpAddr; via_init_futex(dev_priv); - - via_init_dmablit(dev); + dev_priv->pro_group_a = (dev->pdev->device == 0x3118); dev->dev_private = (void *)dev_priv; return 0; @@ -70,7 +75,15 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) int via_do_cleanup_map(drm_device_t * dev) { - via_dma_cleanup(dev); + if (dev->dev_private) { + + drm_via_private_t *dev_priv = dev->dev_private; + + via_dma_cleanup(dev); + + drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); + dev->dev_private = NULL; + } return 0; } @@ -94,29 +107,3 @@ int via_map_init(DRM_IOCTL_ARGS) return -EINVAL; } - -int via_driver_load(drm_device_t *dev, unsigned long chipset) -{ - drm_via_private_t *dev_priv; - - dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return DRM_ERR(ENOMEM); - - dev->dev_private = (void *)dev_priv; - - if (chipset == VIA_PRO_GROUP_A) - dev_priv->pro_group_a = 1; - - return 0; -} - -int via_driver_unload(drm_device_t *dev) -{ - drm_via_private_t *dev_priv = dev->dev_private; - - drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); - - return 0; -} - diff --git a/trunk/drivers/char/drm/via_mm.c b/trunk/drivers/char/drm/via_mm.c index 33e0cb12e4c3..3baddacdff26 100644 --- a/trunk/drivers/char/drm/via_mm.c +++ b/trunk/drivers/char/drm/via_mm.c @@ -42,7 +42,7 @@ static int via_agp_free(drm_via_mem_t * mem); static int via_fb_alloc(drm_via_mem_t * mem); static int via_fb_free(drm_via_mem_t * mem); -static int add_alloc_set(int context, int type, unsigned long val) +static int add_alloc_set(int context, int type, unsigned int val) { int i, retval = 0; @@ -56,7 +56,7 @@ static int add_alloc_set(int context, int type, unsigned long val) return retval; } -static int del_alloc_set(int context, int type, unsigned long val) +static int del_alloc_set(int context, int type, unsigned int val) { int i, retval = 0; @@ -199,13 +199,13 @@ int via_mem_alloc(DRM_IOCTL_ARGS) sizeof(mem)); switch (mem.type) { - case VIA_MEM_VIDEO: + case VIDEO: if (via_fb_alloc(&mem) < 0) return -EFAULT; DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, sizeof(mem)); return 0; - case VIA_MEM_AGP: + case AGP: if (via_agp_alloc(&mem) < 0) return -EFAULT; DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, @@ -232,7 +232,7 @@ static int via_fb_alloc(drm_via_mem_t * mem) if (block) { fb.offset = block->ofs; fb.free = (unsigned long)block; - if (!add_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) { + if (!add_alloc_set(fb.context, VIDEO, fb.free)) { DRM_DEBUG("adding to allocation set fails\n"); via_mmFreeMem((PMemBlock) fb.free); retval = -1; @@ -269,7 +269,7 @@ static int via_agp_alloc(drm_via_mem_t * mem) if (block) { agp.offset = block->ofs; agp.free = (unsigned long)block; - if (!add_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) { + if (!add_alloc_set(agp.context, AGP, agp.free)) { DRM_DEBUG("adding to allocation set fails\n"); via_mmFreeMem((PMemBlock) agp.free); retval = -1; @@ -297,11 +297,11 @@ int via_mem_free(DRM_IOCTL_ARGS) switch (mem.type) { - case VIA_MEM_VIDEO: + case VIDEO: if (via_fb_free(&mem) == 0) return 0; break; - case VIA_MEM_AGP: + case AGP: if (via_agp_free(&mem) == 0) return 0; break; @@ -329,7 +329,7 @@ static int via_fb_free(drm_via_mem_t * mem) via_mmFreeMem((PMemBlock) fb.free); - if (!del_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) { + if (!del_alloc_set(fb.context, VIDEO, fb.free)) { retval = -1; } @@ -352,7 +352,7 @@ static int via_agp_free(drm_via_mem_t * mem) via_mmFreeMem((PMemBlock) agp.free); - if (!del_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) { + if (!del_alloc_set(agp.context, AGP, agp.free)) { retval = -1; } diff --git a/trunk/drivers/char/drm/via_verifier.c b/trunk/drivers/char/drm/via_verifier.c index 70c897c88766..4ac495f297f7 100644 --- a/trunk/drivers/char/drm/via_verifier.c +++ b/trunk/drivers/char/drm/via_verifier.c @@ -237,7 +237,7 @@ static hazard_t table3[256]; static __inline__ int eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) { - if ((buf_end - *buf) >= num_words) { + if ((*buf - buf_end) >= num_words) { *buf += num_words; return 0; } @@ -249,14 +249,14 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) * Partially stolen from drm_memory.h */ -static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, +static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq, unsigned long offset, unsigned long size, drm_device_t * dev) { struct list_head *list; drm_map_list_t *r_list; - drm_local_map_t *map = seq->map_cache; + drm_map_t *map = seq->map_cache; if (map && map->offset <= offset && (offset + size) <= (map->offset + map->size)) { diff --git a/trunk/drivers/char/drm/via_verifier.h b/trunk/drivers/char/drm/via_verifier.h index 256590fcc22a..eb4eda344345 100644 --- a/trunk/drivers/char/drm/via_verifier.h +++ b/trunk/drivers/char/drm/via_verifier.h @@ -47,7 +47,7 @@ typedef struct { int agp_texture; int multitex; drm_device_t *dev; - drm_local_map_t *map_cache; + drm_map_t *map_cache; uint32_t vertex_count; int agp; const uint32_t *buf_start; @@ -55,7 +55,5 @@ typedef struct { extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t * dev, int agp); -extern int via_parse_command_stream(drm_device_t *dev, const uint32_t *buf, - unsigned int size); #endif diff --git a/trunk/drivers/char/drm/via_video.c b/trunk/drivers/char/drm/via_video.c index 300ac61b09ed..7fab9fbdf424 100644 --- a/trunk/drivers/char/drm/via_video.c +++ b/trunk/drivers/char/drm/via_video.c @@ -50,11 +50,8 @@ void via_release_futex(drm_via_private_t * dev_priv, int context) unsigned int i; volatile int *lock; - if (!dev_priv->sarea_priv) - return; - for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) { - lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i); + lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i); if ((_DRM_LOCKING_CONTEXT(*lock) == context)) { if (_DRM_LOCK_IS_HELD(*lock) && (*lock & _DRM_LOCK_CONT)) { @@ -82,7 +79,7 @@ int via_decoder_futex(DRM_IOCTL_ARGS) if (fx.lock > VIA_NR_XVMC_LOCKS) return -EFAULT; - lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx.lock); + lock = (int *)XVMCLOCKPTR(sAPriv, fx.lock); switch (fx.func) { case VIA_FUTEX_WAIT: diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 22cd04556707..23de22631c64 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -132,6 +132,10 @@ * TODO: * o several entry points race with dev->close * o check for tx-no-resources/stop Q races with tx clean/wake Q + * + * FIXES: + * 2005/12/02 - Michael O'Donnell + * - Stratus87247: protect MDI control register manipulations */ #include @@ -578,6 +582,7 @@ struct nic { u16 leds; u16 eeprom_wc; u16 eeprom[256]; + spinlock_t mdio_lock; }; static inline void e100_write_flush(struct nic *nic) @@ -876,15 +881,35 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) { u32 data_out = 0; unsigned int i; + unsigned long flags; + + /* + * Stratus87247: we shouldn't be writing the MDI control + * register until the Ready bit shows True. Also, since + * manipulation of the MDI control registers is a multi-step + * procedure it should be done under lock. + */ + spin_lock_irqsave(&nic->mdio_lock, flags); + for (i = 100; i; --i) { + if (readl(&nic->csr->mdi_ctrl) & mdi_ready) + break; + udelay(20); + } + if (unlikely(!i)) { + printk("e100.mdio_ctrl(%s) won't go Ready\n", + nic->netdev->name ); + spin_unlock_irqrestore(&nic->mdio_lock, flags); + return 0; /* No way to indicate timeout error */ + } writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl); - for(i = 0; i < 100; i++) { + for (i = 0; i < 100; i++) { udelay(20); - if((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready) + if ((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready) break; } - + spin_unlock_irqrestore(&nic->mdio_lock, flags); DPRINTK(HW, DEBUG, "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n", dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out); @@ -2562,6 +2587,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, /* locks must be initialized before calling hw_reset */ spin_lock_init(&nic->cb_lock); spin_lock_init(&nic->cmd_lock); + spin_lock_init(&nic->mdio_lock); /* Reset the device before pci_set_master() in case device is in some * funky state and has an interrupt pending - hint: we don't have the diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 621ec459d27a..0252582b91cd 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -920,37 +920,6 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]); pcmcia_device_stringattr(prod_id3, prod_id[2]); pcmcia_device_stringattr(prod_id4, prod_id[3]); - -static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - - if (p_dev->dev.power.power_state.event != PM_EVENT_ON) - return sprintf(buf, "off\n"); - else - return sprintf(buf, "on\n"); -} - -static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - int ret = 0; - - if (!count) - return -EINVAL; - - if ((p_dev->dev.power.power_state.event == PM_EVENT_ON) && - (!strncmp(buf, "off", 3))) - ret = dpm_runtime_suspend(dev, PMSG_SUSPEND); - else if ((p_dev->dev.power.power_state.event != PM_EVENT_ON) && - (!strncmp(buf, "on", 2))) - dpm_runtime_resume(dev); - - return ret ? ret : count; -} - - static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); @@ -976,9 +945,8 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - - if (!count) - return -EINVAL; + if (!count) + return -EINVAL; down(&p_dev->socket->skt_sem); p_dev->allow_func_id_match = 1; @@ -991,7 +959,6 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, static struct device_attribute pcmcia_dev_attrs[] = { __ATTR(function, 0444, func_show, NULL), - __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state), __ATTR_RO(func_id), __ATTR_RO(manf_id), __ATTR_RO(card_id), diff --git a/trunk/drivers/pcmcia/socket_sysfs.c b/trunk/drivers/pcmcia/socket_sysfs.c index 5ab1cdef7c48..7a7744662d54 100644 --- a/trunk/drivers/pcmcia/socket_sysfs.c +++ b/trunk/drivers/pcmcia/socket_sysfs.c @@ -98,30 +98,6 @@ static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, si } static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); - -static ssize_t pccard_show_card_pm_state(struct class_device *dev, char *buf) -{ - struct pcmcia_socket *s = to_socket(dev); - return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on"); -} - -static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *buf, size_t count) -{ - ssize_t ret = -EINVAL; - struct pcmcia_socket *s = to_socket(dev); - - if (!count) - return -EINVAL; - - if (!(s->state & SOCKET_SUSPEND) && !strncmp(buf, "off", 3)) - ret = pcmcia_suspend_card(s); - else if ((s->state & SOCKET_SUSPEND) && !strncmp(buf, "on", 2)) - ret = pcmcia_resume_card(s); - - return ret ? -ENODEV : count; -} -static CLASS_DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state); - static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count) { ssize_t ret; @@ -344,7 +320,6 @@ static struct class_device_attribute *pccard_socket_attributes[] = { &class_device_attr_card_vpp, &class_device_attr_card_vcc, &class_device_attr_card_insert, - &class_device_attr_card_pm_state, &class_device_attr_card_eject, &class_device_attr_card_irq_mask, &class_device_attr_available_resources_setup_done, diff --git a/trunk/drivers/serial/serial_cs.c b/trunk/drivers/serial/serial_cs.c index c30333694fde..96969cb960a9 100644 --- a/trunk/drivers/serial/serial_cs.c +++ b/trunk/drivers/serial/serial_cs.c @@ -785,8 +785,6 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ - PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ - PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),