18c2ecf20Sopenharmony_ci/* $Id: capiutil.c,v 1.13.6.4 2001/09/23 22:24:33 kai Exp $ 28c2ecf20Sopenharmony_ci * 38c2ecf20Sopenharmony_ci * CAPI 2.0 convert capi message to capi message struct 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * From CAPI 2.0 Development Kit AVM 1995 (msg.c) 68c2ecf20Sopenharmony_ci * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This software may be used and distributed according to the terms 98c2ecf20Sopenharmony_ci * of the GNU General Public License, incorporated herein by reference. 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/string.h> 158c2ecf20Sopenharmony_ci#include <linux/ctype.h> 168c2ecf20Sopenharmony_ci#include <linux/stddef.h> 178c2ecf20Sopenharmony_ci#include <linux/kernel.h> 188c2ecf20Sopenharmony_ci#include <linux/mm.h> 198c2ecf20Sopenharmony_ci#include <linux/init.h> 208c2ecf20Sopenharmony_ci#include <linux/isdn/capiutil.h> 218c2ecf20Sopenharmony_ci#include <linux/slab.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include "kcapi.h" 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* from CAPI2.0 DDK AVM Berlin GmbH */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_citypedef struct { 288c2ecf20Sopenharmony_ci int typ; 298c2ecf20Sopenharmony_ci size_t off; 308c2ecf20Sopenharmony_ci} _cdef; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define _CBYTE 1 338c2ecf20Sopenharmony_ci#define _CWORD 2 348c2ecf20Sopenharmony_ci#define _CDWORD 3 358c2ecf20Sopenharmony_ci#define _CSTRUCT 4 368c2ecf20Sopenharmony_ci#define _CMSTRUCT 5 378c2ecf20Sopenharmony_ci#define _CEND 6 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic _cdef cdef[] = 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci /*00 */ 428c2ecf20Sopenharmony_ci {_CEND}, 438c2ecf20Sopenharmony_ci /*01 */ 448c2ecf20Sopenharmony_ci {_CEND}, 458c2ecf20Sopenharmony_ci /*02 */ 468c2ecf20Sopenharmony_ci {_CEND}, 478c2ecf20Sopenharmony_ci /*03 */ 488c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, adr.adrController)}, 498c2ecf20Sopenharmony_ci /*04 */ 508c2ecf20Sopenharmony_ci {_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)}, 518c2ecf20Sopenharmony_ci /*05 */ 528c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, B1configuration)}, 538c2ecf20Sopenharmony_ci /*06 */ 548c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, B1protocol)}, 558c2ecf20Sopenharmony_ci /*07 */ 568c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, B2configuration)}, 578c2ecf20Sopenharmony_ci /*08 */ 588c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, B2protocol)}, 598c2ecf20Sopenharmony_ci /*09 */ 608c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, B3configuration)}, 618c2ecf20Sopenharmony_ci /*0a */ 628c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, B3protocol)}, 638c2ecf20Sopenharmony_ci /*0b */ 648c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, BC)}, 658c2ecf20Sopenharmony_ci /*0c */ 668c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, BChannelinformation)}, 678c2ecf20Sopenharmony_ci /*0d */ 688c2ecf20Sopenharmony_ci {_CMSTRUCT, offsetof(_cmsg, BProtocol)}, 698c2ecf20Sopenharmony_ci /*0e */ 708c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)}, 718c2ecf20Sopenharmony_ci /*0f */ 728c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)}, 738c2ecf20Sopenharmony_ci /*10 */ 748c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)}, 758c2ecf20Sopenharmony_ci /*11 */ 768c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)}, 778c2ecf20Sopenharmony_ci /*12 */ 788c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, CIPmask)}, 798c2ecf20Sopenharmony_ci /*13 */ 808c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, CIPmask2)}, 818c2ecf20Sopenharmony_ci /*14 */ 828c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, CIPValue)}, 838c2ecf20Sopenharmony_ci /*15 */ 848c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, Class)}, 858c2ecf20Sopenharmony_ci /*16 */ 868c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, ConnectedNumber)}, 878c2ecf20Sopenharmony_ci /*17 */ 888c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)}, 898c2ecf20Sopenharmony_ci /*18 */ 908c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, Data)}, 918c2ecf20Sopenharmony_ci /*19 */ 928c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, DataHandle)}, 938c2ecf20Sopenharmony_ci /*1a */ 948c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, DataLength)}, 958c2ecf20Sopenharmony_ci /*1b */ 968c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)}, 978c2ecf20Sopenharmony_ci /*1c */ 988c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, Facilitydataarray)}, 998c2ecf20Sopenharmony_ci /*1d */ 1008c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)}, 1018c2ecf20Sopenharmony_ci /*1e */ 1028c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)}, 1038c2ecf20Sopenharmony_ci /*1f */ 1048c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, FacilitySelector)}, 1058c2ecf20Sopenharmony_ci /*20 */ 1068c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, Flags)}, 1078c2ecf20Sopenharmony_ci /*21 */ 1088c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, Function)}, 1098c2ecf20Sopenharmony_ci /*22 */ 1108c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, HLC)}, 1118c2ecf20Sopenharmony_ci /*23 */ 1128c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, Info)}, 1138c2ecf20Sopenharmony_ci /*24 */ 1148c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, InfoElement)}, 1158c2ecf20Sopenharmony_ci /*25 */ 1168c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, InfoMask)}, 1178c2ecf20Sopenharmony_ci /*26 */ 1188c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, InfoNumber)}, 1198c2ecf20Sopenharmony_ci /*27 */ 1208c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, Keypadfacility)}, 1218c2ecf20Sopenharmony_ci /*28 */ 1228c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, LLC)}, 1238c2ecf20Sopenharmony_ci /*29 */ 1248c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, ManuData)}, 1258c2ecf20Sopenharmony_ci /*2a */ 1268c2ecf20Sopenharmony_ci {_CDWORD, offsetof(_cmsg, ManuID)}, 1278c2ecf20Sopenharmony_ci /*2b */ 1288c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, NCPI)}, 1298c2ecf20Sopenharmony_ci /*2c */ 1308c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, Reason)}, 1318c2ecf20Sopenharmony_ci /*2d */ 1328c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, Reason_B3)}, 1338c2ecf20Sopenharmony_ci /*2e */ 1348c2ecf20Sopenharmony_ci {_CWORD, offsetof(_cmsg, Reject)}, 1358c2ecf20Sopenharmony_ci /*2f */ 1368c2ecf20Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, Useruserdata)} 1378c2ecf20Sopenharmony_ci}; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistatic unsigned char *cpars[] = 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci /* ALERT_REQ */ [0x01] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01", 1428c2ecf20Sopenharmony_ci /* CONNECT_REQ */ [0x02] = "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01", 1438c2ecf20Sopenharmony_ci /* DISCONNECT_REQ */ [0x04] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01", 1448c2ecf20Sopenharmony_ci /* LISTEN_REQ */ [0x05] = "\x03\x25\x12\x13\x10\x11\x01", 1458c2ecf20Sopenharmony_ci /* INFO_REQ */ [0x08] = "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01", 1468c2ecf20Sopenharmony_ci /* FACILITY_REQ */ [0x09] = "\x03\x1f\x1e\x01", 1478c2ecf20Sopenharmony_ci /* SELECT_B_PROTOCOL_REQ */ [0x0a] = "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01", 1488c2ecf20Sopenharmony_ci /* CONNECT_B3_REQ */ [0x0b] = "\x03\x2b\x01", 1498c2ecf20Sopenharmony_ci /* DISCONNECT_B3_REQ */ [0x0d] = "\x03\x2b\x01", 1508c2ecf20Sopenharmony_ci /* DATA_B3_REQ */ [0x0f] = "\x03\x18\x1a\x19\x20\x01", 1518c2ecf20Sopenharmony_ci /* RESET_B3_REQ */ [0x10] = "\x03\x2b\x01", 1528c2ecf20Sopenharmony_ci /* ALERT_CONF */ [0x13] = "\x03\x23\x01", 1538c2ecf20Sopenharmony_ci /* CONNECT_CONF */ [0x14] = "\x03\x23\x01", 1548c2ecf20Sopenharmony_ci /* DISCONNECT_CONF */ [0x16] = "\x03\x23\x01", 1558c2ecf20Sopenharmony_ci /* LISTEN_CONF */ [0x17] = "\x03\x23\x01", 1568c2ecf20Sopenharmony_ci /* MANUFACTURER_REQ */ [0x18] = "\x03\x2a\x15\x21\x29\x01", 1578c2ecf20Sopenharmony_ci /* INFO_CONF */ [0x1a] = "\x03\x23\x01", 1588c2ecf20Sopenharmony_ci /* FACILITY_CONF */ [0x1b] = "\x03\x23\x1f\x1b\x01", 1598c2ecf20Sopenharmony_ci /* SELECT_B_PROTOCOL_CONF */ [0x1c] = "\x03\x23\x01", 1608c2ecf20Sopenharmony_ci /* CONNECT_B3_CONF */ [0x1d] = "\x03\x23\x01", 1618c2ecf20Sopenharmony_ci /* DISCONNECT_B3_CONF */ [0x1f] = "\x03\x23\x01", 1628c2ecf20Sopenharmony_ci /* DATA_B3_CONF */ [0x21] = "\x03\x19\x23\x01", 1638c2ecf20Sopenharmony_ci /* RESET_B3_CONF */ [0x22] = "\x03\x23\x01", 1648c2ecf20Sopenharmony_ci /* CONNECT_IND */ [0x26] = "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01", 1658c2ecf20Sopenharmony_ci /* CONNECT_ACTIVE_IND */ [0x27] = "\x03\x16\x17\x28\x01", 1668c2ecf20Sopenharmony_ci /* DISCONNECT_IND */ [0x28] = "\x03\x2c\x01", 1678c2ecf20Sopenharmony_ci /* MANUFACTURER_CONF */ [0x2a] = "\x03\x2a\x15\x21\x29\x01", 1688c2ecf20Sopenharmony_ci /* INFO_IND */ [0x2c] = "\x03\x26\x24\x01", 1698c2ecf20Sopenharmony_ci /* FACILITY_IND */ [0x2d] = "\x03\x1f\x1d\x01", 1708c2ecf20Sopenharmony_ci /* CONNECT_B3_IND */ [0x2f] = "\x03\x2b\x01", 1718c2ecf20Sopenharmony_ci /* CONNECT_B3_ACTIVE_IND */ [0x30] = "\x03\x2b\x01", 1728c2ecf20Sopenharmony_ci /* DISCONNECT_B3_IND */ [0x31] = "\x03\x2d\x2b\x01", 1738c2ecf20Sopenharmony_ci /* DATA_B3_IND */ [0x33] = "\x03\x18\x1a\x19\x20\x01", 1748c2ecf20Sopenharmony_ci /* RESET_B3_IND */ [0x34] = "\x03\x2b\x01", 1758c2ecf20Sopenharmony_ci /* CONNECT_B3_T90_ACTIVE_IND */ [0x35] = "\x03\x2b\x01", 1768c2ecf20Sopenharmony_ci /* CONNECT_RESP */ [0x38] = "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01", 1778c2ecf20Sopenharmony_ci /* CONNECT_ACTIVE_RESP */ [0x39] = "\x03\x01", 1788c2ecf20Sopenharmony_ci /* DISCONNECT_RESP */ [0x3a] = "\x03\x01", 1798c2ecf20Sopenharmony_ci /* MANUFACTURER_IND */ [0x3c] = "\x03\x2a\x15\x21\x29\x01", 1808c2ecf20Sopenharmony_ci /* INFO_RESP */ [0x3e] = "\x03\x01", 1818c2ecf20Sopenharmony_ci /* FACILITY_RESP */ [0x3f] = "\x03\x1f\x01", 1828c2ecf20Sopenharmony_ci /* CONNECT_B3_RESP */ [0x41] = "\x03\x2e\x2b\x01", 1838c2ecf20Sopenharmony_ci /* CONNECT_B3_ACTIVE_RESP */ [0x42] = "\x03\x01", 1848c2ecf20Sopenharmony_ci /* DISCONNECT_B3_RESP */ [0x43] = "\x03\x01", 1858c2ecf20Sopenharmony_ci /* DATA_B3_RESP */ [0x45] = "\x03\x19\x01", 1868c2ecf20Sopenharmony_ci /* RESET_B3_RESP */ [0x46] = "\x03\x01", 1878c2ecf20Sopenharmony_ci /* CONNECT_B3_T90_ACTIVE_RESP */ [0x47] = "\x03\x01", 1888c2ecf20Sopenharmony_ci /* MANUFACTURER_RESP */ [0x4e] = "\x03\x2a\x15\x21\x29\x01", 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci#define byteTLcpy(x, y) *(u8 *)(x) = *(u8 *)(y); 1948c2ecf20Sopenharmony_ci#define wordTLcpy(x, y) *(u16 *)(x) = *(u16 *)(y); 1958c2ecf20Sopenharmony_ci#define dwordTLcpy(x, y) memcpy(x, y, 4); 1968c2ecf20Sopenharmony_ci#define structTLcpy(x, y, l) memcpy(x, y, l) 1978c2ecf20Sopenharmony_ci#define structTLcpyovl(x, y, l) memmove(x, y, l) 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci#define byteTRcpy(x, y) *(u8 *)(y) = *(u8 *)(x); 2008c2ecf20Sopenharmony_ci#define wordTRcpy(x, y) *(u16 *)(y) = *(u16 *)(x); 2018c2ecf20Sopenharmony_ci#define dwordTRcpy(x, y) memcpy(y, x, 4); 2028c2ecf20Sopenharmony_ci#define structTRcpy(x, y, l) memcpy(y, x, l) 2038c2ecf20Sopenharmony_ci#define structTRcpyovl(x, y, l) memmove(y, x, l) 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 2068c2ecf20Sopenharmony_cistatic unsigned command_2_index(u8 c, u8 sc) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci if (c & 0x80) 2098c2ecf20Sopenharmony_ci c = 0x9 + (c & 0x0f); 2108c2ecf20Sopenharmony_ci else if (c == 0x41) 2118c2ecf20Sopenharmony_ci c = 0x9 + 0x1; 2128c2ecf20Sopenharmony_ci if (c > 0x18) 2138c2ecf20Sopenharmony_ci c = 0x00; 2148c2ecf20Sopenharmony_ci return (sc & 3) * (0x9 + 0x9) + c; 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci/** 2188c2ecf20Sopenharmony_ci * capi_cmd2par() - find parameter string for CAPI 2.0 command/subcommand 2198c2ecf20Sopenharmony_ci * @cmd: command number 2208c2ecf20Sopenharmony_ci * @subcmd: subcommand number 2218c2ecf20Sopenharmony_ci * 2228c2ecf20Sopenharmony_ci * Return value: static string, NULL if command/subcommand unknown 2238c2ecf20Sopenharmony_ci */ 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic unsigned char *capi_cmd2par(u8 cmd, u8 subcmd) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci return cpars[command_2_index(cmd, subcmd)]; 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 2318c2ecf20Sopenharmony_ci#define TYP (cdef[cmsg->par[cmsg->p]].typ) 2328c2ecf20Sopenharmony_ci#define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off) 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic void jumpcstruct(_cmsg *cmsg) 2358c2ecf20Sopenharmony_ci{ 2368c2ecf20Sopenharmony_ci unsigned layer; 2378c2ecf20Sopenharmony_ci for (cmsg->p++, layer = 1; layer;) { 2388c2ecf20Sopenharmony_ci /* $$$$$ assert (cmsg->p); */ 2398c2ecf20Sopenharmony_ci cmsg->p++; 2408c2ecf20Sopenharmony_ci switch (TYP) { 2418c2ecf20Sopenharmony_ci case _CMSTRUCT: 2428c2ecf20Sopenharmony_ci layer++; 2438c2ecf20Sopenharmony_ci break; 2448c2ecf20Sopenharmony_ci case _CEND: 2458c2ecf20Sopenharmony_ci layer--; 2468c2ecf20Sopenharmony_ci break; 2478c2ecf20Sopenharmony_ci } 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_cistatic char *mnames[] = 2548c2ecf20Sopenharmony_ci{ 2558c2ecf20Sopenharmony_ci [0x01] = "ALERT_REQ", 2568c2ecf20Sopenharmony_ci [0x02] = "CONNECT_REQ", 2578c2ecf20Sopenharmony_ci [0x04] = "DISCONNECT_REQ", 2588c2ecf20Sopenharmony_ci [0x05] = "LISTEN_REQ", 2598c2ecf20Sopenharmony_ci [0x08] = "INFO_REQ", 2608c2ecf20Sopenharmony_ci [0x09] = "FACILITY_REQ", 2618c2ecf20Sopenharmony_ci [0x0a] = "SELECT_B_PROTOCOL_REQ", 2628c2ecf20Sopenharmony_ci [0x0b] = "CONNECT_B3_REQ", 2638c2ecf20Sopenharmony_ci [0x0d] = "DISCONNECT_B3_REQ", 2648c2ecf20Sopenharmony_ci [0x0f] = "DATA_B3_REQ", 2658c2ecf20Sopenharmony_ci [0x10] = "RESET_B3_REQ", 2668c2ecf20Sopenharmony_ci [0x13] = "ALERT_CONF", 2678c2ecf20Sopenharmony_ci [0x14] = "CONNECT_CONF", 2688c2ecf20Sopenharmony_ci [0x16] = "DISCONNECT_CONF", 2698c2ecf20Sopenharmony_ci [0x17] = "LISTEN_CONF", 2708c2ecf20Sopenharmony_ci [0x18] = "MANUFACTURER_REQ", 2718c2ecf20Sopenharmony_ci [0x1a] = "INFO_CONF", 2728c2ecf20Sopenharmony_ci [0x1b] = "FACILITY_CONF", 2738c2ecf20Sopenharmony_ci [0x1c] = "SELECT_B_PROTOCOL_CONF", 2748c2ecf20Sopenharmony_ci [0x1d] = "CONNECT_B3_CONF", 2758c2ecf20Sopenharmony_ci [0x1f] = "DISCONNECT_B3_CONF", 2768c2ecf20Sopenharmony_ci [0x21] = "DATA_B3_CONF", 2778c2ecf20Sopenharmony_ci [0x22] = "RESET_B3_CONF", 2788c2ecf20Sopenharmony_ci [0x26] = "CONNECT_IND", 2798c2ecf20Sopenharmony_ci [0x27] = "CONNECT_ACTIVE_IND", 2808c2ecf20Sopenharmony_ci [0x28] = "DISCONNECT_IND", 2818c2ecf20Sopenharmony_ci [0x2a] = "MANUFACTURER_CONF", 2828c2ecf20Sopenharmony_ci [0x2c] = "INFO_IND", 2838c2ecf20Sopenharmony_ci [0x2d] = "FACILITY_IND", 2848c2ecf20Sopenharmony_ci [0x2f] = "CONNECT_B3_IND", 2858c2ecf20Sopenharmony_ci [0x30] = "CONNECT_B3_ACTIVE_IND", 2868c2ecf20Sopenharmony_ci [0x31] = "DISCONNECT_B3_IND", 2878c2ecf20Sopenharmony_ci [0x33] = "DATA_B3_IND", 2888c2ecf20Sopenharmony_ci [0x34] = "RESET_B3_IND", 2898c2ecf20Sopenharmony_ci [0x35] = "CONNECT_B3_T90_ACTIVE_IND", 2908c2ecf20Sopenharmony_ci [0x38] = "CONNECT_RESP", 2918c2ecf20Sopenharmony_ci [0x39] = "CONNECT_ACTIVE_RESP", 2928c2ecf20Sopenharmony_ci [0x3a] = "DISCONNECT_RESP", 2938c2ecf20Sopenharmony_ci [0x3c] = "MANUFACTURER_IND", 2948c2ecf20Sopenharmony_ci [0x3e] = "INFO_RESP", 2958c2ecf20Sopenharmony_ci [0x3f] = "FACILITY_RESP", 2968c2ecf20Sopenharmony_ci [0x41] = "CONNECT_B3_RESP", 2978c2ecf20Sopenharmony_ci [0x42] = "CONNECT_B3_ACTIVE_RESP", 2988c2ecf20Sopenharmony_ci [0x43] = "DISCONNECT_B3_RESP", 2998c2ecf20Sopenharmony_ci [0x45] = "DATA_B3_RESP", 3008c2ecf20Sopenharmony_ci [0x46] = "RESET_B3_RESP", 3018c2ecf20Sopenharmony_ci [0x47] = "CONNECT_B3_T90_ACTIVE_RESP", 3028c2ecf20Sopenharmony_ci [0x4e] = "MANUFACTURER_RESP" 3038c2ecf20Sopenharmony_ci}; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci/** 3068c2ecf20Sopenharmony_ci * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name 3078c2ecf20Sopenharmony_ci * @cmd: command number 3088c2ecf20Sopenharmony_ci * @subcmd: subcommand number 3098c2ecf20Sopenharmony_ci * 3108c2ecf20Sopenharmony_ci * Return value: static string 3118c2ecf20Sopenharmony_ci */ 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cichar *capi_cmd2str(u8 cmd, u8 subcmd) 3148c2ecf20Sopenharmony_ci{ 3158c2ecf20Sopenharmony_ci char *result; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci result = mnames[command_2_index(cmd, subcmd)]; 3188c2ecf20Sopenharmony_ci if (result == NULL) 3198c2ecf20Sopenharmony_ci result = "INVALID_COMMAND"; 3208c2ecf20Sopenharmony_ci return result; 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci#ifdef CONFIG_CAPI_TRACE 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_cistatic char *pnames[] = 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci /*00 */ NULL, 3338c2ecf20Sopenharmony_ci /*01 */ NULL, 3348c2ecf20Sopenharmony_ci /*02 */ NULL, 3358c2ecf20Sopenharmony_ci /*03 */ "Controller/PLCI/NCCI", 3368c2ecf20Sopenharmony_ci /*04 */ "AdditionalInfo", 3378c2ecf20Sopenharmony_ci /*05 */ "B1configuration", 3388c2ecf20Sopenharmony_ci /*06 */ "B1protocol", 3398c2ecf20Sopenharmony_ci /*07 */ "B2configuration", 3408c2ecf20Sopenharmony_ci /*08 */ "B2protocol", 3418c2ecf20Sopenharmony_ci /*09 */ "B3configuration", 3428c2ecf20Sopenharmony_ci /*0a */ "B3protocol", 3438c2ecf20Sopenharmony_ci /*0b */ "BC", 3448c2ecf20Sopenharmony_ci /*0c */ "BChannelinformation", 3458c2ecf20Sopenharmony_ci /*0d */ "BProtocol", 3468c2ecf20Sopenharmony_ci /*0e */ "CalledPartyNumber", 3478c2ecf20Sopenharmony_ci /*0f */ "CalledPartySubaddress", 3488c2ecf20Sopenharmony_ci /*10 */ "CallingPartyNumber", 3498c2ecf20Sopenharmony_ci /*11 */ "CallingPartySubaddress", 3508c2ecf20Sopenharmony_ci /*12 */ "CIPmask", 3518c2ecf20Sopenharmony_ci /*13 */ "CIPmask2", 3528c2ecf20Sopenharmony_ci /*14 */ "CIPValue", 3538c2ecf20Sopenharmony_ci /*15 */ "Class", 3548c2ecf20Sopenharmony_ci /*16 */ "ConnectedNumber", 3558c2ecf20Sopenharmony_ci /*17 */ "ConnectedSubaddress", 3568c2ecf20Sopenharmony_ci /*18 */ "Data32", 3578c2ecf20Sopenharmony_ci /*19 */ "DataHandle", 3588c2ecf20Sopenharmony_ci /*1a */ "DataLength", 3598c2ecf20Sopenharmony_ci /*1b */ "FacilityConfirmationParameter", 3608c2ecf20Sopenharmony_ci /*1c */ "Facilitydataarray", 3618c2ecf20Sopenharmony_ci /*1d */ "FacilityIndicationParameter", 3628c2ecf20Sopenharmony_ci /*1e */ "FacilityRequestParameter", 3638c2ecf20Sopenharmony_ci /*1f */ "FacilitySelector", 3648c2ecf20Sopenharmony_ci /*20 */ "Flags", 3658c2ecf20Sopenharmony_ci /*21 */ "Function", 3668c2ecf20Sopenharmony_ci /*22 */ "HLC", 3678c2ecf20Sopenharmony_ci /*23 */ "Info", 3688c2ecf20Sopenharmony_ci /*24 */ "InfoElement", 3698c2ecf20Sopenharmony_ci /*25 */ "InfoMask", 3708c2ecf20Sopenharmony_ci /*26 */ "InfoNumber", 3718c2ecf20Sopenharmony_ci /*27 */ "Keypadfacility", 3728c2ecf20Sopenharmony_ci /*28 */ "LLC", 3738c2ecf20Sopenharmony_ci /*29 */ "ManuData", 3748c2ecf20Sopenharmony_ci /*2a */ "ManuID", 3758c2ecf20Sopenharmony_ci /*2b */ "NCPI", 3768c2ecf20Sopenharmony_ci /*2c */ "Reason", 3778c2ecf20Sopenharmony_ci /*2d */ "Reason_B3", 3788c2ecf20Sopenharmony_ci /*2e */ "Reject", 3798c2ecf20Sopenharmony_ci /*2f */ "Useruserdata" 3808c2ecf20Sopenharmony_ci}; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci#include <stdarg.h> 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 3858c2ecf20Sopenharmony_cistatic _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt, ...) 3868c2ecf20Sopenharmony_ci{ 3878c2ecf20Sopenharmony_ci va_list f; 3888c2ecf20Sopenharmony_ci size_t n, r; 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci if (!cdb) 3918c2ecf20Sopenharmony_ci return NULL; 3928c2ecf20Sopenharmony_ci va_start(f, fmt); 3938c2ecf20Sopenharmony_ci r = cdb->size - cdb->pos; 3948c2ecf20Sopenharmony_ci n = vsnprintf(cdb->p, r, fmt, f); 3958c2ecf20Sopenharmony_ci va_end(f); 3968c2ecf20Sopenharmony_ci if (n >= r) { 3978c2ecf20Sopenharmony_ci /* truncated, need bigger buffer */ 3988c2ecf20Sopenharmony_ci size_t ns = 2 * cdb->size; 3998c2ecf20Sopenharmony_ci u_char *nb; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci while ((ns - cdb->pos) <= n) 4028c2ecf20Sopenharmony_ci ns *= 2; 4038c2ecf20Sopenharmony_ci nb = kmalloc(ns, GFP_ATOMIC); 4048c2ecf20Sopenharmony_ci if (!nb) { 4058c2ecf20Sopenharmony_ci cdebbuf_free(cdb); 4068c2ecf20Sopenharmony_ci return NULL; 4078c2ecf20Sopenharmony_ci } 4088c2ecf20Sopenharmony_ci memcpy(nb, cdb->buf, cdb->pos); 4098c2ecf20Sopenharmony_ci kfree(cdb->buf); 4108c2ecf20Sopenharmony_ci nb[cdb->pos] = 0; 4118c2ecf20Sopenharmony_ci cdb->buf = nb; 4128c2ecf20Sopenharmony_ci cdb->p = cdb->buf + cdb->pos; 4138c2ecf20Sopenharmony_ci cdb->size = ns; 4148c2ecf20Sopenharmony_ci va_start(f, fmt); 4158c2ecf20Sopenharmony_ci r = cdb->size - cdb->pos; 4168c2ecf20Sopenharmony_ci n = vsnprintf(cdb->p, r, fmt, f); 4178c2ecf20Sopenharmony_ci va_end(f); 4188c2ecf20Sopenharmony_ci } 4198c2ecf20Sopenharmony_ci cdb->p += n; 4208c2ecf20Sopenharmony_ci cdb->pos += n; 4218c2ecf20Sopenharmony_ci return cdb; 4228c2ecf20Sopenharmony_ci} 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_cistatic _cdebbuf *printstructlen(_cdebbuf *cdb, u8 *m, unsigned len) 4258c2ecf20Sopenharmony_ci{ 4268c2ecf20Sopenharmony_ci unsigned hex = 0; 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci if (!cdb) 4298c2ecf20Sopenharmony_ci return NULL; 4308c2ecf20Sopenharmony_ci for (; len; len--, m++) 4318c2ecf20Sopenharmony_ci if (isalnum(*m) || *m == ' ') { 4328c2ecf20Sopenharmony_ci if (hex) 4338c2ecf20Sopenharmony_ci cdb = bufprint(cdb, ">"); 4348c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%c", *m); 4358c2ecf20Sopenharmony_ci hex = 0; 4368c2ecf20Sopenharmony_ci } else { 4378c2ecf20Sopenharmony_ci if (!hex) 4388c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "<%02x", *m); 4398c2ecf20Sopenharmony_ci else 4408c2ecf20Sopenharmony_ci cdb = bufprint(cdb, " %02x", *m); 4418c2ecf20Sopenharmony_ci hex = 1; 4428c2ecf20Sopenharmony_ci } 4438c2ecf20Sopenharmony_ci if (hex) 4448c2ecf20Sopenharmony_ci cdb = bufprint(cdb, ">"); 4458c2ecf20Sopenharmony_ci return cdb; 4468c2ecf20Sopenharmony_ci} 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_cistatic _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m) 4498c2ecf20Sopenharmony_ci{ 4508c2ecf20Sopenharmony_ci unsigned len; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci if (m[0] != 0xff) { 4538c2ecf20Sopenharmony_ci len = m[0]; 4548c2ecf20Sopenharmony_ci m += 1; 4558c2ecf20Sopenharmony_ci } else { 4568c2ecf20Sopenharmony_ci len = ((u16 *) (m + 1))[0]; 4578c2ecf20Sopenharmony_ci m += 3; 4588c2ecf20Sopenharmony_ci } 4598c2ecf20Sopenharmony_ci cdb = printstructlen(cdb, m, len); 4608c2ecf20Sopenharmony_ci return cdb; 4618c2ecf20Sopenharmony_ci} 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 4648c2ecf20Sopenharmony_ci#define NAME (pnames[cmsg->par[cmsg->p]]) 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_cistatic _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level) 4678c2ecf20Sopenharmony_ci{ 4688c2ecf20Sopenharmony_ci if (!cmsg->par) 4698c2ecf20Sopenharmony_ci return NULL; /* invalid command/subcommand */ 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci for (; TYP != _CEND; cmsg->p++) { 4728c2ecf20Sopenharmony_ci int slen = 29 + 3 - level; 4738c2ecf20Sopenharmony_ci int i; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci if (!cdb) 4768c2ecf20Sopenharmony_ci return NULL; 4778c2ecf20Sopenharmony_ci cdb = bufprint(cdb, " "); 4788c2ecf20Sopenharmony_ci for (i = 0; i < level - 1; i++) 4798c2ecf20Sopenharmony_ci cdb = bufprint(cdb, " "); 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci switch (TYP) { 4828c2ecf20Sopenharmony_ci case _CBYTE: 4838c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); 4848c2ecf20Sopenharmony_ci cmsg->l++; 4858c2ecf20Sopenharmony_ci break; 4868c2ecf20Sopenharmony_ci case _CWORD: 4878c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); 4888c2ecf20Sopenharmony_ci cmsg->l += 2; 4898c2ecf20Sopenharmony_ci break; 4908c2ecf20Sopenharmony_ci case _CDWORD: 4918c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); 4928c2ecf20Sopenharmony_ci cmsg->l += 4; 4938c2ecf20Sopenharmony_ci break; 4948c2ecf20Sopenharmony_ci case _CSTRUCT: 4958c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%-*s = ", slen, NAME); 4968c2ecf20Sopenharmony_ci if (cmsg->m[cmsg->l] == '\0') 4978c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "default"); 4988c2ecf20Sopenharmony_ci else 4998c2ecf20Sopenharmony_ci cdb = printstruct(cdb, cmsg->m + cmsg->l); 5008c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "\n"); 5018c2ecf20Sopenharmony_ci if (cmsg->m[cmsg->l] != 0xff) 5028c2ecf20Sopenharmony_ci cmsg->l += 1 + cmsg->m[cmsg->l]; 5038c2ecf20Sopenharmony_ci else 5048c2ecf20Sopenharmony_ci cmsg->l += 3 + *(u16 *) (cmsg->m + cmsg->l + 1); 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci break; 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci case _CMSTRUCT: 5098c2ecf20Sopenharmony_ci/*----- Metastruktur 0 -----*/ 5108c2ecf20Sopenharmony_ci if (cmsg->m[cmsg->l] == '\0') { 5118c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%-*s = default\n", slen, NAME); 5128c2ecf20Sopenharmony_ci cmsg->l++; 5138c2ecf20Sopenharmony_ci jumpcstruct(cmsg); 5148c2ecf20Sopenharmony_ci } else { 5158c2ecf20Sopenharmony_ci char *name = NAME; 5168c2ecf20Sopenharmony_ci unsigned _l = cmsg->l; 5178c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%-*s\n", slen, name); 5188c2ecf20Sopenharmony_ci cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1; 5198c2ecf20Sopenharmony_ci cmsg->p++; 5208c2ecf20Sopenharmony_ci cdb = protocol_message_2_pars(cdb, cmsg, level + 1); 5218c2ecf20Sopenharmony_ci } 5228c2ecf20Sopenharmony_ci break; 5238c2ecf20Sopenharmony_ci } 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci return cdb; 5268c2ecf20Sopenharmony_ci} 5278c2ecf20Sopenharmony_ci/*-------------------------------------------------------*/ 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_cistatic _cdebbuf *g_debbuf; 5308c2ecf20Sopenharmony_cistatic u_long g_debbuf_lock; 5318c2ecf20Sopenharmony_cistatic _cmsg *g_cmsg; 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_cistatic _cdebbuf *cdebbuf_alloc(void) 5348c2ecf20Sopenharmony_ci{ 5358c2ecf20Sopenharmony_ci _cdebbuf *cdb; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci if (likely(!test_and_set_bit(1, &g_debbuf_lock))) { 5388c2ecf20Sopenharmony_ci cdb = g_debbuf; 5398c2ecf20Sopenharmony_ci goto init; 5408c2ecf20Sopenharmony_ci } else 5418c2ecf20Sopenharmony_ci cdb = kmalloc(sizeof(_cdebbuf), GFP_ATOMIC); 5428c2ecf20Sopenharmony_ci if (!cdb) 5438c2ecf20Sopenharmony_ci return NULL; 5448c2ecf20Sopenharmony_ci cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC); 5458c2ecf20Sopenharmony_ci if (!cdb->buf) { 5468c2ecf20Sopenharmony_ci kfree(cdb); 5478c2ecf20Sopenharmony_ci return NULL; 5488c2ecf20Sopenharmony_ci } 5498c2ecf20Sopenharmony_ci cdb->size = CDEBUG_SIZE; 5508c2ecf20Sopenharmony_ciinit: 5518c2ecf20Sopenharmony_ci cdb->buf[0] = 0; 5528c2ecf20Sopenharmony_ci cdb->p = cdb->buf; 5538c2ecf20Sopenharmony_ci cdb->pos = 0; 5548c2ecf20Sopenharmony_ci return cdb; 5558c2ecf20Sopenharmony_ci} 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci/** 5588c2ecf20Sopenharmony_ci * cdebbuf_free() - free CAPI debug buffer 5598c2ecf20Sopenharmony_ci * @cdb: buffer to free 5608c2ecf20Sopenharmony_ci */ 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_civoid cdebbuf_free(_cdebbuf *cdb) 5638c2ecf20Sopenharmony_ci{ 5648c2ecf20Sopenharmony_ci if (likely(cdb == g_debbuf)) { 5658c2ecf20Sopenharmony_ci test_and_clear_bit(1, &g_debbuf_lock); 5668c2ecf20Sopenharmony_ci return; 5678c2ecf20Sopenharmony_ci } 5688c2ecf20Sopenharmony_ci if (likely(cdb)) 5698c2ecf20Sopenharmony_ci kfree(cdb->buf); 5708c2ecf20Sopenharmony_ci kfree(cdb); 5718c2ecf20Sopenharmony_ci} 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci/** 5758c2ecf20Sopenharmony_ci * capi_message2str() - format CAPI 2.0 message for printing 5768c2ecf20Sopenharmony_ci * @msg: CAPI 2.0 message 5778c2ecf20Sopenharmony_ci * 5788c2ecf20Sopenharmony_ci * Allocates a CAPI debug buffer and fills it with a printable representation 5798c2ecf20Sopenharmony_ci * of the CAPI 2.0 message in @msg. 5808c2ecf20Sopenharmony_ci * Return value: allocated debug buffer, NULL on error 5818c2ecf20Sopenharmony_ci * The returned buffer should be freed by a call to cdebbuf_free() after use. 5828c2ecf20Sopenharmony_ci */ 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci_cdebbuf *capi_message2str(u8 *msg) 5858c2ecf20Sopenharmony_ci{ 5868c2ecf20Sopenharmony_ci _cdebbuf *cdb; 5878c2ecf20Sopenharmony_ci _cmsg *cmsg; 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci cdb = cdebbuf_alloc(); 5908c2ecf20Sopenharmony_ci if (unlikely(!cdb)) 5918c2ecf20Sopenharmony_ci return NULL; 5928c2ecf20Sopenharmony_ci if (likely(cdb == g_debbuf)) 5938c2ecf20Sopenharmony_ci cmsg = g_cmsg; 5948c2ecf20Sopenharmony_ci else 5958c2ecf20Sopenharmony_ci cmsg = kmalloc(sizeof(_cmsg), GFP_ATOMIC); 5968c2ecf20Sopenharmony_ci if (unlikely(!cmsg)) { 5978c2ecf20Sopenharmony_ci cdebbuf_free(cdb); 5988c2ecf20Sopenharmony_ci return NULL; 5998c2ecf20Sopenharmony_ci } 6008c2ecf20Sopenharmony_ci cmsg->m = msg; 6018c2ecf20Sopenharmony_ci cmsg->l = 8; 6028c2ecf20Sopenharmony_ci cmsg->p = 0; 6038c2ecf20Sopenharmony_ci byteTRcpy(cmsg->m + 4, &cmsg->Command); 6048c2ecf20Sopenharmony_ci byteTRcpy(cmsg->m + 5, &cmsg->Subcommand); 6058c2ecf20Sopenharmony_ci cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand); 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n", 6088c2ecf20Sopenharmony_ci capi_cmd2str(cmsg->Command, cmsg->Subcommand), 6098c2ecf20Sopenharmony_ci ((unsigned short *) msg)[1], 6108c2ecf20Sopenharmony_ci ((unsigned short *) msg)[3], 6118c2ecf20Sopenharmony_ci ((unsigned short *) msg)[0]); 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci cdb = protocol_message_2_pars(cdb, cmsg, 1); 6148c2ecf20Sopenharmony_ci if (unlikely(cmsg != g_cmsg)) 6158c2ecf20Sopenharmony_ci kfree(cmsg); 6168c2ecf20Sopenharmony_ci return cdb; 6178c2ecf20Sopenharmony_ci} 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ciint __init cdebug_init(void) 6208c2ecf20Sopenharmony_ci{ 6218c2ecf20Sopenharmony_ci g_cmsg = kmalloc(sizeof(_cmsg), GFP_KERNEL); 6228c2ecf20Sopenharmony_ci if (!g_cmsg) 6238c2ecf20Sopenharmony_ci return -ENOMEM; 6248c2ecf20Sopenharmony_ci g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL); 6258c2ecf20Sopenharmony_ci if (!g_debbuf) { 6268c2ecf20Sopenharmony_ci kfree(g_cmsg); 6278c2ecf20Sopenharmony_ci return -ENOMEM; 6288c2ecf20Sopenharmony_ci } 6298c2ecf20Sopenharmony_ci g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL); 6308c2ecf20Sopenharmony_ci if (!g_debbuf->buf) { 6318c2ecf20Sopenharmony_ci kfree(g_cmsg); 6328c2ecf20Sopenharmony_ci kfree(g_debbuf); 6338c2ecf20Sopenharmony_ci return -ENOMEM; 6348c2ecf20Sopenharmony_ci } 6358c2ecf20Sopenharmony_ci g_debbuf->size = CDEBUG_GSIZE; 6368c2ecf20Sopenharmony_ci g_debbuf->buf[0] = 0; 6378c2ecf20Sopenharmony_ci g_debbuf->p = g_debbuf->buf; 6388c2ecf20Sopenharmony_ci g_debbuf->pos = 0; 6398c2ecf20Sopenharmony_ci return 0; 6408c2ecf20Sopenharmony_ci} 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_civoid cdebug_exit(void) 6438c2ecf20Sopenharmony_ci{ 6448c2ecf20Sopenharmony_ci if (g_debbuf) 6458c2ecf20Sopenharmony_ci kfree(g_debbuf->buf); 6468c2ecf20Sopenharmony_ci kfree(g_debbuf); 6478c2ecf20Sopenharmony_ci kfree(g_cmsg); 6488c2ecf20Sopenharmony_ci} 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci#else /* !CONFIG_CAPI_TRACE */ 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_cistatic _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0}; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci_cdebbuf *capi_message2str(u8 *msg) 6558c2ecf20Sopenharmony_ci{ 6568c2ecf20Sopenharmony_ci return &g_debbuf; 6578c2ecf20Sopenharmony_ci} 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci_cdebbuf *capi_cmsg2str(_cmsg *cmsg) 6608c2ecf20Sopenharmony_ci{ 6618c2ecf20Sopenharmony_ci return &g_debbuf; 6628c2ecf20Sopenharmony_ci} 6638c2ecf20Sopenharmony_ci 6648c2ecf20Sopenharmony_civoid cdebbuf_free(_cdebbuf *cdb) 6658c2ecf20Sopenharmony_ci{ 6668c2ecf20Sopenharmony_ci} 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ciint __init cdebug_init(void) 6698c2ecf20Sopenharmony_ci{ 6708c2ecf20Sopenharmony_ci return 0; 6718c2ecf20Sopenharmony_ci} 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_civoid cdebug_exit(void) 6748c2ecf20Sopenharmony_ci{ 6758c2ecf20Sopenharmony_ci} 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci#endif 678