// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2016 MediaTek Inc. */ #include "udc.h" struct udc_func_info udc_func_table; /* Register UDC API */ int register_udc_func_deflateInit2(deflateInit2_cb_func_t func) { int ret = 0; if (udc_func_table.deflateInit2 == NULL) { udc_func_table.deflateInit2 = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int deflateInit2_cb(struct z_stream_s *strm, int level, int method, int windowBits, int memLevel, int strategy) { deflateInit2_cb_func_t func; int ret = 0; func = udc_func_table.deflateInit2; if (func != NULL) { ret = func(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(struct z_stream_s)); } else { ret = -1;/* E_NO_EXIST */ pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_deflateSetDict( deflateSetDict_cb_func_t func) { int ret = 0; if (udc_func_table.deflateSetDict == NULL) { udc_func_table.deflateSetDict = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int deflateSetDictionary_cb(struct z_stream_s *strm, const char *dictionary, unsigned int dictLength) { deflateSetDict_cb_func_t func; int ret = 0; func = udc_func_table.deflateSetDict; if (func != NULL) { ret = func(strm, dictionary, dictLength); } else { ret = -1;/* E_NO_EXIST */ pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_deflate(deflate_cb_func_t func) { int ret = 0; if (udc_func_table.deflate == NULL) { udc_func_table.deflate = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int deflate_cb(struct z_stream_s *strm, int flush) { deflate_cb_func_t func; int ret = 0; func = udc_func_table.deflate; if (func != NULL) { ret = func(strm, flush); } else { ret = -1;//E_NO_EXIST pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_deflateEnd(deflateEnd_cb_func_t func) { int ret = 0; if (udc_func_table.deflateEnd == NULL) { udc_func_table.deflateEnd = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int deflateEnd_cb(struct z_stream_s *strm) { deflateEnd_cb_func_t func; int ret = 0; func = udc_func_table.deflateEnd; if (func != NULL) { ret = func(strm); } else { ret = -1;//E_NO_EXIST pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_deflateReset(deflateReset_cb_func_t func) { int ret = 0; if (udc_func_table.deflateReset == NULL) { udc_func_table.deflateReset = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int deflateReset_cb(struct z_stream_s *strm) { deflateReset_cb_func_t func; int ret = 0; func = udc_func_table.deflateReset; if (func != NULL) { ret = func(strm); } else { ret = -1;//E_NO_EXIST pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_deflateBound(deflateBound_cb_func_t func) { int ret = 0; if (udc_func_table.deflateBound == NULL) { udc_func_table.deflateBound = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int deflateBound_cb(struct z_stream_s *strm, unsigned long sourceLen) { deflateBound_cb_func_t func; int ret = 0; func = udc_func_table.deflateBound; if (func != NULL) { ret = func(strm, sourceLen); } else { ret = -1;//E_NO_EXIST pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_udc_chksum(udc_chksum_cb_func_t func) { int ret = 0; if (udc_func_table.udc_chksum == NULL) { udc_func_table.udc_chksum = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int udc_chksum_cb(struct z_stream_s *strm) { udc_chksum_cb_func_t func; unsigned int ret = 0; func = udc_func_table.udc_chksum; if (func != NULL) { ret = func(strm); } else { ret = -1;//E_NO_EXIST pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_udc_QueryPara(udc_QueryPara_cb_func_t func) { int ret = 0; if (udc_func_table.udc_QueryPara == NULL) { udc_func_table.udc_QueryPara = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int udc_QueryPara_cb(struct z_stream_s *strm, int id, void *param) { udc_QueryPara_cb_func_t func; unsigned int ret = 0; func = udc_func_table.udc_QueryPara; if (func != NULL) { ret = func(strm, id, param); } else { ret = -1;//E_NO_EXIST pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_func_udc_GetCmpLen(udc_GetCmpLen_cb_func_t func) { int ret = 0; if (udc_func_table.udc_GetCmpLen == NULL) { udc_func_table.udc_GetCmpLen = func; pr_notice("%s success\n", __func__); } else { pr_notice("%s fail: registered!\n", __func__); ret = -1; } return ret; } int udc_GetCmpLen_cb(struct z_stream_s *strm, unsigned char *start, unsigned char *end) { udc_GetCmpLen_cb_func_t func; unsigned int ret = 0; func = udc_func_table.udc_GetCmpLen; if (func != NULL) { ret = func(strm, start, end); } else { ret = -1;//E_NO_EXIST pr_notice("exec %s fail: not register!\n", __func__); } return ret; } int register_udc_functions(unsigned int id, void *f) { switch (id) { case ID_deflateInit2: { deflateInit2_cb_func_t func = (deflateInit2_cb_func_t)f; return register_udc_func_deflateInit2(func); } case ID_deflateSetDict: { deflateSetDict_cb_func_t func = (deflateSetDict_cb_func_t)f; return register_udc_func_deflateSetDict(func); } case ID_deflateEnd: { deflateEnd_cb_func_t func = (deflateEnd_cb_func_t)f; return register_udc_func_deflateEnd(func); } case ID_deflateReset: { deflateReset_cb_func_t func = (deflateReset_cb_func_t)f; return register_udc_func_deflateReset(func); } case ID_deflate: { deflate_cb_func_t func = (deflate_cb_func_t)f; return register_udc_func_deflate(func); } case ID_deflateBound: { deflateBound_cb_func_t func = (deflateBound_cb_func_t)f; return register_udc_func_deflateBound(func); } case ID_udc_chksum: { udc_chksum_cb_func_t func = (udc_chksum_cb_func_t)f; return register_udc_func_udc_chksum(func); } case ID_udc_QueryPara: { udc_QueryPara_cb_func_t func = (udc_QueryPara_cb_func_t)f; return register_udc_func_udc_QueryPara(func); } case ID_udc_GetCmpLen: { udc_GetCmpLen_cb_func_t func = (udc_GetCmpLen_cb_func_t)f; return register_udc_func_udc_GetCmpLen(func); } default: pr_notice("udc func id %d not found\n", id); return -1; } } EXPORT_SYMBOL(register_udc_functions); void my_free(void *my_param, void *ptr) { struct udc_private_data *p = (struct udc_private_data *)my_param; if (p != NULL && p->mem != NULL && p->used > 0) { if ((unsigned char *)ptr >= p->mem && (unsigned char *)ptr < p->mem + p->used) { p->used = (unsigned char *)ptr - p->mem; } } } void *my_malloc(void *my_param, unsigned int size, unsigned int count) { struct udc_private_data *p = (struct udc_private_data *)my_param; unsigned char *ptr; if (p == NULL) return NULL; if (p->mem == NULL || p->size == 0) return NULL; if (p->size < p->used + size*count) return NULL; ptr = p->mem + p->used; p->used += size*count; return (void *)ptr; } int udc_init(struct z_stream_s *zcpr, struct udc_private_data *my_param) { int ret = 0; my_param->used = 0; ret = udc_QueryPara_cb(NULL, UDC_QUERY_WORKSPACE_SIZE, &my_param->size); my_param->mem = vmalloc(my_param->size); pr_debug("%s:alloc memory:%p\n", __func__, my_param->mem); (*zcpr).zalloc = &my_malloc; (*zcpr).zfree = &my_free; (*zcpr).opaque = my_param; return ret; } void udc_deinit(struct z_stream_s *zcpr) { struct udc_private_data *p = (struct udc_private_data *)((*zcpr).opaque); pr_debug("%s:free memory:%p\n", __func__, p->mem); vfree(p->mem); }