Тема: ядро 3.17.2 и ati 14.9

Доброго всем. после долгих мучений было выведано, что без патча не поставить дрова на openmandriva 2014 (ati r7 260)
собсна вопрос, где вять патч?
uname -a
Linux localhost.localdomain 3.17.2-nrjQL-desktop-1omv #1 SMP PREEMPT Sat Nov 1 12:51:13 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
lspci
VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Pitcairn PRO [Radeon HD 7850] (prog-if 00 [VGA controller])
cat /usr/share/ati/fglrx-install.log :

+ открыть спойлер

cat /usr/share/ati/fglrx-install.log
Supported adapter detected.
Check if system has the tools required for installation.
fglrx installation is being forced. Installation will proceed without the required tools on the system.
Uninstalling any previously installed drivers.

Creating symlink /var/lib/dkms/fglrx/14.20/source ->
                 /usr/src/fglrx-14.20

DKMS: add Completed.

Kernel preparation unnecessary for this kernel.  Skipping...

Building module:
cleaning build area....
cd /var/lib/dkms/fglrx/14.20/build; sh make.sh --nohints --uname_r=3.17.2-nrjQL-desktop-1omv --norootcheck....(bad exit status: 1)
[Error] Kernel Module : Failed to build fglrx-14.20 with DKMS
[Error] Kernel Module : Removing fglrx-14.20 from DKMS

------------------------------
Deleting module version: 14.20
completely from the DKMS tree.
------------------------------
Done.
[Reboot] Kernel Module : dracut

2 (17.11.2014 17:27:23 отредактировано GoUpInSmoke)

Re: ядро 3.17.2 и ati 14.9

я нашёл патч (он для 3.17), но он не патчит )))) мож кто в курсе
вот он :

+ открыть спойлер

--- common/lib/modules/fglrx/build_mod/kcl_acpi.c       2014-09-23 10:42:10.000000000 -0400
+++ common/lib/modules/fglrx/build_mod/kcl_acpi.c       2014-11-13 16:44:23.187112123 -0500
@@ -831,7 +831,7 @@

static acpi_status KCL_ACPI_Slot_No_Hotplug(KCL_ACPI_DevHandle handle, u32 lvl, void *data, void **rv)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,7)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,7) && LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)
    struct acpi_device *tdev = NULL;
    struct pci_dev *pdev = (struct pci_dev *)data;
    int device = 0;

собственно вот файл который надо патчить

+ открыть спойлер

/****************************************************************************
*                                                                          *
* Copyright 1999-2005 ATI Technologies Inc., Markham, Ontario, CANADA.     *
* All Rights Reserved.                                                     *
*                                                                          *
* Your use and or redistribution of this software in source and \ or       *
* binary form, with or without modification, is subject to: (i) your       *
* ongoing acceptance of and compliance with the terms and conditions of    *
* the ATI Technologies Inc. software End User License Agreement; and (ii)  *
* your inclusion of this notice in any version of this software that you   *
* use or redistribute.  A copy of the ATI Technologies Inc. software End   *
* User License Agreement is included with this software and is also        *
* available by contacting ATI Technologies Inc. at http://www.ati.com      *
*                                                                          *
****************************************************************************/

#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif
#include <linux/acpi.h>
#include <linux/pci.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
#include <acpi/button.h>
#endif

#include "kcl_config.h"
#include "kcl_type.h"
#include "kcl_acpi.h"
#include "kcl_debug.h"

#include <linux/vt_kern.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)

#if defined(CONFIG_ACPI_INTERPRETER) && defined(CONFIG_ACPI_BOOT) && defined(CONFIG_ACPI_BUS)
#define KCL_ACPI_CONFIGURED
#endif

#else

#if defined(CONFIG_ACPI)
#define KCL_ACPI_CONFIGURED
#endif

#endif

/*
* NOTE: When adding new KCL ACPI functions below, remember to add an appropriate
*       stub function in the #else part of KCL_ACPI_CONFIGURED to handle those
*       cases where ACPI support is not built within the kernel.  If the function
*       should be implemented the same way regardless of whether ACPI support is
*       available, put it after the #endif KCL_ACPI_CONFIGURED section by the end
*       of the file.
*/

#if defined(KCL_ACPI_CONFIGURED)

struct firegl_acpi_pci_data {
    struct acpi_pci_id      id;
    struct pci_bus          *bus;
    struct pci_dev          *dev;
};

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)

