1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)mkioconf.c 5.14 (Berkeley) 06/01/90"; 10 #endif /* not lint */ 11 12 #include <stdio.h> 13 #include "y.tab.h" 14 #include "config.h" 15 16 /* 17 * build the ioconf.c file 18 */ 19 char *qu(); 20 char *intv(); 21 22 #if MACHINE_VAX 23 vax_ioconf() 24 { 25 register struct device *dp, *mp, *np; 26 register int uba_n, slave; 27 FILE *fp; 28 29 fp = fopen(path("ioconf.c"), "w"); 30 if (fp == 0) { 31 perror(path("ioconf.c")); 32 exit(1); 33 } 34 fprintf(fp, "#include \"machine/pte.h\"\n"); 35 fprintf(fp, "#include \"../sys/param.h\"\n"); 36 fprintf(fp, "#include \"../sys/buf.h\"\n"); 37 fprintf(fp, "#include \"../sys/map.h\"\n"); 38 fprintf(fp, "#include \"../sys/vm.h\"\n"); 39 fprintf(fp, "\n"); 40 fprintf(fp, "#include \"../vaxmba/mbavar.h\"\n"); 41 fprintf(fp, "#include \"../vaxuba/ubavar.h\"\n\n"); 42 fprintf(fp, "\n"); 43 fprintf(fp, "#define C (caddr_t)\n\n"); 44 /* 45 * First print the mba initialization structures 46 */ 47 if (seen_mba) { 48 for (dp = dtab; dp != 0; dp = dp->d_next) { 49 mp = dp->d_conn; 50 if (mp == 0 || mp == TO_NEXUS || 51 !eq(mp->d_name, "mba")) 52 continue; 53 fprintf(fp, "extern struct mba_driver %sdriver;\n", 54 dp->d_name); 55 } 56 fprintf(fp, "\nstruct mba_device mbdinit[] = {\n"); 57 fprintf(fp, "\t/* Device, Unit, Mba, Drive, Dk */\n"); 58 for (dp = dtab; dp != 0; dp = dp->d_next) { 59 mp = dp->d_conn; 60 if (dp->d_unit == QUES || mp == 0 || 61 mp == TO_NEXUS || !eq(mp->d_name, "mba")) 62 continue; 63 if (dp->d_addr) { 64 printf("can't specify csr address on mba for %s%d\n", 65 dp->d_name, dp->d_unit); 66 continue; 67 } 68 if (dp->d_vec != 0) { 69 printf("can't specify vector for %s%d on mba\n", 70 dp->d_name, dp->d_unit); 71 continue; 72 } 73 if (dp->d_drive == UNKNOWN) { 74 printf("drive not specified for %s%d\n", 75 dp->d_name, dp->d_unit); 76 continue; 77 } 78 if (dp->d_slave != UNKNOWN) { 79 printf("can't specify slave number for %s%d\n", 80 dp->d_name, dp->d_unit); 81 continue; 82 } 83 fprintf(fp, "\t{ &%sdriver, %d, %s,", 84 dp->d_name, dp->d_unit, qu(mp->d_unit)); 85 fprintf(fp, " %s, %d },\n", 86 qu(dp->d_drive), dp->d_dk); 87 } 88 fprintf(fp, "\t0\n};\n\n"); 89 /* 90 * Print the mbsinit structure 91 * Driver Controller Unit Slave 92 */ 93 fprintf(fp, "struct mba_slave mbsinit [] = {\n"); 94 fprintf(fp, "\t/* Driver, Ctlr, Unit, Slave */\n"); 95 for (dp = dtab; dp != 0; dp = dp->d_next) { 96 /* 97 * All slaves are connected to something which 98 * is connected to the massbus. 99 */ 100 if ((mp = dp->d_conn) == 0 || mp == TO_NEXUS) 101 continue; 102 np = mp->d_conn; 103 if (np == 0 || np == TO_NEXUS || 104 !eq(np->d_name, "mba")) 105 continue; 106 fprintf(fp, "\t{ &%sdriver, %s", 107 mp->d_name, qu(mp->d_unit)); 108 fprintf(fp, ", %2d, %s },\n", 109 dp->d_unit, qu(dp->d_slave)); 110 } 111 fprintf(fp, "\t0\n};\n\n"); 112 } 113 /* 114 * Now generate interrupt vectors for the unibus 115 */ 116 for (dp = dtab; dp != 0; dp = dp->d_next) { 117 if (dp->d_vec != 0) { 118 struct idlst *ip; 119 mp = dp->d_conn; 120 if (mp == 0 || mp == TO_NEXUS || 121 (!eq(mp->d_name, "uba") && !eq(mp->d_name, "bi"))) 122 continue; 123 fprintf(fp, 124 "extern struct uba_driver %sdriver;\n", 125 dp->d_name); 126 fprintf(fp, "extern "); 127 ip = dp->d_vec; 128 for (;;) { 129 fprintf(fp, "X%s%d()", ip->id, dp->d_unit); 130 ip = ip->id_next; 131 if (ip == 0) 132 break; 133 fprintf(fp, ", "); 134 } 135 fprintf(fp, ";\n"); 136 fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name, 137 dp->d_unit); 138 ip = dp->d_vec; 139 for (;;) { 140 fprintf(fp, "X%s%d", ip->id, dp->d_unit); 141 ip = ip->id_next; 142 if (ip == 0) 143 break; 144 fprintf(fp, ", "); 145 } 146 fprintf(fp, ", 0 } ;\n"); 147 } 148 } 149 fprintf(fp, "\nstruct uba_ctlr ubminit[] = {\n"); 150 fprintf(fp, "/*\t driver,\tctlr,\tubanum,\talive,\tintr,\taddr */\n"); 151 for (dp = dtab; dp != 0; dp = dp->d_next) { 152 mp = dp->d_conn; 153 if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || 154 !eq(mp->d_name, "uba")) 155 continue; 156 if (dp->d_vec == 0) { 157 printf("must specify vector for %s%d\n", 158 dp->d_name, dp->d_unit); 159 continue; 160 } 161 if (dp->d_addr == 0) { 162 printf("must specify csr address for %s%d\n", 163 dp->d_name, dp->d_unit); 164 continue; 165 } 166 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 167 printf("drives need their own entries; dont "); 168 printf("specify drive or slave for %s%d\n", 169 dp->d_name, dp->d_unit); 170 continue; 171 } 172 if (dp->d_flags) { 173 printf("controllers (e.g. %s%d) ", 174 dp->d_name, dp->d_unit); 175 printf("don't have flags, only devices do\n"); 176 continue; 177 } 178 fprintf(fp, 179 "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0%o },\n", 180 dp->d_name, dp->d_unit, qu(mp->d_unit), 181 dp->d_name, dp->d_unit, dp->d_addr); 182 } 183 fprintf(fp, "\t0\n};\n"); 184 /* unibus devices */ 185 fprintf(fp, "\nstruct uba_device ubdinit[] = {\n"); 186 fprintf(fp, 187 "\t/* driver, unit, ctlr, ubanum, slave, intr, addr, dk, flags*/\n"); 188 for (dp = dtab; dp != 0; dp = dp->d_next) { 189 mp = dp->d_conn; 190 if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || 191 mp == TO_NEXUS || mp->d_type == MASTER || 192 eq(mp->d_name, "mba")) 193 continue; 194 np = mp->d_conn; 195 if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba")) 196 continue; 197 np = 0; 198 if (eq(mp->d_name, "uba")) { 199 if (dp->d_vec == 0) { 200 printf("must specify vector for device %s%d\n", 201 dp->d_name, dp->d_unit); 202 continue; 203 } 204 if (dp->d_addr == 0) { 205 printf("must specify csr for device %s%d\n", 206 dp->d_name, dp->d_unit); 207 continue; 208 } 209 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 210 printf("drives/slaves can be specified "); 211 printf("only for controllers, "); 212 printf("not for device %s%d\n", 213 dp->d_name, dp->d_unit); 214 continue; 215 } 216 uba_n = mp->d_unit; 217 slave = QUES; 218 } else { 219 if ((np = mp->d_conn) == 0) { 220 printf("%s%d isn't connected to anything ", 221 mp->d_name, mp->d_unit); 222 printf(", so %s%d is unattached\n", 223 dp->d_name, dp->d_unit); 224 continue; 225 } 226 uba_n = np->d_unit; 227 if (dp->d_drive == UNKNOWN) { 228 printf("must specify ``drive number'' "); 229 printf("for %s%d\n", dp->d_name, dp->d_unit); 230 continue; 231 } 232 /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ 233 /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ 234 if (dp->d_slave != UNKNOWN) { 235 printf("slave numbers should be given only "); 236 printf("for massbus tapes, not for %s%d\n", 237 dp->d_name, dp->d_unit); 238 continue; 239 } 240 if (dp->d_vec != 0) { 241 printf("interrupt vectors should not be "); 242 printf("given for drive %s%d\n", 243 dp->d_name, dp->d_unit); 244 continue; 245 } 246 if (dp->d_addr != 0) { 247 printf("csr addresses should be given only "); 248 printf("on controllers, not on %s%d\n", 249 dp->d_name, dp->d_unit); 250 continue; 251 } 252 slave = dp->d_drive; 253 } 254 fprintf(fp, "\t{ &%sdriver, %2d, %s,", 255 eq(mp->d_name, "uba") ? dp->d_name : mp->d_name, dp->d_unit, 256 eq(mp->d_name, "uba") ? " -1" : qu(mp->d_unit)); 257 fprintf(fp, " %s, %2d, %s, C 0%-6o, %d, 0x%x },\n", 258 qu(uba_n), slave, intv(dp), dp->d_addr, dp->d_dk, 259 dp->d_flags); 260 } 261 fprintf(fp, "\t0\n};\n"); 262 (void) fclose(fp); 263 } 264 #endif 265 266 #if MACHINE_TAHOE 267 tahoe_ioconf() 268 { 269 register struct device *dp, *mp, *np; 270 register int vba_n, slave; 271 FILE *fp; 272 273 fp = fopen(path("ioconf.c"), "w"); 274 if (fp == 0) { 275 perror(path("ioconf.c")); 276 exit(1); 277 } 278 fprintf(fp, "#include \"../sys/param.h\"\n"); 279 fprintf(fp, "#include \"machine/pte.h\"\n"); 280 fprintf(fp, "#include \"../sys/buf.h\"\n"); 281 fprintf(fp, "#include \"../sys/map.h\"\n"); 282 fprintf(fp, "\n"); 283 fprintf(fp, "#include \"../tahoevba/vbavar.h\"\n"); 284 fprintf(fp, "\n"); 285 fprintf(fp, "#define C (caddr_t)\n\n"); 286 /* 287 * Now generate interrupt vectors for the versabus 288 */ 289 for (dp = dtab; dp != 0; dp = dp->d_next) { 290 mp = dp->d_conn; 291 if (mp == 0 || mp == TO_NEXUS || !eq(mp->d_name, "vba")) 292 continue; 293 if (dp->d_vec != 0) { 294 struct idlst *ip; 295 fprintf(fp, 296 "extern struct vba_driver %sdriver;\n", 297 dp->d_name); 298 fprintf(fp, "extern "); 299 ip = dp->d_vec; 300 for (;;) { 301 fprintf(fp, "X%s%d()", ip->id, dp->d_unit); 302 ip = ip->id_next; 303 if (ip == 0) 304 break; 305 fprintf(fp, ", "); 306 } 307 fprintf(fp, ";\n"); 308 fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name, 309 dp->d_unit); 310 ip = dp->d_vec; 311 for (;;) { 312 fprintf(fp, "X%s%d", ip->id, dp->d_unit); 313 ip = ip->id_next; 314 if (ip == 0) 315 break; 316 fprintf(fp, ", "); 317 } 318 fprintf(fp, ", 0 } ;\n"); 319 } else if (dp->d_type == DRIVER) /* devices w/o interrupts */ 320 fprintf(fp, 321 "extern struct vba_driver %sdriver;\n", 322 dp->d_name); 323 } 324 fprintf(fp, "\nstruct vba_ctlr vbminit[] = {\n"); 325 fprintf(fp, "/*\t driver,\tctlr,\tvbanum,\talive,\tintr,\taddr */\n"); 326 for (dp = dtab; dp != 0; dp = dp->d_next) { 327 mp = dp->d_conn; 328 if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || 329 !eq(mp->d_name, "vba")) 330 continue; 331 if (dp->d_vec == 0) { 332 printf("must specify vector for %s%d\n", 333 dp->d_name, dp->d_unit); 334 continue; 335 } 336 if (dp->d_addr == 0) { 337 printf("must specify csr address for %s%d\n", 338 dp->d_name, dp->d_unit); 339 continue; 340 } 341 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 342 printf("drives need their own entries; dont "); 343 printf("specify drive or slave for %s%d\n", 344 dp->d_name, dp->d_unit); 345 continue; 346 } 347 if (dp->d_flags) { 348 printf("controllers (e.g. %s%d) ", 349 dp->d_name, dp->d_unit); 350 printf("don't have flags, only devices do\n"); 351 continue; 352 } 353 fprintf(fp, 354 "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0x%x },\n", 355 dp->d_name, dp->d_unit, qu(mp->d_unit), 356 dp->d_name, dp->d_unit, dp->d_addr); 357 } 358 fprintf(fp, "\t0\n};\n"); 359 /* versabus devices */ 360 fprintf(fp, "\nstruct vba_device vbdinit[] = {\n"); 361 fprintf(fp, 362 "\t/* driver, unit, ctlr, vbanum, slave, intr, addr, dk, flags*/\n"); 363 for (dp = dtab; dp != 0; dp = dp->d_next) { 364 mp = dp->d_conn; 365 if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || 366 mp == TO_NEXUS || mp->d_type == MASTER || 367 eq(mp->d_name, "mba")) 368 continue; 369 np = mp->d_conn; 370 if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba")) 371 continue; 372 np = 0; 373 if (eq(mp->d_name, "vba")) { 374 if (dp->d_vec == 0) 375 printf( 376 "Warning, no interrupt vector specified for device %s%d\n", 377 dp->d_name, dp->d_unit); 378 if (dp->d_addr == 0) { 379 printf("must specify csr for device %s%d\n", 380 dp->d_name, dp->d_unit); 381 continue; 382 } 383 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 384 printf("drives/slaves can be specified "); 385 printf("only for controllers, "); 386 printf("not for device %s%d\n", 387 dp->d_name, dp->d_unit); 388 continue; 389 } 390 vba_n = mp->d_unit; 391 slave = QUES; 392 } else { 393 if ((np = mp->d_conn) == 0) { 394 printf("%s%d isn't connected to anything ", 395 mp->d_name, mp->d_unit); 396 printf(", so %s%d is unattached\n", 397 dp->d_name, dp->d_unit); 398 continue; 399 } 400 vba_n = np->d_unit; 401 if (dp->d_drive == UNKNOWN) { 402 printf("must specify ``drive number'' "); 403 printf("for %s%d\n", dp->d_name, dp->d_unit); 404 continue; 405 } 406 /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ 407 /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ 408 if (dp->d_slave != UNKNOWN) { 409 printf("slave numbers should be given only "); 410 printf("for massbus tapes, not for %s%d\n", 411 dp->d_name, dp->d_unit); 412 continue; 413 } 414 if (dp->d_vec != 0) { 415 printf("interrupt vectors should not be "); 416 printf("given for drive %s%d\n", 417 dp->d_name, dp->d_unit); 418 continue; 419 } 420 if (dp->d_addr != 0) { 421 printf("csr addresses should be given only "); 422 printf("on controllers, not on %s%d\n", 423 dp->d_name, dp->d_unit); 424 continue; 425 } 426 slave = dp->d_drive; 427 } 428 fprintf(fp, "\t{ &%sdriver, %2d, %s,", 429 eq(mp->d_name, "vba") ? dp->d_name : mp->d_name, dp->d_unit, 430 eq(mp->d_name, "vba") ? " -1" : qu(mp->d_unit)); 431 fprintf(fp, " %s, %2d, %s, C 0x%-6x, %d, 0x%x },\n", 432 qu(vba_n), slave, intv(dp), dp->d_addr, dp->d_dk, 433 dp->d_flags); 434 } 435 fprintf(fp, "\t0\n};\n"); 436 (void) fclose(fp); 437 } 438 #endif 439 440 #if MACHINE_HP300 441 hp300_ioconf() 442 { 443 register struct device *dp, *mp, *np; 444 register int hpib, slave; 445 FILE *fp; 446 extern char *wnum(); 447 448 fp = fopen(path("ioconf.c"), "w"); 449 if (fp == 0) { 450 perror(path("ioconf.c")); 451 exit(1); 452 } 453 fprintf(fp, "#include \"machine/pte.h\"\n"); 454 fprintf(fp, "#include \"../sys/param.h\"\n"); 455 fprintf(fp, "#include \"../sys/buf.h\"\n"); 456 fprintf(fp, "#include \"../sys/map.h\"\n"); 457 fprintf(fp, "#include \"../sys/vm.h\"\n"); 458 fprintf(fp, "\n"); 459 fprintf(fp, "#include \"../hpdev/device.h\"\n\n"); 460 fprintf(fp, "\n"); 461 fprintf(fp, "#define C (caddr_t)\n"); 462 fprintf(fp, "#define D (struct driver *)\n\n"); 463 /* 464 * First print the hpib controller initialization structures 465 */ 466 for (dp = dtab; dp != 0; dp = dp->d_next) { 467 mp = dp->d_conn; 468 if (dp->d_unit == QUES || mp == 0) 469 continue; 470 fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name); 471 } 472 fprintf(fp, "\nstruct hp_ctlr hp_cinit[] = {\n"); 473 fprintf(fp, "/*\tdriver,\t\tunit,\talive,\taddr,\tflags */\n"); 474 for (dp = dtab; dp != 0; dp = dp->d_next) { 475 mp = dp->d_conn; 476 if (dp->d_unit == QUES || 477 dp->d_type != MASTER && dp->d_type != CONTROLLER) 478 continue; 479 if (mp != TO_NEXUS) { 480 printf("%s%s must be attached to an sc (nexus)\n", 481 dp->d_name, wnum(dp->d_unit)); 482 continue; 483 } 484 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 485 printf("can't specify drive/slave for %s%s\n", 486 dp->d_name, wnum(dp->d_unit)); 487 continue; 488 } 489 fprintf(fp, 490 "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t0x%x },\n", 491 dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags); 492 } 493 fprintf(fp, "\t0\n};\n"); 494 /* devices */ 495 fprintf(fp, "\nstruct hp_device hp_dinit[] = {\n"); 496 fprintf(fp, 497 "/*driver,\tcdriver,\tunit,\tctlr,\tslave,\taddr,\tdk,\tflags*/\n"); 498 for (dp = dtab; dp != 0; dp = dp->d_next) { 499 mp = dp->d_conn; 500 if (mp == 0 || dp->d_type != DEVICE || hpbadslave(mp, dp)) 501 continue; 502 if (mp == TO_NEXUS) { 503 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 504 printf("can't specify drive/slave for %s%s\n", 505 dp->d_name, wnum(dp->d_unit)); 506 continue; 507 } 508 slave = QUES; 509 hpib = QUES; 510 } else { 511 if (dp->d_addr != 0) { 512 printf("can't specify sc for device %s%s\n", 513 dp->d_name, wnum(dp->d_unit)); 514 continue; 515 } 516 if (mp->d_type == CONTROLLER) { 517 if (dp->d_drive == UNKNOWN) { 518 printf("must specify drive for %s%s\n", 519 dp->d_name, wnum(dp->d_unit)); 520 continue; 521 } 522 slave = dp->d_drive; 523 } else { 524 if (dp->d_slave == UNKNOWN) { 525 printf("must specify slave for %s%s\n", 526 dp->d_name, wnum(dp->d_unit)); 527 continue; 528 } 529 slave = dp->d_slave; 530 } 531 hpib = mp->d_unit; 532 } 533 fprintf(fp, "{ &%sdriver,\t", dp->d_name); 534 if (mp == TO_NEXUS) 535 fprintf(fp, "D 0x0,\t"); 536 else 537 fprintf(fp, "&%sdriver,", mp->d_name); 538 fprintf(fp, "\t%d,\t%d,\t%d,\tC 0x%x,\t%d,\t0x%x },\n", 539 dp->d_unit, hpib, slave, 540 dp->d_addr, dp->d_dk, dp->d_flags); 541 } 542 fprintf(fp, "0\n};\n"); 543 (void) fclose(fp); 544 } 545 546 #define ishpibdev(n) (eq(n,"rd") || eq(n,"ct") || eq(n,"mt") || eq(n,"ppi")) 547 #define isscsidev(n) (eq(n,"sd") || eq(n,"st")) 548 549 hpbadslave(mp, dp) 550 register struct device *dp, *mp; 551 { 552 extern char *wnum(); 553 554 if (mp == TO_NEXUS && ishpibdev(dp->d_name) || 555 mp != TO_NEXUS && eq(mp->d_name, "hpib") && 556 !ishpibdev(dp->d_name)) { 557 printf("%s%s must be attached to an hpib\n", 558 dp->d_name, wnum(dp->d_unit)); 559 return (1); 560 } 561 if (mp == TO_NEXUS && isscsidev(dp->d_name) || 562 mp != TO_NEXUS && eq(mp->d_name, "scsi") && 563 !isscsidev(dp->d_name)) { 564 printf("%s%s must be attached to a scsi\n", 565 dp->d_name, wnum(dp->d_unit)); 566 return (1); 567 } 568 return (0); 569 } 570 571 char * 572 wnum(num) 573 { 574 575 if (num == QUES || num == UNKNOWN) 576 return ("?"); 577 (void) sprintf(errbuf, "%d", num); 578 return (errbuf); 579 } 580 #endif 581 582 char * 583 intv(dev) 584 register struct device *dev; 585 { 586 static char buf[20]; 587 588 if (dev->d_vec == 0) 589 return (" 0"); 590 (void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit); 591 return (buf); 592 } 593 594 char * 595 qu(num) 596 { 597 598 if (num == QUES) 599 return ("'?'"); 600 if (num == UNKNOWN) 601 return (" -1"); 602 (void) sprintf(errbuf, "%3d", num); 603 return (errbuf); 604 } 605