diff -Nur common/lib/modules/fglrx/build_mod/drmP.h common-r1/lib/modules/fglrx/build_mod/drmP.h --- common/lib/modules/fglrx/build_mod/drmP.h 2013-05-15 09:26:23.555752577 +0300 +++ common-r1/lib/modules/fglrx/build_mod/drmP.h 2013-05-16 10:39:17.496212055 +0300 @@ -901,10 +901,6 @@ int DRM(stub_unregister)(int minor); /* Proc support (drm_proc.h) */ -extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, - int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root); extern int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root, struct proc_dir_entry *dev_root); diff -Nur common/lib/modules/fglrx/build_mod/drm_proc.h common-r1/lib/modules/fglrx/build_mod/drm_proc.h --- common/lib/modules/fglrx/build_mod/drm_proc.h 2013-05-15 09:26:23.555752577 +0300 +++ common-r1/lib/modules/fglrx/build_mod/drm_proc.h 2013-05-19 02:16:16.584406160 +0300 @@ -75,61 +75,6 @@ #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0])) /** - * Initialize the DRI proc filesystem for a device. - * - * \param dev DRM device. - * \param minor device minor number. - * \param root DRI proc dir entry. - * \param dev_root resulting DRI device proc dir entry. - * \return root entry pointer on success, or NULL on failure. - * - * Create the DRI proc root entry "/proc/ati", the device proc root entry - * "/proc/ati/%minor%/", and each entry in proc_list as - * "/proc/ati/%minor%/%name%". - */ -struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root) -{ - struct proc_dir_entry *ent; - int i, j; - char name[64]; - - if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL); - if (!root) { - DRM_ERROR("Cannot create /proc/ati\n"); - return NULL; - } - - sprintf(name, "%d", minor); - *dev_root = create_proc_entry(name, S_IFDIR, root); - if (!*dev_root) { - DRM_ERROR("Cannot create /proc/ati/%s\n", name); - return NULL; - } - - for (i = 0; i < DRM_PROC_ENTRIES; i++) { - ent = create_proc_entry(DRM(proc_list)[i].name, - S_IFREG|S_IRUGO, *dev_root); - if (!ent) { - DRM_ERROR("Cannot create /proc/ati/%s/%s\n", - name, DRM(proc_list)[i].name); - for (j = 0; j < i; j++) - remove_proc_entry(DRM(proc_list)[i].name, - *dev_root); - remove_proc_entry(name, root); - if (!minor) remove_proc_entry("dri", NULL); - return NULL; - } - ent->read_proc = DRM(proc_list)[i].f; - ent->data = dev; - } - - return root; -} - - -/** * Cleanup the proc filesystem resources. * * \param minor device minor number. diff -Nur common/lib/modules/fglrx/build_mod/firegl_public.c common-r1/lib/modules/fglrx/build_mod/firegl_public.c --- common/lib/modules/fglrx/build_mod/firegl_public.c 2013-05-15 09:26:23.545752925 +0300 +++ common-r1/lib/modules/fglrx/build_mod/firegl_public.c 2013-05-19 03:07:10.236552522 +0300 @@ -583,6 +583,202 @@ { "NULL", NULL, NULL} // Terminate List!!! }; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +typedef int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data); +typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data); +#else +#define PDE_DATA(inode) (PDE((inode))->data) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +typedef struct { + read_proc_t *read_func; + write_proc_t *write_func; + void *data; +} gentoo_proc_wrapper_t; + +#define GENTOO_PROC_WRAPPER_OVERFLOW_MAGIC 939750305 + +static ssize_t gentoo_proc_wrapper_read (struct file *myfile, char __user *buffer, size_t count, loff_t *offset) { + int is_eof=0, retval; + char *start, *usebuffer=NULL; + gentoo_proc_wrapper_t* wrapper_data=(gentoo_proc_wrapper_t*)(myfile->private_data); + if (PAGE_SIZE<*offset) { + printk(KERN_ERR "Trying to read beyond 4k on proc\n"); + return -EIO; + } + //printk(KERN_NOTICE " call with: dev %p, func %p\n", wrapper_data->data, wrapper_data->read_func); + + usebuffer=kmalloc(2*PAGE_SIZE, GFP_KERNEL); + if (!usebuffer) + return -ENOMEM; + ((u32*)usebuffer)[1024]=GENTOO_PROC_WRAPPER_OVERFLOW_MAGIC; + + retval=wrapper_data->read_func(usebuffer, &start, *offset, count, &is_eof, wrapper_data->data); + + BUG_ON(GENTOO_PROC_WRAPPER_OVERFLOW_MAGIC != ((u32*)usebuffer)[1024]); + + if (0 > retval) + { + printk(KERN_ERR "Proc read failed with %d", retval); + goto out; + } + + if (copy_to_user(buffer, start, retval)) { + printk(KERN_NOTICE "copy to user failed in amd drivers proc code\n"); + retval=-EFAULT; + goto out; + } + *offset+=retval; + +out: + if (usebuffer) + kfree(usebuffer); + return retval; +} +static ssize_t gentoo_proc_wrapper_write (struct file *myfile, const char __user *buffer, size_t count, loff_t *offset) { + gentoo_proc_wrapper_t* wrapper_data=(gentoo_proc_wrapper_t*)(myfile->private_data); + int retval=0; + void *usebuffer=NULL; + + BUG_ON(*offset); + if (!wrapper_data->write_func) + return -EPERM; + + usebuffer=kmalloc(count, GFP_KERNEL); + if (!usebuffer) + return -ENOMEM; + if (copy_from_user(usebuffer, buffer, count)) { + printk(KERN_NOTICE "copy from user failed in amd drivers proc code\n"); + retval=-EFAULT; + goto out; + } + + retval=wrapper_data->write_func(myfile, buffer, count, wrapper_data->data); + *offset+=retval; +out: + if (usebuffer) + kfree(usebuffer); + return retval; +} +static int gentoo_proc_wrapper_open(struct inode *myinode, struct file *myfile) { + myfile->private_data=PDE_DATA(myinode); + return generic_file_open(myinode, myfile); +} +struct file_operations gentoo_proc_fops = { + .read=gentoo_proc_wrapper_read, + .write=gentoo_proc_wrapper_write, + .open=gentoo_proc_wrapper_open, +}; + +static void *gentoo_proc_wrapper_data(read_proc_t *reader, write_proc_t *writer, void *mydata) { + gentoo_proc_wrapper_t *retval=kmalloc(sizeof(gentoo_proc_wrapper_t), GFP_KERNEL); + if (!retval) + return retval; + retval->read_func=reader; + retval->write_func=writer; + retval->data=mydata; + return retval; +} + +static struct proc_dir_entry *firegl_proc_init( device_t *dev, + int minor, + struct proc_dir_entry *root, + struct proc_dir_entry **dev_root, + kcl_proc_list_t *proc_list ) // proc_list must be terminated! +{ + struct proc_dir_entry *ent; + char name[64]; + kcl_proc_list_t *list = proc_list; + void *tempdata; + KCL_DEBUG1(FN_FIREGL_PROC, "minor %d, proc_list 0x%08lx\n", minor, (unsigned long)proc_list); + if (!minor) + { + root = proc_mkdir("ati", NULL); + } + + if (!root) + { + KCL_DEBUG_ERROR("Cannot create /proc/ati\n"); + return NULL; + } + + if (minor == 0) + { + // Global major debice number entry + tempdata=gentoo_proc_wrapper_data((read_proc_t*)firegl_major_proc_read, NULL, NULL); + if (!tempdata) + return NULL; + ent = proc_create_data("major", S_IFREG|S_IRUGO, root, &gentoo_proc_fops, tempdata); + if (!ent) + { + remove_proc_entry("ati", NULL); + KCL_DEBUG_ERROR("Cannot create /proc/ati/major\n"); + return NULL; + } + } + + sprintf(name, "%d", minor); + *dev_root = proc_mkdir(name, root); + if (!*dev_root) { + remove_proc_entry("major", root); + remove_proc_entry("ati", NULL); + KCL_DEBUG_ERROR("Cannot create /proc/ati/%s\n", name); + return NULL; + } + + while (list->f || list->fops) + { + struct file_operations *my_fops = &gentoo_proc_fops; + if (list->fops) + { + my_fops = (struct file_operations*)list->fops; + tempdata=(dev->pubdev.signature == FGL_DEVICE_SIGNATURE)? firegl_find_device(minor) : (dev); + } + else { + BUG_ON(!list->f); + tempdata=gentoo_proc_wrapper_data((read_proc_t*)list->f, NULL, (dev->pubdev.signature == FGL_DEVICE_SIGNATURE)? firegl_find_device(minor) : (dev) ); + if (!tempdata) + return NULL; + } + //printk(KERN_NOTICE "name %s, dev %p, func %p, data %p\n", list->name, (dev->pubdev.signature == FGL_DEVICE_SIGNATURE)? firegl_find_device(minor) : (dev), list->f, tempdata); + ent = proc_create_data(list->name, S_IFREG|S_IRUGO, *dev_root, my_fops, tempdata); + + if (!ent) + { + KCL_DEBUG_ERROR("Cannot create /proc/ati/%s/%s\n", name, list->name); + while (proc_list != list) + { + remove_proc_entry(proc_list->name, *dev_root); + proc_list++; + } + remove_proc_entry(name, root); + if (!minor) + { + remove_proc_entry("major", root); + remove_proc_entry("ati", NULL); + } + return NULL; + } + + list++; + } + + if (minor == 0) + { + // Global debug entry, only create it once + tempdata=gentoo_proc_wrapper_data((read_proc_t*)firegl_debug_proc_read_wrap, (write_proc_t*)firegl_debug_proc_write_wrap, dev); + if (!tempdata) + return NULL; + ent=proc_create_data("debug", S_IFREG|S_IRUGO, root, &gentoo_proc_fops, tempdata); + if (!ent) + return NULL; + } + + return root; +} +#else static struct proc_dir_entry *firegl_proc_init( device_t *dev, int minor, struct proc_dir_entry *root, @@ -677,6 +873,7 @@ return root; } +#endif static int firegl_proc_cleanup( int minor, struct proc_dir_entry *root,