diff options
| author | Jeff Hartmann <jhartmann@valinux.com> | 2000-08-07 16:55:10 +0000 | 
|---|---|---|
| committer | Jeff Hartmann <jhartmann@valinux.com> | 2000-08-07 16:55:10 +0000 | 
| commit | 9199075a6a975ebcc44aff53fe0f77080c01a30b (patch) | |
| tree | 8d751731b648043da816d48cce133b2964849fce /linux | |
| parent | f3ae6786f89a4f63dbba93c5519d3792a1744dd7 (diff) | |
Fix for multiple sarea bug + agp built into kernel segfault
Diffstat (limited to 'linux')
| -rw-r--r-- | linux/agpsupport.c | 47 | ||||
| -rw-r--r-- | linux/drmP.h | 6 | ||||
| -rw-r--r-- | linux/vm.c | 52 | 
3 files changed, 89 insertions, 16 deletions
| diff --git a/linux/agpsupport.c b/linux/agpsupport.c index 48a6aa5f..7ed234e1 100644 --- a/linux/agpsupport.c +++ b/linux/agpsupport.c @@ -287,23 +287,40 @@ drm_agp_head_t *drm_agp_init(void)  			return NULL;  		memset((void *)head, 0, sizeof(*head));  		(*drm_agp.copy_info)(&head->agp_info); +		if (head->agp_info.chipset == NOT_SUPPORTED) { +			drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); +			return NULL; +		}  		head->memory = NULL;  		switch (head->agp_info.chipset) { -		case INTEL_GENERIC:  head->chipset = "Intel";          break; -		case INTEL_LX:       head->chipset = "Intel 440LX";    break; -		case INTEL_BX:       head->chipset = "Intel 440BX";    break; -		case INTEL_GX:       head->chipset = "Intel 440GX";    break; -		case INTEL_I810:     head->chipset = "Intel i810";     break; -		case VIA_GENERIC:    head->chipset = "VIA";            break; -		case VIA_VP3:        head->chipset = "VIA VP3";        break; -		case VIA_MVP3:       head->chipset = "VIA MVP3";       break; -		case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break; -		case SIS_GENERIC:    head->chipset = "SiS";            break; -		case AMD_GENERIC:    head->chipset = "AMD";            break; -		case AMD_IRONGATE:   head->chipset = "AMD Irongate";   break; -		case ALI_GENERIC:    head->chipset = "ALi";            break; -		case ALI_M1541:      head->chipset = "ALi M1541";      break; -		default: +		case INTEL_GENERIC:	head->chipset = "Intel";         break; +		case INTEL_LX:		head->chipset = "Intel 440LX";   break; +		case INTEL_BX:		head->chipset = "Intel 440BX";   break; +		case INTEL_GX:		head->chipset = "Intel 440GX";   break; +		case INTEL_I810:	head->chipset = "Intel i810";    break; + +#if LINUX_VERSION_CODE >= 0x020400 +		case INTEL_I840:	head->chipset = "Intel i840";    break; +#endif + +		case VIA_GENERIC:	head->chipset = "VIA";           break; +		case VIA_VP3:		head->chipset = "VIA VP3";       break; +		case VIA_MVP3:		head->chipset = "VIA MVP3";      break; + +#if LINUX_VERSION_CODE >= 0x020400 +		case VIA_MVP4:		head->chipset = "VIA MVP4";      break; +		case VIA_APOLLO_SUPER:	head->chipset = "VIA Apollo Super";  +			break; +#endif + +		case VIA_APOLLO_PRO: 	head->chipset = "VIA Apollo Pro"; +			break; +		case SIS_GENERIC:	head->chipset = "SiS";           break; +		case AMD_GENERIC:	head->chipset = "AMD";           break; +		case AMD_IRONGATE:	head->chipset = "AMD Irongate";  break; +		case ALI_GENERIC:	head->chipset = "ALi";           break; +		case ALI_M1541: 	head->chipset = "ALi M1541";     break; +		default:		head->chipset = "Unknown";       break;  		}  		DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",  			 head->agp_info.version.major, diff --git a/linux/drmP.h b/linux/drmP.h index 3e5149c9..516e9b22 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -558,6 +558,9 @@ extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,  extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,  				       unsigned long address,  				       int write_access); +extern unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma, +					    unsigned long address, +					    int write_access);  extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,  				       unsigned long address,  				       int write_access); @@ -569,6 +572,9 @@ extern struct page *drm_vm_nopage(struct vm_area_struct *vma,  extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,  				      unsigned long address,  				      int write_access); +extern struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma, +					   unsigned long address, +					   int write_access);  extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,  				      unsigned long address,  				      int write_access); @@ -44,6 +44,12 @@ struct vm_operations_struct   drm_vm_shm_ops = {  	close:	 drm_vm_close,  }; +struct vm_operations_struct   drm_vm_shm_lock_ops = { +	nopage:	 drm_vm_shm_nopage_lock, +	open:	 drm_vm_open, +	close:	 drm_vm_close, +}; +  struct vm_operations_struct   drm_vm_dma_ops = {  	nopage:	 drm_vm_dma_nopage,  	open:	 drm_vm_open, @@ -77,6 +83,40 @@ struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,  			       int write_access)  #endif  { +#if LINUX_VERSION_CODE >= 0x020300 +	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data; +#else +	drm_map_t	 *map	 = (drm_map_t *)vma->vm_pte; +#endif +	unsigned long	 physical; +	unsigned long	 offset; + +	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ +	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */ + +	offset	 = address - vma->vm_start; +	physical = (unsigned long)map->handle + offset; +	atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */ + +	DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical); +#if LINUX_VERSION_CODE < 0x020317 +	return physical; +#else +	return mem_map + MAP_NR(physical); +#endif +} + +#if LINUX_VERSION_CODE < 0x020317 +unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma, +				     unsigned long address, +				     int write_access) +#else +				/* Return type changed in 2.3.23 */ +struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma, +				    unsigned long address, +				    int write_access) +#endif +{  	drm_file_t	 *priv	 = vma->vm_file->private_data;  	drm_device_t	 *dev	 = priv->dev;  	unsigned long	 physical; @@ -298,7 +338,17 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)  		vma->vm_ops = &drm_vm_ops;  		break;  	case _DRM_SHM: -		vma->vm_ops = &drm_vm_shm_ops; +		if (map->flags & _DRM_CONTAINS_LOCK) +			vma->vm_ops = &drm_vm_shm_lock_ops; +		else { +			vma->vm_ops = &drm_vm_shm_ops; +#if LINUX_VERSION_CODE >= 0x020300 +			vma->vm_private_data = (void *)map; +#else +			vma->vm_pte = (unsigned long)map; +#endif +		} +  				/* Don't let this area swap.  Change when  				   DRM_KERNEL advisory is supported. */  		vma->vm_flags |= VM_LOCKED; | 