/** \brief kernel call back function when acpi video events happen
* \param nb Notifier block from kernel. Not used in driver.
* \param val Value passed from notifer. Not used in driver.
* \param data Pointer passed unmodified to notifier function. Here it is the acpi_bus_event.
* \return NOTIFY_OK to indicate the event has been handled.
* */
static int firegl_acpi_video_event(struct notifier_block *nb, unsigned long val,
                               void *data)
{
    struct acpi_bus_event *entry;
    KCL_ACPI_ContextHandle ctx_handle;
    unsigned int  ret = 0;
    entry = (struct acpi_bus_event *)data;
    if ( !strcmp(entry->device_class, KCL_ACPI_VIDEO_CLASS) )
    {           
        ctx_handle = firegl_query_acpi_handle((KCL_NOTIFIER_BLOCKER)nb, KCL_ACPI_VIDEO_CLASS);
        if (ctx_handle == NULL)
        {
            KCL_DEBUG_ERROR ("Could not find private acpi context by video busid: %s\n", entry->bus_id);
        }
        else
        {
            ret = libip_video_notify(NULL, entry->type, ctx_handle);
        }
    }

    return (ret == 0)? NOTIFY_OK:NOTIFY_BAD;

}

/** \brief kernel call back function when acpi ac events happen
* \param nb Notifier block from kernel. Not used in driver.
* \param val Value passed from notifer. Not used in driver.
* \param data Pointer passed unmodified to notifier function. Here it is the acpi_bus_event.
* \return NOTIFY_OK to indicate the event has been handled.
* */
static int firegl_acpi_ac_event(struct notifier_block *nb, unsigned long val,
                               void *data)
{
    struct acpi_bus_event *entry;
    KCL_ACPI_ContextHandle ctx_handle;
    unsigned int newstate;

    entry = (struct acpi_bus_event *)data;
    if ( !strcmp(entry->device_class, KCL_ACPI_AC_CLASS) )
    {           
        ctx_handle = firegl_query_acpi_handle((KCL_NOTIFIER_BLOCKER)nb, KCL_ACPI_AC_CLASS);
        if (ctx_handle == NULL)
        {
            KCL_DEBUG_ERROR ("Could not find private acpi context by ac_adpater busid: %s\n", entry->bus_id);
        }
        else
        {
            newstate = entry->data;
            libip_ac_notify(NULL, entry->type, ctx_handle, &newstate);
        }
    }
    return NOTIFY_OK;
}

static int firegl_acpi_lid_event(struct notifier_block *nb, unsigned long val,
                               void *data)
{
    unsigned int status;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
    status = acpi_lid_open();
    libip_lid_open_notify(status);
#endif
    return NOTIFY_OK;
}

static struct notifier_block firegl_acpi_lid_notifier = {
        .notifier_call = firegl_acpi_lid_event,
};
#endif
/** \brief search for acpi namespace node with specified name
*  \param parent specify the search scope
*  \param pathname pointer to a null terminated ascii string
*  \param ret_handle where to put the return handle
*  \return status
*/
unsigned int ATI_API_CALL KCL_ACPI_GetDevHandle(KCL_ACPI_DevHandle parent,
                                                const char *pathname,
                                                KCL_ACPI_DevHandle *ret_handle)
{
    return acpi_get_handle(parent, (acpi_string)pathname, ret_handle);
}

/** \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
*  \return status
*/
unsigned int ATI_API_CALL KCL_ACPI_EvalObject(KCL_ACPI_DevHandle handle,
                                              struct KCL_ACPI_MethodInputInfo *info)
{
    struct acpi_object_list input;
    struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
    union acpi_object *params = NULL;
    union acpi_object *obj = NULL;
    char name[5] = {'\0'};
    struct KCL_ACPI_MethodArgument *argument = NULL;
    unsigned int i, count;
    acpi_status status;
    unsigned int funcNo = 0xFFFFFFFF;

    if (handle == NULL)
    {
        return KCL_ACPI_ERROR;
    }

    memset(&input, 0, sizeof(struct acpi_object_list));

    /* validate input info */
    if (info->size != sizeof(struct KCL_ACPI_MethodInputInfo))
    {
        return KCL_ACPI_ERROR;
    }

