diff options
Diffstat (limited to 'drivers/char/drm/gamma_drv.c')
-rw-r--r-- | drivers/char/drm/gamma_drv.c | 136 |
1 files changed, 87 insertions, 49 deletions
diff --git a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c index 8809d1810..2450d3a7b 100644 --- a/drivers/char/drm/gamma_drv.c +++ b/drivers/char/drm/gamma_drv.c @@ -1,7 +1,8 @@ /* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*- * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com * - * Copyright 1999, 2000 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. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -24,37 +25,50 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Rickard E. (Rik) Faith <faith@valinux.com> * */ #include <linux/config.h> -#include <linux/sched.h> -#include <linux/smp_lock.h> +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif #include "drmP.h" #include "gamma_drv.h" +#include <linux/pci.h> +#include <linux/smp_lock.h> /* For (un)lock_kernel */ EXPORT_SYMBOL(gamma_init); EXPORT_SYMBOL(gamma_cleanup); +#ifndef PCI_DEVICE_ID_3DLABS_GAMMA +#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008 +#endif +#ifndef PCI_DEVICE_ID_3DLABS_MX +#define PCI_DEVICE_ID_3DLABS_MX 0x0006 +#endif + #define GAMMA_NAME "gamma" #define GAMMA_DESC "3dlabs GMX 2000" -#define GAMMA_DATE "19990830" -#define GAMMA_MAJOR 0 +#define GAMMA_DATE "20000719" +#define GAMMA_MAJOR 1 #define GAMMA_MINOR 0 -#define GAMMA_PATCHLEVEL 5 +#define GAMMA_PATCHLEVEL 0 static drm_device_t gamma_device; static struct file_operations gamma_fops = { - owner: THIS_MODULE, - open: gamma_open, - flush: drm_flush, - release: gamma_release, - ioctl: gamma_ioctl, - mmap: drm_mmap, - read: drm_read, - fasync: drm_fasync, - poll: drm_poll, +#if LINUX_VERSION_CODE >= 0x020322 + /* This started being used approx. 2.3.34 */ + owner: THIS_MODULE, +#endif + open: gamma_open, + flush: drm_flush, + release: gamma_release, + ioctl: gamma_ioctl, + mmap: drm_mmap, + read: drm_read, + fasync: drm_fasync, + poll: drm_poll, }; static struct miscdevice gamma_misc = { @@ -98,46 +112,34 @@ static drm_ioctl_desc_t gamma_ioctls[] = { #define GAMMA_IOCTL_COUNT DRM_ARRAY_SIZE(gamma_ioctls) #ifdef MODULE -int init_module(void); -void cleanup_module(void); static char *gamma = NULL; +#endif +static int devices = 0; -MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas."); +MODULE_AUTHOR("VA Linux Systems, Inc."); MODULE_DESCRIPTION("3dlabs GMX 2000"); MODULE_PARM(gamma, "s"); +MODULE_PARM(devices, "i"); +MODULE_PARM_DESC(devices, + "devices=x, where x is the number of MX chips on card\n"); -/* init_module is called when insmod is used to load the module */ - -int init_module(void) -{ - return gamma_init(); -} - -/* cleanup_module is called when rmmod is used to unload the module */ - -void cleanup_module(void) -{ - gamma_cleanup(); -} -#endif +module_init(gamma_init); +module_exit(gamma_cleanup); #ifndef MODULE -/* gamma_setup is called by the kernel to parse command-line options passed - * via the boot-loader (e.g., LILO). It calls the insmod option routine, - * drm_parse_options. - * - * This is not currently supported, since it requires changes to - * linux/init/main.c. */ +/* gamma_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_options. + */ -void __init gamma_setup(char *str, int *ints) +static int __init gamma_options(char *str) { - if (ints[0] != 0) { - DRM_ERROR("Illegal command line format, ignored\n"); - return; - } drm_parse_options(str); + return 1; } + +__setup("gamma=", gamma_options); #endif static int gamma_setup(drm_device_t *dev) @@ -274,6 +276,10 @@ static int gamma_takedown(drm_device_t *dev) - PAGE_SHIFT, DRM_MEM_SAREA); break; + case _DRM_AGP: + /* Do nothing here, because this is all + handled in the AGP/GART driver. */ + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } @@ -313,6 +319,34 @@ static int gamma_takedown(drm_device_t *dev) return 0; } +int gamma_found(void) +{ + return devices; +} + +int gamma_find_devices(void) +{ + struct pci_dev *d = NULL, *one = NULL, *two = NULL; + + d = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_GAMMA,d); + if (!d) return 0; + + one = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,d); + if (!one) return 0; + + /* Make sure it's on the same card, if not - no MX's found */ + if (PCI_SLOT(d->devfn) != PCI_SLOT(one->devfn)) return 0; + + two = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,one); + if (!two) return 1; + + /* Make sure it's on the same card, if not - only 1 MX found */ + if (PCI_SLOT(d->devfn) != PCI_SLOT(two->devfn)) return 1; + + /* Two MX's found - we don't currently support more than 2 */ + return 2; +} + /* gamma_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ @@ -330,6 +364,8 @@ int gamma_init(void) #ifdef MODULE drm_parse_options(gamma); #endif + devices = gamma_find_devices(); + if (devices == 0) return -1; if ((retcode = misc_register(&gamma_misc))) { DRM_ERROR("Cannot register \"%s\"\n", GAMMA_NAME); @@ -341,13 +377,14 @@ int gamma_init(void) drm_mem_init(); drm_proc_init(dev); - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d with %d MX devices\n", GAMMA_NAME, GAMMA_MAJOR, GAMMA_MINOR, GAMMA_PATCHLEVEL, GAMMA_DATE, - gamma_misc.minor); + gamma_misc.minor, + devices); return 0; } @@ -410,6 +447,7 @@ int gamma_open(struct inode *inode, struct file *filp) DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { + MOD_INC_USE_COUNT; atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -424,13 +462,13 @@ int gamma_open(struct inode *inode, struct file *filp) int gamma_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev; + drm_device_t *dev = priv->dev; int retcode = 0; - lock_kernel(); - dev = priv->dev; DRM_DEBUG("open_count = %d\n", dev->open_count); + lock_kernel(); if (!(retcode = drm_release(inode, filp))) { + MOD_DEC_USE_COUNT; atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { |