Announcement

Collapse
No announcement yet.

ATI fglrx Linux 2.6.20 Kernel Patch

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • ATI fglrx Linux 2.6.20 Kernel Patch

    Here is a new patch for fglrx firegl_public.c that SHOULD work with the new drivers later this month -- and last month's 8.33.6 display driver.

    Code:
    --- common/lib/modules/fglrx/build_mod/firegl_public.c    2006-12-18 10:58:15.000000000 -0500
    +++ common/lib/modules/fglrx/build_mod/firegl_public.c    2006-12-18 11:14:04.000000000 -0500
    @@ -181,6 +181,70 @@
     int errno;
     #endif // __ia64__
     
    +#if defined(__i386__)
    +#define __syscall_return(type, res) \
    +do { \
    +        if ((unsigned long)(res) >= (unsigned long)(-(128 + 1))) { \
    +                errno = -(res); \
    +                res = -1; \
    +        } \
    +        return (type) (res); \
    +} while (0)
    +#define _syscall2(type,name,type1,arg1,type2,arg2) \
    +type name(type1 arg1,type2 arg2) \
    +{ \
    +long __res; \
    +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
    +        : "=a" (__res) \
    +        : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \
    +        : "memory"); \
    +__syscall_return(type,__res); \
    +}
    +
    +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
    +type name(type1 arg1,type2 arg2,type3 arg3) \
    +{ \
    +long __res; \
    +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
    +        : "=a" (__res) \
    +        : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
    +                  "d" ((long)(arg3)) : "memory"); \
    +__syscall_return(type,__res); \
    +}
    +#elif defined(__x86_64__)
    +#define __syscall_clobber "r11","rcx","memory" 
    +#define __syscall "syscall"
    +
    +#define __syscall_return(type, res) \
    +do { \
    +        if ((unsigned long)(res) >= (unsigned long)(-127)) { \
    +                errno = -(res); \
    +                res = -1; \
    +        } \
    +        return (type) (res); \
    +} while (0)
    +#define _syscall2(type,name,type1,arg1,type2,arg2) \
    +type name(type1 arg1,type2 arg2) \
    +{ \
    +long __res; \
    +__asm__ volatile (__syscall \
    +        : "=a" (__res) \
    +        : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)) : __syscall_clobber ); \
    +__syscall_return(type,__res); \
    +}
    +
    +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
    +type name(type1 arg1,type2 arg2,type3 arg3) \
    +{ \
    +long __res; \
    +__asm__ volatile (__syscall \
    +        : "=a" (__res) \
    +        : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \
    +                  "d" ((long)(arg3)) : __syscall_clobber); \
    +__syscall_return(type,__res); \
    +}
    +#endif
    +
     // int mlock(const void *addr, size_t len);
     _syscall2(int, mlock, const void *, addr, size_t, len )
     // int munlock(const void *addr, size_t len);
    
    --- common/lib/modules/fglrx/build_mod/firegl_public.c-orig    2007-01-21 23:09:10.027497362 -0600
    +++ common/lib/modules/fglrx/build_mod/firegl_public.c    2007-01-21 23:09:25.219179776 -0600
    @@ -5256,7 +5256,7 @@
         kasThread_t* thread_obj = (kasThread_t*)hThread;
         init_MUTEX(&(thread_obj->sleep_finished));
         init_waitqueue_head(&(thread_obj->wq_head));
    -    INIT_WORK(&(thread_obj->work), routine, pcontext);
    +    INIT_WORK(&(thread_obj->work), routine);
         schedule_work(&(thread_obj->work));
         return 1;
     }
    Michael Larabel
    http://www.michaellarabel.com/

  • #2
    Patch is now used by h2's script from Sidux (www.sidux.com). Thanks.

    Comment


    • #3
      Hi,

      Unfortunatly the patch isn't working here... Firstable patching fails :
      Code:
      $ sudo patch -p5 < ../../patch2.6.20
      patching file firegl_public.c
      Hunk #1 succeeded at 194 (offset 13 lines).
      patching file firegl_public.c
      Hunk #1 FAILED at 5256.
      1 out of 1 hunk FAILED -- saving rejects to file firegl_public.c.rej
      (the unpatched firegl_public.c has only 4494 lines, and there is no "firegl_public.c-orig" file...)

      So running "module-assistant build fglrx" lead me to the following error :
      Code:
      /usr/bin/make -C /lib/modules/2.6.20/source SUBDIRS=/usr/src/modules/fglrx modules
      make[1]: entrant dans le répertoire " /home/goug/kernel/linux-2.6.20 "
       CC [M]  /usr/src/modules/fglrx/firegl_public.o
      /usr/src/modules/fglrx/firegl_public.c:529: warning: initialization from incompatible pointer type
      /usr/src/modules/fglrx/firegl_public.c: In function 'firegl_stub_open':
      /usr/src/modules/fglrx/firegl_public.c:652: warning: assignment discards qualifiers from pointer target type
      /usr/src/modules/fglrx/firegl_public.c: In function '__ke_request_irq':
      /usr/src/modules/fglrx/firegl_public.c:2641: warning: passing argument 2 of 'request_irq' from incompatible pointer type
      /usr/src/modules/fglrx/firegl_public.c: In function 'KAS_ExecuteAtLevel':
      /usr/src/modules/fglrx/firegl_public.c:4506: warning: 'flags' may be used uninitialized in this function
       LD [M]  /usr/src/modules/fglrx/fglrx.o
       Building modules, stage 2.
       MODPOST 1 modules
      FATAL: modpost: GPL-incompatible module fglrx.ko uses GPL-only symbol 'paravirt_ops'
      make[2]: *** [__modpost] Erreur 1
      make[1]: *** [modpost] Erreur 2
      make[1]: quittant le répertoire " /home/goug/kernel/linux-2.6.20 "
      make: *** [build] Erreur 2
      Could somebody please help me to solve this problem ? This is not my own laptop, and I have to leave a perfectly running linux before the end of the week...

      Thanks.

      PS : I'm running a custom 2.6.20 kernel (can't downgrade, bcm43xx inside...) in Ubuntu Edgy, with an ATI Radeon XPress 200M.

      Comment


      • #4
        Your error seems to stem from:

        FATAL: modpost: GPL-incompatible module fglrx.ko uses GPL-only symbol 'paravirt_ops'

        And not the Linux 2.6.20 patch.
        Michael Larabel
        http://www.michaellarabel.com/

        Comment


        • #5
          Yes, actually I thought it was induced by the patching failure, but I found some more informations on the GPL-only error on a few nVidia related forums ( ), and I'll try to recompile after changing
          Code:
          EXPORT_SYMBOL_GPL(paravirt_ops);
          by
          Code:
          EXPORT_SYMBOL(paravirt_ops);
          at the end of paravirt.c, as suggested by this patch. We'll see...

          Thanks for the quick reply and for the patch anyway.

          Edit : It worked (and I also learned that it was BAD to have uppercases in the kernel name...).
          Last edited by SkippyleGrandGourou; 02-13-2007, 04:26 AM.

          Comment


          • #6
            I just switch to kernel 2.6.20.1 (download from www.kernel.org). Unable to build even after applied the patch file.

            Search through the firegl_public.c, I notice the macro: INIT_WORK is passing more than 2 parameters when in linux header, it is declared as accepting only 2 parameters. Change from:

            Code:
            INIT_WORK(&(thread_obj->work), routine, pcontext);
            to

            Code:
            INIT_WORK(&(thread_obj->work), routine);
            Solved my problem. So far, my system seems to be running fine. However, I am not sure if there is any potential problem by removing pcontext here.

            Anyway, just something I thought I share with you guys.

            Comment


            • #7
              Originally posted by lenrek View Post
              I just switch to kernel 2.6.20.1 (download from www.kernel.org). Unable to build even after applied the patch file.

              Search through the firegl_public.c, I notice the macro: INIT_WORK is passing more than 2 parameters when in linux header, it is declared as accepting only 2 parameters. Change from:

              Code:
              INIT_WORK(&(thread_obj->work), routine, pcontext);
              to

              Code:
              INIT_WORK(&(thread_obj->work), routine);
              Solved my problem. So far, my system seems to be running fine. However, I am not sure if there is any potential problem by removing pcontext here.

              Anyway, just something I thought I share with you guys.
              I have a more accurate Linux 2.6.20 patch that I have written for the 8.35 display drivers. Here is part of it; except I seem to have misplaced the main one that controlled the INIT_WORK.

              Code:
              --- firegl_public.c-orig    2007-02-21 19:56:45.000000000 -0500
              +++ firegl_public.c    2007-02-25 12:31:59.000000000 -0500
              @@ -119,6 +119,7 @@
               
               #include <linux/interrupt.h>
               #include <linux/delay.h>
              +#include <linux/freezer.h>
               #include <linux/console.h>
               
               //#include <linux/signal.h>
              @@ -204,6 +205,70 @@
               int errno;
               #endif // __ia64__
               
              +#if defined(__i386__)
              +#define __syscall_return(type, res) \
              +do { \
              +        if ((unsigned long)(res) >= (unsigned long)(-(128 + 1))) { \
              +                errno = -(res); \
              +                res = -1; \
              +        } \
              +        return (type) (res); \
              +} while (0)
              +#define _syscall2(type,name,type1,arg1,type2,arg2) \
              +type name(type1 arg1,type2 arg2) \
              +{ \
              +long __res; \
              +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
              +        : "=a" (__res) \
              +        : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \
              +        : "memory"); \
              +__syscall_return(type,__res); \
              +}
              +
              +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
              +type name(type1 arg1,type2 arg2,type3 arg3) \
              +{ \
              +long __res; \
              +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
              +        : "=a" (__res) \
              +        : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
              +                  "d" ((long)(arg3)) : "memory"); \
              +__syscall_return(type,__res); \
              +}
              +#elif defined(__x86_64__)
              +#define __syscall_clobber "r11","rcx","memory" 
              +#define __syscall "syscall"
              +
              +#define __syscall_return(type, res) \
              +do { \
              +        if ((unsigned long)(res) >= (unsigned long)(-127)) { \
              +                errno = -(res); \
              +                res = -1; \
              +        } \
              +        return (type) (res); \
              +} while (0)
              +#define _syscall2(type,name,type1,arg1,type2,arg2) \
              +type name(type1 arg1,type2 arg2) \
              +{ \
              +long __res; \
              +__asm__ volatile (__syscall \
              +        : "=a" (__res) \
              +        : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)) : __syscall_clobber ); \
              +__syscall_return(type,__res); \
              +}
              +
              +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
              +type name(type1 arg1,type2 arg2,type3 arg3) \
              +{ \
              +long __res; \
              +__asm__ volatile (__syscall \
              +        : "=a" (__res) \
              +        : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \
              +                  "d" ((long)(arg3)) : __syscall_clobber); \
              +__syscall_return(type,__res); \
              +}
              +#endif
              +
               // int mlock(const void *addr, size_t len);
               _syscall2(int, mlock, const void *, addr, size_t, len )
               // int munlock(const void *addr, size_t len);
              @@ -4341,24 +4406,6 @@
               #endif
               }
               
              -/** \brief Freeze the thread if kernel requested so because of going to suspend
              - *
              - * \return Nonzero if freeze has been performed, zero otherwise
              - *
              - */
              -unsigned int kas_try_to_freeze(void)
              -{
              -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
              -    return 0;
              -#else
              -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
              -    return try_to_freeze(PF_FREEZE);
              -#else
              -    return try_to_freeze();
              -#endif
              -#endif
              -}
              -
               /** \brief Storage for execution level(s) */
               #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
               /* SMP support for 2.6.0 and higher */
              @@ -4985,28 +5032,13 @@
                   unsigned int ret = 0;
                   kasSlabCache_t* slabcache_obj = (kasSlabCache_t*)hSlabCache;
               
              -    DBG_ENTER("0x%08X", hSlabCache);
              -
              -    if (!(slabcache_obj->cache))
              -    {
              -        DBG_ERROR("slab object '%s' is not initialized");
              -        DBG_LEAVE("0");
              -        return 0;
              -    }
              -
              -    DBG_TRACE("destroying slab object '%s'", slabcache_obj->name);
              -
              -    if (kmem_cache_destroy(slabcache_obj->cache) == 0)
              +    if (slabcache_obj->cache)
                   {
              -        ret = 1;
              +        kmem_cache_destroy(slabcache_obj->cache);
                       slabcache_obj->cache = NULL;
              -    }
              -    else
              -    {
              -        DBG_ERROR("destroying failed");
              +        ret = 1;
                   }
               
              -    DBG_LEAVE("%d", ret);
                   return ret;
               }
               
              @@ -5190,6 +5222,24 @@
                   return 1;
               }
               
              +/** \brief Freeze the thread if kernel requested so because of going to suspend
              + *
              + * \return Nonzero if freeze has been performed, zero otherwise
              + *
              + */
              +unsigned int kas_try_to_freeze(void)
              +{
              +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
              +    return 0;
              +#else
              +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
              +    return try_to_freeze(PF_FREEZE);
              +#else
              +    return try_to_freeze();
              +#endif
              +#endif
              +}
              +
               /** \brief Wait for the event
                *
                * If event is already signalled, return right away.
              Michael Larabel
              http://www.michaellarabel.com/

              Comment


              • #8
                I just spent some time looking at the patch file, notice it is suppose to change that line to what I did.

                Maybe I did something during copying or patching.

                Comment

                Working...
                X