    input.count = info->inputCount;
    if (info->inputCount > 0)
    {
        if (info->pInputArgument == NULL)
        {
            return KCL_ACPI_ERROR;
        }
        argument = info->pInputArgument;
        funcNo = argument->value;
        for (i = 0; i < info->inputCount; i++)
        {
            if (((argument->type == ACPI_TYPE_STRING) || (argument->type == ACPI_TYPE_BUFFER))
                && (argument->pointer == NULL))
            {
                return KCL_ACPI_ERROR;
            }
            argument++;
        }
    }

    if (info->outputCount > 0)
    {
        if (info->pOutputArgument == NULL)
        {
            return KCL_ACPI_ERROR;
        }
        argument = info->pOutputArgument;
        for (i = 0; i < info->outputCount; i++)
        {
            if (((argument->type == ACPI_TYPE_STRING) || (argument->type == ACPI_TYPE_BUFFER))
                && (argument->pointer == NULL))
            {
                return KCL_ACPI_ERROR;
            }
            argument++;
        }
    }


    /* The path name passed to acpi_evaluate_object should be null terminated */
    if ((info->field & KCL_ACPI_FIELD_METHOD_NAME) != 0)
    {
        strncpy(name, (char *)&(info->name), sizeof(unsigned int));
        name[4] = '\0';
    }

    /* parse input parameters */
    if (input.count > 0)
    {
        input.pointer = params = (union acpi_object *)kmalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL);
        if (params == NULL)
        {
            return KCL_ACPI_ERROR;
        }
        memset(params, 0, sizeof(union acpi_object) * input.count);
        argument = info->pInputArgument;

        for (i = 0; i < input.count; i++)
        {
            params->type = argument->type;
            switch(params->type)
            {
                case ACPI_TYPE_INTEGER:
                    params->integer.value = argument->value;
                    break;
                case ACPI_TYPE_STRING:
                    params->string.length = argument->methodLength;
                    params->string.pointer = argument->pointer;
                    break;
                case ACPI_TYPE_BUFFER:
                    params->buffer.length = argument->methodLength;
                    params->buffer.pointer = argument->pointer;
                    break;
                default:
                    break;
            }
            params++;
            argument++;
        }
    }

    /* parse output info */
    count = info->outputCount;
    argument = info->pOutputArgument;

    /* evaluate the acpi method */
    status = acpi_evaluate_object(handle, name, &input, &output);
    KCL_DEBUG1(FN_FIREGL_ACPI, "Evaluated method: %s, handle: %p, function: %d, status: 0x%x  \n", name, handle, funcNo, (unsigned int)status);

    if (ACPI_FAILURE(status))
    {
        status = KCL_ACPI_ERROR;
        goto error;
    }

    /* return the output info */
    obj = output.pointer;

    if (count > 1)
    {
        if ((obj->type != ACPI_TYPE_PACKAGE) || (obj->package.count != count))
        {
            status = KCL_ACPI_ERROR;
            goto error;
        }
        params = obj->package.elements;
    }
    else
    {
        params = obj;
    }

    if (params == NULL)
    {
        status = KCL_ACPI_ERROR;
        goto error;
    }

    for (i = 0; i < count; i++)
    {
        if (argument->type != params->type)
        {
            status = KCL_ACPI_ERROR;
            goto error;
        }
        switch(params->type)
        {
            case ACPI_TYPE_INTEGER:
                argument->value = params->integer.value;
                break;
            case ACPI_TYPE_STRING:
                if ((params->string.length != argument->dataLength) || (params->string.pointer == NULL))
                {
                    status = KCL_ACPI_ERROR;
                    goto error;
                }
                strncpy(argument->pointer, params->string.pointer, params->string.length);
                break;
            case ACPI_TYPE_BUFFER:
                if (params->buffer.pointer == NULL)
                {
                    status = KCL_ACPI_ERROR;
                    goto error;
                }
                memcpy(argument->pointer, params->buffer.pointer, argument->dataLength);
                break;
            default:
                break;
        }
        argument++;
        params++;
    }

error:
    if (obj != NULL)
    {
        kfree(obj);
    }
    kfree((void *)input.pointer);
    return status;
}

void* KCL_ACPI_GetVfctBios(unsigned long *size)
{
    struct acpi_table_header *hdr;
    acpi_size tbl_size ;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,3)   
    if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
#else
    tbl_size = 0x7fffffff;
    if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
