xref: /linux/drivers/usb/gadget/u_os_desc.h (revision 37a3a533429ef9b3cc9f15a656c19623f0e88df7)
1*37a3a533SAndrzej Pietrasiewicz /*
2*37a3a533SAndrzej Pietrasiewicz  * u_os_desc.h
3*37a3a533SAndrzej Pietrasiewicz  *
4*37a3a533SAndrzej Pietrasiewicz  * Utility definitions for "OS Descriptors" support
5*37a3a533SAndrzej Pietrasiewicz  *
6*37a3a533SAndrzej Pietrasiewicz  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
7*37a3a533SAndrzej Pietrasiewicz  *		http://www.samsung.com
8*37a3a533SAndrzej Pietrasiewicz  *
9*37a3a533SAndrzej Pietrasiewicz  * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
10*37a3a533SAndrzej Pietrasiewicz  *
11*37a3a533SAndrzej Pietrasiewicz  * This program is free software; you can redistribute it and/or modify
12*37a3a533SAndrzej Pietrasiewicz  * it under the terms of the GNU General Public License version 2 as
13*37a3a533SAndrzej Pietrasiewicz  * published by the Free Software Foundation.
14*37a3a533SAndrzej Pietrasiewicz  */
15*37a3a533SAndrzej Pietrasiewicz 
16*37a3a533SAndrzej Pietrasiewicz #ifndef __U_OS_DESC_H__
17*37a3a533SAndrzej Pietrasiewicz #define __U_OS_DESC_H__
18*37a3a533SAndrzej Pietrasiewicz 
19*37a3a533SAndrzej Pietrasiewicz #include <asm/unaligned.h>
20*37a3a533SAndrzej Pietrasiewicz #include <linux/nls.h>
21*37a3a533SAndrzej Pietrasiewicz 
22*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_DW_SIZE			0
23*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_DW_PROPERTY_DATA_TYPE	4
24*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_W_PROPERTY_NAME_LENGTH	8
25*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_B_PROPERTY_NAME		10
26*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH	10
27*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_B_PROPERTY_DATA		14
28*37a3a533SAndrzej Pietrasiewicz 
29*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_RESERVED			0
30*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_UNICODE			1
31*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_UNICODE_ENV		2
32*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_BINARY			3
33*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_LE32			4
34*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_BE32			5
35*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_UNICODE_LINK		6
36*37a3a533SAndrzej Pietrasiewicz #define USB_EXT_PROP_UNICODE_MULTI		7
37*37a3a533SAndrzej Pietrasiewicz 
38*37a3a533SAndrzej Pietrasiewicz static inline void usb_ext_prop_put_size(u8 *buf, int dw_size)
39*37a3a533SAndrzej Pietrasiewicz {
40*37a3a533SAndrzej Pietrasiewicz 	put_unaligned_le32(dw_size, &buf[USB_EXT_PROP_DW_SIZE]);
41*37a3a533SAndrzej Pietrasiewicz }
42*37a3a533SAndrzej Pietrasiewicz 
43*37a3a533SAndrzej Pietrasiewicz static inline void usb_ext_prop_put_type(u8 *buf, int type)
44*37a3a533SAndrzej Pietrasiewicz {
45*37a3a533SAndrzej Pietrasiewicz 	put_unaligned_le32(type, &buf[USB_EXT_PROP_DW_PROPERTY_DATA_TYPE]);
46*37a3a533SAndrzej Pietrasiewicz }
47*37a3a533SAndrzej Pietrasiewicz 
48*37a3a533SAndrzej Pietrasiewicz static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl)
49*37a3a533SAndrzej Pietrasiewicz {
50*37a3a533SAndrzej Pietrasiewicz 	int result;
51*37a3a533SAndrzej Pietrasiewicz 
52*37a3a533SAndrzej Pietrasiewicz 	put_unaligned_le16(pnl, &buf[USB_EXT_PROP_W_PROPERTY_NAME_LENGTH]);
53*37a3a533SAndrzej Pietrasiewicz 	result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN,
54*37a3a533SAndrzej Pietrasiewicz 		(wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_NAME], pnl - 2);
55*37a3a533SAndrzej Pietrasiewicz 	if (result < 0)
56*37a3a533SAndrzej Pietrasiewicz 		return result;
57*37a3a533SAndrzej Pietrasiewicz 
58*37a3a533SAndrzej Pietrasiewicz 	put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl]);
59*37a3a533SAndrzej Pietrasiewicz 
60*37a3a533SAndrzej Pietrasiewicz 	return pnl;
61*37a3a533SAndrzej Pietrasiewicz }
62*37a3a533SAndrzej Pietrasiewicz 
63*37a3a533SAndrzej Pietrasiewicz static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data,
64*37a3a533SAndrzej Pietrasiewicz 					   int data_len)
65*37a3a533SAndrzej Pietrasiewicz {
66*37a3a533SAndrzej Pietrasiewicz 	put_unaligned_le32(data_len,
67*37a3a533SAndrzej Pietrasiewicz 			   &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]);
68*37a3a533SAndrzej Pietrasiewicz 	memcpy(&buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], data, data_len);
69*37a3a533SAndrzej Pietrasiewicz }
70*37a3a533SAndrzej Pietrasiewicz 
71*37a3a533SAndrzej Pietrasiewicz static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string,
72*37a3a533SAndrzej Pietrasiewicz 					   int data_len)
73*37a3a533SAndrzej Pietrasiewicz {
74*37a3a533SAndrzej Pietrasiewicz 	int result;
75*37a3a533SAndrzej Pietrasiewicz 	put_unaligned_le32(data_len,
76*37a3a533SAndrzej Pietrasiewicz 			&buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]);
77*37a3a533SAndrzej Pietrasiewicz 
78*37a3a533SAndrzej Pietrasiewicz 	result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN,
79*37a3a533SAndrzej Pietrasiewicz 			(wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl],
80*37a3a533SAndrzej Pietrasiewicz 			data_len - 2);
81*37a3a533SAndrzej Pietrasiewicz 	if (result < 0)
82*37a3a533SAndrzej Pietrasiewicz 		return result;
83*37a3a533SAndrzej Pietrasiewicz 
84*37a3a533SAndrzej Pietrasiewicz 	put_unaligned_le16(0,
85*37a3a533SAndrzej Pietrasiewicz 			&buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len]);
86*37a3a533SAndrzej Pietrasiewicz 
87*37a3a533SAndrzej Pietrasiewicz 	return data_len;
88*37a3a533SAndrzej Pietrasiewicz }
89*37a3a533SAndrzej Pietrasiewicz 
90*37a3a533SAndrzej Pietrasiewicz #endif /* __U_OS_DESC_H__ */
91