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