#endif
    {
        return NULL;
    }
    *size = tbl_size;
    return hdr;
}

/** \brief install notify handler for acpi device
*  \param device acpi device
*  \param handler_type type of handler
*  \param handler pointer of notify handler
*  \param context context for the handler
*  \return status
*/
unsigned int ATI_API_CALL KCL_ACPI_InstallHandler(KCL_ACPI_DevHandle device,
                                                  unsigned int handler_type,
                                                  KCL_ACPI_CallbackHandle handler,
                                                  KCL_ACPI_ContextHandle context,
                                                  KCL_NOTIFIER_BLOCKER *nb)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
    return acpi_install_notify_handler(device, handler_type, (acpi_notify_handler)handler, context);
#else
    KCL_ACPI_DevHandle dummy_handle;

    //register notifier chain for video switching events
    if ((KCL_ACPI_GetDevHandle(device, "_DOD", &dummy_handle) == KCL_ACPI_OK)
        || (KCL_ACPI_GetDevHandle(device, "_DOS", &dummy_handle) == KCL_ACPI_OK))
    {
        *nb = kmalloc(sizeof(struct notifier_block), GFP_KERNEL);
        if (!*nb)
        {
            KCL_DEBUG_ERROR ("Could not allocate enough memory for video notifier_block\n");
            return -ENOMEM;
        }
        ((struct notifier_block*)(*nb))->notifier_call = firegl_acpi_video_event;
        return register_acpi_notifier((struct notifier_block*)(*nb));
    }

    //register notifier chain for ac adapter events
    if (KCL_ACPI_GetDevHandle(device, "_PSR", &dummy_handle) == KCL_ACPI_OK)
    {
        *nb = kmalloc(sizeof(struct notifier_block), GFP_KERNEL);
        if (!*nb)
        {
            KCL_DEBUG_ERROR ("Could not allocate enough memory for ac notifier_block\n");
            return -ENOMEM;
        }
        ((struct notifier_block*)(*nb))->notifier_call = firegl_acpi_ac_event;
        return register_acpi_notifier((struct notifier_block*)(*nb));
    }

    return 0;
#endif
}

/** \brief uninstall notify handler for acpi device
*  \param device acpi device
*  \param handler_type type of handler
*  \param handler pointer of notify handler
*  \return status
*/
unsigned int ATI_API_CALL KCL_ACPI_RemoveHandler(KCL_ACPI_DevHandle device,
                                                 unsigned int handler_type,
                                                 KCL_ACPI_CallbackHandle handler,
                                                 KCL_NOTIFIER_BLOCKER *nb)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
    return acpi_remove_notify_handler(device, handler_type, (acpi_notify_handler)handler);
#else
    KCL_ACPI_DevHandle dummy_handle;
    int ret = 0;

    //unregister notifier chain for video switching events
    if ((KCL_ACPI_GetDevHandle(device, "_DOD", &dummy_handle) == KCL_ACPI_OK)
        || (KCL_ACPI_GetDevHandle(device, "_DOS", &dummy_handle) == KCL_ACPI_OK))
    {
        ret = unregister_acpi_notifier((struct notifier_block*)(*nb));
        kfree(*nb);
        *nb = NULL;
    }

    //unregister notifier chain for ac adapter events
    if (KCL_ACPI_GetDevHandle(device, "_PSR", &dummy_handle) == KCL_ACPI_OK)
    {
        ret = unregister_acpi_notifier((struct notifier_block*)(*nb));
        kfree(*nb);
        *nb = NULL;
    }

    return ret;
#endif
}

unsigned int ATI_API_CALL KCL_ACPI_InstallLidHandler(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
    if (acpi_lid_notifier_register(&firegl_acpi_lid_notifier))
    {
        KCL_DEBUG_ERROR("lid notifier registration failed\n");
        firegl_acpi_lid_notifier.notifier_call = NULL;
    }
#endif
    return 0;
}

unsigned int ATI_API_CALL KCL_ACPI_RemoveLidHandler(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
    if (firegl_acpi_lid_notifier.notifier_call)
    {
        acpi_lid_notifier_unregister(&firegl_acpi_lid_notifier);
    }
#endif
    return 0;
}
/** \brief get the global variable acpi_disabled in the kernel
*  \return the value of acpi_disabled
*/
int ATI_API_CALL KCL_ACPI_Disabled(void)
{
    return acpi_disabled;
}

