xref: /netbsd/usr.sbin/tadpolectl/tadpolectl.c (revision ad4b6106)
1 /* $NetBSD: tadpolectl.c,v 1.10 2018/01/23 19:01:33 sevan Exp $ */
2 
3 /*-
4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Tim Rightnour.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <ctype.h>
33 #include <err.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <sys/ioctl.h>
40 #include <sys/types.h>
41 #include <sys/envsys.h>
42 #include <machine/apmvar.h>
43 #include <machine/tctrl.h>
44 
45 #define TCTRL_DEV	"/dev/tctrl0"
46 
47 int aflag, nflag, wflag, dev;
48 
49 #define PROTO(x) int x(int, int, int);
50 static void usage(void) __dead;
51 static void parse(char *);
52 char *dashdot(const char *);
53 PROTO(hw_version)
54 PROTO(hw_microcontroller_version)
55 PROTO(hw_poweroncycles)
56 PROTO(hw_poweronseconds)
57 PROTO(hw_power_mains)
58 PROTO(hw_power_battery_int)
59 PROTO(hw_power_battery_ext)
60 PROTO(hw_power_battery_int_chargerate)
61 PROTO(hw_power_battery_ext_chargerate)
62 PROTO(hw_power_battery_int_chargelevel)
63 PROTO(hw_power_battery_ext_chargelevel)
64 PROTO(hw_video_external)
65 PROTO(hw_video_lid)
66 PROTO(hw_video_syncinva)
67 PROTO(hw_video_syncinvb)
68 PROTO(hw_video_compsync)
69 PROTO(hw_video_tft_brightness)
70 PROTO(hw_speaker_freq)
71 PROTO(hw_speaker_volume)
72 PROTO(hw_kbd_repeat_delay)
73 PROTO(hw_kbd_repeat_speed)
74 PROTO(hw_mouse_recalibrate)
75 PROTO(hw_power_battery_chargedisabled)
76 PROTO(hw_mouse_disable)
77 PROTO(hw_kbd_click)
78 PROTO(hw_mouse_intclick)
79 PROTO(hw_mouse_extclick)
80 PROTO(hw_mouse_sensitivity)
81 PROTO(hw_serial_power)
82 
83 #define NUM_MIBS 29
84 #define TABLE(n) { __STRING(n), 0, n }
85 
86 struct {
87 	const char *mib;
88 	int value;
89 	int (*funcptr)(int, int, int);
90 } table[NUM_MIBS] = {
91 	TABLE(hw_microcontroller_version),
92 	TABLE(hw_version),
93 	TABLE(hw_poweroncycles),
94 	TABLE(hw_poweronseconds),
95 	TABLE(hw_power_mains),
96 	TABLE(hw_power_battery_int),
97 	TABLE(hw_power_battery_ext),
98 	TABLE(hw_power_battery_chargedisabled),
99 	TABLE(hw_power_battery_int_chargerate),
100 	TABLE(hw_power_battery_ext_chargerate),
101 	TABLE(hw_power_battery_int_chargelevel),
102 	TABLE(hw_power_battery_ext_chargelevel),
103 	TABLE(hw_video_external),
104 	TABLE(hw_video_lid),
105 	TABLE(hw_video_syncinva),
106 	TABLE(hw_video_syncinvb),
107 	TABLE(hw_video_compsync),
108 	TABLE(hw_video_tft_brightness),
109 	TABLE(hw_speaker_freq),
110 	TABLE(hw_speaker_volume),
111 	TABLE(hw_kbd_repeat_delay),
112 	TABLE(hw_kbd_repeat_speed),
113 	TABLE(hw_kbd_click),
114 	TABLE(hw_mouse_recalibrate),
115 	TABLE(hw_mouse_disable),
116 	TABLE(hw_mouse_intclick),
117 	TABLE(hw_mouse_extclick),
118 	TABLE(hw_mouse_sensitivity),
119 	TABLE(hw_serial_power),
120 };
121 
122 #define FUNC(x) \
123 int \
124 x(readflg, new, num) \
125 	int readflg, new, num;
126 
127 #define READ_REQ(a, b, c) \
128 	req.cmdbuf[0] = a; \
129 	req.cmdlen = b; \
130 	req.rsplen = c; \
131 	ioctl(dev, TCTRL_CMD_REQ, &req)
132 
133 #define WRITE_REQ(a, b, c) \
134 	req.cmdbuf[0] = a; \
135 	req.cmdlen = b; \
136 	req.rsplen = c; \
137 	ioctl(dev, TCTRL_CMD_REQ, &req)
138 
139 #define READ_ONLY \
140 	if (!readflg) \
141 		return(0)
142 
143 /* hardware functions */
144 
FUNC(hw_mouse_sensitivity)145 FUNC(hw_mouse_sensitivity)
146 {
147 	struct tctrl_req req;
148 
149 	req.cmdbuf[1] = 0xff;
150 	req.cmdbuf[2] = 0x00;
151 	READ_REQ(0x2c, 3, 2);
152 	table[num].value = req.rspbuf[0];
153 	if (readflg)
154 		return(1);
155 	if (new == 0)
156 		req.cmdbuf[2] = 0x00;
157 	else if (new > 255)
158 		req.cmdbuf[2] = 0xff;
159 	else
160 		req.cmdbuf[2] = new;
161 	req.cmdbuf[1] = 0x00;
162 	WRITE_REQ(0x2c, 3, 2);
163 	req.cmdbuf[1] = 0xff;
164 	req.cmdbuf[2] = 0x00;
165 	READ_REQ(0x2c, 3, 2);
166 	table[num].value = req.rspbuf[0];
167 	return(1);
168 }
169 
FUNC(hw_power_battery_chargedisabled)170 FUNC(hw_power_battery_chargedisabled)
171 {
172 	struct tctrl_req req;
173 
174 	req.cmdbuf[1] = 0xff;
175 	req.cmdbuf[2] = 0x00;
176 	READ_REQ(0x22, 3, 2);
177 	table[num].value = req.rspbuf[0]&0x01 ? 1 : 0;
178 	if (readflg)
179 		return(1);
180 	if (new == 0)
181 		req.cmdbuf[2] = 0x00;
182 	else
183 		req.cmdbuf[2] = 0x01;
184 	req.cmdbuf[1] = ~0x01;
185 	WRITE_REQ(0x22, 3, 2);
186 	req.cmdbuf[1] = 0xff;
187 	req.cmdbuf[2] = 0x00;
188 	READ_REQ(0x22, 3, 2);
189 	table[num].value = req.rspbuf[0]&0x01 ? 1 : 0;
190 	return(1);
191 }
192 
FUNC(hw_mouse_disable)193 FUNC(hw_mouse_disable)
194 {
195 	struct tctrl_req req;
196 
197 	req.cmdbuf[1] = 0xff;
198 	req.cmdbuf[2] = 0x00;
199 	READ_REQ(0x22, 3, 2);
200 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
201 	if (readflg)
202 		return(1);
203 	if (new == 0)
204 		req.cmdbuf[2] = 0x00;
205 	else
206 		req.cmdbuf[2] = 0x02;
207 	req.cmdbuf[1] = ~0x02;
208 	WRITE_REQ(0x22, 3, 2);
209 	req.cmdbuf[1] = 0xff;
210 	req.cmdbuf[2] = 0x00;
211 	READ_REQ(0x22, 3, 2);
212 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
213 	return(1);
214 }
215 
FUNC(hw_kbd_click)216 FUNC(hw_kbd_click)
217 {
218 	struct tctrl_req req;
219 
220 	req.cmdbuf[1] = 0xff;
221 	req.cmdbuf[2] = 0x00;
222 	READ_REQ(0x22, 3, 2);
223 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
224 	if (readflg)
225 		return(1);
226 	if (new == 0)
227 		req.cmdbuf[2] = 0x00;
228 	else
229 		req.cmdbuf[2] = 0x04;
230 	req.cmdbuf[1] = ~0x04;
231 	WRITE_REQ(0x22, 3, 2);
232 	req.cmdbuf[1] = 0xff;
233 	req.cmdbuf[2] = 0x00;
234 	READ_REQ(0x22, 3, 2);
235 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
236 	return(1);
237 }
238 
FUNC(hw_mouse_intclick)239 FUNC(hw_mouse_intclick)
240 {
241 	struct tctrl_req req;
242 
243 	req.cmdbuf[1] = 0xff;
244 	req.cmdbuf[2] = 0x00;
245 	READ_REQ(0x22, 3, 2);
246 	table[num].value = req.rspbuf[0]&0x08 ? 1 : 0;
247 	if (readflg)
248 		return(1);
249 	if (new == 0)
250 		req.cmdbuf[2] = 0x00;
251 	else
252 		req.cmdbuf[2] = 0x08;
253 	req.cmdbuf[1] = ~0x08;
254 	WRITE_REQ(0x22, 3, 2);
255 	req.cmdbuf[1] = 0xff;
256 	req.cmdbuf[2] = 0x00;
257 	READ_REQ(0x22, 3, 2);
258 	table[num].value = req.rspbuf[0]&0x08 ? 1 : 0;
259 	return(1);
260 }
261 
FUNC(hw_mouse_extclick)262 FUNC(hw_mouse_extclick)
263 {
264 	struct tctrl_req req;
265 
266 	req.cmdbuf[1] = 0xff;
267 	req.cmdbuf[2] = 0x00;
268 	READ_REQ(0x22, 3, 2);
269 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
270 	if (readflg)
271 		return(1);
272 	if (new == 0)
273 		req.cmdbuf[2] = 0x00;
274 	else
275 		req.cmdbuf[2] = 0x10;
276 	req.cmdbuf[1] = ~0x10;
277 	WRITE_REQ(0x22, 3, 2);
278 	req.cmdbuf[1] = 0xff;
279 	req.cmdbuf[2] = 0x00;
280 	READ_REQ(0x22, 3, 2);
281 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
282 	return(1);
283 }
284 
285 /* ARGSUSED */
FUNC(hw_mouse_recalibrate)286 FUNC(hw_mouse_recalibrate)
287 {
288 	struct tctrl_req req;
289 
290 	table[num].value = 0;
291 	if (readflg)
292 		return(1);
293 	READ_REQ(0x36, 1, 1);
294 	return(1);
295 }
296 
FUNC(hw_kbd_repeat_delay)297 FUNC(hw_kbd_repeat_delay)
298 {
299 	struct tctrl_req req;
300 
301 	req.cmdbuf[1] = 0xff;
302 	req.cmdbuf[2] = 0x00;
303 	READ_REQ(0x28, 3, 2);
304 	table[num].value = req.rspbuf[0];
305 	if (readflg)
306 		return(1);
307 	if (new == 0)
308 		req.cmdbuf[2] = 0x00;
309 	else if (new > 255)
310 		req.cmdbuf[2] = 0xff;
311 	else
312 		req.cmdbuf[2] = new;
313 	req.cmdbuf[1] = 0x00;
314 	WRITE_REQ(0x28, 3, 2);
315 	req.cmdbuf[1] = 0xff;
316 	req.cmdbuf[2] = 0x00;
317 	READ_REQ(0x28, 3, 2);
318 	table[num].value = req.rspbuf[0];
319 	return(1);
320 }
321 
FUNC(hw_kbd_repeat_speed)322 FUNC(hw_kbd_repeat_speed)
323 {
324 	struct tctrl_req req;
325 
326 	req.cmdbuf[1] = 0xff;
327 	req.cmdbuf[2] = 0x00;
328 	READ_REQ(0x29, 3, 2);
329 	table[num].value = req.rspbuf[0];
330 	if (readflg)
331 		return(1);
332 	if (new == 0)
333 		req.cmdbuf[2] = 0x00;
334 	else if (new > 255)
335 		req.cmdbuf[2] = 0xff;
336 	else
337 		req.cmdbuf[2] = new;
338 	req.cmdbuf[1] = 0x00;
339 	WRITE_REQ(0x29, 3, 2);
340 	req.cmdbuf[1] = 0xff;
341 	req.cmdbuf[2] = 0x00;
342 	READ_REQ(0x29, 3, 2);
343 	table[num].value = req.rspbuf[0];
344 	return(1);
345 }
346 
FUNC(hw_speaker_freq)347 FUNC(hw_speaker_freq)
348 {
349 	struct tctrl_req req;
350 
351 	table[num].value = 0;
352 	if (readflg)
353 		return(1);
354 	req.cmdbuf[1] = new * 256;
355 	req.cmdbuf[2] = new % 256;
356 	WRITE_REQ(0x37, 3, 1);
357 	return(1);
358 }
359 
FUNC(hw_speaker_volume)360 FUNC(hw_speaker_volume)
361 {
362 	struct tctrl_req req;
363 
364 	req.cmdbuf[1] = 0xff;
365 	req.cmdbuf[2] = 0x00;
366 	READ_REQ(0x23, 3, 2);
367 	table[num].value = req.rspbuf[0];
368 	if (readflg)
369 		return(1);
370 	if (new == 0)
371 		req.cmdbuf[2] = 0x00;
372 	else if (new > 255)
373 		req.cmdbuf[2] = 0xff;
374 	else
375 		req.cmdbuf[2] = new;
376 	req.cmdbuf[1] = 0x00;
377 	WRITE_REQ(0x23, 3, 2);
378 	req.cmdbuf[1] = 0xff;
379 	req.cmdbuf[2] = 0x00;
380 	READ_REQ(0x23, 3, 2);
381 	table[num].value = req.rspbuf[0];
382 	return(1);
383 }
384 
FUNC(hw_video_tft_brightness)385 FUNC(hw_video_tft_brightness)
386 {
387 	struct tctrl_req req;
388 
389 	req.cmdbuf[1] = 0xff;
390 	req.cmdbuf[2] = 0x00;
391 	READ_REQ(0x24, 3, 2);
392 	table[num].value = req.rspbuf[0];
393 	if (readflg)
394 		return(1);
395 	if (new == 0)
396 		req.cmdbuf[2] = 0x00;
397 	else if (new > 255)
398 		req.cmdbuf[2] = 0xff;
399 	else
400 		req.cmdbuf[2] = new;
401 	req.cmdbuf[1] = 0x00;
402 	WRITE_REQ(0x24, 3, 2);
403 	req.cmdbuf[1] = 0xff;
404 	req.cmdbuf[2] = 0x00;
405 	READ_REQ(0x24, 3, 2);
406 	table[num].value = req.rspbuf[0];
407 	return(1);
408 }
409 
FUNC(hw_video_syncinva)410 FUNC(hw_video_syncinva)
411 {
412 	struct tctrl_req req;
413 
414 	req.cmdbuf[1] = 0xff;
415 	req.cmdbuf[2] = 0x00;
416 	READ_REQ(0x21, 3, 2);
417 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
418 	if (readflg)
419 		return(1);
420 	if (new == 0)
421 		req.cmdbuf[2] = 0x00;
422 	else
423 		req.cmdbuf[2] = 0x02;
424 	req.cmdbuf[1] = ~0x02;
425 	WRITE_REQ(0x21, 3, 2);
426 	req.cmdbuf[1] = 0xff;
427 	req.cmdbuf[2] = 0x00;
428 	READ_REQ(0x21, 3, 2);
429 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
430 	return(1);
431 }
432 
FUNC(hw_video_syncinvb)433 FUNC(hw_video_syncinvb)
434 {
435 	struct tctrl_req req;
436 
437 	req.cmdbuf[1] = 0xff;
438 	req.cmdbuf[2] = 0x00;
439 	READ_REQ(0x21, 3, 2);
440 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
441 	if (readflg)
442 		return(1);
443 	if (new == 0)
444 		req.cmdbuf[2] = 0x00;
445 	else
446 		req.cmdbuf[2] = 0x04;
447 	req.cmdbuf[1] = ~0x04;
448 	WRITE_REQ(0x21, 3, 2);
449 	req.cmdbuf[1] = 0xff;
450 	req.cmdbuf[2] = 0x00;
451 	READ_REQ(0x21, 3, 2);
452 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
453 	return(1);
454 }
455 
FUNC(hw_video_compsync)456 FUNC(hw_video_compsync)
457 {
458 	struct tctrl_req req;
459 
460 	req.cmdbuf[1] = 0xff;
461 	req.cmdbuf[2] = 0x00;
462 	READ_REQ(0x21, 3, 2);
463 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
464 	if (readflg)
465 		return(1);
466 	if (new == 0)
467 		req.cmdbuf[2] = 0x00;
468 	else
469 		req.cmdbuf[2] = 0x10;
470 	req.cmdbuf[1] = ~0x10;
471 	WRITE_REQ(0x21, 3, 2);
472 	req.cmdbuf[1] = 0xff;
473 	req.cmdbuf[2] = 0x00;
474 	READ_REQ(0x21, 3, 2);
475 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
476 	return(1);
477 }
478 
479 /* ARGSUSED */
FUNC(hw_video_lid)480 FUNC(hw_video_lid)
481 {
482 	struct tctrl_req req;
483 	short i;
484 
485 	READ_ONLY;
486 	READ_REQ(0x11, 1, 3);
487 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
488 	table[num].value = i&0x0040 ? 0 : 1;
489 	return(1);
490 }
491 
492 /* ARGSUSED */
FUNC(hw_video_external)493 FUNC(hw_video_external)
494 {
495 	struct tctrl_req req;
496 	short i;
497 
498 	READ_ONLY;
499 	READ_REQ(0x11, 1, 3);
500 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
501 	table[num].value = i&0x0008 ? 1 : 0;
502 	return(1);
503 }
504 
505 /* ARGSUSED */
FUNC(hw_power_battery_int_chargelevel)506 FUNC(hw_power_battery_int_chargelevel)
507 {
508 	struct tctrl_req req;
509 
510 	READ_ONLY;
511 	READ_REQ(0x7a, 1, 3);
512 	table[num].value = req.rspbuf[0] == 0xfb ? 0 : req.rspbuf[0];
513 	return(1);
514 
515 }
516 
517 /* ARGSUSED */
FUNC(hw_power_battery_ext_chargelevel)518 FUNC(hw_power_battery_ext_chargelevel)
519 {
520 	struct tctrl_req req;
521 
522 	READ_ONLY;
523 	READ_REQ(0x7b, 1, 3);
524 	table[num].value = req.rspbuf[0] == 0xfb ? 0 : req.rspbuf[0];
525 	return(1);
526 }
527 
FUNC(hw_power_battery_int_chargerate)528 FUNC(hw_power_battery_int_chargerate)
529 {
530 	struct tctrl_req req;
531 
532 	READ_REQ(0x18, 1, 2);
533 	table[num].value = req.rspbuf[0];
534 	if (readflg)
535 		return(1);
536 	req.cmdbuf[1] = new < 255 ? new : 255;
537 	WRITE_REQ(0x39, 2, 1);
538 	READ_REQ(0x18, 1, 2);
539 	table[num].value = req.rspbuf[0];
540 	return(1);
541 }
542 
FUNC(hw_power_battery_ext_chargerate)543 FUNC(hw_power_battery_ext_chargerate)
544 {
545 	struct tctrl_req req;
546 
547 	READ_REQ(0x18, 1, 2);
548 	table[num].value = req.rspbuf[0];
549 	if (readflg)
550 		return(1);
551 	req.cmdbuf[1] = new < 255 ? new : 255;
552 	WRITE_REQ(0x39, 2, 1);
553 	READ_REQ(0x18, 1, 2);
554 	table[num].value = req.rspbuf[0];
555 	return(1);
556 }
557 
558 /* ARGSUSED */
FUNC(hw_power_battery_ext)559 FUNC(hw_power_battery_ext)
560 {
561 	int i;
562 	struct tctrl_req req;
563 
564 	READ_ONLY;
565 	READ_REQ(0x11, 1, 3);
566 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
567 	table[num].value = i&0x0004 ? 1 : 0;
568 	return(1);
569 }
570 
571 /* ARGSUSED */
FUNC(hw_power_battery_int)572 FUNC(hw_power_battery_int)
573 {
574 	int i;
575 	struct tctrl_req req;
576 
577 	READ_ONLY;
578 	READ_REQ(0x11, 1, 3);
579 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
580 	table[num].value = i&0x0002 ? 1 : 0;
581 	return(1);
582 }
583 
584 /* ARGSUSED */
FUNC(hw_power_mains)585 FUNC(hw_power_mains)
586 {
587 	int i;
588 	struct tctrl_req req;
589 
590 	READ_ONLY;
591 	READ_REQ(0x11, 1, 3);
592 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
593 	table[num].value = i&0x0001 ? 1 : 0;
594 	return(1);
595 }
596 
597 /* ARGSUSED */
FUNC(hw_poweroncycles)598 FUNC(hw_poweroncycles)
599 {
600 	struct tctrl_req req;
601 
602 	READ_ONLY;
603 	READ_REQ(0x09, 1, 5);
604 	table[num].value = (req.rspbuf[0]<<24)+(req.rspbuf[1]<<16)+
605 	    (req.rspbuf[2]<<8)+req.rspbuf[3];
606 	return(1);
607 }
608 
609 /* ARGSUSED */
FUNC(hw_poweronseconds)610 FUNC(hw_poweronseconds)
611 {
612 	struct tctrl_req req;
613 
614 	READ_ONLY;
615 	READ_REQ(0x0a, 1, 5);
616 	table[num].value = (req.rspbuf[0]<<24)+(req.rspbuf[1]<<16)+
617 	    (req.rspbuf[2]<<8)+req.rspbuf[3];
618 	return(1);
619 }
620 
621 /* ARGSUSED */
FUNC(hw_microcontroller_version)622 FUNC(hw_microcontroller_version)
623 {
624 	char buf[BUFSIZ];
625 	struct tctrl_req req;
626 
627 	READ_ONLY;
628 	READ_REQ(0x04, 1, 3);
629 	snprintf(buf, sizeof(buf), "%d%d", req.rspbuf[0]*1000,
630 	    req.rspbuf[1]*10);
631 	table[num].value = atoi(strdup(buf));
632 	return(1);
633 }
634 
635 
636 /* ARGSUSED */
FUNC(hw_version)637 FUNC(hw_version)
638 {
639 	char buf[BUFSIZ];
640 	struct tctrl_req req;
641 
642 	READ_ONLY;
643 	READ_REQ(0x03, 1, 3);
644 	snprintf(buf, sizeof(buf), "%d%d", req.rspbuf[0]*1000,
645 	    req.rspbuf[1]*10);
646 	table[num].value = atoi(strdup(buf));
647 	return(1);
648 }
649 
FUNC(hw_serial_power)650 FUNC(hw_serial_power)
651 {
652 	struct tctrl_pwr pwrreq;
653 
654 	if (!readflg) {
655 		pwrreq.rw = 0x00;
656 		pwrreq.state = new;
657 		ioctl(dev, TCTRL_SERIAL_PWR, &pwrreq);
658 	}
659 	pwrreq.rw = 0x01;
660 	ioctl(dev, TCTRL_SERIAL_PWR, &pwrreq);
661 	table[num].value = pwrreq.state;
662 	return(1);
663 }
664 
665 static void
usage(void)666 usage(void)
667 {
668 	(void)fprintf(stderr,
669 	    "usage: tadpolectl [-n] name ...\n"
670 	    "       tadpolectl [-n] -w name=value\n"
671 	    "       tadpolectl [-n] -a\n");
672 	exit(1);
673 }
674 
675 static void
parse(string)676 parse(string)
677 	char *string;
678 {
679 	char *cp, buf[BUFSIZ];
680 	int newval = 0;
681 	int i, j, ret;
682 
683 	string = dashdot(string);
684 	snprintf(buf, (size_t)BUFSIZ, "%s", string);
685 	if ((cp = strchr(string, '=')) != NULL) {
686 		if (!wflag)
687 			errx(2, "Must specify -w to set variables");
688 		*strchr(buf, '=') = '\0';
689 		*cp++ = '\0';
690 		while (isspace((unsigned char) *cp))
691 			cp++;
692 		newval = atoi(cp);
693 	}
694 	for (j=0,i=-1; j < NUM_MIBS; j++) {
695 		if (strcmp(string, table[j].mib) == 0) {
696 			i = j;
697 			break;
698 		}
699 	}
700 	if (i == -1)
701 		errx(2, "Named value does not exist");
702 
703 	if (wflag) {
704 		ret = (*table[i].funcptr)(0, newval, i);
705 		if (!ret)
706 			errx(2, "Cannot modify this value");
707 	} else
708 		ret = (*table[i].funcptr)(1, 0, i);
709 	if (nflag)
710 		printf("%d\n", table[i].value);
711 	else
712 		printf("%s = %d\n", dashdot(table[i].mib), table[i].value);
713 }
714 
715 char *
dashdot(const char * string)716 dashdot(const char *string)
717 {
718 	char *p;
719 	char *save;
720 
721 	p = strdup(string);
722 	save = p;
723 
724 	for (; (*p = *string) != '\0'; ++p, ++string) {
725 		if (*p == '.')
726 			*p = '_';
727 		else if (*p == '_')
728 			*p = '.';
729 	}
730 	return(save);
731 }
732 
733 int
main(int argc,char * argv[])734 main(int argc, char *argv[])
735 {
736 	int ch, j;
737 
738 	while ((ch = getopt(argc, argv, "anw")) != -1) {
739 		switch (ch) {
740 
741 		case 'a':
742 			aflag = 1;
743 			break;
744 		case 'n':
745 			nflag = 1;
746 			break;
747 		case 'w':
748 			wflag = 1;
749 			break;
750 		default:
751 			usage();
752 		}
753 	}
754 	argc -= optind;
755 	argv += optind;
756 
757 	if ((dev = open(TCTRL_DEV, O_RDONLY, NULL)) == -1)
758 		err(1, "%s", TCTRL_DEV);
759 
760 	if (aflag) {
761 		for (j=0; j < NUM_MIBS; j++) {
762 			(void)(*table[j].funcptr)(1, 0, j);
763 			if (nflag)
764 				printf("%d\n", table[j].value);
765 			else
766 				printf("%s = %d\n", dashdot(table[j].mib),
767 				    table[j].value);
768 		}
769 		return(0);
770 	}
771 	if (argc == 0)
772 		usage();
773 	while (argc-- > 0)
774 		parse(*argv++);
775 	return(0);
776 }
777