home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / config / config.y < prev    next >
Encoding:
Text File  |  1991-07-01  |  19.3 KB  |  964 lines

  1. %union {
  2.     char    *str;
  3.     int    val;
  4.     struct    file_list *file;
  5.     struct    idlst *lst;
  6. }
  7.  
  8. %token    AND
  9. %token    ANY
  10. %token    ARGS
  11. %token    AT
  12. %token    BIO
  13. %token    COMMA
  14. %token    CONFIG
  15. %token    CONTROLLER
  16. %token    CPU
  17. %token    CSR
  18. %token    DEVICE
  19. %token    DISK
  20. %token    DRIVE
  21. %token    DRQ
  22. %token    DST
  23. %token    DUMPS
  24. %token    EQUALS
  25. %token    FLAGS
  26. %token    HZ
  27. %token    IDENT
  28. %token    IOMEM
  29. %token    IOSIZ
  30. %token    IRQ
  31. %token    MACHINE
  32. %token    MAJOR
  33. %token    MASTER
  34. %token    MAXUSERS
  35. %token    MINOR
  36. %token    MINUS
  37. %token    NET
  38. %token    NEXUS
  39. %token    ON
  40. %token    OPTIONS
  41. %token    MAKEOPTIONS
  42. %token    PORT
  43. %token    PRIORITY
  44. %token    PSEUDO_DEVICE
  45. %token    ROOT
  46. %token    SEMICOLON
  47. %token    SIZE
  48. %token    SLAVE
  49. %token    SWAP
  50. %token    TIMEZONE
  51. %token    TTY
  52. %token    TRACE
  53. %token    VECTOR
  54.  
  55. %token    <str>    ID
  56. %token    <val>    NUMBER
  57. %token    <val>    FPNUMBER
  58.  
  59. %type    <str>    Save_id
  60. %type    <str>    Opt_value
  61. %type    <str>    Dev
  62. %type    <lst>    Id_list
  63. %type    <val>    optional_size
  64. %type    <str>    device_name
  65. %type    <val>    major_minor
  66. %type    <val>    arg_device_spec
  67. %type    <val>    root_device_spec
  68. %type    <val>    dump_device_spec
  69. %type    <file>    swap_device_spec
  70.  
  71. %{
  72.  
  73. /*
  74.  * Copyright (c) 1988 Regents of the University of California.
  75.  * All rights reserved.
  76.  *
  77.  * Redistribution and use in source and binary forms, with or without
  78.  * modification, are permitted provided that the following conditions
  79.  * are met:
  80.  * 1. Redistributions of source code must retain the above copyright
  81.  *    notice, this list of conditions and the following disclaimer.
  82.  * 2. Redistributions in binary form must reproduce the above copyright
  83.  *    notice, this list of conditions and the following disclaimer in the
  84.  *    documentation and/or other materials provided with the distribution.
  85.  * 3. All advertising materials mentioning features or use of this software
  86.  *    must display the following acknowledgement:
  87.  *    This product includes software developed by the University of
  88.  *    California, Berkeley and its contributors.
  89.  * 4. Neither the name of the University nor the names of its contributors
  90.  *    may be used to endorse or promote products derived from this software
  91.  *    without specific prior written permission.
  92.  *
  93.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  94.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  95.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  96.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  97.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  98.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  99.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  100.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  101.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  102.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  103.  * SUCH DAMAGE.
  104.  *
  105.  *    @(#)config.y    5.14 (Berkeley) 7/1/91
  106.  */
  107.  
  108. #include "config.h"
  109. #include <ctype.h>
  110. #include <stdio.h>
  111.  
  112. struct    device cur;
  113. struct    device *curp = 0;
  114. char    *temp_id;
  115. char    *val_id;
  116.  
  117. %}
  118. %%
  119. Configuration:
  120.     Many_specs
  121.         = { verifysystemspecs(); }
  122.         ;
  123.  
  124. Many_specs:
  125.     Many_specs Spec
  126.         |
  127.     /* lambda */
  128.         ;
  129.  
  130. Spec:
  131.     Device_spec SEMICOLON
  132.           = { newdev(&cur); } |
  133.     Config_spec SEMICOLON
  134.         |
  135.     TRACE SEMICOLON
  136.           = { do_trace = !do_trace; } |
  137.     SEMICOLON
  138.         |
  139.     error SEMICOLON
  140.         ;
  141.  
  142. Config_spec:
  143.     MACHINE Save_id
  144.         = {
  145.         if (!strcmp($2, "vax")) {
  146.             machine = MACHINE_VAX;
  147.             machinename = "vax";
  148.         } else if (!strcmp($2, "tahoe")) {
  149.             machine = MACHINE_TAHOE;
  150.             machinename = "tahoe";
  151.         } else if (!strcmp($2, "hp300")) {
  152.             machine = MACHINE_HP300;
  153.             machinename = "hp300";
  154.         } else if (!strcmp($2, "i386")) {
  155.             machine = MACHINE_I386;
  156.             machinename = "i386";
  157.         } else
  158.             yyerror("Unknown machine type");
  159.           } |
  160.     CPU Save_id
  161.           = {
  162.         struct cputype *cp =
  163.             (struct cputype *)malloc(sizeof (struct cputype));
  164.         cp->cpu_name = ns($2);
  165.         cp->cpu_next = cputype;
  166.         cputype = cp;
  167.         free(temp_id);
  168.           } |
  169.     OPTIONS Opt_list
  170.         |
  171.     MAKEOPTIONS Mkopt_list
  172.         |
  173.     IDENT ID
  174.           = { ident = ns($2); } |
  175.     System_spec
  176.         |
  177.     HZ NUMBER
  178.           = { yyerror("HZ specification obsolete; delete"); } |
  179.     TIMEZONE NUMBER
  180.           = { zone = 60 * $2; check_tz(); } |
  181.     TIMEZONE NUMBER DST NUMBER
  182.           = { zone = 60 * $2; dst = $4; check_tz(); } |
  183.     TIMEZONE NUMBER DST
  184.           = { zone = 60 * $2; dst = 1; check_tz(); } |
  185.     TIMEZONE FPNUMBER
  186.           = { zone = $2; check_tz(); } |
  187.     TIMEZONE FPNUMBER DST NUMBER
  188.           = { zone = $2; dst = $4; check_tz(); } |
  189.     TIMEZONE FPNUMBER DST
  190.           = { zone = $2; dst = 1; check_tz(); } |
  191.     TIMEZONE MINUS NUMBER
  192.           = { zone = -60 * $3; check_tz(); } |
  193.     TIMEZONE MINUS NUMBER DST NUMBER
  194.           = { zone = -60 * $3; dst = $5; check_tz(); } |
  195.     TIMEZONE MINUS NUMBER DST
  196.           = { zone = -60 * $3; dst = 1; check_tz(); } |
  197.     TIMEZONE MINUS FPNUMBER
  198.           = { zone = -$3; check_tz(); } |
  199.     TIMEZONE MINUS FPNUMBER DST NUMBER
  200.           = { zone = -$3; dst = $5; check_tz(); } |
  201.     TIMEZONE MINUS FPNUMBER DST
  202.           = { zone = -$3; dst = 1; check_tz(); } |
  203.     MAXUSERS NUMBER
  204.           = { maxusers = $2; };
  205.  
  206. System_spec:
  207.       System_id System_parameter_list
  208.         = { checksystemspec(*confp); }
  209.     ;
  210.         
  211. System_id:
  212.       CONFIG Save_id
  213.         = { mkconf($2); }
  214.     ;
  215.  
  216. System_parameter_list:
  217.       System_parameter_list System_parameter
  218.     | System_parameter
  219.     ;
  220.  
  221. System_parameter:
  222.       swap_spec
  223.     | root_spec
  224.     | dump_spec
  225.     | arg_spec
  226.     ;
  227.     
  228. swap_spec:
  229.       SWAP optional_on swap_device_list
  230.     ;
  231.     
  232. swap_device_list:
  233.       swap_device_list AND swap_device
  234.     | swap_device
  235.     ;
  236.     
  237. swap_device:
  238.       swap_device_spec optional_size
  239.           = { mkswap(*confp, $1, $2); }
  240.     ;
  241.  
  242. swap_device_spec:
  243.       device_name
  244.         = {
  245.             struct file_list *fl = newswap();
  246.  
  247.             if (eq($1, "generic"))
  248.                 fl->f_fn = $1;
  249.             else {
  250.                 fl->f_swapdev = nametodev($1, 0, 'b');
  251.                 fl->f_fn = devtoname(fl->f_swapdev);
  252.             }
  253.             $$ = fl;
  254.         }
  255.     | major_minor
  256.         = {
  257.             struct file_list *fl = newswap();
  258.  
  259.             fl->f_swapdev = $1;
  260.             fl->f_fn = devtoname($1);
  261.             $$ = fl;
  262.         }
  263.     ;
  264.  
  265. root_spec:
  266.       ROOT optional_on root_device_spec
  267.         = {
  268.             struct file_list *fl = *confp;
  269.  
  270.             if (fl && fl->f_rootdev != NODEV)
  271.                 yyerror("extraneous root device specification");
  272.             else
  273.                 fl->f_rootdev = $3;
  274.         }
  275.     ;
  276.  
  277. root_device_spec:
  278.       device_name
  279.         = { $$ = nametodev($1, 0, 'a'); }
  280.     | major_minor
  281.     ;
  282.  
  283. dump_spec:
  284.       DUMPS optional_on dump_device_spec
  285.         = {
  286.             struct file_list *fl = *confp;
  287.  
  288.             if (fl && fl->f_dumpdev != NODEV)
  289.                 yyerror("extraneous dump device specification");
  290.             else
  291.                 fl->f_dumpdev = $3;
  292.         }
  293.  
  294.     ;
  295.  
  296. dump_device_spec:
  297.       device_name
  298.         = { $$ = nametodev($1, 0, 'b'); }
  299.     | major_minor
  300.     ;
  301.  
  302. arg_spec:
  303.       ARGS optional_on arg_device_spec
  304.         = { yyerror("arg device specification obsolete, ignored"); }
  305.     ;
  306.  
  307. arg_device_spec:
  308.       device_name
  309.         = { $$ = nametodev($1, 0, 'b'); }
  310.     | major_minor
  311.     ;
  312.  
  313. major_minor:
  314.       MAJOR NUMBER MINOR NUMBER
  315.         = { $$ = makedev($2, $4); }
  316.     ;
  317.  
  318. optional_on:
  319.       ON
  320.     | /* empty */
  321.     ;
  322.  
  323. optional_size:
  324.       SIZE NUMBER
  325.           = { $$ = $2; }
  326.     | /* empty */
  327.           = { $$ = 0; }
  328.     ;
  329.  
  330. device_name:
  331.       Save_id
  332.         = { $$ = $1; }
  333.     | Save_id NUMBER
  334.         = {
  335.             char buf[80];
  336.  
  337.             (void) sprintf(buf, "%s%d", $1, $2);
  338.             $$ = ns(buf); free($1);
  339.         }
  340.     | Save_id NUMBER ID
  341.         = {
  342.             char buf[80];
  343.  
  344.             (void) sprintf(buf, "%s%d%s", $1, $2, $3);
  345.             $$ = ns(buf); free($1);
  346.         }
  347.     ;
  348.  
  349. Opt_list:
  350.     Opt_list COMMA Option
  351.         |
  352.     Option
  353.         ;
  354.  
  355. Option:
  356.     Save_id
  357.           = {
  358.         struct opt *op = (struct opt *)malloc(sizeof (struct opt));
  359.         op->op_name = ns($1);
  360.         op->op_next = opt;
  361.         op->op_value = 0;
  362.         opt = op;
  363.         free(temp_id);
  364.           } |
  365.     Save_id EQUALS Opt_value
  366.           = {
  367.         struct opt *op = (struct opt *)malloc(sizeof (struct opt));
  368.         op->op_name = ns($1);
  369.         op->op_next = opt;
  370.         op->op_value = ns($3);
  371.         opt = op;
  372.         free(temp_id);
  373.         free(val_id);
  374.           } ;
  375.  
  376. Opt_value:
  377.     ID
  378.           = { $$ = val_id = ns($1); } |
  379.     NUMBER
  380.           = {
  381.         char nb[16];
  382.             (void) sprintf(nb, "%d", $1);
  383.         $$ = val_id = ns(nb);
  384.           } ;
  385.  
  386.  
  387. Save_id:
  388.     ID
  389.           = { $$ = temp_id = ns($1); }
  390.     ;
  391.  
  392. Mkopt_list:
  393.     Mkopt_list COMMA Mkoption
  394.         |
  395.     Mkoption
  396.         ;
  397.  
  398. Mkoption:
  399.     Save_id EQUALS Opt_value
  400.           = {
  401.         struct opt *op = (struct opt *)malloc(sizeof (struct opt));
  402.         op->op_name = ns($1);
  403.         op->op_next = mkopt;
  404.         op->op_value = ns($3);
  405.         mkopt = op;
  406.         free(temp_id);
  407.         free(val_id);
  408.           } ;
  409.  
  410. Dev:
  411.     ID
  412.           = { $$ = ns($1); }
  413.     ;
  414.  
  415. Device_spec:
  416.     DEVICE Dev_name Dev_info Int_spec
  417.           = { cur.d_type = DEVICE; } |
  418.     MASTER Dev_name Dev_info Int_spec
  419.           = { cur.d_type = MASTER; } |
  420.     DISK Dev_name Dev_info Int_spec
  421.           = { cur.d_dk = 1; cur.d_type = DEVICE; } |
  422.     CONTROLLER Dev_name Dev_info Int_spec
  423.           = { cur.d_type = CONTROLLER; } |
  424.     PSEUDO_DEVICE Init_dev Dev
  425.           = {
  426.         cur.d_name = $3;
  427.         cur.d_type = PSEUDO_DEVICE;
  428.         } |
  429.     PSEUDO_DEVICE Init_dev Dev NUMBER
  430.           = {
  431.         cur.d_name = $3;
  432.         cur.d_type = PSEUDO_DEVICE;
  433.         cur.d_slave = $4;
  434.         };
  435.  
  436. Dev_name:
  437.     Init_dev Dev NUMBER
  438.           = {
  439.         cur.d_name = $2;
  440.         if (eq($2, "mba"))
  441.             seen_mba = 1;
  442.         else if (eq($2, "uba"))
  443.             seen_uba = 1;
  444.         else if (eq($2, "vba"))
  445.             seen_vba = 1;
  446.         else if (eq($2, "isa"))
  447.             seen_isa = 1;
  448.         cur.d_unit = $3;
  449.         };
  450.  
  451. Init_dev:
  452.     /* lambda */
  453.           = { init_dev(&cur); };
  454.  
  455. Dev_info:
  456.     Con_info Info_list
  457.         |
  458.     /* lambda */
  459.         ;
  460.  
  461. Con_info:
  462.     AT Dev NUMBER
  463.           = {
  464.         if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) {
  465.             (void) sprintf(errbuf,
  466.                 "%s must be connected to a nexus", cur.d_name);
  467.             yyerror(errbuf);
  468.         }
  469.         cur.d_conn = connect($2, $3);
  470.         } |
  471.     AT NEXUS NUMBER
  472.           = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; };
  473.     
  474. Info_list:
  475.     Info_list Info
  476.         |
  477.     /* lambda */
  478.         ;
  479.  
  480. Info:
  481.     CSR NUMBER
  482.           = { cur.d_addr = $2; } |
  483.     DRIVE NUMBER
  484.           = { cur.d_drive = $2; } |
  485.     SLAVE NUMBER
  486.           = {
  487.         if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS &&
  488.             cur.d_conn->d_type == MASTER)
  489.             cur.d_slave = $2;
  490.         else
  491.             yyerror("can't specify slave--not to master");
  492.         } |
  493.     IRQ NUMBER
  494.           = { cur.d_irq = $2; } |
  495.     DRQ NUMBER
  496.           = { cur.d_drq = $2; } |
  497.     IOMEM NUMBER
  498.           = { cur.d_maddr = $2; } |
  499.     IOSIZ NUMBER
  500.           = { cur.d_msize = $2; } |
  501.     PORT device_name
  502.           = { cur.d_port = ns($2); } |
  503.     PORT NUMBER
  504.           = { cur.d_portn = $2; } |
  505.     TTY 
  506.           = { cur.d_mask = "tty"; } |
  507.     BIO 
  508.           = { cur.d_mask = "bio"; } |
  509.     NET 
  510.           = { cur.d_mask = "net"; } |
  511.     FLAGS NUMBER
  512.           = { cur.d_flags = $2; };
  513.  
  514. Int_spec:
  515.     VECTOR Id_list
  516.           = { cur.d_vec = $2; } |
  517.     PRIORITY NUMBER
  518.           = { cur.d_pri = $2; } |
  519.     /* lambda */
  520.         ;
  521.  
  522. Id_list:
  523.     Save_id
  524.           = {
  525.         struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
  526.         a->id = $1; a->id_next = 0; $$ = a;
  527.         } |
  528.     Save_id Id_list =
  529.         {
  530.         struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
  531.             a->id = $1; a->id_next = $2; $$ = a;
  532.         };
  533.  
  534. %%
  535.  
  536. yyerror(s)
  537.     char *s;
  538. {
  539.  
  540.     fprintf(stderr, "config: line %d: %s\n", yyline + 1, s);
  541. }
  542.  
  543. /*
  544.  * return the passed string in a new space
  545.  */
  546. char *
  547. ns(str)
  548.     register char *str;
  549. {
  550.     register char *cp;
  551.  
  552.     cp = malloc((unsigned)(strlen(str)+1));
  553.     (void) strcpy(cp, str);
  554.     return (cp);
  555. }
  556.  
  557. /*
  558.  * add a device to the list of devices
  559.  */
  560. newdev(dp)
  561.     register struct device *dp;
  562. {
  563.     register struct device *np;
  564.  
  565.     np = (struct device *) malloc(sizeof *np);
  566.     *np = *dp;
  567.     np->d_next = 0;
  568.     if (curp == 0)
  569.         dtab = np;
  570.     else
  571.         curp->d_next = np;
  572.     curp = np;
  573. }
  574.  
  575. /*
  576.  * note that a configuration should be made
  577.  */
  578. mkconf(sysname)
  579.     char *sysname;
  580. {
  581.     register struct file_list *fl, **flp;
  582.  
  583.     fl = (struct file_list *) malloc(sizeof *fl);
  584.     fl->f_type = SYSTEMSPEC;
  585.     fl->f_needs = sysname;
  586.     fl->f_rootdev = NODEV;
  587.     fl->f_dumpdev = NODEV;
  588.     fl->f_fn = 0;
  589.     fl->f_next = 0;
  590.     for (flp = confp; *flp; flp = &(*flp)->f_next)
  591.         ;
  592.     *flp = fl;
  593.     confp = flp;
  594. }
  595.  
  596. struct file_list *
  597. newswap()
  598. {
  599.     struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
  600.  
  601.     fl->f_type = SWAPSPEC;
  602.     fl->f_next = 0;
  603.     fl->f_swapdev = NODEV;
  604.     fl->f_swapsize = 0;
  605.     fl->f_needs = 0;
  606.     fl->f_fn = 0;
  607.     return (fl);
  608. }
  609.  
  610. /*
  611.  * Add a swap device to the system's configuration
  612.  */
  613. mkswap(system, fl, size)
  614.     struct file_list *system, *fl;
  615.     int size;
  616. {
  617.     register struct file_list **flp;
  618.     char name[80];
  619.  
  620.     if (system == 0 || system->f_type != SYSTEMSPEC) {
  621.         yyerror("\"swap\" spec precedes \"config\" specification");
  622.         return;
  623.     }
  624.     if (size < 0) {
  625.         yyerror("illegal swap partition size");
  626.         return;
  627.     }
  628.     /*
  629.      * Append swap description to the end of the list.
  630.      */
  631.     flp = &system->f_next;
  632.     for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next)
  633.         ;
  634.     fl->f_next = *flp;
  635.     *flp = fl;
  636.     fl->f_swapsize = size;
  637.     /*
  638.      * If first swap device for this system,
  639.      * set up f_fn field to insure swap
  640.      * files are created with unique names.
  641.      */
  642.     if (system->f_fn)
  643.         return;
  644.     if (eq(fl->f_fn, "generic"))
  645.         system->f_fn = ns(fl->f_fn);
  646.     else
  647.         system->f_fn = ns(system->f_needs);
  648. }
  649.  
  650. /*
  651.  * find the pointer to connect to the given device and number.
  652.  * returns 0 if no such device and prints an error message
  653.  */
  654. struct device *
  655. connect(dev, num)
  656.     register char *dev;
  657.     register int num;
  658. {
  659.     register struct device *dp;
  660.     struct device *huhcon();
  661.  
  662.     if (num == QUES)
  663.         return (huhcon(dev));
  664.     for (dp = dtab; dp != 0; dp = dp->d_next) {
  665.         if ((num != dp->d_unit) || !eq(dev, dp->d_name))
  666.             continue;
  667.         if (dp->d_type != CONTROLLER && dp->d_type != MASTER) {
  668.             (void) sprintf(errbuf,
  669.                 "%s connected to non-controller", dev);
  670.             yyerror(errbuf);
  671.             return (0);
  672.         }
  673.         return (dp);
  674.     }
  675.     (void) sprintf(errbuf, "%s %d not defined", dev, num);
  676.     yyerror(errbuf);
  677.     return (0);
  678. }
  679.  
  680. /*
  681.  * connect to an unspecific thing
  682.  */
  683. struct device *
  684. huhcon(dev)
  685.     register char *dev;
  686. {
  687.     register struct device *dp, *dcp;
  688.     struct device rdev;
  689.     int oldtype;
  690.  
  691.     /*
  692.      * First make certain that there are some of these to wildcard on
  693.      */
  694.     for (dp = dtab; dp != 0; dp = dp->d_next)
  695.         if (eq(dp->d_name, dev))
  696.             break;
  697.     if (dp == 0) {
  698.         (void) sprintf(errbuf, "no %s's to wildcard", dev);
  699.         yyerror(errbuf);
  700.         return (0);
  701.     }
  702.     oldtype = dp->d_type;
  703.     dcp = dp->d_conn;
  704.     /*
  705.      * Now see if there is already a wildcard entry for this device
  706.      * (e.g. Search for a "uba ?")
  707.      */
  708.     for (; dp != 0; dp = dp->d_next)
  709.         if (eq(dev, dp->d_name) && dp->d_unit == -1)
  710.             break;
  711.     /*
  712.      * If there isn't, make one because everything needs to be connected
  713.      * to something.
  714.      */
  715.     if (dp == 0) {
  716.         dp = &rdev;
  717.         init_dev(dp);
  718.         dp->d_unit = QUES;
  719.         dp->d_name = ns(dev);
  720.         dp->d_type = oldtype;
  721.         newdev(dp);
  722.         dp = curp;
  723.         /*
  724.          * Connect it to the same thing that other similar things are
  725.          * connected to, but make sure it is a wildcard unit
  726.          * (e.g. up connected to sc ?, here we make connect sc? to a
  727.          * uba?).  If other things like this are on the NEXUS or
  728.          * if they aren't connected to anything, then make the same
  729.          * connection, else call ourself to connect to another
  730.          * unspecific device.
  731.          */
  732.         if (dcp == TO_NEXUS || dcp == 0)
  733.             dp->d_conn = dcp;
  734.         else
  735.             dp->d_conn = connect(dcp->d_name, QUES);
  736.     }
  737.     return (dp);
  738. }
  739.  
  740. init_dev(dp)
  741.     register struct device *dp;
  742. {
  743.  
  744.     dp->d_name = "OHNO!!!";
  745.     dp->d_type = DEVICE;
  746.     dp->d_conn = 0;
  747.     dp->d_vec = 0;
  748.     dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0;
  749.     dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
  750.     dp->d_port = (char *)0;
  751.     dp->d_portn = 0;
  752.     dp->d_irq = -1;
  753.     dp->d_drq = -1;
  754.     dp->d_maddr = 0;
  755.     dp->d_msize = 0;
  756.     dp->d_mask = "null";
  757. }
  758.  
  759. /*
  760.  * make certain that this is a reasonable type of thing to connect to a nexus
  761.  */
  762. check_nexus(dev, num)
  763.     register struct device *dev;
  764.     int num;
  765. {
  766.  
  767.     switch (machine) {
  768.  
  769.     case MACHINE_VAX:
  770.         if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") &&
  771.             !eq(dev->d_name, "bi"))
  772.             yyerror("only uba's, mba's, and bi's should be connected to the nexus");
  773.         if (num != QUES)
  774.             yyerror("can't give specific nexus numbers");
  775.         break;
  776.  
  777.     case MACHINE_TAHOE:
  778.         if (!eq(dev->d_name, "vba")) 
  779.             yyerror("only vba's should be connected to the nexus");
  780.         break;
  781.  
  782.     case MACHINE_HP300:
  783.         if (num != QUES)
  784.             dev->d_addr = num;
  785.         break;
  786.  
  787.     case MACHINE_I386:
  788.         if (!eq(dev->d_name, "isa"))
  789.             yyerror("only isa's should be connected to the nexus");
  790.         break;
  791.     }
  792. }
  793.  
  794. /*
  795.  * Check the timezone to make certain it is sensible
  796.  */
  797.  
  798. check_tz()
  799. {
  800.     if (abs(zone) > 12 * 60)
  801.         yyerror("timezone is unreasonable");
  802.     else
  803.         hadtz = 1;
  804. }
  805.  
  806. /*
  807.  * Check system specification and apply defaulting
  808.  * rules on root, argument, dump, and swap devices.
  809.  */
  810. checksystemspec(fl)
  811.     register struct file_list *fl;
  812. {
  813.     char buf[BUFSIZ];
  814.     register struct file_list *swap;
  815.     int generic;
  816.  
  817.     if (fl == 0 || fl->f_type != SYSTEMSPEC) {
  818.         yyerror("internal error, bad system specification");
  819.         exit(1);
  820.     }
  821.     swap = fl->f_next;
  822.     generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
  823.     if (fl->f_rootdev == NODEV && !generic) {
  824.         yyerror("no root device specified");
  825.         exit(1);
  826.     }
  827.     /*
  828.      * Default swap area to be in 'b' partition of root's
  829.      * device.  If root specified to be other than on 'a'
  830.      * partition, give warning, something probably amiss.
  831.      */
  832.     if (swap == 0 || swap->f_type != SWAPSPEC) {
  833.         dev_t dev;
  834.  
  835.         swap = newswap();
  836.         dev = fl->f_rootdev;
  837.         if (minor(dev) & 07) {
  838.             (void) sprintf(buf, 
  839. "Warning, swap defaulted to 'b' partition with root on '%c' partition",
  840.                 (minor(dev) & 07) + 'a');
  841.             yyerror(buf);
  842.         }
  843.         swap->f_swapdev =
  844.            makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a'));
  845.         swap->f_fn = devtoname(swap->f_swapdev);
  846.         mkswap(fl, swap, 0);
  847.     }
  848.     /*
  849.      * Make sure a generic swap isn't specified, along with
  850.      * other stuff (user must really be confused).
  851.      */
  852.     if (generic) {
  853.         if (fl->f_rootdev != NODEV)
  854.             yyerror("root device specified with generic swap");
  855.         if (fl->f_dumpdev != NODEV)
  856.             yyerror("dump device specified with generic swap");
  857.         return;
  858.     }
  859.     /*
  860.      * Default dump device and warn if place is not a
  861.      * swap area.
  862.      */
  863.     if (fl->f_dumpdev == NODEV)
  864.         fl->f_dumpdev = swap->f_swapdev;
  865.     if (fl->f_dumpdev != swap->f_swapdev) {
  866.         struct file_list *p = swap->f_next;
  867.  
  868.         for (; p && p->f_type == SWAPSPEC; p = p->f_next)
  869.             if (fl->f_dumpdev == p->f_swapdev)
  870.                 return;
  871.         (void) sprintf(buf,
  872.             "Warning: dump device is not a swap partition");
  873.         yyerror(buf);
  874.     }
  875. }
  876.  
  877. /*
  878.  * Verify all devices specified in the system specification
  879.  * are present in the device specifications.
  880.  */
  881. verifysystemspecs()
  882. {
  883.     register struct file_list *fl;
  884.     dev_t checked[50], *verifyswap();
  885.     register dev_t *pchecked = checked;
  886.  
  887.     for (fl = conf_list; fl; fl = fl->f_next) {
  888.         if (fl->f_type != SYSTEMSPEC)
  889.             continue;
  890.         if (!finddev(fl->f_rootdev))
  891.             deverror(fl->f_needs, "root");
  892.         *pchecked++ = fl->f_rootdev;
  893.         pchecked = verifyswap(fl->f_next, checked, pchecked);
  894. #define    samedev(dev1, dev2) \
  895.     ((minor(dev1) &~ 07) != (minor(dev2) &~ 07))
  896.         if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) {
  897.             if (!finddev(fl->f_dumpdev))
  898.                 deverror(fl->f_needs, "dump");
  899.             *pchecked++ = fl->f_dumpdev;
  900.         }
  901.     }
  902. }
  903.  
  904. /*
  905.  * Do as above, but for swap devices.
  906.  */
  907. dev_t *
  908. verifyswap(fl, checked, pchecked)
  909.     register struct file_list *fl;
  910.     dev_t checked[];
  911.     register dev_t *pchecked;
  912. {
  913.  
  914.     for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
  915.         if (eq(fl->f_fn, "generic"))
  916.             continue;
  917.         if (alreadychecked(fl->f_swapdev, checked, pchecked))
  918.             continue;
  919.         if (!finddev(fl->f_swapdev))
  920.             fprintf(stderr,
  921.                "config: swap device %s not configured", fl->f_fn);
  922.         *pchecked++ = fl->f_swapdev;
  923.     }
  924.     return (pchecked);
  925. }
  926.  
  927. /*
  928.  * Has a device already been checked
  929.  * for it's existence in the configuration?
  930.  */
  931. alreadychecked(dev, list, last)
  932.     dev_t dev, list[];
  933.     register dev_t *last;
  934. {
  935.     register dev_t *p;
  936.  
  937.     for (p = list; p < last; p++)
  938.         if (samedev(*p, dev))
  939.             return (1);
  940.     return (0);
  941. }
  942.  
  943. deverror(systemname, devtype)
  944.     char *systemname, *devtype;
  945. {
  946.  
  947.     fprintf(stderr, "config: %s: %s device not configured\n",
  948.         systemname, devtype);
  949. }
  950.  
  951. /*
  952.  * Look for the device in the list of
  953.  * configured hardware devices.  Must
  954.  * take into account stuff wildcarded.
  955.  */
  956. /*ARGSUSED*/
  957. finddev(dev)
  958.     dev_t dev;
  959. {
  960.  
  961.     /* punt on this right now */
  962.     return (1);
  963. }
  964.