/** \brief a function of acpi notify handler type, called when state of ac adapter changed
*  \param handle      acpi handle
*  \param event       acpi event type
*  \param data        context for the notify handler
*  \return void
*/
void KCL_ACPI_AcNotify(KCL_ACPI_DevHandle handle, unsigned int event, KCL_ACPI_ContextHandle data)
{
    libip_ac_notify(handle, event, data, NULL);
}

/** \brief execute a specified acpi notify handler
*  \param handler     pointer to the notify handler
*  \param handle      acpi handle
*  \param event       acpi event type
*  \param data        context for the notifyhandler
*  \return void
*/
void ATI_API_CALL KCL_ACPI_ExecHandler(KCL_ACPI_CallbackHandle handler, KCL_ACPI_DevHandle handle, unsigned int event, KCL_ACPI_ContextHandle data)
{
    if (handler != NULL)
    {
        ((acpi_notify_handler)handler)(handle, event, data);
    }
}

/** \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)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
    struct acpi_namespace_node *node = NULL;

    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
#endif
    /* No alternative on 2.6.29 and later for now. The internal ACPI data
     * structures are no longer included in the kernel headers.
     * For 2.6.29 and later, this is not used. Return null here.
     * And for 2.6.9, there is no ACPI video module, so also return null
     */
    {
        return NULL;
    }
}

/** \brief get notify context for the device notify operand object
*  \param handle acpi handle
*  \return pointer to notify context
*/
KCL_ACPI_ContextHandle ATI_API_CALL KCL_ACPI_GetNotifyContext(KCL_ACPI_DevHandle handle)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
    struct acpi_namespace_node *node = NULL;

    node = (struct acpi_namespace_node *)handle;

    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
#endif
    /* No alternative on 2.6.29 and later for now. The internal ACPI data
     * structures are no longer included in the kernel headers.
     * For 2.6.29 and later, this is not used. Return null here.
     * And for 2.6.9, there is no ACPI video module, so also return null
     */
    {
        return NULL;
    }
}

/** \brief update notify handler for the device notify operand object
*  \param handle acpi handle
*  \param handler new notify handler
*  \return
*/
void ATI_API_CALL KCL_ACPI_UpdateNotifyHandler(KCL_ACPI_DevHandle handle, KCL_ACPI_CallbackHandle handler)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
    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;
    }
#endif
    /* No alternative on 2.6.29 and later for now. The internal ACPI data
     * structures are no longer included in the kernel headers.
     * For 2.6.29 and later, this is not used.  */
    return;
}

/** \brief update notify context for the device notify operand object
*  \param handle acpi handle
*  \param context new notify context
*  \return
*/
void ATI_API_CALL KCL_ACPI_UpdateNotifyContext(KCL_ACPI_DevHandle handle, KCL_ACPI_ContextHandle context)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
    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;
    }
#endif
    /* No alternative on 2.6.29 and later for now. The internal ACPI data
     * structures are no longer included in the kernel headers.
     * For 2.6.29 and later, this is not used.  */
    return;
}

/** \brief get child device in ACPI namespace
* \param handle acpi handle for parent device
* \return acpi handle for child device
*/
KCL_ACPI_DevHandle ATI_API_CALL KCL_ACPI_GetChildDevice(KCL_ACPI_DevHandle handle)
{
    KCL_ACPI_DevHandle child_handle;
    acpi_status status = acpi_get_next_object (ACPI_TYPE_ANY, handle, NULL, &child_handle);
    if (ACPI_SUCCESS(status))
    {
        return child_handle;
    }
    else
    {
        return NULL;
    }
}

/** \brief get peer device in ACPI namespace
* \param handle acpi handle
* \return acpi handle for peer device
*/
KCL_ACPI_DevHandle ATI_API_CALL KCL_ACPI_GetPeerDevice(KCL_ACPI_DevHandle handle)
{
    KCL_ACPI_DevHandle peer_handle;
    acpi_status status = acpi_get_next_object (ACPI_TYPE_ANY, NULL, handle, &peer_handle);
    if (ACPI_SUCCESS(status))
    {
        return peer_handle;
    }
    else
    {
        return NULL;
    }
}

