home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / telecomm / fser096b / xsdd.txt < prev   
Text File  |  1992-09-11  |  19KB  |  441 lines

  1. Extended Serial Device Driver (XSDD)
  2.  
  3. Entwurf eines Protokolls mit erweiterten Funktionen zur seriellen I/O
  4.  
  5. Author: Stephan Baucke
  6. Erste Niederschrift: 7-Sept-1992
  7. Letzte Änderung: 11-Sept-1992
  8.  
  9. Einleitung
  10. ----------
  11.  
  12. Bekanntlich sind die Möglichkeiten des TOS zur Bedienung der seriellen Schnitt-
  13. stellen recht beschränkt:
  14.  
  15. - die Bedienung diverser Kontrolleitungen (wie DCD, DTR, RI usw.) ist nur durch
  16.   Direktzugriff auf die Hardware möglich
  17. - Es sind nur die von Rsconf angebotenen Baudraten einstellbar, auch wenn die
  18.   Hardware mehr erlaubt
  19. - Der Zugriff auf eine Schnittstelle von mehreren Programmen kann nicht koordiniert
  20.   werden
  21. - Da mit BIOS jedes Zeichen einzeln übertragen werden muß, ist die I/O-Performance
  22.   nicht sehr hoch
  23.  
  24. Im Rahmen der Entwicklung eines seriellen Treibers für MiNT, der diese Schwächen
  25. beheben sollte, kam die Idee auf, die erweiterte Funktionalität auch unter reinem
  26. TOS zugänglich zu machen. Dies ist ein erster Vorschlag, wie das aussehen könnte.
  27. Im wesentlichen werden dabei die Low-Level-Routinen des MiNT-Treibers über einen
  28. Cookie von außen zugänglich gemacht. Denkbar wäre jedoch auch, die beiden Ebenen
  29. völlig zu trennen und den MiNT-Treiber auf einen separaten TOS-Treiber aufzu-
  30. setzen.
  31.  
  32.  
  33. Das XSDD-Protokoll
  34. ------------------
  35.  
  36. Das XSDD-Protokoll unterstützt die über Bconmap verwalteten Devices 6 bis ein-
  37. schließlich <maptabsize+5> (soweit das zugrundeliegende TOS sie zur Verfügung
  38. stellt), sowie das Device 1 (AUX). Operationen auf AUX beziehen sich immer auf
  39. das zum Zeitpunkt des Aufrufs von XSDD gerade aktuelle Bconmap-Device. In Zu-
  40. kunft wird AUX möglicherweise aus technischen Gründen nur noch dann unterstützt,
  41. wenn das zugrundeliegende TOS kein Bconmap hat.
  42.  
  43. Der Treiber installiert einen Cookie "XSDD". Der Cookie zeigt auf den Einsprung-
  44. punkt des XSDD-Treibers. Unmittelbar vor der Routine (also an Offset -4 vor der
  45. Adresse aus dem Cookie) steht zur Absicherung nochmals die Long-Konstante "XSDD".
  46.  
  47. Aufruf: Welche Funktion ausgeführt werden soll, wird durch einen Opcode (WORD)
  48. angegeben. Dieser Opcode ist bei jedem Aufruf das erste Argument. Wenn ein un-
  49. gültiger Opcode angegeben wird, wird EINVFN zurückgeliefert.
  50.  
  51. Die Übergabe aller Parameter erfolgt nach GEMDOS-Konvention, d.h. auf dem Stack.
  52. Der Rückgabewert wird in D0 geliefert. Außer D0 werden keine Register verändert.
  53. Der Aufruf von XSDD darf AUSSCHLIESSLICH im Supervisor-Modus erfolgen. 
  54.  
  55. Z.Zt. sind die im folgenden aufgelisteten Funktionen vorgesehen (Opcodes müssen
  56. noch vergeben werden). Für die Parametertypen gilt folgende Vereinbarung:
  57.  
  58. BYTE:  8-Bit-Zeichen
  59. WORD:  16-Bit signed Integer
  60. UWORD: 16-Bit unsigned Integer
  61. LONG:  32-Bit signed Integer
  62.  
  63. -----------------------------------------------------------------------------------
  64. WORD XSVersion(void)
  65.   Liefert die Versionsnummer des vom XSDD-Treibers implementierten Protokolls
  66.   zurück, Major-Version im Hi-Byte, Minor-Version im Low-Byte (Beispiel: 0x0102
  67.   entspricht Version 1.2). Diese Nummer soll nicht etwa die Version des Treiber-
  68.   programms wiederspiegeln, sondern nur die des implementierten Protokolls.
  69.  
  70.   Rückgabe:
  71.   Protokollversion.
  72.  
  73. -----------------------------------------------------------------------------------
  74. WORD XSDriverInfo(BYTE *info, LONG *product, WORD *version)
  75.   Dieser Aufruf liefert einen Info-String, eine Produktkennung, sowie die Version
  76.   des jeweiligen Treiberprogramms zurück. `info' muß dabei auf einen mindestens 80
  77.   Bytes großen Puffer zeigen, in den der Info-String nullterminiert eingetragen
  78.   wird (der String kann z.B. den Author und den Namen des Treibers enthalten). In
  79.   den LONG, auf den `product' zeigt, wird die Produktkennung eingetragen, sowie in
  80.   das WORD, auf das `version' zeigt, die Treiberversion.
  81.   
  82.   Rückgabe
  83.   0
  84.  
  85. -----------------------------------------------------------------------------------
  86. WORD XSDevName(WORD device, BYTE *name)
  87.   Ermittelt den Namen des zum BIOS-Device gehörigen Ports (z.B. "Modem1"). `name'
  88.   muß auf ein mindestens 9 Bytes großes Array zeigen. Dort wird der Name nulltermi-
  89.   niert eingetragen.
  90.   
  91.   Rückgabe:
  92.   0 bei Erfolg
  93.   EUNDEV - Ungültiges Device
  94.  
  95. -----------------------------------------------------------------------------------
  96. WORD XSReserve(WORD device)
  97.   Device reservieren. Es handelt sich hier um ein "advisory" Locking, d.h. es ist
  98.   darauf angewiesen, daß jedes Programm den Lock abfragt und freiwillig auf weitere
  99.   Zugriffe verzichtet, wenn das Device bereits belegt ist. Jedes Programm hat vor
  100.   irgendeinem Zugriff auf das Device diesen Aufruf durchzuführen. Wenn das Device
  101.   noch frei  war, ist es nach dem Aufruf reserviert. Wenn es bereits reserviert war,
  102.   wird ein Fehlercode zurückgeliefert. In diesem Fall sollte keinerlei Zugriff mehr
  103.   auf das Device erfolgen.
  104.   
  105.   Rückgabewert:
  106.   0 - das Device ist jetzt reserviert
  107.   EACCDN - das Gerät war bereits reserviert
  108.   EUNDEV - Ungültiges Device
  109.  
  110. -----------------------------------------------------------------------------------
  111. WORD XSRelease(WORD device)
  112.   Device wieder freigeben. Dieser Aufruf darf NUR gemacht werden, wenn vorher
  113.   ein erfolgreicher XSReserve durchgeführt werden konnte (mit Rückgabe 0).
  114.  
  115.   Falls auf dem Device noch eine XSCtlSig-Routine angemeldet war, wird sie
  116.   automatisch freigegeben.
  117.  
  118.   Rückgabewert:
  119.   0 bei Erfolg, 
  120.   EACCDN - wenn das Device nicht reserviert war.
  121.   EUNDEV - Ungültiges Device
  122.  
  123. -----------------------------------------------------------------------------------
  124. LONG XSCapMap(WORD device)
  125.   Fragt diverse Eigenschaften von Treiber und Device ab. Wenn kein Fehler vorliegt,
  126.   wird ein Bitvektor zurückgeliefert. Folgende Bits sind z.Zt. definiert:
  127.  
  128.   #define XS_BREAK    0x01   /* Device kann Break senden */
  129.   #define XS_RTSCTS 0x02   /* Device beherrscht RTS/CTS-Handshaking */
  130.   #define XS_TANDEM 0x04   /* Device beherrscht XON/XOFF-Handshaking */  
  131.   #define XS_IOBAUD 0x08   /* Device beherrscht verschiedene I- und O-Baudraten */
  132.  
  133.   #define XS_BIOSRW 0x8000 /* Treiber benutzt BIOS zum Lesen/Schreiben */
  134.   
  135.   Alle anderen Bits sind reserviert und sollten bis auf weiteres ignoriert
  136.   werden.
  137.   
  138.   Rückgabewert:
  139.   >=0 (LONG!) - Verfügbare Fähigkeiten
  140.   EUNDEV - Ungültiges Device
  141.  
  142. -----------------------------------------------------------------------------------
  143. LONG XSIBaud(WORD device, LONG baudrate)
  144.   Eingabe-Baudrate (genauer: bps) des angegebenen Devices setzen/abfragen. Die Baud-
  145.   rate wird unkodiert im "Klartext" angegeben (38400L entspricht z.B. 38400 bps).
  146.   Wenn -1L angegeben wird, wird die Baudrate nicht verändert (nur Abfrage). Falls
  147.   eine Baudrate angfordert wird, die auf dem Device nicht zur Verfügung steht, wird
  148.   die nächst niedrigere verfügbare eingestellt und zurückgeliefert.
  149.  
  150.   Die meisten Devices unterstützen keine getrennten Baudraten für Ein- und Aus-
  151.   gabe. In diesem Fall wird mit einem XSIBaud gleichzeitig auch die Ausgabe-
  152.   Baudrate verändert (dies kann mit XSCapMap abgefragt werden).
  153.  
  154.   Rückgabewert:
  155.   >0 - eingestellte Baudrate
  156.   EUNDEV - Ungültiges Device
  157.  
  158.   Anmerkung: Durch die Rückgabe der nächst niedrigen verfügbaren Baudrate kann
  159.   der Aufrufer alle für dieses Device verfügbaren Baudraten durch "Abklappern"
  160.   von oben nach unten ermitteln.
  161.  
  162. -----------------------------------------------------------------------------------
  163. LONG XSOBaud(WORD device, LONG baudrate)
  164.   Ausgabe-Baudrate (genauer: bps) des angegebenen Devices setzen/abfragen. Die
  165.   Funktionsweise ist ansonsten analog zu XSIBaud.
  166.  
  167.   Die meisten Devices unterstützen keine getrennten Baudraten für Ein- und Aus-
  168.   gabe. In diesem Fall wird mit einem XSOBaud gleichzeitig auch die Eingabe-
  169.   Baudrate verändert (dies kann mit XSCapMap abgefragt werden).
  170.  
  171.   Rückgabewert:
  172.   >0 - eingestellte Baudrate
  173.   EUNDEV - Ungültiges Device
  174.  
  175. -----------------------------------------------------------------------------------
  176. WORD XSBreak(WORD device, WORD on)
  177.   Ein BREAK auf dem Device setzen/löschen. Wenn `on' ungleich 0 ist, wird BREAK
  178.   gesetzt, ansonsten gelöscht. Wenn das Device BREAK nicht beherrscht, wird der
  179.   Aufruf ignoriert.
  180.  
  181.   Rückgabe: 
  182.   0 bei Erfolg
  183.   EUNDEV - Ungültiges Device
  184.  
  185. -----------------------------------------------------------------------------------
  186. LONG XSSetFlags(WORD device, UWORD flags)
  187.   Übertragungsparameter einstellen. Versuche, Einstellungen zu machen, die auf dem
  188.   Device nicht möglich sind (d.h. solche, die XSCapMap als nicht verfügbar meldet),
  189.   werden ignoriert. `flags' enthält die Einstellung in folgender Kodierung (ent-
  190.   spricht der des TIOCGFLAGS-Fcntl von MiNT):
  191.  
  192.   Maske: TF_STOPBITS 0x0003
  193.   Werte:
  194.     0x0000    Ungültig
  195.     0x0001    1 Stop-Bit
  196.     0x0002    1.5 Stop-Bits
  197.     0x0003    2 Stop-Bits
  198.  
  199.   Maske: TF_CHARBITS 0x000C
  200.   Werte:
  201.     0x0000    8 Bits pro Zeichen
  202.     0x0004    7 Bits
  203.     0x0008    6 Bits
  204.     0x000C    5 Bits
  205.  
  206.   Maske: TF_PARITY 0xc000
  207.   Werte:
  208.     0x0000  Keine Parität
  209.     0x4000    Gerade Parität
  210.     0x8000    Ungerade Parität
  211.     0xc000  Ungültig
  212.     
  213.   Weitere Bits:
  214.     T_TANDEM    0x1000    XON/XOFF Handshake
  215.     T_RTSCTS    0x2000    RTS/CTS Handshake
  216.  
  217.   Alle übrigen Bits sind reserviert und sollten 0 sein.
  218.  
  219.   Rückgabewert:
  220.   >=0 (LONG!) - die vor dem Aufruf eingestellten Flags
  221.   ERANGE - es wurden ungültige Parameter festgestellt
  222.   EUNDEV - Ungültiges Device
  223.  
  224. -----------------------------------------------------------------------------------
  225. LONG XSGetFlags(WORD device)
  226.   Übertragungsparameter abfragen.
  227.  
  228.   Rückgabewert:
  229.   >=0 (LONG!) - Eingestellte Parameter (Kodierung siehe XSSetFlags).
  230.   EUNDEV - Ungültiges Device
  231.  
  232. -----------------------------------------------------------------------------------
  233. LONG XSCtlMap(WORD device)
  234.   Auf dem Device verfügbare Kontrolleitungen abfragen. Wenn kein Fehler vorliegt,
  235.   wird ein Bitvektor zurückgeliefert, in dem für die verfügbaren Kontrolleitungen
  236.   das entsprechende Bit 1 ist, für die nicht verfügbaren 0. Folgende Bits sind
  237.   definiert:
  238.  
  239.   #define TIOCM_LE  0x01              /* line enable */
  240.   #define TIOCM_DTR 0x02              /* data terminal ready */
  241.   #define TIOCM_RTS 0x04              /* ready to send */
  242.   #define TIOCM_CTS 0x08              /* clear to send */
  243.   #define TIOCM_CAR 0x10              /* carrier detect */
  244.   #define TIOCM_RNG 0x20              /* ring */
  245.   #define TIOCM_DSR 0x40              /* data set ready */
  246.  
  247.   Alle anderen Bits sind reserviert und sollten bis auf weiteres ignoriert
  248.   werden.
  249.  
  250.   Rückgabewert:
  251.   >=0 (LONG!) - Verfügbare Kontrolleitungen
  252.   EUNDEV - Ungültiges Device
  253.  
  254.   Anmerkung: Die Werte werden möglicherweise noch geändert, um sie an die (hof-
  255.   fentlich bald festgelegten) Definitionen der entsprechenden MiNT-Fcntls anzu-
  256.   passen.
  257.  
  258. -----------------------------------------------------------------------------------
  259. LONG XSGetCtl(WORD device)
  260.   Status der Kontrolleitungen abfragen (DCD, RI etc.). Falls kein Fehler auf-
  261.   tritt, wird ein Bit-Vektor geliefert (Kodierung wie bei XSCtlMap beschrieben).
  262.   Die Bits sind 1, wenn die entsprechende Leitung aktiviert ist, sonst 0.
  263.  
  264.   Rückgabewert:
  265.   >=0 (LONG!) - Status der Kontrolleitungen
  266.   EUNDEV - Ungültiges Device
  267.  
  268. -----------------------------------------------------------------------------------
  269. WORD XSSetCtl(WORD device, UWORD ctl)
  270.   Kontrolleitungen setzen. Kodierung wieder wie in XSCtlMap. Manche Leitungen (z.B.
  271.   CTS) sind Read-only und können daher nicht beeinflußt werden (das sollte aus dem
  272.   Kontext hervorgehen). Versuche, solche und Leitungen, die nicht von dem Device
  273.   unterstützt werden (d.h. von XSCtlMap als nicht verfügbar gemeldet wurden), zu
  274.   beeinflussen, werden ignoriert.
  275.  
  276.   Rückgabewert:
  277.   0 bei Erfolg
  278.   EUNDEV - Ungültiges Device
  279.  
  280. -----------------------------------------------------------------------------------
  281. WORD XSOnCtl(WORD device, UWORD on_mask)
  282.   Die Kontrolleitungen, deren Bit in `on_mask' gesetzt ist, aktivieren, ohne die
  283.   anderen zu beeiflussen. Ansonsten gelten dieselben Bedingungen, wie bei XSSetCtl.
  284.  
  285.   Rückgabewert:
  286.   0 bei Erfolg
  287.   EUNDEV - Ungültiges Device
  288.  
  289. -----------------------------------------------------------------------------------
  290. WORD XSOffCtl(WORD device, UWORD off_mask)
  291.   Die Kontrolleitungen, deren Bit in `off_mask' gesetzt ist, ausschalten, ohne die
  292.   anderen zu beeiflussen. Ansonsten gelten dieselben Bedingungen, wie beiXSSetCtl.
  293.  
  294.   Rückgabewert:
  295.   0 bei Erfolg
  296.   EUNDEV - Ungültiges Device
  297.  
  298. -----------------------------------------------------------------------------------
  299. LONG XSInStat(WORD device)
  300.   Ermittelt Anzahl der Zeichen, die z.Zt. auf dem Device zum Lesen verfügbar sind.
  301.   Der zurückgelieferte Wert muß nicht exakt sein. Es ist nur garantiert, daß mit
  302.   dem nächsten Lesezugriff mindestens soviele Bytes gelesen werden können, es
  303.   können aber auch mehr sein.
  304.   
  305.   Rückgabewert:
  306.   >=0 - Anzahl der verfügbaren Zeichen
  307.   EUNDEV - Ungültiges Device
  308.  
  309. -----------------------------------------------------------------------------------
  310. LONG XSOutStat(WORD device)
  311.   Ermittelt Anzahl der Zeichen, die z.Zt. auf das Device geschrieben werden können.
  312.   Der zurückgelieferte Wert muß nicht exakt sein. Es ist nur garantiert, daß mit
  313.   dem nächsten Schreibzugriff mindestens soviele Bytes ausgegeben werden können,
  314.   es können aber auch mehr sein.
  315.  
  316.   Rückgabewert:
  317.   >=0 - Anzahl der Zeichen, die ausgegeben werden können
  318.   EUNDEV - Ungültiges Device
  319.  
  320. -----------------------------------------------------------------------------------
  321. LONG XSRead(WORD device, LONG count, BYTE *buffer)
  322.   Maximal `count' Zeichen in den durch `buffer' angegebenen Speicherbereich lesen.
  323.   Wenn z. Zt. nicht soviele Zeichen verfügbar sind, kehrt XSWrite sofort zurück
  324.   (non-blocking).
  325.  
  326.   Rückgabewert:
  327.   >=0 - Anzahl der Zeichen, die gelesen wurden wurden
  328.   EUNDEV - Ungültiges Device
  329.   Weitere (negative) TOS-Fehlernummern bei I/O-fehlern
  330.  
  331. -----------------------------------------------------------------------------------
  332. LONG XSWrite(WORD device, LONG count, BYTE *buffer)
  333.   `count' Zeichen aus dem durch `buffer' angegebenen Speicherbereich auf das Device
  334.   schreiben. Wenn z. Zt. nicht so viele Zeichen geschrieben werden können, kehrt
  335.   XSWrite sofort zurück (non-blocking).
  336.  
  337.   Rückgabewert:
  338.   >=0 - Anzahl der Zeichen, die geschrieben wurden
  339.   EUNDEV - Ungültiges Device
  340.   Weitere (negative) TOS-Fehlernummern bei I/O-Fehlern
  341.  
  342. -----------------------------------------------------------------------------------
  343. WORD XSFlush(WORD device, WORD mode)
  344.   Verwerfe Zeichen, die noch im Puffer des Treibers stehen. `mode' gibt genauer
  345.   an, was verworfen wird:
  346.   0: Verwerfe Zeichen, die empfangen, aber noch nicht ausgelesen wurden
  347.   1: Verwerfe Zeichen, die geschrieben, aber noch nicht gesendet wurden
  348.   2: Verwerfe alle noch gepufferten Zeichen
  349.   
  350.   Wenn die Operation auf dem Device nicht möglich ist, wird der Aufruf ignoriert.
  351.   
  352.   Rückgabewert:
  353.   0 bei Erfolg
  354.   ERANGE - wenn `mode' nicht 0, 1 oder 2 ist
  355.   EUNDEV - Ungültiges Device
  356.  
  357. -----------------------------------------------------------------------------------
  358. WORD XSInSig(WORD device, void (*func)(WORD device))
  359.   Weist den Treiber an, die durch `func' angegebene Funktion anzuspringen, sobald
  360.   ein neues Zeichen von dem Device  eingetroffen ist. Der Routine wird dabei die
  361.   Device-Nummer auf dem Stack übergeben. Die angegebene Routine wird sehr wahr-
  362.   scheinlich aus einem Interrupt heraus aufgerufen. Dementsprechend darf sie keine
  363.   Register verändern und sollte möglichst kurz sein. Die Routine wird nur genau
  364.   einmal aufgerufen, danach wird der XSInSig automatisch wieder deaktiviert. Wenn
  365.   vor dem Aufruf bereits ein XSInSig aktiv war, wird der neue nicht installiert
  366.   und EACCDN zurückgeliefert.
  367.   
  368.   Wenn als `func' ein Null-Zeiger übergeben wird, wird ein vorher gesetzter XSInSig
  369.   annuliert.
  370.   
  371.   XSInSig muß nicht auf jedem Device verfügbar sein; in diesem Fall wird EINVFN
  372.   zurückgeliefert.
  373.  
  374.   Rückgabe:
  375.   0 - bei Erfolg
  376.   EINVFN - Device unterstützt XSInSig nicht
  377.   EACCDN - Es ist bereits ein XSInSig aktiv
  378.   EUNDEV - Ungültiges Device  
  379.  
  380.   Anmerkung: Diese Funktion ist in der Hauptsache zur Implementation von MiNT-
  381.   Treibern gedacht und sollte von Anwendungsprogrammen nicht verwendet werden.
  382.  
  383. -----------------------------------------------------------------------------------
  384. WORD XSOutSig(WORD device, void (*func)(WORD device))
  385.   Weist den Treiber an, die durch `func' angegebene Funktion anzuspringen, sobald
  386.   ein neues Zeichen auf das Device ausgegeben werden kann. Die Funktionsweise ist
  387.   ansonsten analog zu XSInSig.
  388.  
  389.   Wenn als `func' ein Null-Zeiger übergeben wird, wird ein vorher gesetzter
  390.   XSOutSig annuliert.
  391.   
  392.   XSOutSig muß nicht auf jedem Device verfügbar sein; in diesem Fall wird EINVFN
  393.   zurückgeliefert.
  394.  
  395.  Rückgabe:
  396.   0 - bei Erfolg
  397.   EINVFN - Device unterstützt XSOutSig nicht
  398.   EACCDN - Es ist bereits ein XSOutSig aktiv
  399.   EUNDEV - Ungültiges Device  
  400.  
  401.   Anmerkung: Diese Funktion ist in der Hauptsache zur Implementation von MiNT-
  402.   Treibern gedacht und sollte von Anwendungsprogrammen nicht verwendet werden.
  403.  
  404. -----------------------------------------------------------------------------------
  405. LONG XSCtlSig(WORD device, UWORD ctl_mask, void (*func)(WORD device, UWORD ctl))
  406.   Weist den Treiber an, die durch `func' angegebene Funktion anzuspringen, sobald
  407.   sich der Zustand einer der in `ctl_mask' spezifizierten Kontrolleitungen ändert
  408.   (Kodierung wie bei XSCtlMap angegeben). Der Routine wird dabei die Device-Nummer
  409.   und ein Bitvektor, in dem das Bit der auslösenden Kontrolleitung gesetzt ist,
  410.   auf dem Stack übergeben. Die angegebene Routine wird sehr wahrscheinlich aus
  411.   einem Interrupt heraus aufgerufen. Dementsprechend darf sie keine Register ver-
  412.   ändern und sollte möglichst kurz sein. Die Routine wird nur genau einmal aufge-
  413.   rufen, danach wird der XSCtlSig automatisch wieder deaktiviert. Wenn vor dem
  414.   Aufruf bereits ein XSCtlSig aktiv war, wird der neue nicht installiert und
  415.   EACCDN zurückgeliefert.
  416.  
  417.   Wenn als `func' ein Null-Zeiger übergeben wird, wird ein vorher gesetzter
  418.   XSCtlSig annuliert.
  419.   
  420.   XSCtlSig muß nicht auf jedem Device verfügbar sein; in diesem Fall wird EINVFN
  421.   zurückgeliefert. Ebenso muß er nicht für alle verfügbaren Kontrolleitungen ver-
  422.   fügbar sein. Wenn in `ctl_mask' Kontrolleitungen angegeben werden, die durch
  423.   XSCtlSig nicht unterstützt werden, wird das ignoriert. Auf welche Leitungen
  424.   tatsächlich reagiert wird, kann man aus dem Rückgabewert ersehen.
  425.  
  426.   Sobald ein Device mit XSRelease freigegeben wird, werden noch darauf installierte
  427.   XCtlSig automatisch abgemeldet.
  428.   
  429.   Rückgabe:
  430.   >0 (LONG!) - Maske mit den tatsächlich berücksichtigten Kontrolleitungen.
  431.   EINVFN - Device unterstützt XSCtlSig nicht
  432.   EACCDN - Es ist bereits ein XSCtlSig aktiv
  433.   EUNDEV - Ungültiges Device  
  434.  
  435.   Anmerkung: Diese Funktion kann z.B. verwendet werden, um effizient die RI- oder
  436.   DCD-Leitungen zu überwachen (man installiert eine Routine, die im eigenen Pro-
  437.   gramm ein Flag setzt und fragt dieses periodisch ab). ACHTUNG: Ein Programm,
  438.   daß diese Funktion benutzt, darf keinesfalls vergessen, den XSCtlSig vor dem
  439.   Beenden wieder zu annulieren.
  440.  
  441. END-OF-TEXT