--- build_mod.orig/firegl_public.c 2005-11-02 20:29:43.535048712 -0800 +++ build_mod/firegl_public.c 2005-11-02 20:27:19.013019400 -0800 @@ -122,7 +122,6 @@ #ifdef __x86_64__ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) -#include "linux/ioctl32.h" #else #include "asm/ioctl32.h" #endif @@ -191,6 +190,16 @@ _syscall3( int, modify_ldt, int, func, v // ============================================================ /* globals */ +int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file*)); +long realHandler_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +void unregister_ioctl32_conversion(unsigned int cmd); +struct HandlerList { + unsigned int cmd; + void *handler; + struct HandlerList *next; +}; +struct HandlerList *HandlerListHead = 0x0; + char* firegl = NULL; int __ke_debuglevel = 0; int __ke_moduleflags = 0; @@ -258,6 +267,7 @@ static struct file_operations firegl_fop open: ip_firegl_open, release: ip_firegl_release, ioctl: ip_firegl_ioctl, + compat_ioctl: realHandler_compat_ioctl, mmap: ip_firegl_mmap, }; @@ -2220,10 +2230,68 @@ int ATI_API_CALL __ke_register_ioctl32_c return register_ioctl32_conversion(cmd, handler); } + + int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file*)) + { + sizeof(struct HandlerList); + struct HandlerList *newHandler = kmalloc(sizeof(struct HandlerList), 0); + newHandler->cmd = cmd; + newHandler->handler = handler; + newHandler->next = HandlerListHead; + HandlerListHead = newHandler; + return 0; + } + + long realHandler_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + { + int fd; + int (*handler)(unsigned int, unsigned int, unsigned long, struct file*); + struct fdtable *fdt; + struct HandlerList *HandlerEntry = HandlerListHead; + + while(HandlerEntry->cmd != cmd){ + if(HandlerEntry->next == 0x0){ + return -1; + } + HandlerEntry = HandlerEntry->next; + } + handler = HandlerEntry->handler; + fdt = files_fdtable(current->files); + for(fd=0;fdmax_fds;fd++){ + if(fdt->fd[fd] == filp){ + return handler(fd, cmd, arg, filp); + } + } + return -1; +} + + + void ATI_API_CALL __ke_unregister_ioctl32_conversion(unsigned int cmd) { unregister_ioctl32_conversion(cmd); } + + void unregister_ioctl32_conversion(unsigned int cmd) + { + struct HandlerList *ahead, *behind; + if(HandlerListHead == 0x0) return; + behind = HandlerListHead; + ahead = HandlerListHead->next; + if(behind->cmd == cmd){ + HandlerListHead = ahead; + kfree(behind); + return; + } + while(ahead->cmd != cmd){ + behind = ahead; + ahead = ahead->next; + } + behind->next = ahead->next; + kfree(ahead); + return; + } + #endif /* agp_memory related routine for IGP */