Le vendredi 10 avril 2009 à 09:53 +0200, Emmanuel Fleury a écrit :
> Package: fglrx-kernel-src
> Version: 1:9-3-1
> Severity: normal
> 
> What did change in the 2.6.29 seems to be the following struct:
> 
> - current->euid --> current->cred->euid
> - current->uid --> current->cred->uid
> - current->gid --> current->cred->gid

Way more things changed, especially with respect to the ACPI subsystem
(specifically, the driver made use of a sizeable amount of private
structures)

The following patch kind of works for me; it seems DPMS is still bust
and I get the occasional lock-up, but otherwise I've been happily
compiz'ing and gaming with it for a couple weeks.

As one of the comments mentions, some parts are still quite dirty and
possibly not DFSG compliant (borderline, at least)

The ACPI side almost works, after running it, I noticed I made the
effort to keep track of fglrx-private data (which used to be stuffed
within the acpi layer's own private data), but I forgot to rewire the
actual notifications. Should be trivial now; might explain the DPMS
troubles.

Anyway, right now I'm pretty satisfied with the way my HD 4350 behaves
with this driver... YMMV, HTH.

        -- Cyrille

Seulement dans fglrx.vanilla/: configure-stamp
Seulement dans fglrx.vanilla/debian: control
diff -ur fglrx.vanilla/firegl_public.c fglrx/firegl_public.c
--- fglrx.vanilla/firegl_public.c	2009-03-29 21:08:16.000000000 +0200
+++ fglrx/firegl_public.c	2009-03-30 00:17:17.000000000 +0200
@@ -1402,7 +1402,7 @@
  */
 KCL_TYPE_Uid ATI_API_CALL KCL_GetEffectiveUid(void)
 {
-    return current->euid;
+    return current_euid();
 }
 
 /** /brief Delay execution for the specified number of microseconds
@@ -1774,15 +1774,19 @@
  */
 void ATI_API_CALL KCL_PosixSecurityCapSetIPCLock(unsigned int lock)
 {
+    struct cred *new;
+    new = prepare_creds();
+    if (!new) return /* -ENOMEM */;
+    
     if (lock == 0 )
     {
-        cap_lower(current->cap_effective, CAP_IPC_LOCK);
+        cap_raise(new->cap_effective, CAP_IPC_LOCK);
     }
     else
     {
-        cap_raise(current->cap_effective, CAP_IPC_LOCK);
+        cap_lower(new->cap_effective, CAP_IPC_LOCK);
     }    
-    return; 
+    commit_creds(new);
 }
 
 /** \brief Get number of available RAM pages
@@ -2256,13 +2260,16 @@
  * kernel <  2.6.27, on_each_cpu has 4 parameters.
  * kernel >= 2.6.27, on_each_cpu has 3 parameters (removed the "retry" parameter)
  */
-#if defined(__x86_64__) && defined(__SMP__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) 
+#if defined(__x86_64__) && defined(__SMP__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28))
 #   if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
         on_each_cpu(KCL_flush_tlb_one, &va, 1, 1);
 #   else
         on_each_cpu(KCL_flush_tlb_one, &va, 1);
 #   endif
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
+        on_each_cpu(KCL_flush_tlb_one, &va, 1);
 #else
+    /* old code */
     flush_tlb_page(vma, va);
 #endif
 }
diff -ur fglrx.vanilla/firegl_public.h fglrx/firegl_public.h
--- fglrx.vanilla/firegl_public.h	2009-03-29 21:08:16.000000000 +0200
+++ fglrx/firegl_public.h	2009-03-30 00:11:20.000000000 +0200
@@ -161,7 +161,9 @@
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
 #define PMSG_EVENT(pmsg_state) (pmsg_state).event
+#ifndef PM_EVENT_SUSPEND
 #define PM_EVENT_SUSPEND 2
+#endif
 #else
 #define PMSG_EVENT(pmsg_state) (pmsg_state)
 #define PM_EVENT_SUSPEND 3
