--- firegl_public.c.orig 2005-11-10 18:04:24.000000000 +0100 +++ firegl_public.c 2005-11-25 22:13:34.000000000 +0100 @@ -123,7 +123,9 @@ #ifdef __x86_64__ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) #include "linux/ioctl32.h" +#endif #else #include "asm/ioctl32.h" #endif @@ -192,6 +194,18 @@ // ============================================================ /* globals */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) +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; +#endif + char* firegl = NULL; int __ke_debuglevel = 0; int __ke_moduleflags = 0; @@ -259,6 +273,9 @@ open: ip_firegl_open, release: ip_firegl_release, ioctl: ip_firegl_ioctl, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) + compat_ioctl: realHandler_compat_ioctl, +#endif mmap: ip_firegl_mmap, }; @@ -2365,10 +2382,69 @@ return register_ioctl32_conversion(cmd, handler); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) + 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; +} +#endif + void ATI_API_CALL __ke_unregister_ioctl32_conversion(unsigned int cmd) { unregister_ioctl32_conversion(cmd); } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) + 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 + #endif /* agp_memory related routine for IGP */