Conversion of old init_timer in new linux kernel

Viewed 2075

I am trying to build a SDK driver (with no documentation or support from the manufacturer). The original driver uses init_timer() and passes in a pointer to the timer_list structure. And it uses the 'data' element. Now I know that some of the timer functions are deprecated in the newer Linux kernels. Currently I am using kernel version 4.15.

What is the best way to access the 'data' element?

Current function looks like this -

OS_RESULT OS_TimerCreate(OS_DRV_CONTEXT* aContext, OS_TIMER* aTimer, OS_UINT32 aPeriodic, OS_TIMER_FNC aFunction, 
            OS_VOID* aData, OS_UINT32 aPeriod)
{
    struct timer_list* lTimer = (struct timer_list*) aTimer->Space;
    unsigned long lJiffies = jiffies;
    unsigned long lPeriod = msecs_to_jiffies(aPeriod);

    OS_UNREFERENCED_PARAMETER(aContext);
    OS_ASSERT( OS_TIMER_SIZE >= sizeof(timer_list));

    init_timer(lTimer);

    lTimer->expires = lJiffies + lPeriod;
    lTimer->data = (unsigned long) aTimer;
    aTimer->Function = aFunction;
    aTimer->Data = aData;   
    aTimer->Period = lPeriod;
    if (aPeriodic)
    {
        lTimer->function = OS_TimerPeriodicInternalFunc; 
    }
    else
    {
        lTimer->function = OS_TimerInternalFunc; 
    }

    add_timer(lTimer);

    return OS_RESULT_OK;
}

Declaration for reference -

typedef struct
{
    OS_UINT8      Space[OS_TIMER_SIZE];
    OS_TIMER_FNC  Function;
    OS_VOID*      Data;
    OS_UINT32     Period;
} OS_TIMER;

OS_DECL_EXTERN OS_RESULT OS_TimerCreate(OS_DRV_CONTEXT* aContext, OS_TIMER* aTimer, OS_UINT32 aPeriodic, OS_TIMER_FNC aFunction, OS_VOID* aData, OS_UINT32 aPeriod /* ms */);

Any help will be appreciated.

1 Answers

You first need to change the member that stores the struct timer_list to be of the correct type instead of using an array of bytes:

typedef struct
{
    struct timer_list Timer;
    OS_TIMER_FNC  Function;
    OS_VOID*      Data;
    OS_UINT32     Period;
} OS_TIMER;

(and lTimer is just set to &aTimer->Timer).

In the old code the data member is just set to a pointer to the OS_TIMER structure that contains the timer. In the new code, the callback can instead get this pointer using the from_timer macro, eg if in the old callback you had this:

OS_TIMER *aTimer = lTimer->data;

then in the new code you would instead have:

OS_TIMER *aTimer = from_timer(aTimer, lTimer, Timer);

(where the last parameter Timer is the name of the struct timer_list field in OS_TIMER).

Related