From 56bd9c207770d41a497f3e8237a1099dd9d4cd91 Mon Sep 17 00:00:00 2001 From: David Dawes Date: Mon, 30 Jul 2001 19:59:39 +0000 Subject: Merge the multihead-1-0-0 branch into the trunk, with the exception of the glide header files. The changes include: - Brian Paul's changes to the tdfx client-side 3D driver to make it dlopen() the correct glide library (Voodoo3 or Voodoo5). This allows both types of the glide library to co-exist, and allows Voodoo3/Voodoo5 cards to be mixed in multi-head configs. - DRM kernel driver changes to allow a driver to set up multiple instances (minor numbers), one for each card present that the driver supports. This is currently implemented and tested only for the tdfx DRM driver. - Add some missing missing includes. - Some log message cleanups. - Change the 2D tdfx driver to access VGA legacy registers via their PCI I/O space access points rather than their legacy addresses, and fix some problems with the way the VGA-related bits are initialised. Status: - With these changes, multi-head direct rendering works with multiple Voodoo3 and/or Voodoo5 cards. This has been tested with two PCI Voodoo3 cards and an AGP Voodoo5 card, and all permutations of those. Caveats: - Xinerama is not supported. If Xinerama is enabled, then direct rendering gets disabled. - The text mode on secondary screens will show junk after the X server exits. - On some hardware, starting the X server on multiple 3dfx cards will result in a hard lockup. One workaround is to enable APIC support in a uni-processor kernel, or use an SMP kernel. --- libdrm/xf86drm.c | 62 ++++++++++++++-- linux-core/drm_drv.c | 192 ++++++++++++++++++++++++++++++++++++-------------- linux-core/drm_init.c | 6 +- linux-core/drm_stub.c | 8 ++- linux-core/tdfx_drv.c | 9 +++ linux/drm_drv.h | 192 ++++++++++++++++++++++++++++++++++++-------------- linux/drm_init.h | 6 +- linux/drm_stub.h | 8 ++- linux/tdfx_drv.c | 9 +++ 9 files changed, 369 insertions(+), 123 deletions(-) diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a04cf7ae6..5ed8f1f86 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -55,6 +55,7 @@ # include # include # include +# include # ifdef DRM_USE_MALLOC # define _DRM_MALLOC malloc # define _DRM_FREE free @@ -107,6 +108,28 @@ extern unsigned long _bus_base(void); #define makedev(x,y) ((dev_t)(((x) << 8) | (y))) #endif +#define DRM_MSG_VERBOSITY 3 + +static void +drmMsg(const char *format, ...) +{ + va_list ap; + +#ifndef XFree86Server + const char *env; + if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) +#endif + { + va_start(ap, format); +#ifdef XFree86Server + xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap); +#else + vfprintf(stderr, format, ap); +#endif + va_end(ap); + } +} + static void *drmHashTable = NULL; /* Context switch callbacks */ typedef struct drmHashEntry { @@ -182,6 +205,8 @@ static int drmOpenDevice(long dev, int minor) gid_t group = DRM_DEV_GID; #endif + drmMsg("drmOpenDevice: minor is %d\n", minor); + #if defined(XFree86Server) devmode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE; dirmode = (devmode & S_IRUSR) ? S_IXUSR : 0; @@ -203,6 +228,7 @@ static int drmOpenDevice(long dev, int minor) #endif sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); + drmMsg("drmOpenDevice: node name is %s\n", buf); if (stat(buf, &st) || st.st_rdev != dev) { if (!isroot) return DRM_ERR_NOT_ROOT; remove(buf); @@ -213,7 +239,11 @@ static int drmOpenDevice(long dev, int minor) chmod(buf, devmode); #endif - if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; + fd = open(buf, O_RDWR, 0); + drmMsg("drmOpenDevice: open result is %d, (%s)\n", + fd, fd < 0 ? strerror(errno) : "OK"); + if (fd >= 0) return fd; + drmMsg("drmOpenDevice: Open failed\n"); remove(buf); return -errno; } @@ -261,9 +291,13 @@ static int drmOpenByBusid(const char *busid) int fd; const char *buf; + drmMsg("drmOpenByBusid: busid is %s\n", busid); for (i = 0; i < DRM_MAX_MINOR; i++) { - if ((fd = drmOpenMinor(i, 0)) >= 0) { + fd = drmOpenMinor(i, 1); + drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); + if (fd >= 0) { buf = drmGetBusid(fd); + drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); if (buf && !strcmp(buf, busid)) { drmFreeBusid(buf); return fd; @@ -280,6 +314,7 @@ static int drmOpenByName(const char *name) int i; int fd; drmVersionPtr version; + char * id; if (!drmAvailable()) { #if !defined(XFree86Server) @@ -294,15 +329,30 @@ static int drmOpenByName(const char *name) #endif } + /* + * Open the first minor number that matches the driver name and isn't + * already in use. If it's in use it will have a busid assigned already. + */ for (i = 0; i < DRM_MAX_MINOR; i++) { if ((fd = drmOpenMinor(i, 1)) >= 0) { if ((version = drmGetVersion(fd))) { if (!strcmp(version->name, name)) { drmFreeVersion(version); - return fd; + id = drmGetBusid(fd); + drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL"); + if (!id || !*id) { + if (id) { + drmFreeBusid(id); + } + return fd; + } else { + drmFreeBusid(id); + } + } else { + drmFreeVersion(version); } - drmFreeVersion(version); } + close(fd); } } @@ -459,7 +509,9 @@ int drmSetBusid(int fd, const char *busid) u.unique = (char *)busid; u.unique_len = strlen(busid); - if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) return -errno; + if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) { + return -errno; + } return 0; } diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index c5f231c71..dd46f227e 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -101,9 +101,16 @@ #define DRIVER_IOCTLS #endif +/* + * The default number of instances (minor numbers) to initialize. + */ +#ifndef DRIVER_NUM_CARDS +#define DRIVER_NUM_CARDS 1 +#endif -static drm_device_t DRM(device); -static int DRM(minor); +static drm_device_t *DRM(device); +static int *DRM(minor); +static int DRM(numdevs) = 0; static struct file_operations DRM(fops) = { #if LINUX_VERSION_CODE >= 0x020400 @@ -460,46 +467,102 @@ static int DRM(takedown)( drm_device_t *dev ) return 0; } +/* + * Figure out how many instances to initialize. + */ +static int drm_count_cards(void) +{ + int num = 0; +#if defined(DRIVER_CARD_LIST) + u_int *l; + u_int device, vendor; + struct pci_dev *pdev = NULL; +#endif + + DRM_DEBUG( "\n" ); + +#if defined(DRIVER_COUNT_CARDS) + num = DRIVER_COUNT_CARDS(); +#elif defined(DRIVER_CARD_LIST) + for (l = DRIVER_CARD_LIST; *l; l++) { + pdev = NULL; + device = *l & 0xFFFF; + if (device == 0xFFFF) + device = PCI_ANY_ID; + vendor = (*l >> 16) & 0xFFFF; + if (vendor == 0xFFFF) + vendor = PCI_ANY_ID; + while ((pdev = pci_find_device(vendor, device, pdev))) { + num++; + } + } +#else + num = DRIVER_NUM_CARDS; +#endif + DRM_DEBUG("numdevs = %d\n", num); + return num; +} + /* drm_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ static int __init drm_init( void ) { - drm_device_t *dev = &DRM(device); + + drm_device_t *dev; + int i; #if __HAVE_CTX_BITMAP int retcode; #endif DRM_DEBUG( "\n" ); - memset( (void *)dev, 0, sizeof(*dev) ); - dev->count_lock = SPIN_LOCK_UNLOCKED; - sema_init( &dev->struct_sem, 1 ); - #ifdef MODULE DRM(parse_options)( drm_opts ); #endif + + DRM(numdevs) = drm_count_cards(); + /* Force at least one instance. */ + if (DRM(numdevs) <= 0) + DRM(numdevs) = 1; + + DRM(device) = kmalloc(sizeof(*DRM(device)) * DRM(numdevs), GFP_KERNEL); + if (!DRM(device)) { + return -ENOMEM; + } + DRM(minor) = kmalloc(sizeof(*DRM(minor)) * DRM(numdevs), GFP_KERNEL); + if (!DRM(minor)) { + kfree(DRM(device)); + return -ENOMEM; + } + DRIVER_PREINIT(); DRM(mem_init)(); - if ((DRM(minor) = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0) - return -EPERM; - dev->device = MKDEV(DRM_MAJOR, DRM(minor) ); - dev->name = DRIVER_NAME; + for (i = 0; i < DRM(numdevs); i++) { + dev = &(DRM(device)[i]); + memset( (void *)dev, 0, sizeof(*dev) ); + dev->count_lock = SPIN_LOCK_UNLOCKED; + sema_init( &dev->struct_sem, 1 ); + + if ((DRM(minor)[i] = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0) + return -EPERM; + dev->device = MKDEV(DRM_MAJOR, DRM(minor)[i] ); + dev->name = DRIVER_NAME; #if __REALLY_HAVE_AGP - dev->agp = DRM(agp_init)(); + dev->agp = DRM(agp_init)(); #if __MUST_HAVE_AGP - if ( dev->agp == NULL ) { - DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(stub_unregister)(DRM(minor)); - DRM(takedown)( dev ); - return -ENOMEM; - } + if ( dev->agp == NULL ) { + DRM_ERROR( "Cannot initialize the agpgart module.\n" ); + DRM(stub_unregister)(DRM(minor)[i]); + DRM(takedown)( dev ); + return -ENOMEM; + } #endif #if __REALLY_HAVE_MTRR - if (dev->agp) - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, + if (dev->agp) + dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size*1024*1024, MTRR_TYPE_WRCOMB, 1 ); @@ -507,25 +570,25 @@ static int __init drm_init( void ) #endif #if __HAVE_CTX_BITMAP - retcode = DRM(ctxbitmap_init)( dev ); - if( retcode ) { - DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(stub_unregister)(DRM(minor)); - DRM(takedown)( dev ); - return retcode; - } + retcode = DRM(ctxbitmap_init)( dev ); + if( retcode ) { + DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); + DRM(stub_unregister)(DRM(minor)[i]); + DRM(takedown)( dev ); + return retcode; + } #endif + DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, + DRM(minor)[i] ); + } DRIVER_POSTINIT(); - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - DRM(minor) ); - return 0; } @@ -533,38 +596,48 @@ static int __init drm_init( void ) */ static void __exit drm_cleanup( void ) { - drm_device_t *dev = &DRM(device); + drm_device_t *dev; + int i; DRM_DEBUG( "\n" ); - if ( DRM(stub_unregister)(DRM(minor)) ) { - DRM_ERROR( "Cannot unload module\n" ); - } else { - DRM_INFO( "Module unloaded\n" ); - } + for (i = DRM(numdevs) - 1; i >= 0; i--) { + dev = &(DRM(device)[i]); + if ( DRM(stub_unregister)(DRM(minor)[i]) ) { + DRM_ERROR( "Cannot unload module\n" ); + } else { + DRM_DEBUG("minor %d unregistered\n", DRM(minor)[i]); + if (i == 0) { + DRM_INFO( "Module unloaded\n" ); + } + } #if __HAVE_CTX_BITMAP - DRM(ctxbitmap_cleanup)( dev ); + DRM(ctxbitmap_cleanup)( dev ); #endif #if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR - if ( dev->agp && dev->agp->agp_mtrr ) { - int retval; - retval = mtrr_del( dev->agp->agp_mtrr, + if ( dev->agp && dev->agp->agp_mtrr ) { + int retval; + retval = mtrr_del( dev->agp->agp_mtrr, dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size*1024*1024 ); - DRM_DEBUG( "mtrr_del=%d\n", retval ); - } + DRM_DEBUG( "mtrr_del=%d\n", retval ); + } #endif - DRM(takedown)( dev ); + DRM(takedown)( dev ); #if __REALLY_HAVE_AGP - if ( dev->agp ) { - DRM(agp_uninit)(); - DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); - dev->agp = NULL; - } + if ( dev->agp ) { + DRM(agp_uninit)(); + DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); + dev->agp = NULL; + } #endif + } + kfree(DRM(minor)); + kfree(DRM(device)); + DRM(numdevs) = 0; } module_init( drm_init ); @@ -608,8 +681,19 @@ int DRM(version)( struct inode *inode, struct file *filp, int DRM(open)( struct inode *inode, struct file *filp ) { - drm_device_t *dev = &DRM(device); + drm_device_t *dev = NULL; int retcode = 0; + int i; + + for (i = 0; i < DRM(numdevs); i++) { + if (MINOR(inode->i_rdev) == DRM(minor)[i]) { + dev = &(DRM(device)[i]); + break; + } + } + if (!dev) { + return -ENODEV; + } DRM_DEBUG( "open_count = %d\n", dev->open_count ); diff --git a/linux-core/drm_init.c b/linux-core/drm_init.c index d9d8e3a23..2d6b6a3c9 100644 --- a/linux-core/drm_init.c +++ b/linux-core/drm_init.c @@ -64,18 +64,18 @@ static void DRM(parse_option)(char *s) return; } -/* drm_parse_options parse the insmod "drm=" options, or the command-line +/* drm_parse_options parse the insmod "drm_opts=" options, or the command-line * options passed to the kernel via LILO. The grammar of the format is as * follows: * - * drm ::= 'drm=' option_list + * drm ::= 'drm_opts=' option_list * option_list ::= option [ ';' option_list ] * option ::= 'device:' major * | 'debug' * | 'noctx' * major ::= INTEGER * - * Note that 's' contains option_list without the 'drm=' part. + * Note that 's' contains option_list without the 'drm_opts=' part. * * device=major,minor specifies the device number used for /dev/drm * if major == 0 then the misc device is used diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index bc9587963..6811d6ba0 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -121,11 +121,13 @@ static int DRM(stub_putminor)(int minor) return 0; } + int DRM(stub_register)(const char *name, struct file_operations *fops, drm_device_t *dev) { struct drm_stub_info *i = NULL; - + + DRM_DEBUG("\n"); if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) i = (struct drm_stub_info *)inter_module_get("drm"); @@ -133,9 +135,11 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, /* Already registered */ DRM(stub_info).info_register = i->info_register; DRM(stub_info).info_unregister = i->info_unregister; - } else { + DRM_DEBUG("already registered\n"); + } else if (DRM(stub_info).info_register != DRM(stub_getminor)) { DRM(stub_info).info_register = DRM(stub_getminor); DRM(stub_info).info_unregister = DRM(stub_putminor); + DRM_DEBUG("calling inter_module_register\n"); inter_module_register("drm", THIS_MODULE, &DRM(stub_info)); } if (DRM(stub_info).info_register) diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c index b6c95498a..94e5d41c5 100644 --- a/linux-core/tdfx_drv.c +++ b/linux-core/tdfx_drv.c @@ -44,6 +44,15 @@ #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 +static u_int DRM(idlist)[] = { + 0x121A0003, /* Banshee */ + 0x121A0005, /* Voodoo3 */ + 0x121A0009, /* Voodoo5 */ + 0 +}; + +#define DRIVER_CARD_LIST DRM(idlist) + #include "drm_auth.h" #include "drm_bufs.h" diff --git a/linux/drm_drv.h b/linux/drm_drv.h index c5f231c71..dd46f227e 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -101,9 +101,16 @@ #define DRIVER_IOCTLS #endif +/* + * The default number of instances (minor numbers) to initialize. + */ +#ifndef DRIVER_NUM_CARDS +#define DRIVER_NUM_CARDS 1 +#endif -static drm_device_t DRM(device); -static int DRM(minor); +static drm_device_t *DRM(device); +static int *DRM(minor); +static int DRM(numdevs) = 0; static struct file_operations DRM(fops) = { #if LINUX_VERSION_CODE >= 0x020400 @@ -460,46 +467,102 @@ static int DRM(takedown)( drm_device_t *dev ) return 0; } +/* + * Figure out how many instances to initialize. + */ +static int drm_count_cards(void) +{ + int num = 0; +#if defined(DRIVER_CARD_LIST) + u_int *l; + u_int device, vendor; + struct pci_dev *pdev = NULL; +#endif + + DRM_DEBUG( "\n" ); + +#if defined(DRIVER_COUNT_CARDS) + num = DRIVER_COUNT_CARDS(); +#elif defined(DRIVER_CARD_LIST) + for (l = DRIVER_CARD_LIST; *l; l++) { + pdev = NULL; + device = *l & 0xFFFF; + if (device == 0xFFFF) + device = PCI_ANY_ID; + vendor = (*l >> 16) & 0xFFFF; + if (vendor == 0xFFFF) + vendor = PCI_ANY_ID; + while ((pdev = pci_find_device(vendor, device, pdev))) { + num++; + } + } +#else + num = DRIVER_NUM_CARDS; +#endif + DRM_DEBUG("numdevs = %d\n", num); + return num; +} + /* drm_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ static int __init drm_init( void ) { - drm_device_t *dev = &DRM(device); + + drm_device_t *dev; + int i; #if __HAVE_CTX_BITMAP int retcode; #endif DRM_DEBUG( "\n" ); - memset( (void *)dev, 0, sizeof(*dev) ); - dev->count_lock = SPIN_LOCK_UNLOCKED; - sema_init( &dev->struct_sem, 1 ); - #ifdef MODULE DRM(parse_options)( drm_opts ); #endif + + DRM(numdevs) = drm_count_cards(); + /* Force at least one instance. */ + if (DRM(numdevs) <= 0) + DRM(numdevs) = 1; + + DRM(device) = kmalloc(sizeof(*DRM(device)) * DRM(numdevs), GFP_KERNEL); + if (!DRM(device)) { + return -ENOMEM; + } + DRM(minor) = kmalloc(sizeof(*DRM(minor)) * DRM(numdevs), GFP_KERNEL); + if (!DRM(minor)) { + kfree(DRM(device)); + return -ENOMEM; + } + DRIVER_PREINIT(); DRM(mem_init)(); - if ((DRM(minor) = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0) - return -EPERM; - dev->device = MKDEV(DRM_MAJOR, DRM(minor) ); - dev->name = DRIVER_NAME; + for (i = 0; i < DRM(numdevs); i++) { + dev = &(DRM(device)[i]); + memset( (void *)dev, 0, sizeof(*dev) ); + dev->count_lock = SPIN_LOCK_UNLOCKED; + sema_init( &dev->struct_sem, 1 ); + + if ((DRM(minor)[i] = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0) + return -EPERM; + dev->device = MKDEV(DRM_MAJOR, DRM(minor)[i] ); + dev->name = DRIVER_NAME; #if __REALLY_HAVE_AGP - dev->agp = DRM(agp_init)(); + dev->agp = DRM(agp_init)(); #if __MUST_HAVE_AGP - if ( dev->agp == NULL ) { - DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(stub_unregister)(DRM(minor)); - DRM(takedown)( dev ); - return -ENOMEM; - } + if ( dev->agp == NULL ) { + DRM_ERROR( "Cannot initialize the agpgart module.\n" ); + DRM(stub_unregister)(DRM(minor)[i]); + DRM(takedown)( dev ); + return -ENOMEM; + } #endif #if __REALLY_HAVE_MTRR - if (dev->agp) - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, + if (dev->agp) + dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size*1024*1024, MTRR_TYPE_WRCOMB, 1 ); @@ -507,25 +570,25 @@ static int __init drm_init( void ) #endif #if __HAVE_CTX_BITMAP - retcode = DRM(ctxbitmap_init)( dev ); - if( retcode ) { - DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(stub_unregister)(DRM(minor)); - DRM(takedown)( dev ); - return retcode; - } + retcode = DRM(ctxbitmap_init)( dev ); + if( retcode ) { + DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); + DRM(stub_unregister)(DRM(minor)[i]); + DRM(takedown)( dev ); + return retcode; + } #endif + DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, + DRM(minor)[i] ); + } DRIVER_POSTINIT(); - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - DRM(minor) ); - return 0; } @@ -533,38 +596,48 @@ static int __init drm_init( void ) */ static void __exit drm_cleanup( void ) { - drm_device_t *dev = &DRM(device); + drm_device_t *dev; + int i; DRM_DEBUG( "\n" ); - if ( DRM(stub_unregister)(DRM(minor)) ) { - DRM_ERROR( "Cannot unload module\n" ); - } else { - DRM_INFO( "Module unloaded\n" ); - } + for (i = DRM(numdevs) - 1; i >= 0; i--) { + dev = &(DRM(device)[i]); + if ( DRM(stub_unregister)(DRM(minor)[i]) ) { + DRM_ERROR( "Cannot unload module\n" ); + } else { + DRM_DEBUG("minor %d unregistered\n", DRM(minor)[i]); + if (i == 0) { + DRM_INFO( "Module unloaded\n" ); + } + } #if __HAVE_CTX_BITMAP - DRM(ctxbitmap_cleanup)( dev ); + DRM(ctxbitmap_cleanup)( dev ); #endif #if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR - if ( dev->agp && dev->agp->agp_mtrr ) { - int retval; - retval = mtrr_del( dev->agp->agp_mtrr, + if ( dev->agp && dev->agp->agp_mtrr ) { + int retval; + retval = mtrr_del( dev->agp->agp_mtrr, dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size*1024*1024 ); - DRM_DEBUG( "mtrr_del=%d\n", retval ); - } + DRM_DEBUG( "mtrr_del=%d\n", retval ); + } #endif - DRM(takedown)( dev ); + DRM(takedown)( dev ); #if __REALLY_HAVE_AGP - if ( dev->agp ) { - DRM(agp_uninit)(); - DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); - dev->agp = NULL; - } + if ( dev->agp ) { + DRM(agp_uninit)(); + DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); + dev->agp = NULL; + } #endif + } + kfree(DRM(minor)); + kfree(DRM(device)); + DRM(numdevs) = 0; } module_init( drm_init ); @@ -608,8 +681,19 @@ int DRM(version)( struct inode *inode, struct file *filp, int DRM(open)( struct inode *inode, struct file *filp ) { - drm_device_t *dev = &DRM(device); + drm_device_t *dev = NULL; int retcode = 0; + int i; + + for (i = 0; i < DRM(numdevs); i++) { + if (MINOR(inode->i_rdev) == DRM(minor)[i]) { + dev = &(DRM(device)[i]); + break; + } + } + if (!dev) { + return -ENODEV; + } DRM_DEBUG( "open_count = %d\n", dev->open_count ); diff --git a/linux/drm_init.h b/linux/drm_init.h index d9d8e3a23..2d6b6a3c9 100644 --- a/linux/drm_init.h +++ b/linux/drm_init.h @@ -64,18 +64,18 @@ static void DRM(parse_option)(char *s) return; } -/* drm_parse_options parse the insmod "drm=" options, or the command-line +/* drm_parse_options parse the insmod "drm_opts=" options, or the command-line * options passed to the kernel via LILO. The grammar of the format is as * follows: * - * drm ::= 'drm=' option_list + * drm ::= 'drm_opts=' option_list * option_list ::= option [ ';' option_list ] * option ::= 'device:' major * | 'debug' * | 'noctx' * major ::= INTEGER * - * Note that 's' contains option_list without the 'drm=' part. + * Note that 's' contains option_list without the 'drm_opts=' part. * * device=major,minor specifies the device number used for /dev/drm * if major == 0 then the misc device is used diff --git a/linux/drm_stub.h b/linux/drm_stub.h index bc9587963..6811d6ba0 100644 --- a/linux/drm_stub.h +++ b/linux/drm_stub.h @@ -121,11 +121,13 @@ static int DRM(stub_putminor)(int minor) return 0; } + int DRM(stub_register)(const char *name, struct file_operations *fops, drm_device_t *dev) { struct drm_stub_info *i = NULL; - + + DRM_DEBUG("\n"); if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) i = (struct drm_stub_info *)inter_module_get("drm"); @@ -133,9 +135,11 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, /* Already registered */ DRM(stub_info).info_register = i->info_register; DRM(stub_info).info_unregister = i->info_unregister; - } else { + DRM_DEBUG("already registered\n"); + } else if (DRM(stub_info).info_register != DRM(stub_getminor)) { DRM(stub_info).info_register = DRM(stub_getminor); DRM(stub_info).info_unregister = DRM(stub_putminor); + DRM_DEBUG("calling inter_module_register\n"); inter_module_register("drm", THIS_MODULE, &DRM(stub_info)); } if (DRM(stub_info).info_register) diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c index b6c95498a..94e5d41c5 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -44,6 +44,15 @@ #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 +static u_int DRM(idlist)[] = { + 0x121A0003, /* Banshee */ + 0x121A0005, /* Voodoo3 */ + 0x121A0009, /* Voodoo5 */ + 0 +}; + +#define DRIVER_CARD_LIST DRM(idlist) + #include "drm_auth.h" #include "drm_bufs.h" -- cgit v1.2.3