xref: /linux/sound/pci/asihpi/hpidebug.c (revision d39d0ed196aa1685bb24771e92f78633c66ac9cb)
1 /************************************************************************
2 
3     AudioScience HPI driver
4     Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of version 2 of the GNU General Public License as
8     published by the Free Software Foundation;
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19 Debug macro translation.
20 
21 ************************************************************************/
22 
23 #include "hpi_internal.h"
24 #include "hpidebug.h"
25 
26 /* Debug level; 0 quiet; 1 informative, 2 debug, 3 verbose debug.  */
27 int hpi_debug_level = HPI_DEBUG_LEVEL_DEFAULT;
28 
29 void hpi_debug_init(void)
30 {
31 	printk(KERN_INFO "debug start\n");
32 }
33 
34 int hpi_debug_level_set(int level)
35 {
36 	int old_level;
37 
38 	old_level = hpi_debug_level;
39 	hpi_debug_level = level;
40 	return old_level;
41 }
42 
43 int hpi_debug_level_get(void)
44 {
45 	return hpi_debug_level;
46 }
47 
48 #ifdef HPIOS_DEBUG_PRINT
49 /* implies OS has no printf-like function */
50 #include <stdarg.h>
51 
52 void hpi_debug_printf(char *fmt, ...)
53 {
54 	va_list arglist;
55 	char buffer[128];
56 
57 	va_start(arglist, fmt);
58 
59 	if (buffer[0])
60 		HPIOS_DEBUG_PRINT(buffer);
61 	va_end(arglist);
62 }
63 #endif
64 
65 struct treenode {
66 	void *array;
67 	unsigned int num_elements;
68 };
69 
70 #define make_treenode_from_array(nodename, array) \
71 static void *tmp_strarray_##nodename[] = array; \
72 static struct treenode nodename = { \
73 	&tmp_strarray_##nodename, \
74 	ARRAY_SIZE(tmp_strarray_##nodename) \
75 };
76 
77 #define get_treenode_elem(node_ptr, idx, type)  \
78 	(&(*((type *)(node_ptr)->array)[idx]))
79 
80 make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
81 
82 	make_treenode_from_array(hpi_subsys_strings, HPI_SUBSYS_STRINGS)
83 	make_treenode_from_array(hpi_adapter_strings, HPI_ADAPTER_STRINGS)
84 	make_treenode_from_array(hpi_istream_strings, HPI_ISTREAM_STRINGS)
85 	make_treenode_from_array(hpi_ostream_strings, HPI_OSTREAM_STRINGS)
86 	make_treenode_from_array(hpi_mixer_strings, HPI_MIXER_STRINGS)
87 	make_treenode_from_array(hpi_node_strings,
88 	{
89 	"NODE is invalid object"})
90 
91 	make_treenode_from_array(hpi_control_strings, HPI_CONTROL_STRINGS)
92 	make_treenode_from_array(hpi_nvmemory_strings, HPI_OBJ_STRINGS)
93 	make_treenode_from_array(hpi_digitalio_strings, HPI_DIGITALIO_STRINGS)
94 	make_treenode_from_array(hpi_watchdog_strings, HPI_WATCHDOG_STRINGS)
95 	make_treenode_from_array(hpi_clock_strings, HPI_CLOCK_STRINGS)
96 	make_treenode_from_array(hpi_profile_strings, HPI_PROFILE_STRINGS)
97 	make_treenode_from_array(hpi_asyncevent_strings, HPI_ASYNCEVENT_STRINGS)
98 #define HPI_FUNCTION_STRINGS \
99 { \
100   &hpi_subsys_strings,\
101   &hpi_adapter_strings,\
102   &hpi_ostream_strings,\
103   &hpi_istream_strings,\
104   &hpi_mixer_strings,\
105   &hpi_node_strings,\
106   &hpi_control_strings,\
107   &hpi_nvmemory_strings,\
108   &hpi_digitalio_strings,\
109   &hpi_watchdog_strings,\
110   &hpi_clock_strings,\
111   &hpi_profile_strings,\
112   &hpi_control_strings, \
113   &hpi_asyncevent_strings \
114 }
115 	make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
116 
117 	compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);
118 
119 static char *hpi_function_string(unsigned int function)
120 {
121 	unsigned int object;
122 	struct treenode *tmp;
123 
124 	object = function / HPI_OBJ_FUNCTION_SPACING;
125 	function = function - object * HPI_OBJ_FUNCTION_SPACING;
126 
127 	if (object == 0 || object == HPI_OBJ_NODE
128 		|| object > hpi_function_strings.num_elements)
129 		return "invalid object";
130 
131 	tmp = get_treenode_elem(&hpi_function_strings, object - 1,
132 		struct treenode *);
133 
134 	if (function == 0 || function > tmp->num_elements)
135 		return "invalid function";
136 
137 	return get_treenode_elem(tmp, function - 1, char *);
138 }
139 
140 void hpi_debug_message(struct hpi_message *phm, char *sz_fileline)
141 {
142 	if (phm) {
143 		if ((phm->object <= HPI_OBJ_MAXINDEX) && phm->object) {
144 			u16 index = 0;
145 			u16 attrib = 0;
146 			int is_control = 0;
147 
148 			index = phm->obj_index;
149 			switch (phm->object) {
150 			case HPI_OBJ_ADAPTER:
151 			case HPI_OBJ_PROFILE:
152 				break;
153 			case HPI_OBJ_MIXER:
154 				if (phm->function ==
155 					HPI_MIXER_GET_CONTROL_BY_INDEX)
156 					index = phm->u.m.control_index;
157 				break;
158 			case HPI_OBJ_OSTREAM:
159 			case HPI_OBJ_ISTREAM:
160 				break;
161 
162 			case HPI_OBJ_CONTROLEX:
163 			case HPI_OBJ_CONTROL:
164 				if (phm->version == 1)
165 					attrib = HPI_CTL_ATTR(UNIVERSAL, 1);
166 				else
167 					attrib = phm->u.c.attribute;
168 				is_control = 1;
169 				break;
170 			default:
171 				break;
172 			}
173 
174 			if (is_control && (attrib & 0xFF00)) {
175 				int control_type = (attrib & 0xFF00) >> 8;
176 				int attr_index = HPI_CTL_ATTR_INDEX(attrib);
177 				/* note the KERN facility level
178 				   is in szFileline already */
179 				printk("%s adapter %d %s "
180 					"ctrl_index x%04x %s %d\n",
181 					sz_fileline, phm->adapter_index,
182 					hpi_function_string(phm->function),
183 					index,
184 					get_treenode_elem
185 					(&hpi_control_type_strings,
186 						control_type, char *),
187 					attr_index);
188 
189 			} else
190 				printk("%s adapter %d %s "
191 					"idx x%04x attr x%04x \n",
192 					sz_fileline, phm->adapter_index,
193 					hpi_function_string(phm->function),
194 					index, attrib);
195 		} else {
196 			printk("adap=%d, invalid obj=%d, func=0x%x\n",
197 				phm->adapter_index, phm->object,
198 				phm->function);
199 		}
200 	} else
201 		printk(KERN_ERR
202 			"NULL message pointer to hpi_debug_message!\n");
203 }
204 
205 void hpi_debug_data(u16 *pdata, u32 len)
206 {
207 	u32 i;
208 	int j;
209 	int k;
210 	int lines;
211 	int cols = 8;
212 
213 	lines = (len + cols - 1) / cols;
214 	if (lines > 8)
215 		lines = 8;
216 
217 	for (i = 0, j = 0; j < lines; j++) {
218 		printk(KERN_DEBUG "%p:", (pdata + i));
219 
220 		for (k = 0; k < cols && i < len; i++, k++)
221 			printk("%s%04x", k == 0 ? "" : " ", pdata[i]);
222 
223 		printk("\n");
224 	}
225 }
226