/** \brief called for Notify(VGA, 0x80)
* \param handle acpi handle
* \param event  acpi event type
* \param data   context for the notify handler
* \return void
* */
void KCL_ACPI_VideoNotify(KCL_ACPI_DevHandle handle, unsigned int event, KCL_ACPI_ContextHandle data)
{
    libip_video_notify(handle, event, data);
}

static unsigned int KCL_ACPI_videoDevice(KCL_ACPI_DevHandle handle)
{
    KCL_ACPI_DevHandle dummy_handle;

    if ((KCL_ACPI_GetDevHandle(handle, "_DOD", &dummy_handle) == KCL_ACPI_OK)
       || (KCL_ACPI_GetDevHandle(handle, "_DOS", &dummy_handle) == KCL_ACPI_OK))
    {
        return KCL_ACPI_OK;
    }
    else
    {
        return KCL_ACPI_ERROR;
    }
}

static unsigned int KCL_ACPI_acDevice(KCL_ACPI_DevHandle handle)
{
    KCL_ACPI_DevHandle dummy_handle;

    if (KCL_ACPI_GetDevHandle(handle, "_PSR", &dummy_handle) == KCL_ACPI_OK)
    {
        return KCL_ACPI_OK;
    }
    else
    {
        return KCL_ACPI_ERROR;
    }
}

unsigned int ATI_API_CALL KCL_ACPI_PowerXpressDevice(KCL_ACPI_DevHandle handle)
{
    KCL_ACPI_DevHandle dummy_handle = NULL;

    if ((KCL_ACPI_GetDevHandle(handle, "ATPX", &dummy_handle) == KCL_ACPI_OK) && dummy_handle)
    {
        return KCL_ACPI_OK;
    }
    else
    {
        return KCL_ACPI_ERROR;
    }
}

/* call back function for acpi_get_devices */
static unsigned int KCL_ACPI_SearchHandles(KCL_ACPI_DevHandle handle, unsigned int level, void* context, void **retval)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
    acpi_status status;
    struct acpi_device *tdev;
    struct firegl_acpi_pci_data    *pdata = NULL;
    struct acpi_namespace_node     *node;
    union acpi_operand_object      *obj_desc;
#endif
    struct KCL_ACPI_MatchInfo *pInfo = (struct KCL_ACPI_MatchInfo *)context;

    if ( pInfo->ac_handle == NULL && KCL_ACPI_acDevice(handle) == KCL_ACPI_OK )
    {
        pInfo->ac_handle = handle;
    }

    //Hack: search video handle for old kernels. 
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
    if ( pInfo->video_handle == NULL &&  (KCL_ACPI_videoDevice(handle) == KCL_ACPI_OK) )
    {
        status = acpi_bus_get_device(handle, &tdev);
        if ( ACPI_FAILURE(status) )
        {
            KCL_DEBUG_ERROR ("Could not find acpi device for video handle: %p, status: 0x%x.\n", handle, status);
            return KCL_ACPI_OK;
        }

        node = (struct acpi_namespace_node *)handle;
        if ( node != NULL && node->object != NULL )
        {
            obj_desc = node->object;
            while (obj_desc)
            {
                if ( (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
                     obj_desc->data.handler != NULL )
                {
                    // Only two kinds of data is attached to a video device: "struct acpi_device" and "struct acpi_pci_data"
                    if ( obj_desc->data.pointer != NULL && (void *)obj_desc->data.pointer != (void *)tdev )
                    {
                        pdata = (struct firegl_acpi_pci_data *)obj_desc->data.pointer;
                        if ( pdata && pdata->dev == pInfo->pcidev )
                        {
                            pInfo->video_handle = handle;
                        }
                        break;
                    }
                }
                obj_desc = obj_desc->common.next_object;
            }
        }
    }
    if (pInfo->video_handle)
    {
#endif   
        if (pInfo->ac_handle)
        {
            return AE_CTRL_TERMINATE;
        }
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
    }
#endif
    return KCL_ACPI_OK;
}

unsigned int ATI_API_CALL KCL_ACPI_GetHandles(kcl_match_info_t *pInfo)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
        #ifdef ACPI_HANDLE
        pInfo->video_handle = ACPI_HANDLE(&(pInfo->pcidev->dev));
        #else
        pInfo->video_handle = pInfo->pcidev->dev.acpi_node.handle;
        #endif
    #elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
        pInfo->video_handle = pInfo->pcidev->dev.archdata.acpi_handle;
    #else
        pInfo->video_handle = pInfo->pcidev->dev.firmware_data;
    #endif   
    if ( pInfo->video_handle &&
        (KCL_ACPI_videoDevice(pInfo->video_handle) != KCL_ACPI_OK) )
    {
        KCL_DEBUG1(FN_FIREGL_KCL, "Video handle doesn't have ACPI function: %p for video device: %p\n", pInfo->video_handle, pInfo->pcidev);
        pInfo->video_handle = NULL;
    }
