drm_drv.h

来自「优龙2410linux2.6.8内核源代码」· C头文件 代码 · 共 1,210 行 · 第 1/3 页

H
1,210
字号
	del_timer( &dev->timer );	if ( dev->devname ) {		DRM(free)( dev->devname, strlen( dev->devname ) + 1,			   DRM_MEM_DRIVER );		dev->devname = NULL;	}	if ( dev->unique ) {		DRM(free)( dev->unique, strlen( dev->unique ) + 1,			   DRM_MEM_DRIVER );		dev->unique = NULL;		dev->unique_len = 0;	}				/* Clear pid list */	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {		for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {			next = pt->next;			DRM(free)( pt, sizeof(*pt), DRM_MEM_MAGIC );		}		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;	}#if __REALLY_HAVE_AGP				/* Clear AGP information */	if ( dev->agp ) {		drm_agp_mem_t *entry;		drm_agp_mem_t *nexte;				/* Remove AGP resources, but leave dev->agp                                   intact until drv_cleanup is called. */		for ( entry = dev->agp->memory ; entry ; entry = nexte ) {			nexte = entry->next;			if ( entry->bound ) DRM(unbind_agp)( entry->memory );			DRM(free_agp)( entry->memory, entry->pages );			DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS );		}		dev->agp->memory = NULL;		if ( dev->agp->acquired ) DRM(agp_do_release)();		dev->agp->acquired = 0;		dev->agp->enabled  = 0;	}#endif				/* Clear vma list (only built for debugging) */	if ( dev->vmalist ) {		for ( vma = dev->vmalist ; vma ; vma = vma_next ) {			vma_next = vma->next;			DRM(free)( vma, sizeof(*vma), DRM_MEM_VMAS );		}		dev->vmalist = NULL;	}	if( dev->maplist ) {		list_for_each_safe( list, list_next, &dev->maplist->head ) {			r_list = (drm_map_list_t *)list;			if ( ( map = r_list->map ) ) {				switch ( map->type ) {				case _DRM_REGISTERS:				case _DRM_FRAME_BUFFER:#if __REALLY_HAVE_MTRR					if ( map->mtrr >= 0 ) {						int retcode;						retcode = mtrr_del( map->mtrr,								    map->offset,								    map->size );						DRM_DEBUG( "mtrr_del=%d\n", retcode );					}#endif					DRM(ioremapfree)( map->handle, map->size, dev );					break;				case _DRM_SHM:					vfree(map->handle);					break;				case _DRM_AGP:					/* Do nothing here, because this is all					 * handled in the AGP/GART driver.					 */					break;				case _DRM_SCATTER_GATHER:					/* Handle it, but do nothing, if HAVE_SG					 * isn't defined.					 */#if __HAVE_SG					if(dev->sg) {						DRM(sg_cleanup)(dev->sg);						dev->sg = NULL;					}#endif					break;				}				DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);			}			list_del( list );			DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS); 		}		DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);		dev->maplist = NULL; 	}#if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES	if ( dev->queuelist ) {		for ( i = 0 ; i < dev->queue_count ; i++ ) {#if __HAVE_DMA_WAITLIST			DRM(waitlist_destroy)( &dev->queuelist[i]->waitlist );#endif			if ( dev->queuelist[i] ) {				DRM(free)( dev->queuelist[i],					  sizeof(*dev->queuelist[0]),					  DRM_MEM_QUEUES );				dev->queuelist[i] = NULL;			}		}		DRM(free)( dev->queuelist,			  dev->queue_slots * sizeof(*dev->queuelist),			  DRM_MEM_QUEUES );		dev->queuelist = NULL;	}	dev->queue_count = 0;#endif#if __HAVE_DMA	DRM(dma_takedown)( dev );#endif	if ( dev->lock.hw_lock ) {		dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */		dev->lock.filp = NULL;		wake_up_interruptible( &dev->lock.lock_queue );	}	up( &dev->struct_sem );	return 0;}#include "drm_pciids.h"static struct pci_device_id DRM(pciidlist)[] = {	DRM(PCI_IDS)};static int DRM(probe)(struct pci_dev *pdev){	drm_device_t *dev;#if __HAVE_CTX_BITMAP	int retcode;#endif	int i;	int is_compat = 0;	DRM_DEBUG( "\n" );	for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) {		if ((DRM(pciidlist)[i].vendor == pdev->vendor) &&		    (DRM(pciidlist)[i].device == pdev->device)) {			is_compat = 1;		}	}	if (is_compat == 0)		return -ENODEV;	if (DRM(numdevs) >= MAX_DEVICES)		return -ENODEV;	dev = &(DRM(device)[DRM(numdevs)]);	memset( (void *)dev, 0, sizeof(*dev) );	dev->count_lock = SPIN_LOCK_UNLOCKED;	init_timer( &dev->timer );	sema_init( &dev->struct_sem, 1 );	sema_init( &dev->ctxlist_sem, 1 );	if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)		return -EPERM;	dev->device = MKDEV(DRM_MAJOR, dev->minor );	dev->name   = DRIVER_NAME;	dev->pdev   = pdev;#ifdef __alpha__	dev->hose   = pdev->sysdata;	dev->pci_domain = dev->hose->bus->number;#else	dev->pci_domain = 0;#endif	dev->pci_bus = pdev->bus->number;	dev->pci_slot = PCI_SLOT(pdev->devfn);	dev->pci_func = PCI_FUNC(pdev->devfn);	dev->irq = pdev->irq;	DRIVER_PREINIT();#if __REALLY_HAVE_AGP	dev->agp = DRM(agp_init)();#if __MUST_HAVE_AGP	if ( dev->agp == NULL ) {		DRM_ERROR( "Cannot initialize the agpgart module.\n" );		DRM(stub_unregister)(dev->minor);		DRM(takedown)( dev );		return -EINVAL;	}#endif#if __REALLY_HAVE_MTRR	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 );#endif#endif#if __HAVE_CTX_BITMAP	retcode = DRM(ctxbitmap_init)( dev );	if( retcode ) {		DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );		DRM(stub_unregister)(dev->minor);		DRM(takedown)( dev );		return retcode; 	}#endif	DRM(numdevs)++; /* no errors, mark it reserved */		DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",		DRIVER_NAME,		DRIVER_MAJOR,		DRIVER_MINOR,		DRIVER_PATCHLEVEL,		DRIVER_DATE,		dev->minor,		pci_pretty_name(pdev));	DRIVER_POSTINIT();	return 0;}/** * Module initialization. Called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). * * \return zero on success or a negative number on failure. * * Initializes an array of drm_device structures, and attempts to * initialize all available devices, using consecutive minors, registering the * stubs and initializing the AGP device. *  * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and * after the initialization for driver customization. */static int __init drm_init( void ){	struct pci_dev *pdev = NULL;	DRM_DEBUG( "\n" );#ifdef MODULE	DRM(parse_options)( drm_opts );#endif	DRM(mem_init)();	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {		DRM(probe)(pdev);	}	return 0;}/** * Called via cleanup_module() at module unload time. * * Cleans up all DRM device, calling takedown(). *  * \sa drm_init(). */static void __exit drm_cleanup( void ){	drm_device_t *dev;	int i;	DRM_DEBUG( "\n" );	for (i = DRM(numdevs) - 1; i >= 0; i--) {		dev = &(DRM(device)[i]);		if ( DRM(stub_unregister)(dev->minor) ) {			DRM_ERROR( "Cannot unload module\n" );		} else {			DRM_DEBUG("minor %d unregistered\n", dev->minor);			if (i == 0) {				DRM_INFO( "Module unloaded\n" );			}		}#if __HAVE_CTX_BITMAP		DRM(ctxbitmap_cleanup)( dev );#endif#if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR		if ( dev->agp && dev->agp->agp_mtrr >= 0) {			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 );		}#endif		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;		}#endif	}	DRIVER_POSTCLEANUP();	DRM(numdevs) = 0;}module_init( drm_init );module_exit( drm_cleanup );/** * Get version information * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg user argument, pointing to a drm_version structure. * \return zero on success or negative number on failure. * * Fills in the version information in \p arg. */int DRM(version)( struct inode *inode, struct file *filp,		  unsigned int cmd, unsigned long arg ){	drm_version_t __user *argp = (void __user *)arg;	drm_version_t version;	int len;	if ( copy_from_user( &version, argp, sizeof(version) ) )		return -EFAULT;#define DRM_COPY( name, value )						\	len = strlen( value );						\	if ( len > name##_len ) len = name##_len;			\	name##_len = strlen( value );					\	if ( len && name ) {						\		if ( copy_to_user( name, value, len ) )			\			return -EFAULT;					\	}	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 );	if ( copy_to_user( argp, &version, sizeof(version) ) )		return -EFAULT;	return 0;}/** * Open file. *  * \param inode device inode * \param filp file pointer. * \return zero on success or a negative number on failure. * * Searches the DRM device with the same minor number, calls open_helper(), and * increments the device open count. If the open count was previous at zero, * i.e., it's the first that the device is open, then calls setup(). */int DRM(open)( struct inode *inode, struct file *filp ){	drm_device_t *dev = NULL;	int retcode = 0;	int i;	for (i = 0; i < DRM(numdevs); i++) {		if (iminor(inode) == DRM(device)[i].minor) {			dev = &(DRM(device)[i]);			break;		}	}	if (!dev) {		return -ENODEV;	}	retcode = DRM(open_helper)( inode, filp, dev );	if ( !retcode ) {		atomic_inc( &dev->counts[_DRM_STAT_OPENS] );		spin_lock( &dev->count_lock );		if ( !dev->open_count++ ) {			spin_unlock( &dev->count_lock );			return DRM(setup)( dev );		}		spin_unlock( &dev->count_lock );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?