@@ -591,6 +593,14 @@
 #define cpu_has_pge test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability)
 #endif
 
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28)
+/* this is DIRTY but will circumvent the GPL-only restriction for now? */
+#undef pgprot_writecombine
+#undef pgprot_noncached
+
+#endif
+
 #ifndef pgprot_writecombine
 #define pgprot_writecombine(prot) __pgprot((pgprot_val(prot) & ~(_PAGE_PCD)) | _PAGE_PWT)
 #endif
Seulement dans fglrx.vanilla/: .firegl_public.o.d
diff -ur fglrx.vanilla/kcl_acpi.c fglrx/kcl_acpi.c
--- fglrx.vanilla/kcl_acpi.c	2009-03-29 21:08:16.000000000 +0200
+++ fglrx/kcl_acpi.c	2009-03-30 00:13:41.000000000 +0200
@@ -12,6 +12,11 @@
  * User License Agreement is included with this software and is also        *
  * available by contacting ATI Technologies Inc. at http://www.ati.com      *
  *                                                                          *
+ *                                                                          *
+ * ----                                                                     *
+ *  blah, blah, blah.                                                       *
+ *   I wanted to run this on kernel 2.6.29, had to do some dirty work to    *
+ *   get it limping. YMMV.   Cyrille Chepelov <cyri...@chepelov.org>        *
  ****************************************************************************/
 
 #include <linux/version.h>
@@ -62,6 +67,76 @@
     return acpi_get_devices(NULL, (acpi_walk_callback)callback, context, NULL);
 }
 
+
+/* store the first child */
+struct kcl_acpi_find_child {
+    unsigned int type;
+    union acpi_object *obj;
+    struct acpi_object_list *input;
+    struct acpi_buffer *output;
+    char *name;
+    int found;
+};
+
+static acpi_status
+try_find_node_in_child_namespace_cb(acpi_handle handle, u32 level, void *context, void **return_value)
+{
+     acpi_status status;
+     struct kcl_acpi_find_child *wb = context;
+          
+     struct acpi_buffer *output = wb->output;
+     switch(wb->type)
+     {
+         case ACPI_TYPE_INTEGER:
+             output->length = sizeof(union acpi_object);
+             output->pointer = wb->obj;
+             break;
+         case ACPI_TYPE_STRING:
+         case ACPI_TYPE_BUFFER:
+         case ACPI_TYPE_PACKAGE:
+             output->length = ACPI_ALLOCATE_BUFFER;
+             output->pointer = NULL;
+             break;
+         default:  
+             output->length = 0;
+             output->pointer = NULL;
+         break;
+     }
+     
+     status = acpi_evaluate_object(handle, wb->name, wb->input, wb->output);
+     if (ACPI_SUCCESS(status))
+     {
+         wb->found = 1;
+         return AE_CTRL_TERMINATE;
+     }
+     return 0;
+}
+
+static int 
+try_find_node_in_child_namespace(unsigned int type, 
+            acpi_handle start_object,
+            char *name,
+            union acpi_object *obj,
+            struct acpi_object_list *input,
+            struct acpi_buffer *output)
+{
+   struct kcl_acpi_find_child wb;
+   wb.type = type;
+   wb.name = name;
+   wb.obj = obj;
+   wb.output = output;
+   wb.found = 0;
+   
+   acpi_walk_namespace(type, start_object, 1, 
+       try_find_node_in_child_namespace_cb, 
+       &wb, NULL);
+   if (!wb.found) 
+       return -ENOENT;
+   
+   return 0;
+}            
+        
+ 
 /** \brief evaluate acpi namespace object, handle or pathname must be valid
  *  \param handle namespace object handle
  *  \param info input/output arguments for the control method
@@ -74,7 +149,6 @@
     struct acpi_buffer output;
     union acpi_object *params = NULL;
     union acpi_object *obj = NULL;
-    struct acpi_namespace_node *parent_node, *node;
     char name[5] = {'\0'};
     struct KCL_ACPI_MethodArgument *argument = NULL;
     unsigned int i, count;
@@ -225,39 +299,8 @@
     if (ACPI_FAILURE(status))
     {
         /* if failed, try the child namespace node */
