//---------------------------------------------------------------- // engine2d.c // // This character-mode Linux device-driver supports mapping // of the SiS 2D graphics engine registers into user space. // // NOTE: Written and tested w/ Linux kernel version 2.4.21. // // programmer: ALLAN CRUSE // written on: 01 NOV 2003 //---------------------------------------------------------------- #define __KERNEL__ #define MODULE #include // for init_module() #include // for pci_find_device() #define VGA_CLASS 0x030000 #define VENDOR_ID 0x1039 #define SUCCESS 0 static char modname[] = "engine2d"; static int my_major = 101; static unsigned long mm_base; static unsigned long mm_size; static struct pci_dev *devp = NULL; static int my_mmap( struct file *file, struct vm_area_struct *vma ) { unsigned long region_length = vma->vm_end - vma->vm_start; unsigned long region_origin = vma->vm_pgoff * PAGE_SIZE; unsigned long phys_address = mm_base + region_origin; unsigned long virt_address = vma->vm_start; // sanity check: mapped region cannot extend beyond device if ( region_origin + region_length > mm_size ) return -EINVAL; // let the kernel know not to try swapping out this region vma->vm_flags |= VM_RESERVED; // tell the kernel to exclude this region from core dumps vma->vm_flags |= VM_IO; if ( io_remap_page_range( virt_address, phys_address, region_length, vma->vm_page_prot ) ) return -EAGAIN; return SUCCESS; } static struct file_operations my_fops = { owner: THIS_MODULE, mmap: my_mmap, }; int init_module( void ) { printk( "<1>\nInstalling \'%s\' module ", modname ); printk( "(major=%d) \n", my_major ); devp = pci_find_class( VGA_CLASS, devp ); if ( !devp ) return -ENODEV; mm_base = pci_resource_start( devp, 1 ); mm_size = pci_resource_len( devp, 1 ); printk( "<1> %s \n", devp->name ); printk( " vendor=%04X device=%04X \n", devp->vendor, devp->device ); printk( " base=%08X size=%08X \n", mm_base, mm_size ); if ( devp->vendor != VENDOR_ID ) return -ENODEV; return register_chrdev( my_major, modname, &my_fops ); } void cleanup_module( void ) { unregister_chrdev( my_major, modname ); printk( "<1>Removing \'%s\' module\n", modname ); } MODULE_LICENSE( "GPL" );