xref: /openbsd-src/sys/arch/hppa/stand/libsa/cmd_hppa.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: cmd_hppa.c,v 1.8 2004/04/07 18:24:20 mickey Exp $	*/
2 
3 /*
4  * Copyright (c) 2002 Miodrag Vallat
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*#define	DEBUG*/
30 
31 #include <sys/param.h>
32 /* would come from <sys/param.h> if -D_KERNEL */
33 #define offsetof(s, e) ((size_t)&((s *)0)->e)
34 
35 #include <machine/iomod.h>
36 #include <machine/pdc.h>
37 
38 #include <arch/hppa/dev/cpudevs.h>
39 
40 #include <libsa.h>
41 #include "cmd.h"
42 #include "dev_hppa.h"	/* pdc */
43 
44 extern struct stable_storage sstor;
45 extern int sstorsiz;
46 
47 /* storage sizes we're interested in */
48 #define	CONSOLEOFFSET \
49 	offsetof(struct stable_storage, ss_console)
50 #define	CONSOLESIZE \
51 	(offsetof(struct stable_storage, ss_console) + \
52 	 sizeof(struct device_path))
53 
54 #define	KEYBOARDOFFSET \
55 	offsetof(struct stable_storage, ss_keyboard)
56 #define	KEYBOARDSIZE \
57 	(offsetof(struct stable_storage, ss_keyboard) + \
58 	 sizeof(struct device_path))
59 
60 /*
61  * Table for the possible console devices found during the device walk.
62  */
63 struct consoledev {
64 	struct device_path dp;
65 	int	type;
66 	int	iodc_type;
67 	int	iodc_model;
68 };
69 
70 #define	PS2		1
71 #define	HIL		2
72 #define	SERIAL		3
73 #define	GRAPHICS	4
74 
75 /* max. serial ports */
76 #define	MAX_SERIALS	4
77 /* max. HIL and PS2 */
78 #define	MAX_KEYBOARDS	2
79 /* max. heads */
80 #define	MAX_GRAPHICS	4
81 
82 struct consoledev serials[MAX_SERIALS];
83 struct consoledev keyboards[MAX_KEYBOARDS];
84 struct consoledev graphics[MAX_GRAPHICS];
85 
86 /* Relaxed device comparison */
87 #define	MATCH(dev1, dev2) \
88 	(dev1).dp_mod == (dev2).dp_mod && \
89 	(dev1).dp_bc[0] == (dev2).dp_bc[0] && \
90 	(dev1).dp_bc[1] == (dev2).dp_bc[1] && \
91 	(dev1).dp_bc[2] == (dev2).dp_bc[2] && \
92 	(dev1).dp_bc[3] == (dev2).dp_bc[3] && \
93 	(dev1).dp_bc[4] == (dev2).dp_bc[4] && \
94 	(dev1).dp_bc[5] == (dev2).dp_bc[5]
95 
96 int walked;
97 
98 void bus_walk(struct device_path *);
99 void register_device(struct consoledev *, int,
100 			  struct device_path *, struct iodc_data *, int, int);
101 
102 int Xconsole(void);
103 void print_console(void);
104 int set_graphics(struct device_path *, int, char *);
105 int set_serial(struct device_path *, int, char *);
106 int set_console(struct device_path *);
107 
108 int Xkeyboard(void);
109 void print_keyboard(void);
110 int set_keyboard(struct device_path *);
111 
112 struct cmd_table cmd_machine[] = {
113 	{ "console",	CMDT_CMD,	Xconsole },
114 	{ "keyboard",	CMDT_CMD,	Xkeyboard },
115 	{ NULL, },
116 };
117 
118 /* value to console speed table */
119 int i_speeds[] = {
120 	50,
121 	75,
122 	110,
123 	150,
124 	300,
125 	600,
126 	1200,
127 	2400,
128 	4800,
129 	7200,
130 	9600,
131 	19200,
132 	38400,
133 	57600,
134 	115200,
135 	230400,
136 };
137 
138 char *c_speeds[] = {
139 	"50",
140 	"75",
141 	"110",
142 	"150",
143 	"300",
144 	"600",
145 	"1200",
146 	"2400",
147 	"4800",
148 	"7200",
149 	"9600",
150 	"19200",
151 	"38400",
152 	"57600",
153 	"115200",
154 	"230400",
155 };
156 
157 /* values to console parity table */
158 char *parities[] = {
159 	"none",
160 	"odd",
161 	"<unknown parity>",
162 	"even",
163 };
164 
165 /*
166  * C O N S O L E   S E T T I N G S
167  */
168 
169 void
170 print_console()
171 {
172 	int port, mode, speed, parity, bits;
173 	int i;
174 
175 #ifdef DEBUG
176 	printf("console flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
177 	    sstor.ss_console.dp_flags,
178 	    sstor.ss_console.dp_mod,
179 	    sstor.ss_console.dp_bc[0],
180 	    sstor.ss_console.dp_bc[1],
181 	    sstor.ss_console.dp_bc[2],
182 	    sstor.ss_console.dp_bc[3],
183 	    sstor.ss_console.dp_bc[4],
184 	    sstor.ss_console.dp_bc[5]);
185 
186 	printf("console path %x/%x/%x/%x/%x/%x\n",
187 	    sstor.ss_console.dp_layers[0],
188 	    sstor.ss_console.dp_layers[1],
189 	    sstor.ss_console.dp_layers[2],
190 	    sstor.ss_console.dp_layers[3],
191 	    sstor.ss_console.dp_layers[4],
192 	    sstor.ss_console.dp_layers[5]);
193 #endif
194 
195 	printf("Console path: ");
196 
197 	/* look for a serial console */
198 	for (port = i = 0; i < MAX_SERIALS; i++)
199 		if (MATCH(serials[i].dp, sstor.ss_console)) {
200 			port = i + 1;
201 			break;
202 		}
203 
204 	if (port == 0) {
205 		/*
206 		 * Graphics console
207 		 */
208 
209 		for (port = i = 0; i < MAX_GRAPHICS; i++)
210 			if (MATCH(graphics[i].dp, sstor.ss_console)) {
211 				port = i;
212 				break;
213 			}
214 
215 		/*
216 		 * If the console could still not be identified, consider
217 		 * it is a simplified encoding for the default graphics
218 		 * console. Hence port == 0, no need to check.
219 		 */
220 		if (port == 0)
221 			printf("graphics");
222 		else
223 			printf("graphics_%d", port);
224 
225 		mode = sstor.ss_console.dp_layers[0];
226 		if (mode != 0)
227 			printf(".%d", mode);
228 	} else {
229 		/*
230 		 * Serial console
231 		 */
232 
233 		if (port == 1)
234 			printf("rs232");
235 		else
236 			printf("rs232_%d", port);
237 
238 		speed = PZL_SPEED(sstor.ss_console.dp_layers[0]);
239 		printf(".%d", i_speeds[speed]);
240 
241 		bits = PZL_BITS(sstor.ss_console.dp_layers[0]);
242 		printf(".%d", bits);
243 
244 		parity = PZL_PARITY(sstor.ss_console.dp_layers[0]);
245 		printf(".%s", parities[parity]);
246 	}
247 
248 	printf("\n");
249 }
250 
251 int
252 set_graphics(console, port, arg)
253 	struct device_path *console;
254 	int port;
255 	char *arg;
256 {
257 	int maxmode, mode = 0;
258 	char *digit;
259 
260 	/* head */
261 	if (graphics[port].type == 0) {
262 		printf("no such device found\n");
263 		return 0;
264 	}
265 
266 	/* mode */
267 	if (arg != NULL) {
268 		for (digit = arg; *digit != '\0'; digit++) {
269 			if (*digit >= '0' && *digit <= '9')
270 				mode = 10 * mode + (*digit - '0');
271 			else {
272 				printf("invalid mode specification, %s\n",
273 				    arg);
274 				return 0;
275 			}
276 		}
277 
278 		if (mode <= 0) {
279 			printf("invalid mode specification, %s\n",
280 			    arg);
281 			return 0;
282 		}
283 	}
284 
285 	/*
286 	 * If we are just changing the mode of the same graphics
287 	 * console, check that our mode is in the valid range.
288 	 */
289 	if (MATCH(graphics[port].dp, sstor.ss_console)) {
290 		maxmode = sstor.ss_console.dp_layers[1];
291 
292 		/* pick back same mode if unspecified */
293 		if (mode == 0)
294 			mode = sstor.ss_console.dp_layers[0];
295 
296 		if (mode > maxmode) {
297 			printf("invalid mode value, available range is 1-%d\n",
298 			    maxmode);
299 			return 0;
300 		}
301 	} else {
302 		if (mode == 0)
303 			mode = 1;
304 		maxmode = mode;
305 	}
306 
307 	*console = graphics[port].dp;
308 	console->dp_layers[0] = mode;
309 	console->dp_layers[1] = maxmode;
310 	console->dp_layers[2] = console->dp_layers[3] =
311 	console->dp_layers[4] = console->dp_layers[5] = 0;
312 
313 	return 1;
314 }
315 
316 int
317 set_serial(console, port, arg)
318 	struct device_path *console;
319 	int port;
320 	char *arg;
321 {
322 	char *dot;
323 	int i;
324 	int speed, parity, bits;
325 
326 	/* port */
327 	port--;
328 	if (serials[port].type == 0) {
329 		printf("no such device found\n");
330 		return 0;
331 	}
332 
333 	/* speed */
334 	dot = strchr(arg, '.');
335 	if (dot != NULL)
336 		*dot++ = '\0';
337 
338 	speed = 0;
339 	if (arg == NULL || *arg == '\0') {
340 		for (i = 0; i < NENTS(i_speeds); i++)
341 			if (i_speeds[i] == 9600) {
342 				speed = i;
343 				break;
344 			}
345 	} else {
346 		for (i = 0; i < NENTS(c_speeds); i++)
347 			if (strcmp(arg, c_speeds[i]) == 0) {
348 				speed = i;
349 				break;
350 			}
351 		if (speed == 0) {
352 			printf("invalid speed specification, %s\n", arg);
353 			return 0;
354 		}
355 	}
356 
357 	/* data bits */
358 	arg = dot;
359 	dot = strchr(arg, '.');
360 
361 	if (arg == NULL || *arg == '\0')
362 		bits = 8;
363 	else {
364 		if (dot == arg + 1)
365 			bits = *arg - '0';
366 		else
367 			bits = 0;
368 
369 		if (bits < 5 || bits > 8) {
370 			printf("invalid bits specification, %s\n", arg);
371 			return 0;
372 		}
373 	}
374 	if (dot != NULL)
375 		*dot++ = '\0';
376 
377 	/* parity */
378 	arg = dot;
379 	if (arg == NULL || *arg == '\0')
380 		parity = 0;	/* none */
381 	else {
382 		parity = -1;
383 		for (i = 0; i <= 3; i++)
384 			if (strcmp(arg, parities[i]) == 0) {
385 				parity = i;
386 				break;
387 			}
388 		if (parity == 2)
389 			parity = -1;	/* unknown parity */
390 	}
391 	if (parity < 0) {
392 		printf("invalid parity specification, %s\n", arg);
393 		return 0;
394 	}
395 
396 	*console = serials[port].dp;
397 	console->dp_layers[0] = PZL_ENCODE(bits, parity, speed);
398 
399 	return 1;
400 }
401 
402 int
403 set_console(console)
404 	struct device_path *console;
405 {
406 	char *arg = cmd.argv[1], *dot;
407 	int port;
408 
409 	/* extract first word */
410 	dot = strchr(arg, '.');
411 	if (dot != NULL)
412 		*dot++ = '\0';
413 
414 	/*
415 	 * Graphics console
416 	 */
417 	if (strcmp(arg, "graphics") == 0)
418 		return set_graphics(console, 0, dot);
419 	if (strncmp(arg, "graphics_", 9) == 0) {
420 		port = arg[9] - '0';
421 		if (port > 0 && port < MAX_GRAPHICS)
422 			return set_graphics(console, port, dot);
423 	}
424 
425 	/*
426 	 * Serial console
427 	 */
428 	if (strcmp(arg, "rs232") == 0)
429 		return set_serial(console, 1, dot);
430 	if (strncmp(arg, "rs232_", 6) == 0) {
431 		port = arg[6] - '0';
432 		if (port > 0 && port <= MAX_SERIALS)
433 			return set_serial(console, port, dot);
434 	}
435 
436 	printf("invalid device specification, %s\n", arg);
437 	return 0;
438 }
439 
440 int
441 Xconsole()
442 {
443 	struct device_path console;
444 	int rc;
445 
446 	/* walk the device list if not already done */
447 	if (walked == 0) {
448 		bus_walk(NULL);
449 		walked++;
450 	}
451 
452 	if (sstorsiz < CONSOLESIZE) {
453 		printf("no console information in stable storage\n");
454 		return 0;
455 	}
456 
457 	if (cmd.argc == 1) {
458 		print_console();
459 	} else {
460 		console = sstor.ss_console;
461 		if (set_console(&console)) {
462 			if (memcmp(&sstor.ss_console, &console,
463 			    sizeof console) != 0) {
464 				sstor.ss_console = console;
465 
466 				/* alea jacta est */
467 				rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
468 				    CONSOLEOFFSET, &sstor.ss_console,
469 				    sizeof(sstor.ss_console));
470 				if (rc != 0) {
471 					printf("failed to save console settings, error %d\n",
472 					    rc);
473 					/* read sstor again for safety */
474 					(*pdc)(PDC_STABLE, PDC_STABLE_READ,
475 					    CONSOLEOFFSET, &sstor.ss_console,
476 					    sizeof(sstor.ss_console));
477 				} else
478 					printf("you will need to power-cycle "
479 					       "your machine for the changes "
480 					       "to take effect.\n");
481 			}
482 			print_console();
483 		}
484 	}
485 
486 	return 0;
487 }
488 
489 /*
490  * K E Y B O A R D   S E T T I N G S
491  */
492 
493 void
494 print_keyboard()
495 {
496 	int type;
497 	int i;
498 
499 #ifdef DEBUG
500 	printf("keyboard flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
501 	    sstor.ss_keyboard.dp_flags,
502 	    sstor.ss_keyboard.dp_mod,
503 	    sstor.ss_keyboard.dp_bc[0],
504 	    sstor.ss_keyboard.dp_bc[1],
505 	    sstor.ss_keyboard.dp_bc[2],
506 	    sstor.ss_keyboard.dp_bc[3],
507 	    sstor.ss_keyboard.dp_bc[4],
508 	    sstor.ss_keyboard.dp_bc[5]);
509 
510 	printf("keyboard path %x/%x/%x/%x/%x/%x\n",
511 	    sstor.ss_keyboard.dp_layers[0],
512 	    sstor.ss_keyboard.dp_layers[1],
513 	    sstor.ss_keyboard.dp_layers[2],
514 	    sstor.ss_keyboard.dp_layers[3],
515 	    sstor.ss_keyboard.dp_layers[4],
516 	    sstor.ss_keyboard.dp_layers[5]);
517 #endif
518 
519 	printf("Keyboard path: ");
520 
521 	for (type = i = 0; i < MAX_KEYBOARDS; i++)
522 		if (MATCH(keyboards[i].dp, sstor.ss_keyboard)) {
523 			type = keyboards[i].type;
524 			break;
525 		}
526 
527 	switch (type) {
528 	case HIL:
529 		printf("hil");
530 		break;
531 	case PS2:
532 		printf("ps2");
533 		break;
534 	default:
535 		printf("unknown");
536 		break;
537 	}
538 
539 	printf("\n");
540 }
541 
542 int
543 set_keyboard(keyboard)
544 	struct device_path *keyboard;
545 {
546 	int i;
547 	char *arg = cmd.argv[1];
548 	int type;
549 
550 	if (strcmp(arg, "hil") == 0)
551 		type = HIL;
552 	else if (strcmp(arg, "ps2") == 0)
553 		type = PS2;
554 	else {
555 		printf("invalid device specification, %s\n", arg);
556 		return 0;
557 	}
558 
559 	for (i = 0; i < MAX_KEYBOARDS; i++)
560 		if (keyboards[i].type == type) {
561 			*keyboard = keyboards[i].dp;
562 			return 1;
563 		}
564 
565 	printf("no such device found\n");
566 	return 0;
567 }
568 
569 int
570 Xkeyboard()
571 {
572 	struct device_path keyboard;
573 	int rc;
574 
575 	/* walk the device list if not already done */
576 	if (walked == 0) {
577 		bus_walk(NULL);
578 		walked++;
579 	}
580 
581 	if (sstorsiz < KEYBOARDSIZE) {
582 		printf("no keyboard information in stable storage\n");
583 		return 0;
584 	}
585 
586 	if (cmd.argc == 1) {
587 		print_keyboard();
588 	} else {
589 		keyboard = sstor.ss_keyboard;
590 		if (set_keyboard(&keyboard)) {
591 			if (memcmp(&sstor.ss_keyboard, &keyboard,
592 			    sizeof keyboard) != 0) {
593 				sstor.ss_keyboard = keyboard;
594 
595 				/* alea jacta est */
596 				rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
597 				    KEYBOARDOFFSET, &sstor.ss_keyboard,
598 				    sizeof(sstor.ss_keyboard));
599 				if (rc != 0) {
600 					printf("failed to save keyboard settings, error %d\n",
601 					    rc);
602 					/* read sstor again for safety */
603 					(*pdc)(PDC_STABLE, PDC_STABLE_READ,
604 					    KEYBOARDOFFSET, &sstor.ss_keyboard,
605 					    sizeof(sstor.ss_keyboard));
606 				} else
607 					printf("you will need to power-cycle "
608 					       "your machine for the changes "
609 					       "to take effect.\n");
610 			}
611 			print_keyboard();
612 		}
613 	}
614 
615 	return 0;
616 }
617 
618 /*
619  * U T I L I T I E S
620  */
621 
622 /*
623  * Bus walker.
624  * This routine will walk all the modules on a given bus, registering
625  * serial ports, keyboard and graphics devices as they are found.
626  */
627 void
628 bus_walk(struct device_path *idp)
629 {
630 	struct device_path dp;
631 	struct pdc_memmap memmap;
632 	struct iodc_data mptr;
633 	int err, i, kluge_ps2 = 0;	/* kluge, see below */
634 
635 	for (i = 0; i < MAXMODBUS; i++) {
636 
637 		if (idp) {
638 			dp.dp_bc[0] = idp->dp_bc[1];
639 			dp.dp_bc[1] = idp->dp_bc[2];
640 			dp.dp_bc[2] = idp->dp_bc[3];
641 			dp.dp_bc[3] = idp->dp_bc[4];
642 			dp.dp_bc[4] = idp->dp_bc[5];
643 			dp.dp_bc[5] = idp->dp_mod;
644 		} else {
645 			dp.dp_bc[0] = dp.dp_bc[1] = dp.dp_bc[2] =
646 			dp.dp_bc[3] = dp.dp_bc[4] = dp.dp_bc[5] = -1;
647 		}
648 
649 		dp.dp_mod = i;
650 		if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap, &dp) < 0 &&
651 		    (pdc)(PDC_SYSMAP, PDC_SYSMAP_HPA, &memmap, &dp) < 0)
652 			continue;
653 
654 		if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, memmap.hpa,
655 		    IODC_DATA, &mptr, sizeof(mptr))) < 0)
656 			continue;
657 
658 #ifdef DEBUG
659 		printf("device %d/%d/%d/%d/%d/%d "
660 		    "flags %d mod %x type %x model %x\n",
661 		    dp.dp_bc[0], dp.dp_bc[1], dp.dp_bc[2], dp.dp_bc[3],
662 		    dp.dp_bc[4], dp.dp_bc[5], dp.dp_flags, dp.dp_mod,
663 		    mptr.iodc_type, mptr.iodc_sv_model);
664 #endif
665 		/*
666 		 * If the device can be considered as a valid rs232,
667 		 * graphics console or keyboard, register it.
668 		 *
669 		 * Unfortunately, devices which should be considered as
670 		 * ``main'' aren't necessarily seen first.
671 		 * The rules we try to enforce here are as follows:
672 		 * - GIO PS/2 ports wins over any other PS/2 port.
673 		 * - the first GIO serial found wins over any other
674 		 *   serial port.
675 		 * The second rule is a bit tricky to achieve, since on
676 		 * some machines (for example, 715/100XC), the two serial
677 		 * ports are not seen as attached to the same busses...
678 		 */
679 		switch (mptr.iodc_type) {
680 		case HPPA_TYPE_BCPORT:
681 			bus_walk(&dp);
682 			break;
683 		case HPPA_TYPE_BHA:
684 		case HPPA_TYPE_BRIDGE:
685 			/* if there was no phantomas here */
686 			if (dp.dp_bc[5] == -1) {
687 				dp.dp_bc[0] = dp.dp_bc[1];
688 				dp.dp_bc[1] = dp.dp_bc[2];
689 				dp.dp_bc[2] = dp.dp_bc[3];
690 				dp.dp_bc[3] = dp.dp_bc[4];
691 				dp.dp_bc[4] = dp.dp_bc[5];
692 				dp.dp_bc[5] = dp.dp_mod;
693 				dp.dp_mod = 0;
694 			}
695 			bus_walk(&dp);
696 			break;
697 		case HPPA_TYPE_ADIRECT:
698 			switch (mptr.iodc_sv_model) {
699 			case HPPA_ADIRECT_RS232:
700 				register_device(serials, MAX_SERIALS,
701 				    &dp, &mptr, SERIAL, 0);
702 				break;
703 			case HPPA_ADIRECT_HIL:
704 				register_device(keyboards, MAX_KEYBOARDS,
705 				    &dp, &mptr, HIL, 0);
706 				break;
707 			case HPPA_ADIRECT_PEACOCK:
708 			case HPPA_ADIRECT_LEONARDO:
709 				register_device(graphics, MAX_GRAPHICS,
710 				    &dp, &mptr, GRAPHICS, 0);
711 				break;
712 			}
713 			break;
714 		case HPPA_TYPE_FIO:
715 			switch (mptr.iodc_sv_model) {
716 			case HPPA_FIO_HIL:
717 				register_device(keyboards, MAX_KEYBOARDS,
718 				    &dp, &mptr, HIL, 0);
719 				break;
720 			case HPPA_FIO_RS232:
721 				register_device(serials, MAX_SERIALS,
722 				    &dp, &mptr, SERIAL, 0);
723 				break;
724 			case HPPA_FIO_DINOPCK:
725 				register_device(keyboards, MAX_KEYBOARDS,
726 				    &dp, &mptr, PS2, 0);
727 				break;
728 			case HPPA_FIO_GPCIO:
729 				/*
730 				 * KLUGE! At this point, there is no way to
731 				 * know if this port is the keyboard port or
732 				 * the mouse port.
733 				 * Let's assume the first port found is the
734 				 * keyboard, and ignore the others.
735 				 */
736 				if (kluge_ps2 != 0)
737 					break;
738 				register_device(keyboards, MAX_KEYBOARDS,
739 				    &dp, &mptr, PS2, 1);
740 				kluge_ps2++;
741 				break;
742 			case HPPA_FIO_GRS232:
743 			{
744 				int j, first;
745 
746 				/*
747 				 * If a GIO serial port is already registered,
748 				 * register as extra port...
749 				 */
750 				first = 1;
751 				for (j = 0; j < MAX_SERIALS; j++)
752 					if (serials[j].type == SERIAL &&
753 					    serials[j].iodc_type ==
754 					      HPPA_TYPE_FIO &&
755 					    serials[j].iodc_model ==
756 					      HPPA_FIO_GRS232) {
757 						first = 0;
758 						break;
759 					}
760 
761 				register_device(serials, MAX_SERIALS,
762 				    &dp, &mptr, SERIAL, first);
763 			}
764 				break;
765 			case HPPA_FIO_SGC:
766 				register_device(graphics, MAX_GRAPHICS,
767 				    &dp, &mptr, GRAPHICS, 0);
768 				break;
769 			case HPPA_FIO_GSGC:
770 				register_device(graphics, MAX_GRAPHICS,
771 				    &dp, &mptr, GRAPHICS, 1);
772 				break;
773 			}
774 			break;
775 		}
776 	}
777 }
778 
779 void
780 register_device(devlist, cnt, dp, mptr, type, first)
781 	struct consoledev *devlist;
782 	int cnt;
783 	struct device_path *dp;
784 	struct iodc_data *mptr;
785 	int type;
786 	int first;
787 {
788 	int i;
789 	struct consoledev *dev;
790 
791 	for (i = 0, dev = devlist; i < cnt; i++, dev++)
792 		if (dev->type == 0)
793 			break;
794 
795 	if (i == cnt) {
796 #ifdef DEBUG
797 		printf("can't register device, need more room!\n");
798 #endif
799 		return;
800 	}
801 
802 	/*
803 	 * If this is supposedly the main device, insert on top
804 	 */
805 	if (first != 0) {
806 		memcpy(devlist + 1, devlist,
807 		    (cnt - 1) * sizeof(struct consoledev));
808 		dev = devlist;
809 	}
810 
811 	dev->dp = *dp;
812 	dev->type = type;
813 	dev->iodc_type = mptr->iodc_type;
814 	dev->iodc_model = mptr->iodc_sv_model;
815 
816 #ifdef DEBUG
817 	printf("(registered as type %d)\n", type);
818 #endif
819 }
820