-        parent_node = (struct acpi_namespace_node *)handle;
-        node = parent_node->child;
-        while ((node != NULL) && ( node != parent_node))
-        {
-            switch(type)
-            {
-                case ACPI_TYPE_INTEGER:
-                    output.length = sizeof(union acpi_object);
-                    output.pointer = obj;
-                    break;
-                case ACPI_TYPE_STRING:
-                case ACPI_TYPE_BUFFER:
-                case ACPI_TYPE_PACKAGE:
-                    output.length = ACPI_ALLOCATE_BUFFER;
-                    output.pointer = NULL;
-                    break;
-                default:
-                    output.length = 0;
-                    output.pointer = NULL;
-                    break;
-            }
-
-            status = acpi_evaluate_object((acpi_handle)node, name, &input, &output);
-            if (ACPI_SUCCESS(status))
-            {
-                break;
-            }
-            node = node->peer;
-        }
-        if ((node == NULL) || (node == parent_node))
-        {
-            goto error;
-        }
+        if (try_find_node_in_child_namespace(type, handle, name, obj, &input, &output) < 0)
+           goto error;
     }
 
     /* return the output info */
@@ -470,31 +513,56 @@
     }
 }
 
+
+static DEFINE_SPINLOCK(kcl_cb_lock);
+struct kcl_callback {
+    struct list_head cb_list;
+    KCL_ACPI_DevHandle dev_handle;
+    KCL_ACPI_CallbackHandle cb_handler;
+    KCL_ACPI_ContextHandle cb_context;
+};
+static LIST_HEAD(kcl_cb);
+
+/* note: this structure is not efficient; it's meant to get me going
+on 2.6.29, period. */
+struct kcl_callback* 
+find_kcl_callback_xxx(KCL_ACPI_DevHandle dev_handle)
+{
+   /* assuming kcl_cb_lock is held! */
+   struct kcl_callback* cur;
+     
+   list_for_each_entry(cur, &kcl_cb, cb_list)
+   {	
+      if (cur->dev_handle == dev_handle) 
+      {
+         return cur;
+      }         
+   }
+   return NULL; /* not found */
+}
+
+
 /** \brief get notify handler for the device notify operand object
  *  \param handle acpi handle
  *  \return pointer to notify handler
  */
 KCL_ACPI_CallbackHandle ATI_API_CALL KCL_ACPI_GetNotifyHandler(KCL_ACPI_DevHandle handle)
 {
-    struct acpi_namespace_node *node = NULL;
+    struct kcl_callback* cbk;
+    KCL_ACPI_CallbackHandle result;
+    spin_lock(&kcl_cb_lock);
+
+    cbk = find_kcl_callback_xxx(handle);        
+    if (!cbk) goto error; /* unknown? */
+    
+    result = cbk->cb_handler;
+    
+    spin_unlock(&kcl_cb_lock);    
+    return result;
 
-    node = (struct acpi_namespace_node *)handle;
-
-    if ((node != NULL) && (node->object != NULL))
-    {
-        if (node->object->common_notify.device_notify != NULL)
-        {
-            return (KCL_ACPI_CallbackHandle)node->object->common_notify.device_notify->notify.handler;
-        }
-        else
-        {
-            return NULL;
-        }
-    }
-    else
-    {
-        return NULL;
-    }
+error:
+    spin_unlock(&kcl_cb_lock);    
+    return NULL;
 }
 
 /** \brief get notify context for the device notify operand object
@@ -503,25 +571,46 @@
  */
 KCL_ACPI_ContextHandle ATI_API_CALL KCL_ACPI_GetNotifyContext(KCL_ACPI_DevHandle handle)
 {
-    struct acpi_namespace_node *node = NULL;
-
-    node = (struct acpi_namespace_node *)handle;
+    struct kcl_callback* cbk;
+    KCL_ACPI_ContextHandle result;
+    spin_lock(&kcl_cb_lock);
+
+    cbk = find_kcl_callback_xxx(handle);        
+    if (!cbk) goto error; /* unknown? */
+    
+    result = cbk->cb_context;
+    
+    spin_unlock(&kcl_cb_lock);    
+    return result;
+error:
+    spin_unlock(&kcl_cb_lock);    
+    return NULL;
+}
 
