14a49301eSmrg/*
24a49301eSmrg * Copyright 2009 VMware, Inc.
34a49301eSmrg * All Rights Reserved.
44a49301eSmrg *
54a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a
64a49301eSmrg * copy of this software and associated documentation files (the "Software"),
74a49301eSmrg * to deal in the Software without restriction, including without limitation
84a49301eSmrg * on the rights to use, copy, modify, merge, publish, distribute, sub
94a49301eSmrg * license, and/or sell copies of the Software, and to permit persons to whom
104a49301eSmrg * the Software is furnished to do so, subject to the following conditions:
114a49301eSmrg *
124a49301eSmrg * The above copyright notice and this permission notice (including the next
134a49301eSmrg * paragraph) shall be included in all copies or substantial portions of the
144a49301eSmrg * Software.
154a49301eSmrg *
164a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
174a49301eSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
184a49301eSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
194a49301eSmrg * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
204a49301eSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
214a49301eSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
224a49301eSmrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
234a49301eSmrg */
244a49301eSmrg
254a49301eSmrg/*
264a49301eSmrg * This file holds the function implementation for one of the rbug extensions.
274a49301eSmrg * Prototypes and declerations of functions and structs is in the same folder
284a49301eSmrg * in the header file matching this file's name.
294a49301eSmrg *
304a49301eSmrg * The functions starting rbug_send_* encodes a call to the write format and
314a49301eSmrg * sends that to the supplied connection, while functions starting with
324a49301eSmrg * rbug_demarshal_* demarshal data in the wire protocol.
334a49301eSmrg *
344a49301eSmrg * Functions ending with _reply are replies to requests.
354a49301eSmrg */
364a49301eSmrg
374a49301eSmrg#include "rbug_internal.h"
38af69d88dSmrg#include "rbug_shader.h"
394a49301eSmrg
404a49301eSmrgint rbug_send_shader_list(struct rbug_connection *__con,
414a49301eSmrg                          rbug_context_t context,
424a49301eSmrg                          uint32_t *__serial)
434a49301eSmrg{
444a49301eSmrg	uint32_t __len = 0;
454a49301eSmrg	uint32_t __pos = 0;
464a49301eSmrg	uint8_t *__data = NULL;
474a49301eSmrg	int __ret = 0;
484a49301eSmrg
494a49301eSmrg	LEN(8); /* header */
504a49301eSmrg	LEN(8); /* context */
514a49301eSmrg
524a49301eSmrg	/* align */
534a49301eSmrg	PAD(__len, 8);
544a49301eSmrg
554a49301eSmrg	__data = (uint8_t*)MALLOC(__len);
564a49301eSmrg	if (!__data)
574a49301eSmrg		return -ENOMEM;
584a49301eSmrg
594a49301eSmrg	WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_LIST));
604a49301eSmrg	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
614a49301eSmrg	WRITE(8, rbug_context_t, context); /* context */
624a49301eSmrg
634a49301eSmrg	/* final pad */
644a49301eSmrg	PAD(__pos, 8);
654a49301eSmrg
664a49301eSmrg	if (__pos != __len) {
674a49301eSmrg		__ret = -EINVAL;
684a49301eSmrg	} else {
694a49301eSmrg		rbug_connection_send_start(__con, RBUG_OP_SHADER_LIST, __len);
704a49301eSmrg		rbug_connection_write(__con, __data, __len);
714a49301eSmrg		__ret = rbug_connection_send_finish(__con, __serial);
724a49301eSmrg	}
734a49301eSmrg
744a49301eSmrg	FREE(__data);
754a49301eSmrg	return __ret;
764a49301eSmrg}
774a49301eSmrg
784a49301eSmrgint rbug_send_shader_info(struct rbug_connection *__con,
794a49301eSmrg                          rbug_context_t context,
804a49301eSmrg                          rbug_shader_t shader,
814a49301eSmrg                          uint32_t *__serial)
824a49301eSmrg{
834a49301eSmrg	uint32_t __len = 0;
844a49301eSmrg	uint32_t __pos = 0;
854a49301eSmrg	uint8_t *__data = NULL;
864a49301eSmrg	int __ret = 0;
874a49301eSmrg
884a49301eSmrg	LEN(8); /* header */
894a49301eSmrg	LEN(8); /* context */
904a49301eSmrg	LEN(8); /* shader */
914a49301eSmrg
924a49301eSmrg	/* align */
934a49301eSmrg	PAD(__len, 8);
944a49301eSmrg
954a49301eSmrg	__data = (uint8_t*)MALLOC(__len);
964a49301eSmrg	if (!__data)
974a49301eSmrg		return -ENOMEM;
984a49301eSmrg
994a49301eSmrg	WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_INFO));
1004a49301eSmrg	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
1014a49301eSmrg	WRITE(8, rbug_context_t, context); /* context */
1024a49301eSmrg	WRITE(8, rbug_shader_t, shader); /* shader */
1034a49301eSmrg
1044a49301eSmrg	/* final pad */
1054a49301eSmrg	PAD(__pos, 8);
1064a49301eSmrg
1074a49301eSmrg	if (__pos != __len) {
1084a49301eSmrg		__ret = -EINVAL;
1094a49301eSmrg	} else {
1104a49301eSmrg		rbug_connection_send_start(__con, RBUG_OP_SHADER_INFO, __len);
1114a49301eSmrg		rbug_connection_write(__con, __data, __len);
1124a49301eSmrg		__ret = rbug_connection_send_finish(__con, __serial);
1134a49301eSmrg	}
1144a49301eSmrg
1154a49301eSmrg	FREE(__data);
1164a49301eSmrg	return __ret;
1174a49301eSmrg}
1184a49301eSmrg
1194a49301eSmrgint rbug_send_shader_disable(struct rbug_connection *__con,
1204a49301eSmrg                             rbug_context_t context,
1214a49301eSmrg                             rbug_shader_t shader,
1224a49301eSmrg                             uint8_t disable,
1234a49301eSmrg                             uint32_t *__serial)
1244a49301eSmrg{
1254a49301eSmrg	uint32_t __len = 0;
1264a49301eSmrg	uint32_t __pos = 0;
1274a49301eSmrg	uint8_t *__data = NULL;
1284a49301eSmrg	int __ret = 0;
1294a49301eSmrg
1304a49301eSmrg	LEN(8); /* header */
1314a49301eSmrg	LEN(8); /* context */
1324a49301eSmrg	LEN(8); /* shader */
1334a49301eSmrg	LEN(1); /* disable */
1344a49301eSmrg
1354a49301eSmrg	/* align */
1364a49301eSmrg	PAD(__len, 8);
1374a49301eSmrg
1384a49301eSmrg	__data = (uint8_t*)MALLOC(__len);
1394a49301eSmrg	if (!__data)
1404a49301eSmrg		return -ENOMEM;
1414a49301eSmrg
1424a49301eSmrg	WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_DISABLE));
1434a49301eSmrg	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
1444a49301eSmrg	WRITE(8, rbug_context_t, context); /* context */
1454a49301eSmrg	WRITE(8, rbug_shader_t, shader); /* shader */
1464a49301eSmrg	WRITE(1, uint8_t, disable); /* disable */
1474a49301eSmrg
1484a49301eSmrg	/* final pad */
1494a49301eSmrg	PAD(__pos, 8);
1504a49301eSmrg
1514a49301eSmrg	if (__pos != __len) {
1524a49301eSmrg		__ret = -EINVAL;
1534a49301eSmrg	} else {
1544a49301eSmrg		rbug_connection_send_start(__con, RBUG_OP_SHADER_DISABLE, __len);
1554a49301eSmrg		rbug_connection_write(__con, __data, __len);
1564a49301eSmrg		__ret = rbug_connection_send_finish(__con, __serial);
1574a49301eSmrg	}
1584a49301eSmrg
1594a49301eSmrg	FREE(__data);
1604a49301eSmrg	return __ret;
1614a49301eSmrg}
1624a49301eSmrg
1634a49301eSmrgint rbug_send_shader_replace(struct rbug_connection *__con,
1644a49301eSmrg                             rbug_context_t context,
1654a49301eSmrg                             rbug_shader_t shader,
1664a49301eSmrg                             uint32_t *tokens,
1674a49301eSmrg                             uint32_t tokens_len,
1684a49301eSmrg                             uint32_t *__serial)
1694a49301eSmrg{
1704a49301eSmrg	uint32_t __len = 0;
1714a49301eSmrg	uint32_t __pos = 0;
1724a49301eSmrg	uint8_t *__data = NULL;
1734a49301eSmrg	int __ret = 0;
1744a49301eSmrg
1754a49301eSmrg	LEN(8); /* header */
1764a49301eSmrg	LEN(8); /* context */
1774a49301eSmrg	LEN(8); /* shader */
1784a49301eSmrg	LEN_ARRAY(4, tokens); /* tokens */
1794a49301eSmrg
1804a49301eSmrg	/* align */
1814a49301eSmrg	PAD(__len, 8);
1824a49301eSmrg
1834a49301eSmrg	__data = (uint8_t*)MALLOC(__len);
1844a49301eSmrg	if (!__data)
1854a49301eSmrg		return -ENOMEM;
1864a49301eSmrg
1874a49301eSmrg	WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_REPLACE));
1884a49301eSmrg	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
1894a49301eSmrg	WRITE(8, rbug_context_t, context); /* context */
1904a49301eSmrg	WRITE(8, rbug_shader_t, shader); /* shader */
1914a49301eSmrg	WRITE_ARRAY(4, uint32_t, tokens); /* tokens */
1924a49301eSmrg
1934a49301eSmrg	/* final pad */
1944a49301eSmrg	PAD(__pos, 8);
1954a49301eSmrg
1964a49301eSmrg	if (__pos != __len) {
1974a49301eSmrg		__ret = -EINVAL;
1984a49301eSmrg	} else {
1994a49301eSmrg		rbug_connection_send_start(__con, RBUG_OP_SHADER_REPLACE, __len);
2004a49301eSmrg		rbug_connection_write(__con, __data, __len);
2014a49301eSmrg		__ret = rbug_connection_send_finish(__con, __serial);
2024a49301eSmrg	}
2034a49301eSmrg
2044a49301eSmrg	FREE(__data);
2054a49301eSmrg	return __ret;
2064a49301eSmrg}
2074a49301eSmrg
2084a49301eSmrgint rbug_send_shader_list_reply(struct rbug_connection *__con,
2094a49301eSmrg                                uint32_t serial,
2104a49301eSmrg                                rbug_shader_t *shaders,
2114a49301eSmrg                                uint32_t shaders_len,
2124a49301eSmrg                                uint32_t *__serial)
2134a49301eSmrg{
2144a49301eSmrg	uint32_t __len = 0;
2154a49301eSmrg	uint32_t __pos = 0;
2164a49301eSmrg	uint8_t *__data = NULL;
2174a49301eSmrg	int __ret = 0;
2184a49301eSmrg
2194a49301eSmrg	LEN(8); /* header */
2204a49301eSmrg	LEN(4); /* serial */
2214a49301eSmrg	LEN_ARRAY(8, shaders); /* shaders */
2224a49301eSmrg
2234a49301eSmrg	/* align */
2244a49301eSmrg	PAD(__len, 8);
2254a49301eSmrg
2264a49301eSmrg	__data = (uint8_t*)MALLOC(__len);
2274a49301eSmrg	if (!__data)
2284a49301eSmrg		return -ENOMEM;
2294a49301eSmrg
2304a49301eSmrg	WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_LIST_REPLY));
2314a49301eSmrg	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
2324a49301eSmrg	WRITE(4, uint32_t, serial); /* serial */
2334a49301eSmrg	WRITE_ARRAY(8, rbug_shader_t, shaders); /* shaders */
2344a49301eSmrg
2354a49301eSmrg	/* final pad */
2364a49301eSmrg	PAD(__pos, 8);
2374a49301eSmrg
2384a49301eSmrg	if (__pos != __len) {
2394a49301eSmrg		__ret = -EINVAL;
2404a49301eSmrg	} else {
2414a49301eSmrg		rbug_connection_send_start(__con, RBUG_OP_SHADER_LIST_REPLY, __len);
2424a49301eSmrg		rbug_connection_write(__con, __data, __len);
2434a49301eSmrg		__ret = rbug_connection_send_finish(__con, __serial);
2444a49301eSmrg	}
2454a49301eSmrg
2464a49301eSmrg	FREE(__data);
2474a49301eSmrg	return __ret;
2484a49301eSmrg}
2494a49301eSmrg
2504a49301eSmrgint rbug_send_shader_info_reply(struct rbug_connection *__con,
2514a49301eSmrg                                uint32_t serial,
2524a49301eSmrg                                uint32_t *original,
2534a49301eSmrg                                uint32_t original_len,
2544a49301eSmrg                                uint32_t *replaced,
2554a49301eSmrg                                uint32_t replaced_len,
2564a49301eSmrg                                uint8_t disabled,
2574a49301eSmrg                                uint32_t *__serial)
2584a49301eSmrg{
2594a49301eSmrg	uint32_t __len = 0;
2604a49301eSmrg	uint32_t __pos = 0;
2614a49301eSmrg	uint8_t *__data = NULL;
2624a49301eSmrg	int __ret = 0;
2634a49301eSmrg
2644a49301eSmrg	LEN(8); /* header */
2654a49301eSmrg	LEN(4); /* serial */
2664a49301eSmrg	LEN_ARRAY(4, original); /* original */
2674a49301eSmrg	LEN_ARRAY(4, replaced); /* replaced */
2684a49301eSmrg	LEN(1); /* disabled */
2694a49301eSmrg
2704a49301eSmrg	/* align */
2714a49301eSmrg	PAD(__len, 8);
2724a49301eSmrg
2734a49301eSmrg	__data = (uint8_t*)MALLOC(__len);
2744a49301eSmrg	if (!__data)
2754a49301eSmrg		return -ENOMEM;
2764a49301eSmrg
2774a49301eSmrg	WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_INFO_REPLY));
2784a49301eSmrg	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
2794a49301eSmrg	WRITE(4, uint32_t, serial); /* serial */
2804a49301eSmrg	WRITE_ARRAY(4, uint32_t, original); /* original */
2814a49301eSmrg	WRITE_ARRAY(4, uint32_t, replaced); /* replaced */
2824a49301eSmrg	WRITE(1, uint8_t, disabled); /* disabled */
2834a49301eSmrg
2844a49301eSmrg	/* final pad */
2854a49301eSmrg	PAD(__pos, 8);
2864a49301eSmrg
2874a49301eSmrg	if (__pos != __len) {
2884a49301eSmrg		__ret = -EINVAL;
2894a49301eSmrg	} else {
2904a49301eSmrg		rbug_connection_send_start(__con, RBUG_OP_SHADER_INFO_REPLY, __len);
2914a49301eSmrg		rbug_connection_write(__con, __data, __len);
2924a49301eSmrg		__ret = rbug_connection_send_finish(__con, __serial);
2934a49301eSmrg	}
2944a49301eSmrg
2954a49301eSmrg	FREE(__data);
2964a49301eSmrg	return __ret;
2974a49301eSmrg}
2984a49301eSmrg
2994a49301eSmrgstruct rbug_proto_shader_list * rbug_demarshal_shader_list(struct rbug_proto_header *header)
3004a49301eSmrg{
3014a49301eSmrg	uint32_t len = 0;
3024a49301eSmrg	uint32_t pos = 0;
3034a49301eSmrg	uint8_t *data =  NULL;
3044a49301eSmrg	struct rbug_proto_shader_list *ret;
3054a49301eSmrg
3064a49301eSmrg	if (!header)
3074a49301eSmrg		return NULL;
3083464ebd5Sriastradh	if (header->opcode != (int32_t)RBUG_OP_SHADER_LIST)
3094a49301eSmrg		return NULL;
3104a49301eSmrg
3114a49301eSmrg	pos = 0;
3124a49301eSmrg	len = header->length * 4;
3134a49301eSmrg	data = (uint8_t*)&header[1];
3144a49301eSmrg	ret = MALLOC(sizeof(*ret));
3154a49301eSmrg	if (!ret)
3164a49301eSmrg		return NULL;
3174a49301eSmrg
3184a49301eSmrg	ret->header.__message = header;
3194a49301eSmrg	ret->header.opcode = header->opcode;
3204a49301eSmrg
3214a49301eSmrg	READ(8, rbug_context_t, context); /* context */
3224a49301eSmrg
3234a49301eSmrg	return ret;
3244a49301eSmrg}
3254a49301eSmrg
3264a49301eSmrgstruct rbug_proto_shader_info * rbug_demarshal_shader_info(struct rbug_proto_header *header)
3274a49301eSmrg{
3284a49301eSmrg	uint32_t len = 0;
3294a49301eSmrg	uint32_t pos = 0;
3304a49301eSmrg	uint8_t *data =  NULL;
3314a49301eSmrg	struct rbug_proto_shader_info *ret;
3324a49301eSmrg
3334a49301eSmrg	if (!header)
3344a49301eSmrg		return NULL;
3353464ebd5Sriastradh	if (header->opcode != (int32_t)RBUG_OP_SHADER_INFO)
3364a49301eSmrg		return NULL;
3374a49301eSmrg
3384a49301eSmrg	pos = 0;
3394a49301eSmrg	len = header->length * 4;
3404a49301eSmrg	data = (uint8_t*)&header[1];
3414a49301eSmrg	ret = MALLOC(sizeof(*ret));
3424a49301eSmrg	if (!ret)
3434a49301eSmrg		return NULL;
3444a49301eSmrg
3454a49301eSmrg	ret->header.__message = header;
3464a49301eSmrg	ret->header.opcode = header->opcode;
3474a49301eSmrg
3484a49301eSmrg	READ(8, rbug_context_t, context); /* context */
3494a49301eSmrg	READ(8, rbug_shader_t, shader); /* shader */
3504a49301eSmrg
3514a49301eSmrg	return ret;
3524a49301eSmrg}
3534a49301eSmrg
3544a49301eSmrgstruct rbug_proto_shader_disable * rbug_demarshal_shader_disable(struct rbug_proto_header *header)
3554a49301eSmrg{
3564a49301eSmrg	uint32_t len = 0;
3574a49301eSmrg	uint32_t pos = 0;
3584a49301eSmrg	uint8_t *data =  NULL;
3594a49301eSmrg	struct rbug_proto_shader_disable *ret;
3604a49301eSmrg
3614a49301eSmrg	if (!header)
3624a49301eSmrg		return NULL;
3633464ebd5Sriastradh	if (header->opcode != (int32_t)RBUG_OP_SHADER_DISABLE)
3644a49301eSmrg		return NULL;
3654a49301eSmrg
3664a49301eSmrg	pos = 0;
3674a49301eSmrg	len = header->length * 4;
3684a49301eSmrg	data = (uint8_t*)&header[1];
3694a49301eSmrg	ret = MALLOC(sizeof(*ret));
3704a49301eSmrg	if (!ret)
3714a49301eSmrg		return NULL;
3724a49301eSmrg
3734a49301eSmrg	ret->header.__message = header;
3744a49301eSmrg	ret->header.opcode = header->opcode;
3754a49301eSmrg
3764a49301eSmrg	READ(8, rbug_context_t, context); /* context */
3774a49301eSmrg	READ(8, rbug_shader_t, shader); /* shader */
3784a49301eSmrg	READ(1, uint8_t, disable); /* disable */
3794a49301eSmrg
3804a49301eSmrg	return ret;
3814a49301eSmrg}
3824a49301eSmrg
3834a49301eSmrgstruct rbug_proto_shader_replace * rbug_demarshal_shader_replace(struct rbug_proto_header *header)
3844a49301eSmrg{
3854a49301eSmrg	uint32_t len = 0;
3864a49301eSmrg	uint32_t pos = 0;
3874a49301eSmrg	uint8_t *data =  NULL;
3884a49301eSmrg	struct rbug_proto_shader_replace *ret;
3894a49301eSmrg
3904a49301eSmrg	if (!header)
3914a49301eSmrg		return NULL;
3923464ebd5Sriastradh	if (header->opcode != (int32_t)RBUG_OP_SHADER_REPLACE)
3934a49301eSmrg		return NULL;
3944a49301eSmrg
3954a49301eSmrg	pos = 0;
3964a49301eSmrg	len = header->length * 4;
3974a49301eSmrg	data = (uint8_t*)&header[1];
3984a49301eSmrg	ret = MALLOC(sizeof(*ret));
3994a49301eSmrg	if (!ret)
4004a49301eSmrg		return NULL;
4014a49301eSmrg
4024a49301eSmrg	ret->header.__message = header;
4034a49301eSmrg	ret->header.opcode = header->opcode;
4044a49301eSmrg
4054a49301eSmrg	READ(8, rbug_context_t, context); /* context */
4064a49301eSmrg	READ(8, rbug_shader_t, shader); /* shader */
4074a49301eSmrg	READ_ARRAY(4, uint32_t, tokens); /* tokens */
4084a49301eSmrg
4094a49301eSmrg	return ret;
4104a49301eSmrg}
4114a49301eSmrg
4124a49301eSmrgstruct rbug_proto_shader_list_reply * rbug_demarshal_shader_list_reply(struct rbug_proto_header *header)
4134a49301eSmrg{
4144a49301eSmrg	uint32_t len = 0;
4154a49301eSmrg	uint32_t pos = 0;
4164a49301eSmrg	uint8_t *data =  NULL;
4174a49301eSmrg	struct rbug_proto_shader_list_reply *ret;
4184a49301eSmrg
4194a49301eSmrg	if (!header)
4204a49301eSmrg		return NULL;
4213464ebd5Sriastradh	if (header->opcode != (int32_t)RBUG_OP_SHADER_LIST_REPLY)
4224a49301eSmrg		return NULL;
4234a49301eSmrg
4244a49301eSmrg	pos = 0;
4254a49301eSmrg	len = header->length * 4;
4264a49301eSmrg	data = (uint8_t*)&header[1];
4274a49301eSmrg	ret = MALLOC(sizeof(*ret));
4284a49301eSmrg	if (!ret)
4294a49301eSmrg		return NULL;
4304a49301eSmrg
4314a49301eSmrg	ret->header.__message = header;
4324a49301eSmrg	ret->header.opcode = header->opcode;
4334a49301eSmrg
4344a49301eSmrg	READ(4, uint32_t, serial); /* serial */
4354a49301eSmrg	READ_ARRAY(8, rbug_shader_t, shaders); /* shaders */
4364a49301eSmrg
4374a49301eSmrg	return ret;
4384a49301eSmrg}
4394a49301eSmrg
4404a49301eSmrgstruct rbug_proto_shader_info_reply * rbug_demarshal_shader_info_reply(struct rbug_proto_header *header)
4414a49301eSmrg{
4424a49301eSmrg	uint32_t len = 0;
4434a49301eSmrg	uint32_t pos = 0;
4444a49301eSmrg	uint8_t *data =  NULL;
4454a49301eSmrg	struct rbug_proto_shader_info_reply *ret;
4464a49301eSmrg
4474a49301eSmrg	if (!header)
4484a49301eSmrg		return NULL;
4493464ebd5Sriastradh	if (header->opcode != (int32_t)RBUG_OP_SHADER_INFO_REPLY)
4504a49301eSmrg		return NULL;
4514a49301eSmrg
4524a49301eSmrg	pos = 0;
4534a49301eSmrg	len = header->length * 4;
4544a49301eSmrg	data = (uint8_t*)&header[1];
4554a49301eSmrg	ret = MALLOC(sizeof(*ret));
4564a49301eSmrg	if (!ret)
4574a49301eSmrg		return NULL;
4584a49301eSmrg
4594a49301eSmrg	ret->header.__message = header;
4604a49301eSmrg	ret->header.opcode = header->opcode;
4614a49301eSmrg
4624a49301eSmrg	READ(4, uint32_t, serial); /* serial */
4634a49301eSmrg	READ_ARRAY(4, uint32_t, original); /* original */
4644a49301eSmrg	READ_ARRAY(4, uint32_t, replaced); /* replaced */
4654a49301eSmrg	READ(1, uint8_t, disabled); /* disabled */
4664a49301eSmrg
4674a49301eSmrg	return ret;
4684a49301eSmrg}
469