#endif
    return acpi_get_devices(NULL, (acpi_walk_callback)KCL_ACPI_SearchHandles, pInfo, NULL);
}

static unsigned int KCL_ACPI_SearchAlternateHandle(KCL_ACPI_DevHandle handle, unsigned int level, void* context, void **retval)
{
    /*This function is only used by PowerXpress handle search for now*/
    KCL_ACPI_DevHandle pHandle = (KCL_ACPI_DevHandle) context;
    if ((KCL_ACPI_PowerXpressDevice(handle) == KCL_ACPI_OK) && handle != pHandle)
    {
        *retval = handle;
        return AE_CTRL_TERMINATE;
    }
    return AE_OK;
}

/** \brief get a different video handle in ACPI namespace
* \param handle acpi handle for current video handle
* \return alternate acpi video handle
*/
KCL_ACPI_DevHandle ATI_API_CALL KCL_ACPI_GetAlternateHandle(KCL_ACPI_DevHandle pHandle)
{
    acpi_status status;
    KCL_ACPI_DevHandle retHandle = NULL;
    status = acpi_get_devices(NULL, (acpi_walk_callback)KCL_ACPI_SearchAlternateHandle, pHandle, &retHandle);
    if ( ACPI_FAILURE(status) )
    {
        return NULL;
    }
    return retHandle;
}

static acpi_status KCL_ACPI_Slot_No_Hotplug(KCL_ACPI_DevHandle handle, u32 lvl, void *data, void **rv)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,7)
   struct acpi_device *tdev = NULL;
   struct pci_dev *pdev = (struct pci_dev *)data;
   int device = 0;

   acpi_bus_get_device(handle, &tdev);
   if(tdev != NULL)
   {
      device = (acpi_device_adr(tdev) >> 16) & 0xffff;
      if(PCI_SLOT(pdev->devfn) == device)
      {
         tdev->flags.no_hotplug = true;
      }
   }
#endif
   return 0;
}

void ATI_API_CALL KCL_ACPI_No_Hotplug(void* dev)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,7)
    struct pci_dev  *pdev = (struct pci_dev*)dev;

    if(pdev && pdev->bus && pdev->bus->bridge)
    {
       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(pdev->bus->bridge), 1, KCL_ACPI_Slot_No_Hotplug, NULL, pdev , NULL);
    }
#endif
}

#else

/*
* ACPI support was never built into the kernel,
* stub out all the KCL ACPI funtions.
*/

unsigned int ATI_API_CALL KCL_ACPI_GetDevHandle(KCL_ACPI_DevHandle parent,
                                                const char *pathname,
                                                KCL_ACPI_DevHandle *ret_handle)
{
    return KCL_ACPI_NOT_AVAILABLE;
}

unsigned int ATI_API_CALL KCL_ACPI_EvalObject(KCL_ACPI_DevHandle handle,
                                              struct KCL_ACPI_MethodInputInfo *info)
{
    return KCL_ACPI_NOT_AVAILABLE;
}

unsigned int ATI_API_CALL KCL_ACPI_InstallHandler(KCL_ACPI_DevHandle device,
                                                  unsigned int handler_type,
                                                  KCL_ACPI_CallbackHandle handler,
                                                  KCL_ACPI_ContextHandle context)
{
    return KCL_ACPI_NOT_AVAILABLE;
}

unsigned int ATI_API_CALL KCL_ACPI_RemoveHandler(KCL_ACPI_DevHandle device,
                                                 unsigned int handler_type,
                                                 KCL_ACPI_CallbackHandle handler)
{
    return KCL_ACPI_NOT_AVAILABLE;
}

unsigned int ATI_API_CALL KCL_ACPI_InstallLidHandler()
{
    return KCL_ACPI_NOT_AVAILABLE;
}
unsigned int ATI_API_CALL KCL_ACPI_RemoveLidHandler();
{
    return KCL_ACPI_NOT_AVAILABLE;
}