-    if ((node != NULL) && (node->object != NULL))
-    {
-        if (node->object->common_notify.device_notify != NULL)
-        {
-            return (KCL_ACPI_ContextHandle)node->object->common_notify.device_notify->notify.context;
-        }
-        else
-        {
-            return NULL;
-        }
-    }
-    else
-    {
-        return NULL;
+struct kcl_callback*
+find_or_make_kcl_callback_xxx(KCL_ACPI_DevHandle handle)
+{
+    struct kcl_callback* cbk;
+    
+    cbk = find_kcl_callback_xxx(handle);
+    if (!cbk)
+    {
+       cbk = kzalloc(sizeof(struct kcl_callback), GFP_KERNEL);
+       if (!cbk) 
+       {
+           printk(KERN_ERR "can't allocate memory\n");
+           return NULL;
+       }
+           
+       INIT_LIST_HEAD(&cbk->cb_list);              
+       cbk->dev_handle = handle;
+       list_add(&cbk->cb_list, &kcl_cb);
+           /* FIXME: we will never, ever remove things from this list
+           this is a bad leak. Unfortunately fglrx does not allow us
+           to be clean */
+           
     }
+    return cbk;
 }
 
 /** \brief update notify handler for the device notify operand object
@@ -531,15 +620,17 @@
  */
 void ATI_API_CALL KCL_ACPI_UpdateNotifyHandler(KCL_ACPI_DevHandle handle, KCL_ACPI_CallbackHandle handler)
 {
-    struct acpi_namespace_node *node = NULL;
-
-    node = (struct acpi_namespace_node *)handle;
-
-    if ((node != NULL) && (node->object != NULL) && (node->object->common_notify.device_notify != NULL))
-    {
-        node->object->common_notify.device_notify->notify.handler = (acpi_notify_handler)handler;
-    }
+    struct kcl_callback* cbk;
+    spin_lock(&kcl_cb_lock);
 
+    cbk = find_or_make_kcl_callback_xxx(handle);        
+    if (!cbk) goto error; /* out of memory? */
+    cbk->cb_handler = handler;
+    
+    spin_unlock(&kcl_cb_lock);    
+    return;
+error:
+    spin_unlock(&kcl_cb_lock);    
     return;
 }
 
@@ -550,15 +641,17 @@
  */
 void ATI_API_CALL KCL_ACPI_UpdateNotifyContext(KCL_ACPI_DevHandle handle, KCL_ACPI_ContextHandle context)
 {
-    struct acpi_namespace_node *node = NULL;
-
-    node = (struct acpi_namespace_node *)handle;
-
-    if ((node != NULL) && (node->object != NULL) && (node->object->common_notify.device_notify != NULL))
-    {
-        node->object->common_notify.device_notify->notify.context = context;
-    }
+    struct kcl_callback* cbk;
+    spin_lock(&kcl_cb_lock);
 
+    cbk = find_or_make_kcl_callback_xxx(handle);        
+    if (!cbk) goto error; /* out of memory? */
+    cbk->cb_context = context;
+    
+    spin_unlock(&kcl_cb_lock);    
+    return;
+error:
+    spin_unlock(&kcl_cb_lock);    
     return;
 }
 
Seulement dans fglrx: Module.markers
Seulement dans fglrx: modules.order
Seulement dans fglrx: Module.symvers
Seulement dans fglrx.vanilla/: .tmp_versions

Reply via email to