/***************************************************************************/
/*                             Druckersoftware                             */
/*                    Copyright (C) Carl Valentin GmbH                     */
/***************************************************************************/

/*
 * JobApi_waitForAnyDmaCompletion.h
 *
 *  Created on: 22.04.2022
 *      Author: preitinger
 */

#ifndef JOBAPI_JOBAPI_WAITFORANYDMACOMPLETION_H_
#define JOBAPI_JOBAPI_WAITFORANYDMACOMPLETION_H_

#include "../KM_CvKernelAccess.h"
#include <linux/types.h>

typedef struct SCvWaitForAnyCompletionResp {
    uint32_t resp;
    int size;
} CvWaitForAnyCompletionResp;

static inline void CvWaitForAnyCompletionResp_init(CvWaitForAnyCompletionResp* x) {
    x->resp = 0;
    x->size = 0;
}

/**
 * shifted resp um 8 nach rechts, setzt ch und count im hoechsten Byte (das "ganz links"),
 * erhoeht size um 1 und gibt true zurueck gdw. size == 4 erreicht wurde.
 */
static inline bool CvWaitForAnyCompletionResp_put(CvWaitForAnyCompletionResp* x, int ch, int count) {
    ASSERT(ch >= 0 && ch < 64);
    ASSERT(count >= 0 && count < 4);
    x->resp >>= 8;
    x->resp &= 0xffffff;
    x->resp |= ((ch & 63) << 24);
    x->resp |= ((count & 3) << 30);
    ++x->size;
    ASSERT(x->size > 0 && x->size <= 4);
    return x->size >= 4;
}

/**
 * falls size < 4 ist, wird resp um ((4 - size) * 8) nach rechts geschoben, so dass erste mit
 * ~put eingefuegte Byte ganz rechts ist.
 */
static inline void CvWaitForAnyCompletionResp_close(CvWaitForAnyCompletionResp* x) {
    int i;

    for (i = x->size; i < 4; ++i) {
        CvWaitForAnyCompletionResp_put(x, 0, 0);
    }

//    pr_info("nach CvWaitForAnyCompletionResp_close: x->size=%d; resp=0x%x\n", x->size, (int) x->resp);
}

/**
 * kopiert die Werte aus dem niedrigsten Byte (das "ganz rechts") nach *ch und *count,
 * shifted dann resp um 8 nach rechts, reduziert size um 1.
 */
static inline void CvWaitForAnyCompletionResp_get(CvWaitForAnyCompletionResp* x, int* ch, int* count) {
    *ch = (x->resp & 63);
    x->resp >>= 6;
    *count = (x->resp & 3);
    x->resp >>= 2;
    --x->size;
}


#endif /* JOBAPI_JOBAPI_WAITFORANYDMACOMPLETION_H_ */
