1 /* Copyright (C) 2010 - 2015 UNISYS CORPORATION
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for more
15 #ifndef __VBUSDEVICEINFO_H__
16 #define __VBUSDEVICEINFO_H__
18 #include <linux/types.h>
20 #pragma pack(push, 1) /* both GCC and VC now allow this pragma */
23 * An array of this struct is present in the channel area for each vbus.
24 * (See vbuschannel.h.)
25 * It is filled in by the client side to provide info about the device
26 * and driver from the client's perspective.
28 struct ultra_vbus_deviceinfo
{
29 u8 devtype
[16]; /* short string identifying the device type */
30 u8 drvname
[16]; /* driver .sys file name */
31 u8 infostrs
[96]; /* sequence of tab-delimited id strings: */
32 /* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */
33 u8 reserved
[128]; /* pad size to 256 bytes */
39 * vbuschannel_sanitize_buffer() - remove non-printable chars from buffer
40 * @p: destination buffer where chars are written to
41 * @remain: number of bytes that can be written starting at #p
42 * @src: pointer to source buffer
43 * @srcmax: number of valid characters at #src
45 * Reads chars from the buffer at @src for @srcmax bytes, and writes to
46 * the buffer at @p, which is @remain bytes long, ensuring never to
47 * overflow the buffer at @p, using the following rules:
48 * - printable characters are simply copied from the buffer at @src to the
50 * - intervening streaks of non-printable characters in the buffer at @src
51 * are replaced with a single space in the buffer at @p
52 * Note that we pay no attention to '\0'-termination.
54 * Pass @p == NULL and @remain == 0 for this special behavior -- In this
55 * case, we simply return the number of bytes that WOULD HAVE been written
56 * to a buffer at @p, had it been infinitely big.
58 * Return: the number of bytes written to @p (or WOULD HAVE been written to
59 * @p, as described in the previous paragraph)
62 vbuschannel_sanitize_buffer(char *p
, int remain
, char *src
, int srcmax
)
65 int nonprintable_streak
= 0;
68 if ((*src
>= ' ') && (*src
< 0x7f)) {
69 if (nonprintable_streak
) {
78 nonprintable_streak
= 0;
89 nonprintable_streak
= 1;
97 #define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \
102 p++; chars++; remain--; \
106 * vbuschannel_itoa() - convert non-negative int to string
107 * @p: destination string
108 * @remain: max number of bytes that can be written to @p
109 * @num: input int to convert
111 * Converts the non-negative value at @num to an ascii decimal string
112 * at @p, writing at most @remain bytes. Note there is NO '\0' termination
115 * Return: number of bytes written to @p
119 vbuschannel_itoa(char *p
, int remain
, int num
)
126 /* '0' is a special case */
132 /* form a backwards decimal ascii string in <s> */
134 if (digits
>= (int)sizeof(s
))
136 s
[digits
++] = (num
% 10) + '0';
139 if (remain
< digits
) {
140 /* not enough room left at <p> to hold number, so fill with
143 for (i
= 0; i
< remain
; i
++, p
++)
147 /* plug in the decimal ascii string representing the number, by */
148 /* reversing the string we just built in <s> */
159 * vbuschannel_devinfo_to_string() - format a struct ultra_vbus_deviceinfo
160 * to a printable string
161 * @devinfo: the struct ultra_vbus_deviceinfo to format
162 * @p: destination string area
163 * @remain: size of destination string area in bytes
164 * @devix: the device index to be included in the output data, or -1 if no
165 * device index is to be included
167 * Reads @devInfo, and converts its contents to a printable string at @p,
168 * writing at most @remain bytes. Note there is NO '\0' termination
171 * Return: number of bytes written to @p
174 vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo
*devinfo
,
175 char *p
, int remain
, int devix
)
181 psrc
= &devinfo
->devtype
[0];
182 nsrc
= sizeof(devinfo
->devtype
);
183 if (vbuschannel_sanitize_buffer(NULL
, 0, psrc
, nsrc
) <= 0)
186 /* emit device index */
188 VBUSCHANNEL_ADDACHAR('[', p
, remain
, chars
);
189 x
= vbuschannel_itoa(p
, remain
, devix
);
193 VBUSCHANNEL_ADDACHAR(']', p
, remain
, chars
);
195 VBUSCHANNEL_ADDACHAR(' ', p
, remain
, chars
);
196 VBUSCHANNEL_ADDACHAR(' ', p
, remain
, chars
);
197 VBUSCHANNEL_ADDACHAR(' ', p
, remain
, chars
);
200 /* emit device type */
201 x
= vbuschannel_sanitize_buffer(p
, remain
, psrc
, nsrc
);
205 pad
= 15 - x
; /* pad device type to be exactly 15 chars */
206 for (i
= 0; i
< pad
; i
++)
207 VBUSCHANNEL_ADDACHAR(' ', p
, remain
, chars
);
208 VBUSCHANNEL_ADDACHAR(' ', p
, remain
, chars
);
210 /* emit driver name */
211 psrc
= &devinfo
->drvname
[0];
212 nsrc
= sizeof(devinfo
->drvname
);
213 x
= vbuschannel_sanitize_buffer(p
, remain
, psrc
, nsrc
);
217 pad
= 15 - x
; /* pad driver name to be exactly 15 chars */
218 for (i
= 0; i
< pad
; i
++)
219 VBUSCHANNEL_ADDACHAR(' ', p
, remain
, chars
);
220 VBUSCHANNEL_ADDACHAR(' ', p
, remain
, chars
);
223 psrc
= &devinfo
->infostrs
[0];
224 nsrc
= sizeof(devinfo
->infostrs
);
225 x
= vbuschannel_sanitize_buffer(p
, remain
, psrc
, nsrc
);
229 VBUSCHANNEL_ADDACHAR('\n', p
, remain
, chars
);