home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / Drivers / Mux-1.9-I / PostLoad.tproj / PostLoad.m < prev   
Encoding:
Text File  |  1994-05-29  |  5.7 KB  |  200 lines

  1. /*
  2.  * Post-Load command for Mux.   Checks and installs /dev/tty*.
  3.  *
  4.  *    Based on the code in the Example Parallel and Serial Port post loaders
  5.  *    supplied by NeXT.
  6.  *    Author: Mark Salyzyn  mark@ve6mgs.ampr.ab.ca  January 15 1994
  7.  */
  8.  
  9. #import <driverkit/IODeviceMaster.h>
  10. #import <driverkit/IODevice.h>
  11. #import <driverkit/IOConfigTable.h>
  12. #import <errno.h>
  13. #import <libc.h>
  14. #import <stdio.h>
  15. #import "../MuxParm.h"
  16. #ifdef Use_syslog
  17. # import <syslog.h>
  18. #else
  19. # undef LOG_CRIT
  20. # define LOG_CRIT    stderr
  21. # undef LOG_WARNING
  22. # define LOG_WARNING    stderr
  23. # undef LOG_DEBUG
  24. # define LOG_DEBUG    stderr
  25. # undef syslog
  26. # define syslog        fprintf
  27. #endif
  28.  
  29. #define DEBUG_LOG    0
  30.  
  31. /*
  32.  * A list of nodes to create. One per minor number, with a letter appended
  33.  * to eaach indicating minor number. 
  34.  */
  35. typedef struct {
  36.     const char *name;
  37.     int minorNum;        /* in addition to 0..(NTTY - 1) */
  38.     int mode;
  39.     const char *key;    /* Key in Instance Table */
  40. } ttyNode;
  41.  
  42. ttyNode nodeList[] = {    /* Minor  chmod            Override */
  43.     { "tty",    0,    (0666 | S_IFCHR),    "Path %d"    },
  44.     { "ttyf",    32,    (0666 | S_IFCHR),    "Path %d CTS"    }, 
  45.     { "ttyd",    64,    (0666 | S_IFCHR),    "Path %d IN"    },
  46.     { "ttydf",    96,    (0666 | S_IFCHR),    "Path %d IN CTS"},
  47.     { "cu",        192,    (0666 | S_IFCHR),    "Path %d OUT"    },
  48.     { "cuf",    224,    (0666 | S_IFCHR),    "Path %d OUT CTS"},
  49.     /* Two new devices that open LOCAL, but detect DCD drop */
  50.     { "cud",    128,    (0666 | S_IFCHR),    "Path %d OUT DCD"},
  51.     { "cudf",    160,    (0666 | S_IFCHR),    "Path %d OUT DCD CTS"},
  52.     { NULL,        0,    0,            ""        },    
  53. };
  54.         
  55. int main(int argc, char **argv)
  56. {    id         deviceMaster = [IODeviceMaster new];
  57.     IOObjectNumber     objectNum;
  58.     IOString     kind;
  59.     IOReturn     rtn;
  60.     id        config;
  61.     char        name[sizeof(MuxDeviceName)+1];
  62.     unsigned     array[1], ntty, minorNum, firstMinorNum, majorNum;
  63.     unsigned    count = 1;
  64.     const char *    instance;
  65.     extern char *    strcpy();
  66.  
  67.     /*
  68.      *    Parse out the Instance information from the passed arguments
  69.      */
  70.     instance = "0";
  71.     if ((argc > 1) && (strncmp (argv[1], "Instance=", 9) == 0))
  72.         instance = argv[1] + 9;
  73.     (void)strcpy (name, MuxDeviceName);
  74.     (void)strcpy (kind, MuxDeviceKind);
  75.     name[sizeof(name)-1] = '\0';
  76.     name[sizeof(name)-2] = *instance;
  77.     rtn = [deviceMaster lookUpByDeviceName : name
  78.                   objectNumber : &objectNum
  79.                     deviceKind : &kind];
  80.     if (rtn) {
  81.         syslog(LOG_CRIT,"Error contacting %s (%s)\n",
  82.             name, [IODevice stringFromReturn : rtn]);
  83.         exit(1);    
  84.     }
  85.     rtn = [deviceMaster getIntValues : array
  86.                 forParameter : "IONumberDevice"
  87.                 objectNumber : objectNum
  88.                        count : &count];    // in/out
  89.     if(rtn || (count != 1)) {
  90.         syslog(LOG_WARNING,"Error performing NTTY (%s), Using %d\n",
  91.             [IODevice stringFromReturn : rtn], NTTY);
  92.         ntty = NTTY;
  93.     } else    ntty = array[0] ;
  94.     rtn = [deviceMaster getIntValues : array
  95.                 forParameter : "IOMinorDevice"
  96.                 objectNumber : objectNum
  97.                        count : &count];    // in/out
  98.     if(rtn || (count != 1)) {
  99.         syslog(LOG_CRIT,"Error performing IOMinorDevice (%s)\n",
  100.             [IODevice stringFromReturn : rtn]);
  101.         firstMinorNum = (NTTY * (name[sizeof(name)-2] - '0'));
  102.     } else    firstMinorNum = array[0] ;
  103.     rtn = [deviceMaster getIntValues : array
  104.                 forParameter : "IOMajorDevice"
  105.                 objectNumber : objectNum
  106.                        count : &count];    // in/out
  107.     if(rtn || (count != 1)) {
  108.         syslog(LOG_CRIT,"Error performing IOMajorDevice (%s)\n",
  109.             [IODevice stringFromReturn : rtn]);
  110.         exit(1);    
  111.     }
  112.     majorNum = array[0];
  113.     /*
  114.      *    Open Instance?.table/Default.table for this system to
  115.      *    get the information from them about the paths to use
  116.      *    for the serial ports
  117.      */
  118.     config = [IOConfigTable newForDriver : name
  119.                     unit : 0];
  120.     if (config == nil) {
  121.         config = [IOConfigTable newDefaultTableForDriver : name];
  122.         if (config == nil) {
  123.             List *        ids;
  124.             int        index;
  125.             const char *    cp;
  126.  
  127.             /*
  128.              *    Plan B (only picks up Instance? Tables), not
  129.              *    a problem since our default values match
  130.              *    somewhat to the default values in the tables.
  131.              */
  132.             ids = [IOConfigTable tablesForInstalledDrivers];
  133.             for (index = 0; index < [ids count]; ++index) {
  134.                 if ((cp = [[ids objectAt : index]
  135.                     valueForStringKey : "Driver Name"])
  136.                  && (strcmp (cp, MuxDeviceName) == 0)
  137.                  && (cp = [[ids objectAt : index]
  138.                     valueForStringKey : "Instance"])
  139.                  && (strcmp (cp, instance) == 0)) {
  140.                     config = [ids objectAt : index];
  141.                     break ;
  142.                 }
  143.             }
  144.  
  145.             if (config == nil)
  146.                 syslog(LOG_WARNING,
  147.                     "Error getting either Instance%s.table or Default.table for %s\n\tWill use built in default for device naming\n",
  148.                     instance, MuxDeviceName);
  149.         }
  150.     }
  151.     for(minorNum=0; minorNum<ntty; minorNum++) {
  152.         IOString     nodeName;
  153.         ttyNode     *node;
  154.         int        dev;
  155.  
  156.         /*
  157.          *    The starting point should be programmable from the
  158.          *    instance ... this is the default set, we start at
  159.          *    `c' since we assume the user has SerialPorts set up.
  160.          */
  161.         name[sizeof(name)-2] = '0';
  162.         for(node=nodeList; node->name; node++) {
  163.             count = 0;
  164.             if (config) {
  165.                 const char *    cp ;
  166.  
  167.                 sprintf(nodeName, node->key, minorNum);
  168.                 cp = [config valueForStringKey : nodeName];
  169.                 if (cp) {
  170.                     (void)strcpy (nodeName, cp);
  171.                     ++count;
  172.                 }
  173.             }
  174.             if (count == 0) {
  175.                 /*
  176.                  * Default assumes first two NeXT serial ports
  177.                  * are *not* installed (start at ttya).
  178.                  */
  179.                 sprintf(nodeName, "/dev/%s%c", 
  180.                     node->name, 'a' + firstMinorNum + minorNum);
  181.             }
  182.             /*
  183.              * First delete existing node, then create a new one. 
  184.              */
  185.             unlink(nodeName);
  186.             dev = makedev(majorNum,
  187.                 (node->minorNum + minorNum + firstMinorNum));
  188.             if(mknod(nodeName, node->mode, dev))
  189.                 syslog(LOG_WARNING,"Can\'t create %s\r\n", nodeName);
  190.             /* Lets just rub it in ... */
  191.             if(chmod(nodeName,node->mode&~S_IFCHR))
  192.                 syslog(LOG_WARNING,"Can\'t ensure %s is +rw\r\n", nodeName);
  193. #if defined(DEBUG_LOG) && (DEBUG_LOG > 0)
  194.             syslog(LOG_DEBUG,"Created %s\n", nodeName);
  195. #endif
  196.         }
  197.     }
  198.     return 0;
  199. }
  200.