|
|
1.1 ! root 1: .de EX ! 2: .DS ! 3: .ft CW ! 4: .. ! 5: .de EE ! 6: .ft ! 7: .DE ! 8: .. ! 9: .de CW ! 10: \&\\$3\f(CW\\$1\\fP\\$2 ! 11: .. ! 12: .de CP ! 13: .IP "\&\\$3\f(CW\\$1\\fP\\$2" .7i ! 14: .. ! 15: .de Bh ! 16: .NH ! 17: .. ! 18: .de Sh ! 19: .SH ! 20: .. ! 21: .Bh ! 22: What ! 23: .CW mkconf ! 24: gets ! 25: .PP ! 26: There are three interesting files read: ! 27: one describing the devices and drivers ! 28: that may be configured, ! 29: one describing the system control block, ! 30: and one listing the pieces to be configured ! 31: into the particular system being built. ! 32: .PP ! 33: General rules: ! 34: all the files contain ! 35: lines of text, ! 36: which are broken into fields ! 37: separated by white space. ! 38: .CW # ! 39: introduces a comment; ! 40: the remainder of the line is ignored. ! 41: When a field contains a number, ! 42: it is interpreted as hexadecimal ! 43: if introduced by ! 44: .CW 0x , ! 45: octal if by ! 46: .CW 0 , ! 47: decimal otherwise. ! 48: .Sh ! 49: .CW devs ! 50: .PP ! 51: The master list of devices and drivers ! 52: lives in a file called ! 53: .CW devs . ! 54: This contains one line ! 55: for each device, driver, or driver-like entity ! 56: that may be added to the system. ! 57: Each line is of the form ! 58: .EX ! 59: name tag things ! 60: .EE ! 61: .PP ! 62: .CW Name ! 63: is the name of the thing described. ! 64: It need have nothing to do with ! 65: filenames, ! 66: driver entry points, ! 67: or anything else; ! 68: it is used only by ! 69: .CW mkconf . ! 70: .PP ! 71: .CW Tag ! 72: is a string known by the driver, ! 73: prepended to entry points in ! 74: (e.g.) ! 75: .CW conf.c . ! 76: .PP ! 77: .CW Things ! 78: are various bits of information: ! 79: which table the driver should be entered in, ! 80: what sort of addressing this device requires, ! 81: and some miscellaneous hacks. ! 82: They are encoded as words, ! 83: sometimes followed by other words. ! 84: .PP ! 85: Tables are encoded by ! 86: .CP bdev ! 87: Block device driver; ! 88: enter in ! 89: .CW bdevsw . ! 90: .CP cdev ! 91: Character device driver; ! 92: enter in ! 93: .CW cdevsw . ! 94: .CP fs ! 95: File system driver; ! 96: enter in ! 97: .CW fstypsw . ! 98: .CP ld ! 99: Stream line discipline; ! 100: enter in ! 101: .CW streamtab . ! 102: .LP ! 103: Each of these should be followed by a number, ! 104: which is used as the index in the table; ! 105: e.g. ! 106: .CW "bdev 3" ! 107: means the block device ! 108: with major number 3. ! 109: It's perfectly acceptable ! 110: to enter a driver ! 111: in several tables ! 112: (e.g. block and character device) ! 113: or in no table at all; ! 114: device addresses and the like are declared anyway if appropriate. ! 115: .PP ! 116: Address type words are ! 117: .CP sbi ! 118: This is an old-fashioned (SBI or CMI) nexus device. ! 119: .CP vaxbi ! 120: This is a VAXBI device. ! 121: .CP mb ! 122: This is a MASSBUS device. ! 123: .CP ub ! 124: This is a UNIBUS device. ! 125: .CP sub ! 126: This is a subdevice ! 127: (like a disk drive connected to a controller). ! 128: .CP count ! 129: This device has no address, ! 130: but needs to know its count anyway. ! 131: (Perhaps there are data structures.) ! 132: .LP ! 133: Again, ! 134: it's permissable ! 135: not to specify any address type at all; ! 136: this simply means ! 137: .CW mkconf ! 138: won't bother to print an address. ! 139: .PP ! 140: Some words indicate that the device ! 141: is an adapter into which other devices ! 142: (with one of the address types above) ! 143: are plugged: ! 144: .CP sbia ! 145: SBI adapter. ! 146: .CP bia ! 147: VAXBI adapter ! 148: .CP mba ! 149: MASSBUS adapter. ! 150: .CP uba ! 151: UNIBUS adapter. ! 152: .LP ! 153: By preference, ! 154: new adapter types ! 155: should be named by appending ! 156: .CW a ! 157: to the corresponding address name. ! 158: .PP ! 159: Other hacks: ! 160: .CP vec " n" ! 161: Vector size. ! 162: Devices are generally assumed to have ! 163: one interrupt vector ! 164: (if any, depending on address type). ! 165: .CW "vec 3" ! 166: means the device ! 167: really has three vectors, ! 168: presumably contiguous. ! 169: .CP rep " n" ! 170: Repeat count. ! 171: .CW "rep 8" ! 172: means there are really 8 devices ! 173: per device controller; ! 174: .CW mkconf ! 175: should scale counts by 8. ! 176: .PP ! 177: The magic word ! 178: .CW strs ! 179: introduces a list of data structures ! 180: associated with this device, ! 181: named by the remaining words on the line. ! 182: Obviously, ! 183: this flag must be last. ! 184: .Sh ! 185: scb ! 186: .PP ! 187: Annoyingly, ! 188: different VAXes have different low-level traps ! 189: in the system control block. ! 190: Hence, ! 191: for each kind of VAX ! 192: (or at least each variant kind of SCB) ! 193: there is an SCB template file. ! 194: .PP ! 195: The file contains lines like ! 196: .EX ! 197: offset type name label ! 198: .EE ! 199: meaning that traps to the given byte ! 200: .CW offset ! 201: are to be vectored to ! 202: .CW name . ! 203: The name is just a label in some assembly language routine ! 204: to which control should be transferred on the trap ! 205: with some arbitrary trap-dependent stuff on the stack. ! 206: It should be longword-aligned, as the low-order bits of the vector ! 207: are meaningful to the VAX. ! 208: .CW Type ! 209: is ! 210: .CW t ! 211: for traps that should be taken ! 212: on the kernel stack, ! 213: .CW i ! 214: for those that should be ! 215: on the interrupt stack. ! 216: .PP ! 217: It would be nice to eliminate this file entirely, ! 218: or at least cause there to be only one. ! 219: There must be something somewhere ! 220: as most of the system control block ! 221: consists of I/O vectors, ! 222: which ! 223: .CW mkconf ! 224: must generate, ! 225: or placeholders for stray interrupts, ! 226: which are best generated by a program. ! 227: .Sh ! 228: conf ! 229: .PP ! 230: This is the file ! 231: that describes what's to be configured ! 232: into a particular copy of the system. ! 233: Each real device ! 234: (individual object with an address) ! 235: takes up one line. ! 236: Each driver-like thing ! 237: (such as a line discipline) ! 238: takes up a line too. ! 239: .PP ! 240: Lines look like ! 241: .EX ! 242: name id addr ... ! 243: .EE ! 244: .CW Name ! 245: is one of the ones ! 246: in the ! 247: .CW devs ! 248: file. ! 249: .CW Id ! 250: is a sequence number. ! 251: It is used as an index ! 252: into data structures ! 253: (like the address) ! 254: generated by ! 255: .CW mkconf . ! 256: For honest devices ! 257: (that have entries in ! 258: .CW /dev ) ! 259: the ! 260: .CW id ! 261: is probably related in some simple way ! 262: to the minor device number; ! 263: for devices that exist only as places to plug in other devices ! 264: (such as MASSBUS adapters ! 265: and UNIBUS disk controllers), ! 266: the ! 267: .CW id ! 268: is part of the address ! 269: for devices so plugged. ! 270: .CW Mkconf ! 271: uses the ! 272: .CW id ! 273: to connect devices to their adapters, ! 274: to build tables of addresses, ! 275: and to decide how many devices there are ! 276: (the highest ! 277: .CW id ! 278: plus one, ! 279: multiplied by the ! 280: repeat count). ! 281: .PP ! 282: Syntactically, ! 283: the address stuff ! 284: is just a handful of blank-separated numbers ! 285: whose interpretation ! 286: depends on the address type of the device: ! 287: .IP ! 288: SBI devices take an adapter number, ! 289: a nexus (TR) number, ! 290: and perhaps a vector base. ! 291: The adapter number ! 292: is useful when there's more than one bus, ! 293: is 0 otherwise. ! 294: The vector base is used for things like ! 295: UNIBUS adapters. ! 296: .IP ! 297: VAXBI devices ! 298: take an adapter number, ! 299: a node (TR) number, ! 300: a vector, ! 301: and perhaps a vector base. ! 302: .IP ! 303: MASSBUS devices ! 304: take an adapter number ! 305: (the ! 306: .CW id ! 307: of the corresponding ! 308: RH device) ! 309: and a unit number ! 310: (the controller number on the MASSBUS). ! 311: .IP ! 312: UNIBUS devices ! 313: take an adapter number ! 314: (the ! 315: .CW id ! 316: of the UNIBUS adapter), ! 317: a UNIBUS address, ! 318: and a vector. ! 319: Both the address and the vector ! 320: are relative to that UNIBUS. ! 321: .IP ! 322: Subdevices ! 323: take a controller number ! 324: and a unit number. ! 325: .PP ! 326: Devices that take only a count ! 327: are a special case: ! 328: the ! 329: .CW id ! 330: is really the count, ! 331: and there is no address ! 332: (or more exactly, ! 333: the address is ignored). ! 334: .Bh ! 335: What ! 336: .CW mkconf ! 337: puts out ! 338: .PP ! 339: .CW Mkconf ! 340: writes two files: ! 341: one with interrupt vectors, ! 342: one with tables and address stuff. ! 343: .Sh ! 344: scb.s ! 345: .PP ! 346: .CW Mkconf ! 347: writes one assembly language file ! 348: containing the SCB, ! 349: stray interrupt catching hooks, ! 350: and interface routines to call ! 351: interrupt handlers written in C. ! 352: .PP ! 353: Traps described in the SCB template file ! 354: are put out as entered. ! 355: Other interrupts are placed as described by the vectors ! 356: in the configuration file. ! 357: .CW Mkconf ! 358: doesn't know anything about, ! 359: say, ! 360: the peculiarities of comet UNIBUS adapters; ! 361: it's up to the person writing the ! 362: .CW conf ! 363: file to get it right ! 364: (in this case ! 365: by saying that the UNIBUS adapters have vector bases ! 366: at 0x200 and 0x400). ! 367: All I/O interrupts ! 368: are placed on the interrupt stack. ! 369: .PP ! 370: SCB slots with nothing assigned ! 371: are filled in with stray catchers. ! 372: In fact, ! 373: they are vectored into tables of ! 374: code of the form ! 375: .EX ! 376: straycatch: ! 377: .align 2; bsbw stray # here on stray interrupt from offset 0 ! 378: .align 2; bsbw stray # offset 4 ! 379: .align 2; bsbw stray # and so on ! 380: . ! 381: . ! 382: . ! 383: .EE ! 384: thus doubling the size of the SCB ! 385: (each page of vectors requires a page of stray catchers), ! 386: but making it possible ! 387: to see where strays come from. ! 388: .PP ! 389: .CW mkconf ! 390: only writes the tables; ! 391: .CW stray ! 392: is expected to be provided elsewhere in the system. ! 393: A plausible implementation might look like ! 394: .EX ! 395: stray: ! 396: pushr $0x3f # save some registers ! 397: subl3 $straycatch,7*4(sp),-(sp) # get offset of stray ! 398: calls $1,_strayintr ! 399: popr $0x3f ! 400: tstl (sp)+ ! 401: rei ! 402: .EE ! 403: .PP ! 404: After the SCB, ! 405: .CW mkconf ! 406: writes a handful of interface routines of the form ! 407: .EX ! 408: Xdz31: ! 409: pushr $0x3f ! 410: pushl $3 # dz3 ! 411: calls $1,_dz1int # call second interrupt ! 412: popr $3 ! 413: rei ! 414: .EE ! 415: Device interrupt routines should be named ! 416: .CW xx0int , ! 417: .CW xx1int , ! 418: and so on for successive vectors, ! 419: where ! 420: .CW xx ! 421: is the tag for that device driver. ! 422: Even if there's only one interrupt vector, ! 423: the interrupt routine is named ! 424: .CW xx0int . ! 425: .Sh ! 426: conf.c ! 427: .PP ! 428: There are tables, ! 429: and per-device data structures. ! 430: .PP ! 431: The tables may be summarized as follows: ! 432: .EX ! 433: struct bdevsw *bdevsw[]; /* block devices */ ! 434: struct cdevsw *cdevsw[]; /* character devices */ ! 435: struct fstypsw *fstypsw[]; /* file systems */ ! 436: struct streamtab *streamtab[]; /* line disciplines */ ! 437: ! 438: int nblkdev, nchrdev, nfstyp, nstreamtab; /* number of entries */ ! 439: .EE ! 440: The names need to be slightly straightened out ! 441: for consistency. ! 442: .PP ! 443: Note that the tables contain pointers ! 444: to entry point tables, ! 445: not the entry points themselves. ! 446: Empty slots in the tables ! 447: contain ! 448: .CW NULL ! 449: pointers. ! 450: .PP ! 451: A device driver is expected to define ! 452: an appropriate table entry ! 453: for each table it is entered in. ! 454: The table entry should be named ! 455: .CW xxbdev , ! 456: .CW xxcdev , ! 457: .CW xxfs , ! 458: or ! 459: .CW xxstream ! 460: for the driver with tag ! 461: .CW xx . ! 462: .PP ! 463: Most drivers will expect ! 464: .CW conf.c ! 465: to define some data for them ! 466: as well. ! 467: A count of configured devices ! 468: will be defined: ! 469: .EX ! 470: int xxcnt; ! 471: .EE ! 472: The count is scaled by the repeat count, ! 473: if any; ! 474: e.g. declaring three DZ11s will probably cause ! 475: .CW dzcnt ! 476: to contain 24. ! 477: .PP ! 478: If the driver expects some address information, ! 479: it will be defined ! 480: with the name ! 481: .CW xxaddr . ! 482: The type of the data ! 483: and the meaning of its contents ! 484: depends on the kind of device; ! 485: see the section on addresses. ! 486: .PP ! 487: If the driver requested any structure definitions, ! 488: they will be there as well: ! 489: .EX ! 490: struct gumby xxgumby[N]; ! 491: .EE ! 492: where ! 493: .CW N ! 494: is the same number as in ! 495: .CW xxcnt . ! 496: .PP ! 497: Things to think about: ! 498: it would be nice to declare, ! 499: e.g., ! 500: inode table. ! 501: inode device with empty tag ! 502: (never mind the syntax), ! 503: but how do you get the count out? ! 504: .Bh ! 505: How devices are addressed ! 506: .Sh ! 507: The hardware model ! 508: .PP ! 509: There are buses, ! 510: to which adapters are attached. ! 511: Older VAXes have only one bus apiece ! 512: (the 780's SBI, ! 513: the 750's CMI); ! 514: newer ones can have several ! 515: (two SBIs on the 8600, ! 516: up to four VAXBIs on 8800-like machines). ! 517: .PP ! 518: Each bus contains some number of nexus ! 519: and some number of address windows. ! 520: A nexus is a space of 0x2000 bytes, ! 521: some of which are registers for the device at that nexus. ! 522: Sometimes the `device' is really a peripheral ! 523: (especially VAXBI devices, ! 524: but things like the DR780 as well), ! 525: but on older machines it is usually an adapter to some other kind of bus ! 526: (UNIBUS or MASSBUS). ! 527: UNIBUS adapters (and perhaps other adapters too) ! 528: need to allow the VAX to get at the address space they control; ! 529: hence the address windows. ! 530: .PP ! 531: The first few registers ! 532: in a nexus are usually well-defined, ! 533: but only for devices in the same bus ! 534: (e.g. SBI and VAXBI differ noticeably). ! 535: The low-order part of the first longword ! 536: is generally supposed to contain some sort of ! 537: nexus type code, ! 538: but even this is sometimes violated. ! 539: In general, ! 540: within a nexus, ! 541: all rules are off. ! 542: For example, ! 543: MASSBUS adapters ! 544: use part of their nexus space ! 545: for an array of eight sets of device registers ! 546: for each of eight possible multiplexed devices; ! 547: UNIBUS adapters ! 548: have registers controlling data paths; ! 549: memory controllers just have error flags. ! 550: .PP ! 551: Interrupt vectors are more poorly defined. ! 552: In some buses ! 553: (CMI, SBI), ! 554: nexus interrupts ! 555: are vectored to well-known places in the system control block, ! 556: determined by the interrupt priority and the nexus address. ! 557: In others ! 558: (VAXBI), ! 559: the vector is partly or wholly up to the software. ! 560: UNIBUS adapters ! 561: steal a whole page somewhere ! 562: for UNIBUS interrupts; ! 563: sometimes (CMI) ! 564: this is in a hard-wired place, ! 565: sometimes (VAXBI) ! 566: it must be set by software. ! 567: .Sh ! 568: The software model ! 569: .PP ! 570: The fundamental address unit is the nexus. ! 571: There is an array of nexus defined ! 572: in the system virtual address space. ! 573: It would be nice if the array could be at a fixed address, ! 574: but it's too hard to do. ! 575: Hence there's just a pointer to its base ! 576: which is initialized at boot time: ! 577: .EX ! 578: struct nexus { ! 579: char nx[0x2000]; ! 580: char wind[0x40000]; ! 581: } *nexus; ! 582: ! 583: /* who needs counts? */ ! 584: int nexus_cnt = N; ! 585: .EE ! 586: .PP ! 587: The array bears no necessary resemblance to the ! 588: layout of nexus spaces in physical I/O space; ! 589: indices into ! 590: .CW nexus ! 591: are dreamt up by ! 592: .CW mkconf . ! 593: The appropriate mappings are set up ! 594: by machine-dependent startup code, ! 595: according to tables ! 596: generated by ! 597: .CW mkconf : ! 598: .EX ! 599: /* ! 600: * example: a typical 780 ! 601: */ ! 602: ! 603: struct nextab { ! 604: char bus; ! 605: char nex; ! 606: }; ! 607: ! 608: struct nextab nextab[] = { ! 609: {0, 1}, /* ms780 */ ! 610: {0, 8}, /* first rh780 */ ! 611: {0, 3}, /* unibus adapter */ ! 612: -1 /* end */ ! 613: }; ! 614: .EE ! 615: Bus numbers are defined in a machine-dependent, ! 616: presumably straightforward way; ! 617: nexus numbers are within the relevant bus. ! 618: It is assumed ! 619: that the mapping between ! 620: the bus and nexus numbers ! 621: and the corresponding address window ! 622: can be doped out by the machine-dependent startup code. ! 623: This is utterly straightforward in the VAXBI world. ! 624: Elsewhere it's a couple of simple special cases ! 625: (UNIBUS adapters have a known mapping, ! 626: other devices just don't get windows). ! 627: .PP ! 628: Why the configuration-dependent mapping ! 629: between real nexus numbers ! 630: and positions in the ! 631: .CW nexus ! 632: array? ! 633: Implementation horrors: ! 634: each nexus takes up 8kb of address space ! 635: for its registers, ! 636: and 256Kb for its window. ! 637: Address space isn't in short supply on the VAX, ! 638: but huge amounts of address space in the system ! 639: take up large quantities of physical memory ! 640: for system page table entries. ! 641: Hence it's nicer only to map ! 642: the nexus that matter. ! 643: The address windows are the bulk of the issue, ! 644: which is particularly annoying ! 645: because relatively few devices use them. ! 646: In practice, ! 647: older machines have relatively few nexus ! 648: (with or without windows), ! 649: and newer (VAXBI) systems ! 650: have a little more memory to waste, ! 651: so always mapping a (perhaps nonexistent) address window ! 652: isn't that great a burden (yet). ! 653: .PP ! 654: Interrupt vectors are harder to understand. ! 655: In older VAXes, ! 656: nexus interrupts go through vectors ! 657: in the second half of the first page of the system control block. ! 658: UNIBUS interrupts are handled in software (780) ! 659: or put into specific higher-numbered SCB pages. ! 660: In the 8600, ! 661: this is further complicated ! 662: by having two SBIs, ! 663: hence two pages of nexus interrupts. ! 664: In the VAXBI machines, ! 665: things are looser; ! 666: the vectors are really set in software, ! 667: though there are prefixes ! 668: (to point UNIBUS interrupts ! 669: or interrupts from a specific BI bus ! 670: to a particular page) ! 671: and arcane rules about the prefixes. ! 672: .PP ! 673: .CW mkconf ! 674: knows nothing about this mess. ! 675: In general, ! 676: it's necessary to specify the interrupt vector in the configuration file. ! 677: The fixed relationship between nexus number and vector ! 678: for SBI devices ! 679: is understood; ! 680: for VAXBI devices, ! 681: the vector must always be explicit. ! 682: In either case, ! 683: devices like UNIBUS adapters ! 684: and NMI-BI adapters ! 685: that have associated pages of ! 686: interrupts from the buses they control ! 687: require that the pages be named explicitly. ! 688: .Sh ! 689: What drivers are told ! 690: .PP ! 691: Device drivers ! 692: need to know the address ! 693: of the I/O registers interesting to them, ! 694: perhaps their interrupt vector and priority ! 695: (the latter is set in software on the VAXBI!), ! 696: and perhaps a cookie identifying the bus or adapter ! 697: to which their device is connected. ! 698: Different data structures are used ! 699: to pass this information ! 700: for different kinds of bus. ! 701: .PP ! 702: Unfortunately, ! 703: it's hard to specify the address exactly at compile time; ! 704: in practice it is given as a nexus index ! 705: and perhaps some kind of offset. ! 706: I/O adapters like the UNIBUS adapter ! 707: are expected ! 708: to provide routines ! 709: that map address structures ! 710: into virtual addresses in I/O space; ! 711: details are elsewhere. ! 712: .PP ! 713: SBI devices get ! 714: .EX ! 715: struct nxaddr { ! 716: short nexus; /* nexus number */ ! 717: short adno; /* adapter number */ ! 718: }; ! 719: .EE ! 720: `Devices' here includes I/O adapters. ! 721: Interrupt vectors are assumed to be those ! 722: implied by the nexus number; ! 723: interrupts for all four BR levels ! 724: are sent to the same single interrupt routine. ! 725: If ! 726: .CW nexus ! 727: is \-1, ! 728: the device doesn't exist ! 729: (e.g. device 1 is configured ! 730: but device 0 isn't). ! 731: .PP ! 732: MASSBUS devices get ! 733: .EX ! 734: struct mbaddr { ! 735: char unit; /* MASSBUS unit number */ ! 736: char mbno; /* adapter number */ ! 737: }; ! 738: .EE ! 739: .PP ! 740: The device doesn't exist ! 741: if ! 742: .CW unit ! 743: is \-1. ! 744: The MASSBUS adapter driver ! 745: will probably want to supply entry points ! 746: yielding both the address of the device registers proper ! 747: (determined by the unit number) ! 748: and just the MASSBUS registers ! 749: (to check for errors after a transfer). ! 750: .PP ! 751: What do we do about interrupt vectors? ! 752: A MASSBUS can only have one transfer going at a time, ! 753: but when that transfer completes ! 754: there can be several devices needing attention. ! 755: Pretty clearly the vectors in the SCB ! 756: need to point to the MASSBUS adapter code, ! 757: not that for the device on the MASSBUS; ! 758: the mba driver ! 759: has to have some way to forward the interrupts on ! 760: to the correct driver, ! 761: though. ! 762: Maybe some dynamic registry is appropriate; ! 763: consider it to be like mapping. ! 764: .PP ! 765: UNIBUS devices get ! 766: .EX ! 767: struct ubaddr { ! 768: long uboff; /* UNIBUS space address */ ! 769: short vec; /* unibus vector, not scb */ ! 770: short ubno; /* UNIBUS adapter number; implies nexus */ ! 771: }; ! 772: .EE ! 773: .PP ! 774: If ! 775: .CW uboff ! 776: is zero, ! 777: the device doesn't exist. ! 778: There are already devices that need the vector ! 779: (UDA50); ! 780: there will doubtless be more. ! 781: .PP ! 782: VAXBI devices probably need ! 783: .EX ! 784: struct biaddr { ! 785: short nexus; /* BI device nexus */ ! 786: short vec; /* error interrupt */ ! 787: short ovec; /* controlled devices */ ! 788: short adno; /* adapter, e.g. NBI */ ! 789: }; ! 790: .EE ! 791: If ! 792: .CW nexus ! 793: is \-1, ! 794: the device doesn't exist. ! 795: .CW Vec ! 796: is the vector for the BI device itself; ! 797: .CW ovec ! 798: is the base of the page of interrupts ! 799: belonging to the device, ! 800: if it's a bus adapter ! 801: like the DWBUA. ! 802: .CW Vec ! 803: is always the vector ! 804: used for BIIC-generated errors. ! 805: If the device wants to have a separate interrupt ! 806: for I/O completion ! 807: (using, say, the UIR), ! 808: it should be described as having ! 809: multiple vectors, ! 810: which will have consecutive addresses. ! 811: The interrupt priority level is set in software ! 812: for some VAXBI devices, ! 813: but this might as well be a manifest in the driver ! 814: as it's rather inconvenient for it not to be a known constant ! 815: (e.g. for ! 816: .CW spl ! 817: calls). ! 818: .PP ! 819: There are also funny `subdevices', ! 820: which are addressed merely as sub-pieces of some controller. ! 821: The usual example is disk drives on a UNIBUS controller; ! 822: one needs to know about the controllers as entities, ! 823: but also about the individual drives. ! 824: These get ! 825: .EX ! 826: struct subaddr { ! 827: short ctl; /* controller number */ ! 828: short unit; /* unit number within the controller */ ! 829: }; ! 830: .EE ! 831: where ctl and unit are in a language known only to the driver. ! 832: If ! 833: .CW ctl ! 834: is \-1, ! 835: the device doesn't exist.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.