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