int ATI_API_CALL KCL_ACPI_Disabled(void)
{
    return (1); /* Needs to mimic acpi_disabled value when permanently disabled */
}

void KCL_ACPI_AcNotify(KCL_ACPI_DevHandle handle, unsigned int event, KCL_ACPI_ContextHandle data)
{
    return;
}

void ATI_API_CALL KCL_ACPI_ExecHandler(KCL_ACPI_CallbackHandle handler, KCL_ACPI_DevHandle handle, unsigned int event, KCL_ACPI_ContextHandle data)
{
    return;
}

KCL_ACPI_CallbackHandle ATI_API_CALL KCL_ACPI_GetNotifyHandler(KCL_ACPI_DevHandle handle)
{
    return NULL;
}

KCL_ACPI_ContextHandle ATI_API_CALL KCL_ACPI_GetNotifyContext(KCL_ACPI_DevHandle handle)
{
    return NULL;
}

void ATI_API_CALL KCL_ACPI_UpdateNotifyHandler(KCL_ACPI_DevHandle handle, KCL_ACPI_CallbackHandle handler)
{
    return;
}

void ATI_API_CALL KCL_ACPI_UpdateNotifyContext(KCL_ACPI_DevHandle handle, KCL_ACPI_ContextHandle context)
{
    return;
}

KCL_ACPI_DevHandle ATI_API_CALL KCL_ACPI_GetChildDevice(KCL_ACPI_DevHandle handle)
{
    return NULL;
}

KCL_ACPI_DevHandle ATI_API_CALL KCL_ACPI_GetPeerDevice(KCL_ACPI_DevHandle handle)
{
    return NULL;
}

void KCL_ACPI_VideoNotify(KCL_ACPI_DevHandle handle, unsigned int event, KCL_ACPI_ContextHandle data)
{
    return NULL;
}

unsigned int ATI_API_CALL KCL_ACPI_PowerXpressDevice(KCL_ACPI_DevHandle handle)
{
    return (1);
}

unsigned int ATI_API_CALL KCL_ACPI_GetHandles(struct KCL_ACPI_MatchInfo *pInfo)
{
    return KCL_ACPI_NOT_AVAILABLE;
}

KCL_ACPI_DevHandle ATI_API_CALL KCL_ACPI_GetAlternateHandle(KCL_ACPI_DevHandle pHandle)
{
    return NULL;
}

void ATI_API_CALL KCL_ACPI_No_Hotplug(void *)
{
    return;
}

#endif

/*
* The following KCL ACPI functions need to always work regardless
* of whether or not ACPI support has been built into the kernel.
*/

int ATI_API_CALL KCL_ACPI_GetFgConsole(void)
{
    return fg_console;
}

int ATI_API_CALL KCL_ACPI_GetNewVt(int console)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11)
    return vc_cons[console].d->vt_newvt;
#else
    return vt_cons[console]->vt_newvt;
#endif
}

/** \Parse a ACPI table with user defined function
*  \param id           ACPI signatures
*  \param handler      Callback function to parse ACPI table
*  \return
*/
int ATI_API_CALL KCL_ACPI_ParseTable(char *id, KCL_ACPI_IntCallbackHandle handler)
{
    struct acpi_table_header *hdr = NULL;
    acpi_size tbl_size;

    if (!handler)
    {
        return KCL_ACPI_ERROR;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,3)   
    if (!ACPI_SUCCESS(acpi_get_table_with_size(id, 0, &hdr, &tbl_size)))
#else
    tbl_size = 0x7fffffff;
    if (!ACPI_SUCCESS(acpi_get_table(id, 0, &hdr)))
#endif
    {
        return KCL_ACPI_ERROR;
    }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1)
    ((acpi_tbl_table_handler)handler)(hdr);
#else
    ((acpi_table_handler)handler)(hdr);
#endif
    return KCL_ACPI_OK;
}

3 (18.11.2014 12:55:37 отредактировано GoUpInSmoke)

Re: ядро 3.17.2 и ati 14.9

если верить комрадам с http://www.phoronix.com, то ядро 3.18 нормально работает с r7 r9 серией и драйверами ati 14.9
сейчас соберу, отпишусь...

ядро не собирается(пока).

4

Re: ядро 3.17.2 и ati 14.9

Вобщем, ати исправили драйвера
всё работает как надо с сайта amd.com