isdn-11
reconstructed from isdn-18 with reverse application of the individual patches.
This commit is contained in:
parent
215846b0ff
commit
1097952088
338
DOKU
338
DOKU
|
@ -15,11 +15,25 @@ unter der GPL bzw. ihrem deutschen
|
|||
|
||||
Achtung:
|
||||
=======
|
||||
Mit der Version für 1.2.0 hat sich die Syntax der cf-Datei leicht geändert.
|
||||
|
||||
Mit der Version 11 ist das OK am Ende des statischen Teils der AT/L-Ausgabe
|
||||
weggefallen, weil das zu viele Leute irritiert hat.
|
||||
|
||||
Mit der Version 11 hat sich die Installationsprozedur fuer ISDN-Karten
|
||||
geaendert. Vorher: Config.c editieren, Modul bauen. Jetzt: d_teles.o
|
||||
laden, dann fuer jede Karte "insmod -o Tel0 teles.o name=$(cardname Tel0)
|
||||
mem=0xD6000 irq=5" ausfuehren. Daten anpassen! Unterschiedliche Namen
|
||||
verwenden! Das rc-Skript in tools/ wurde entsprechend angepasst.
|
||||
16-Bit-Karten: Zusaetzlich "ipl=X" (X=1..3) fuer die erste bis dritte Karte.
|
||||
Damit sollte es problemlos sein, zwischen verschiedenen Systemen (mit
|
||||
einigermaßen identisch konfigurierten Kernels) die Treiber auszutauschen.
|
||||
|
||||
Mit der Version für 1.2.0 hat sich die Syntax der cf-Datei leicht geändert:
|
||||
|
||||
Der :ea-Parameter in der P-Zeile wurde durch den :lr-Parameter ersetzt:
|
||||
verwende ":lr /X" statt ":ea X".
|
||||
hänge an die DL-Zeile einen / an.
|
||||
- verwende ":lr /X" statt ":ea X".
|
||||
- hänge an die DL-Zeile an die Nummer einen / an und danach ":pr 0 :sp 65
|
||||
:pr 63" für 1TR6 oder :sp 8 für Euro-ISDN.
|
||||
Generell steht nun "/" für EAZs und so; "." steht für Nebenstellennummern.
|
||||
Bei externen Nummern verwende ich generell ".", aber das ist
|
||||
Geschmackssache.
|
||||
|
@ -28,7 +42,7 @@ Einige Konfigzeilen haben als zus
|
|||
verpaßt bekommen.
|
||||
|
||||
Die Parameter :pr und :sp stehen nun in der DL-Zeile und nicht mehr in
|
||||
der P-Zeile; siehe unten.
|
||||
der P-Zeile.
|
||||
|
||||
Die I- und O-Flags werden nun klein geschrieben.
|
||||
|
||||
|
@ -63,9 +77,10 @@ Die Konfigurationsdatei ist manchmal etwas undurchsichtig.
|
|||
_Ich_ werde das nicht ändern, keine Zeit; wenn jemand ein Frontend
|
||||
schreiben will -- nur zu!
|
||||
|
||||
Das Masterprogramm könnte noch Speicherlecks haben...
|
||||
Das Masterprogramm hat noch Speicherlecks.
|
||||
|
||||
Euro-ISDN ist moderat getestet; Gebührenerfassen geht noch nicht.
|
||||
Euro-ISDN ist moderat getestet; Gebührenerfassen während der Verbindung
|
||||
geht noch nicht.
|
||||
|
||||
Login über ISDN macht noch leichte Probleme.
|
||||
|
||||
|
@ -122,11 +137,17 @@ wer kann und will, m
|
|||
Kernelpatches
|
||||
=============
|
||||
|
||||
Die Patches basieren auf dem Kernel Linux-1.1.86. Frühere und spätere
|
||||
Kernels auf eigene Gefahr bzw. Bastelei.
|
||||
Die Patches basieren auf dem in der Versionsnummer bezeichneten Kernel.
|
||||
Frühere bzw. spätere Kernels auf eigene Gefahr bzw. Bastelei.
|
||||
|
||||
Was die einzelnen Patches machen und ob sie benötigt werden,
|
||||
steht in den einzelnen Dateien am Anfang.
|
||||
|
||||
Der Kernel muß mit CONFIG_MODVERSION gebaut werden. Alternativ (aber das ist
|
||||
unsicherer) kann im ISDN-Paket aus config/config.data -DCONFIG_MODVERSION
|
||||
entfernt werden. Das modutils-1.2.8-Paket wird in jedem Fall benötigt, um
|
||||
Parameter an die einzelnen Module zu übergeben.
|
||||
|
||||
|
||||
Grundstruktur
|
||||
=============
|
||||
|
@ -149,7 +170,7 @@ Sache des Steuerprogramms (D-Kanal) bzw. anderer Streams-Module (B-Kan
|
|||
|
||||
Ein kommunikationswilliges Programm öffnet einen freien ISDN-Port
|
||||
(/dev/isdn/isdnX, X von 1 bis 99 oder so) und sendet einen Verbindungs-
|
||||
wunsch an das Steuerprogramm ("atd/subnet/login", ffnen einer Verbindung
|
||||
wunsch an das Steuerprogramm ("atd/subnet/login", öffnen einer Verbindung
|
||||
zum System "subnet" im Protokollmodus "login"). Das Steuerprogramm schiebt
|
||||
diesem Kanal nun automatisch die notwendigen B-Kanal-Module unter (X.75,
|
||||
T.70, V.110, was-auch-immer), baut die Verbindung auf, meldet den Zustand
|
||||
|
@ -162,14 +183,8 @@ Dasselbe passiert bei abgehenden Anrufen, die auf das zust
|
|||
beschränkt sind, zB TCP/IP.
|
||||
|
||||
Beispiel:
|
||||
% kermit
|
||||
> set lin /dev/isdn/isdn31
|
||||
% cu -l isdn/isdn22
|
||||
beliebig, muß nur frei sein.
|
||||
> set spe 1200
|
||||
Die eingestellte Geschwindigkeit wird ignoriert, aber Kermit besteht
|
||||
darauf...
|
||||
> c
|
||||
Verbindung herstellen.
|
||||
AT
|
||||
OK
|
||||
Der Interpreter im Kontrollprogramm tut so, als wäre er ein Modem mit
|
||||
|
@ -180,12 +195,12 @@ ATD/subnet/login
|
|||
RRING
|
||||
CONNECT
|
||||
login:
|
||||
Die Verbindung steht. Viel Spaß beim Hacken eines Paßworts für die subnet. ;-)
|
||||
Die Verbindung steht. Viel Spaß beim Hacken eines Paßworts. ;-)
|
||||
|
||||
BETA-BEMERKUNG: Loginverbindungen sind in der jetztigen Version nicht allzu
|
||||
gut getestet. Was sehr gut tut, ist TCP/IP; siehe dazu die Beispielkonfi-
|
||||
guration cf.tcp. Ein Anrufbeantworter existiert ebenfalls (leider noch ohne
|
||||
DMTF-Erkennung); siehe dazu die Beispielkonfiguration cf.answer.
|
||||
guration. Ein Anrufbeantworter existiert ebenfalls (leider noch ohne
|
||||
DMTF-Erkennung).
|
||||
|
||||
Statt eines Sitenamens tut auch ATD und die Nummer; /login ist der Default
|
||||
für das Protokoll.
|
||||
|
@ -209,9 +224,12 @@ vi config/config.data
|
|||
vi isdn/cards/dumb/Config.c # Speicherlage+Interrupts der ISDN-Karten
|
||||
make.isdn
|
||||
make load # Einbau der Module in den laufenden Kernel
|
||||
cd /usr/local/isdn
|
||||
vi cf.tcp # ISDN-Nummern, Dienste, etc. eintragen
|
||||
bin/master cf.tcp # geht automatisch in den Hintergrund
|
||||
cd /usr/local/isdn/bin
|
||||
vi /etc/isdn.conf # ISDN-Nummern, Dienste, etc. eintragen
|
||||
bin/master /etc/isdn.conf # geht automatisch in den Hintergrund
|
||||
|
||||
Sämtliche Gerätedateien werden automatisch angelegt.
|
||||
|
||||
|
||||
Testen:
|
||||
-------
|
||||
|
@ -238,18 +256,27 @@ AT/K
|
|||
Kann nur vom Superuser ausgeführt werden.
|
||||
AT/Kn
|
||||
Beendet die Verbindung <n>, beendet das betreffende Programm.
|
||||
Kann nur vom Superuser ausgeführt werden.
|
||||
AT/L
|
||||
Listet den momentanen Status aller Verbindungen.
|
||||
<n> <Art> <Partner> <Key> <pid> <Modus/Karte> <UnitNow> <UnitAll> <Stat>
|
||||
<Modus> ist:
|
||||
<[minor:]id> <Art> <Partner> <Key> <pid> <Modus/Karte> <UnitNow> <UnitAll> <Status>
|
||||
<minor> Nummer der Verbindung, für AT/K o.ä.
|
||||
<n> interne Folgenummer der Statusmeldung; Meldungen, die einen
|
||||
alten Status ersetzen, bekommen dieselbe Nummer.
|
||||
<pid> PID des Prozesses, der für die Verbindung gestartet wurde.
|
||||
<Modus>
|
||||
off Verbindung nicht aktiv, wird bei ankommendem Ruf reaktiviert.
|
||||
down Standby; sobald ein Datenpaket ansteht, wird die Verbindung
|
||||
aufgebaut.
|
||||
up Verbindung steht
|
||||
->down
|
||||
->up Verbindung wird gerade ab- bzw. aufgebaut.
|
||||
Ein Ausrufezeichen an erster Stelle bedeutet, daß die Verbindung bereits
|
||||
->down
|
||||
->up Verbindung wird gerade ab- bzw. aufgebaut.
|
||||
<UnitNow> Einheiten in der aktuellen Verbindung.
|
||||
<UnitAll> Einheiten insgesamt seit Start des Prozesses.
|
||||
<Flags> interner Zustand der Verbindung, komma remote-Nummer,
|
||||
strichpunkt lokale-Nummer (jeweils wenn bekannt/vorhanden)
|
||||
<Status> Text; Meldung der Vermittlung (Groß/Kleinschreibung) oder
|
||||
interner Zustand (Großschreibung).
|
||||
Ein Ausrufezeichen an erster Stelle bedeutet, daß die Verbindung intern
|
||||
nicht mehr bekannt ist, der Zustand aber noch eine Zeitlang angezeigt wird.
|
||||
|
||||
Bis zum nächsten AT-Befehl bleibt der Kanal im Monitormodus und meldet
|
||||
|
@ -257,7 +284,7 @@ AT/L
|
|||
AT/I
|
||||
Listet den internen Zustand. In der ersten Zeile stehen die erkannten
|
||||
ISDN-Karten, die zweite Zeile enthält den internen Zustand des ISDN-
|
||||
Protokolls.
|
||||
Systems. Zum Debuggen.
|
||||
AT/M foo
|
||||
Sendet den Systembefehl "foo" nach unten. Gefährlich.
|
||||
Kann zum Online-Rekonfigurieren von Modulen verwendet werden. Beispiel:
|
||||
|
@ -284,7 +311,7 @@ ATH
|
|||
|
||||
Diverse andere Befehle sind 100% ungetestet. <BREAK> habe ich seit Ewigkeiten
|
||||
nicht mehr ausprobiert.
|
||||
ATA existiert übrigens nicht; stattdessen Konfigdatei ändern.
|
||||
ATA existiert nicht; stattdessen Konfigdatei ändern.
|
||||
|
||||
|
||||
Einschub: Was ist dieser Streams-Kram eigentlich?
|
||||
|
@ -301,28 +328,31 @@ pro Fragment) oder von der Gegenseite weggeschmissen werden (Overhead:
|
|||
unendlich ;-) , muß man sie so kennzeichnen, daß die Gegenseite sie direkt
|
||||
wieder zusammensetzen kann (Overhead: 2 Bytes; braucht aber besagte gesicherte
|
||||
Verbindung, um vernünftig zu funktionieren). BTX beispielsweise arbeitet
|
||||
so.
|
||||
so. Außerdem ist ISDN bytesynchrton, d.h. irgendjemand muß kennzeichnen, wo
|
||||
ein Datenpaket aufhört und wo/wann das nächste anfängt. Dafür gibt es, wie
|
||||
üblich, mehrere Methoden...
|
||||
|
||||
Streams sind nun eine Möglichkeit, mehrere speziell geschriebene Module
|
||||
so auf einem ebenfalls speziell geschriebenen Treiber so zu stapeln, daß
|
||||
jedes Modul eine Einzelaufgabe dieser Arbeit erledigt. Im Idealfall sind
|
||||
die einzelnen Module recht klein und damit debugbar, lassen sich vielseitig
|
||||
auf einem ebenfalls speziell geschriebenen Treiber so zu stapeln, daß jedes
|
||||
Modul eine Einzelaufgabe dieser Arbeit erledigt. Im Idealfall sind die
|
||||
einzelnen Module recht klein und damit debugbar, lassen sich vielseitig
|
||||
zusammenstöpseln, etc.pp. In der Praxis ist die Sache natürlich nicht ganz
|
||||
so einfach; insbesondere ist der Overhead, die Pakete von einem Modul zum
|
||||
nächsten zu schaufeln, nicht zu vernachlässigen. Er ist aber tolerierbar,
|
||||
vor allem wenn man auf die ganzen überflüssigen "Features" (von vielen
|
||||
vernünftigen Menschen als "Bugs" oder "Designfehler" bezeichnet...)
|
||||
verzichtet, die USL und Co. in Sys5 Release 4 dazuerfunden haben.
|
||||
vor allem wenn man auf die ganzen überflüssigen "Features" (von manchen
|
||||
Menschen als "Bugs" oder "Designfehler" bezeichnet...) verzichtet, die
|
||||
USL und Co. in Sys5 Release 4 dazuerfunden haben.
|
||||
|
||||
Die einzelnen Module müssen parametrisiert werden. Im Normalfall spricht
|
||||
man sich mit der Gegenseite vorher ab, ob beispielsweise X.75 verwendet
|
||||
wird und in welchem Modus. Alternativ, und wenn man die Normen auswendig
|
||||
weiß, schaltet man ein Monitor-Modul zuunterst auf den Datenstrom, ruft
|
||||
die Gegenseite an, beobachte genau was da passiert, und richtet die Konfi-
|
||||
guration entsprechend ein. (Das klingt nicht nur kompliziert, das ist
|
||||
es auch. Außerdem gibt es ein paar Details, die sich nicht ohne weiteres
|
||||
beobachten lassen.) Zum Glück haben sich ein paar "normale" Betriebsarten
|
||||
herauskristallisiert, an die sich die meisten Systeme halten.
|
||||
weiß, schaltet man ein Monitor-Modul zuunterst auf den Datenstrom, läßt
|
||||
sich von der Gegenseite anrufen, beobachtet genau was da passiert, und
|
||||
richtet die Konfiguration entsprechend ein. (Das klingt nicht nur
|
||||
kompliziert, das ist es auch. Außerdem gibt es ein paar Details, die sich
|
||||
nicht ohne weiteres beobachten lassen.) Zum Glück haben sich ein paar
|
||||
"normale" Betriebsarten herauskristallisiert, an die sich die meisten
|
||||
Systeme halten.
|
||||
|
||||
|
||||
Noch ein Einschub: TCP-IP-Routing
|
||||
|
@ -340,48 +370,51 @@ Wichtige Spezialf
|
|||
slipto mit -d starten und auf den ganzen anderen Rechnern im lokalen Netz
|
||||
eine Defaultroute zum ISDN-Rechner eintragen. ACHTUNG! ALLE LOKALEN
|
||||
RECHNER BRAUCHEN OFFIZIELL ZUGETEILTE IP-NUMMERN. Das Weiterleiten von
|
||||
Nummernbereichen nach RFC 1597 muß unterbunden werden (IP-Firewall in den
|
||||
Kernel einbauen); andere unzulässige Netznummern müssen durch einen
|
||||
zweiten Gatewayrechner mit zwei Ethernetkarten o.ä., auf dem _keine_
|
||||
Route eingetragen ist, die auf den ISDN-Rechner zeigt, abgeschottet
|
||||
werden.
|
||||
Nummernbereichen nach RFC 1597 muß unterbunden werden (wenn diese lokal
|
||||
verwendet werden: unbedingt IP-Firewall in den Kernel einbauen und
|
||||
rausfiltern); andere unzulässige Netznummern müssen durch einen zweiten
|
||||
Gatewayrechner mit zwei Ethernetkarten o.ä. abgeschottet werden.
|
||||
|
||||
- Ein System, das eigentlich Teil des lokalen Netzes wäre, sitzt am anderen
|
||||
Ende der Leitung. Am einfachsten ist hier Proxy-ARP; der benötigte Befehl
|
||||
beim Booten lautet "arp -s IP_der_entfernten_Kiste Ether_des_ISDN_-
|
||||
_Rechners pub". Die Ethernetadresse spuckt "ifconfig eth0" aus.
|
||||
|
||||
diplogin (für IP über serielle Leitung) kann den arp-Eintrag automatisch
|
||||
setzen. Wenn jemand entsprechende Patches für slipto macht -> her zu mir.
|
||||
|
||||
- Ein Netz mit stupidem ISDN-Router, der ein Transfernetz sehen will, ist
|
||||
auf der anderen Seite. Einfachste Methode: Vom lokalen Netzbereich wird
|
||||
ein 4-Adressen-Bereich abgezwackt und als Transfernetz mißbraucht. Sei
|
||||
die lokale Adresse 129.130.131.x, so wird zum Beispiel der Bereich x =
|
||||
[224..227] verwendet (die beiden untersten Bits der unteren Kante des
|
||||
[224..227] verwendet (die beiden untersten Bits des unteren Endes des
|
||||
Adressbereichs, hier 224, müssen(!!!) 00 sein). Die nächste Adresse
|
||||
(hier: 225) wird die lokale Adresse (am besten eintragen via
|
||||
dummy-Interface: "ifconfig dummy0 129.130.131.225; route add -host
|
||||
129.130.131.225 dev lo" -- in der Konfigdatei wird die normale
|
||||
Ethernetadresse des Rechners als lokale Adresse verwendet). Danach (hier
|
||||
..226) kommt die entfernte Adresse (eintragen via Proxy-ARP).
|
||||
(hier: 225) wird die lokale Adresse (entweder als lokale Adresse im
|
||||
slipto, oder via dummy-Interface: "ifconfig dummy0 129.130.131.225; route
|
||||
add -host 129.130.131.225 dev lo" -- in der Konfigdatei wird in diesem
|
||||
Fall die normale Ethernetadresse des Rechners als lokale Adresse
|
||||
verwendet). Danach (hier; .226) kommt die entfernte Adresse (eintragen
|
||||
via Proxy-ARP).
|
||||
|
||||
Auf der Gegenstelle wird dann das Transfernetz mit einer Netmask von
|
||||
255.255.255.252 konfiguriert, die ..225 wird dort die entfernte
|
||||
Adresse und die Defaultroute an der Gegenstelle zeigt darauf.
|
||||
(Außerdem muß manchmal eine Route für das Netz, hier 129.130.131.0,
|
||||
eingetragen werden.)
|
||||
eingetragen werden, die auf die Gegenseite, hier .225, zeigt.)
|
||||
|
||||
Diese Methode verschwendet 75% des Adressbereichs (die Nummern ..224,
|
||||
..225 und ..227 werden nie in Erscheinung treten) und einer der Rechner
|
||||
auf der Gegenseite verwendet dummerweise eine Nummer aus dem lokalen
|
||||
Netz, für die ein funktionierender Nameserver-Eintrag gepflegt werden
|
||||
muß, hat aber den Vorteil, daß sie funktioniert.
|
||||
Diese Methode verschwendet 75% des Adressbereichs (die Nummern .224,
|
||||
.225 und .227 werden im Internet nie in Erscheinung treten) und einer der
|
||||
Rechner auf der Gegenseite verwendet dummerweise eine Nummer aus dem
|
||||
lokalen Netz, für die ein funktionierender Nameserver-Eintrag gepflegt
|
||||
werden muß, hat aber den Vorteil, daß sie funktioniert.
|
||||
|
||||
Es fällt außerdem auf, daß die lokale Adresse und Konfiguration des
|
||||
ISDN-Links nichts, aber auch gar nichts, mit dem zu tun hat, was die
|
||||
Gegenseite von uns denkt. Das ist auch total egal. Das einzige, auf das
|
||||
es ankommt, ist, daß die jeweils lokalen Adressen auch als lokal
|
||||
angesehen werden und _nicht_ irgendwie wieder zur Gegenseite geroutet
|
||||
werden. Pingpongpakete haben auf einer ISDN-Leitung nichts verloren!
|
||||
(Und auch nirgends anders.)
|
||||
ISDN-Links nichts mit dem zu tun haben muß, was die Gegenseite von uns
|
||||
denkt. Das ist auch total egal -- im Gegensatz zu PPP werden die Adressen
|
||||
nicht mit der Gegenstelle abgeglichen. Das einzige, auf das es ankommt,
|
||||
ist, daß die jeweils lokalen Adressen auch als lokal angesehen werden und
|
||||
_nicht_ irgendwie wieder zur Gegenseite geroutet werden. Pingpongpakete
|
||||
haben auf einer ISDN-Leitung nichts verloren! (Und auch nirgends anders.)
|
||||
|
||||
Es fällt außerdem auf, daß ich nichts von routed und ähnlichen Programmen
|
||||
gesagt habe. Das ist Absicht. Konfiguriert eure Routen lieber statisch,
|
||||
|
@ -409,8 +442,8 @@ Alle Zeilentypen:
|
|||
behandlung verpassen.
|
||||
<Parameter...> ist eine Folge von einem oder mehr Parameter-Wert-Angaben.
|
||||
(Manche Parameter haben keine Wertangabe.)
|
||||
Merke: Zeilen ohne Parameter sind im allgemeinen nicht sinnvoll
|
||||
und führen (momentan noch) zu Fehlverhalten des Treibers.
|
||||
Merke: Zeilen ohne Parameter sind im allgemeinen nicht sinnvoll
|
||||
und führen (momentan noch) zu Fehlverhalten des Treibers.
|
||||
|
||||
|
||||
P-Zeile ("Protokoll")
|
||||
|
@ -420,11 +453,7 @@ Form:
|
|||
P <Art> <Partner> <Key> <Karte> <Mod> <Parameter...>
|
||||
|
||||
Beispiel:
|
||||
P login * * R :sv 0700 :nr .2 :ea 2 :pr 0 :sp 65
|
||||
|
||||
Anderes Beispiel, mit derselben Wirkung:
|
||||
P login * * R :sv 0700 :nr .2 :ea 2
|
||||
P * * * MX :pr 0 :sp 65
|
||||
P login * * R :sv 0700 :nr .2 :lr /2
|
||||
|
||||
Parameter:
|
||||
:Ft Bei Festverbindungen angeben. (Erzwingt das Laden des
|
||||
|
@ -437,6 +466,8 @@ Parameter:
|
|||
Bei Festverbindungen wird dieser Parameter nicht benötigt.
|
||||
:bc Zu verwendender B-Kanal, 1 oder 2. Nur für Festverbindungen
|
||||
interessant; im normalen ISDN managt die Vermittlung B-Kanäle für uns.
|
||||
:nj Kann der Ruf nicht angenommen werden, wird BUSY statt CallRejected
|
||||
gesendet.
|
||||
:xi Wenn ankommende und abgehende Anrufe kollidieren, soll der an-
|
||||
kommende abgewiesen werden. (Default: Der abgehende Ruf wird
|
||||
abgebrochen.) (Nicht allzu gut getestet.)
|
||||
|
@ -478,8 +509,8 @@ Spezifisch f
|
|||
Angaben lokale und
|
||||
|
||||
Mod:
|
||||
R Die Zeile kann primär für einen Verbindungsaufbau verwendet werden.
|
||||
M Die Zeile wird nur dann analysiert, wenn eine über ihr gefundene R-Zeile
|
||||
R Die Zeile wird primär für einen Verbindungsaufbau verwendet.
|
||||
M Die Zeile wird nur dann analysiert, wenn eine über ihr gefundene P-Zeile
|
||||
"paßt".
|
||||
X Wenn diese Zeile (oder eine darüberliegende) "paßt", wird das Scannen
|
||||
nach weiteren passenden Angaben hier abgebrochen.
|
||||
|
@ -603,8 +634,54 @@ DL Tel0 +49=911-34567. :pr 0 :sp 8 :pr 63
|
|||
Beispiel Festverbindung:
|
||||
DL Tel2 - :pr 64
|
||||
|
||||
Beispiel intelligente Karte mit CAPI:
|
||||
DL Bin0 +49=911-45678. :pr 65
|
||||
|
||||
Bedeutung der Spezialzeichen in der Nummer: Siehe "DP" unten.
|
||||
|
||||
Protokolle und Flags in der DL-Zeile:
|
||||
--------------------
|
||||
|
||||
Die Reihenfolge ist wichtig.
|
||||
|
||||
:pp Punkt-zu-Punkt-Verbindung, feste TEI (0x00). :kl ebenfalls
|
||||
angeben!
|
||||
:mp Verbindung am Bus, variabler TEI-Identifier. Bei manchen 1TR6-
|
||||
Vermittlungen und Nebenstellenanlagen sinnvoll.
|
||||
:mf Verbindung am Bus, fester TEI-Identifier. Default.
|
||||
:mt Verbindung am Bus, feste TEI(0x12). In Spezialfällen notwendig.
|
||||
|
||||
:ud XX Verzögerung zwischen dem Verbindungsaufbau (D-Kanal) und dem
|
||||
eigentlichen Datenaustausch (B-Kanal). Zehntelsekunden; max.
|
||||
2 Sekunden; Default 1/4 Sekunde. Mit :ud 0 geht der Verbindungs-
|
||||
aufbau entweder etwas schneller, oder das erste Paket wird
|
||||
verschluckt, oder die Vermittlung kommt durcheinander und die
|
||||
Verbindung ist tot. :-(
|
||||
|
||||
:pr 0 Normaler ISDN-D-Kanal, angeschlossen am Netz oder an einer
|
||||
Telefonanlage. Darf nur zusammen mit TEI-Handler (:pr 63)
|
||||
verwendet werden.
|
||||
:kl Level-2-Verbindung zur Vermittlung nicht trennen. Bei Punkt-
|
||||
zu-Punkt-Verbindungen und bei entsprechend konfigurierten
|
||||
ISDN-Anschlüssen ("Dauer-irgendwas") notwendig.
|
||||
:cl Level-2-Verbindung zur Vermittlung trennen. Default.
|
||||
|
||||
:sp 8 DSS1, Euro-ISDN.
|
||||
:sp 65 1TR6, deutscher Standard.
|
||||
|
||||
:ai Ankommenden Anruf mit dem ISDN-Äquivalent von "RINGING"
|
||||
beantworten, dann prüfen ob der Anruf angenommen werden kann.
|
||||
Notwendig bei langsamen Rechnern.
|
||||
:ad Ankommende Anrufe erst prüfen, dann annehmen (oder auch nicht).
|
||||
Default.
|
||||
:pr 63 TEI-Handler (Transport Endpoint Identifier).
|
||||
:ti TEI sofort zuordnen lassen. Notwendig bei langsamen / sehr
|
||||
beschäftigten Rechnern und bei manchen Telefonanlagen.
|
||||
:td TEI beim ersten Verbindungsaufbau zuordnen lassen. Default.
|
||||
:pr 64 Festverbindung: kein D-Kanal.
|
||||
:pr 65 Intelligente Karte mit CAPI 1.x-Schnittstelle.
|
||||
(Noch nicht!)
|
||||
|
||||
|
||||
DP-Zeile ("Dial Prefix")
|
||||
--------
|
||||
|
@ -623,9 +700,13 @@ typischerweise eine vorgestellte Null o.
|
|||
Gesprächen nicht mit angezeigt wird.
|
||||
|
||||
Die Zeichen sind immer "+" für internationale Verbindungen, "=" für
|
||||
nationale Verbindungen, "-" für Ortsverbindungen und "." für Verbindungen
|
||||
innerhalb einer Nebenstellenanlage. Außerdem gibt es noch "/" für EAZs etc.,
|
||||
die bei externen Nummern verwendet werden können. Beispiel:
|
||||
nationale Verbindungen, "-" für Ortsverbindungen, "." oder "/" für
|
||||
Verbindungen innerhalb einer Nebenstellenanlage oder EAZs/MSNs etc. Der
|
||||
Unterschied ist, daß Nummern einer Nebenstellenanlage direkt angerufen
|
||||
werden können, während ich für eine Verbindung zu einer anderen MSN die
|
||||
Teilnehmernummer mitwählen muß.
|
||||
|
||||
Beispiel: Eine Konfiguration
|
||||
D ... -1234/[456]
|
||||
DL... -23456
|
||||
DP... -
|
||||
|
@ -647,6 +728,10 @@ oder abgehenden Gespr
|
|||
mit "R"-Zeile ist also direkt nicht möglich, da der Datenaustausch zum
|
||||
betreffenden Programm geht.
|
||||
|
||||
Eine R-Zeile wird ignoriert, sobald das betreffende Programm einen Fehler
|
||||
gemeldet hat (Exitstatus != 0) oder bei der Verbindungssteuerung ein Fehler
|
||||
aufgetreten ist.
|
||||
|
||||
Im Environment dieses Programms werden folgende Variablen abgelegt:
|
||||
SITE <Partner>
|
||||
PROTOCOL <Art>
|
||||
|
@ -662,6 +747,7 @@ Mod:
|
|||
nach n Sekunden der Verbindungsaufbau wieder erlaubt. (Noch nicht
|
||||
implementiert)
|
||||
$ Die Befehlszeile wird nicht direkt ausgeführt, sondern der Shell übergeben.
|
||||
E Beim Auftreten eines Fehlers wird dieses Programm deaktiviert.
|
||||
D /dev/ttyiXX wird angelegt und nach Programmende gelöscht.
|
||||
F Das Programm wird sofort gestartet, und die Verbindung wird aufgebaut.
|
||||
Interessant insbesondere bei Festverbindungen und SPVs.
|
||||
|
@ -678,7 +764,7 @@ f f
|
|||
d für Wählverbindungen
|
||||
p für Verbindungsaufbau nach Bedarf ("reconn"-Modul nicht vergessen!);
|
||||
wird beim Programmstart automatisch mitgestartet. Die eigentliche
|
||||
ISDN-Verbindung wird hierdurch _nicht_ aufgebaut, dafür ist "b" gedacht.
|
||||
ISDN-Verbindung wird hierdurch _nicht_ aufgebaut, dafür ist "B" gedacht.
|
||||
|
||||
|
||||
CM-Zeile ("Card Mode")
|
||||
|
@ -737,6 +823,15 @@ Ueber das Limit hinausgehende Anrufe werden mit BUSY abgelehnt, es sei denn
|
|||
in der entsprechenden P-Zeile steht der entsprechende Parameter.
|
||||
|
||||
|
||||
LF-Zeile ("Load File")
|
||||
--------
|
||||
|
||||
Form: LF <Karte> <Segmentgröße> <Dateiname>
|
||||
|
||||
Lädt die Datei auf die (aktive) Karte. Mehrere LF-Zeilen können angegeben
|
||||
werden.
|
||||
|
||||
|
||||
RP-Zeile ("Run Program")
|
||||
--------
|
||||
Noch nicht implementiert.
|
||||
|
@ -758,11 +853,11 @@ Zus
|
|||
unterhalb derer keine Uebertragung zugelassen wird, um in Gesprächspausen
|
||||
die Rechnerlast zu senken.
|
||||
|
||||
:ro 0-127 Ansprechschwelle beim Empfang. Null schaltet permanent auf
|
||||
"Durchgang".
|
||||
:rx 0-127 Abschaltschwelle. Töne werden blockiert, wenn mehr als ..:
|
||||
:rc 1-32767 aufeinanderfolgende Samples unterhalb der :rx-Schwelle liegen.
|
||||
:xo :xx :xc wie :ro :rx :rc, aber für den Sendeteil.
|
||||
:ro 0-127 Ansprechschwelle beim Empfang. Null schaltet permanent auf
|
||||
"Durchgang".
|
||||
:rx 0-127 Abschaltschwelle. Töne werden blockiert, wenn mehr als ..:
|
||||
:rc 1-32767 aufeinanderfolgende Samples unterhalb der :rx-Schwelle liegen.
|
||||
:xo :xx :xc wie :ro :rx :rc, aber für den Sendeteil.
|
||||
|
||||
|
||||
Befehlsinterpreter "proto"
|
||||
|
@ -830,8 +925,13 @@ Alle Zeitangaben sind in Sekunden.
|
|||
:lo dto, bei abgehenden Verbindungen
|
||||
:lb dto, beide Verbindungsarten (Default).
|
||||
|
||||
Vorsicht: Es macht keinen Sinn, den Timer unterhalb von übertragungssichernden
|
||||
Modulen wie x.75 oder gar Datenstrom-Modulen wie v110 anzuordnen.
|
||||
Vorsicht: Es macht absolut keinen Sinn, den Timer unterhalb von
|
||||
übertragungssichernden Modulen wie x.75 oder gar Datenstrom-Modulen wie
|
||||
v110 anzuordnen.
|
||||
|
||||
Der Timeout sollte mindestens dreimal so groß sein wie die Zeit, die
|
||||
typischerweise zum Verbindungsaufbau benötigt wird, weil es sonst
|
||||
scheußliche Interaktionen mit den TCP-Retryalgorithmen gebenb kann.
|
||||
|
||||
|
||||
T.70 "t70"
|
||||
|
@ -855,9 +955,9 @@ Van-Jacobsen-Kompression "vanj"
|
|||
------------------------
|
||||
Komprimiert TCP-IP-Header.
|
||||
Sollte nur auf einer gesicherten Verbindung verwendet werden.
|
||||
:ac Aktiv komprimieren. (Default bei abgehenden Verbindungen.)
|
||||
:pa Komprimieren nur, nachdem ein komprimiertes Paket ankam.
|
||||
(Default bei ankommenden Verbindungen.)
|
||||
:ac Aktiv komprimieren. (Default bei abgehenden Verbindungen.)
|
||||
:pa Komprimieren nur, nachdem ein komprimiertes Paket ankam.
|
||||
(Default bei ankommenden Verbindungen.)
|
||||
|
||||
|
||||
X.75 "x75"
|
||||
|
@ -896,6 +996,12 @@ Interframezeichen etc.) wird von der Hardware auf der Karte erledigt.
|
|||
4 wenn der erste Datenblock zur Übertragung ansteht.
|
||||
8 gar nicht -- es werden UI-Frames verwendet.
|
||||
|
||||
pr_on
|
||||
-----
|
||||
Spezialmodul, um die "Verbindung hergestellt"-Kennung auf einem Stream
|
||||
abzusenden, der nicht über ISDN arbeitet. Wird zB vom slipto-Programm
|
||||
verwendet.
|
||||
|
||||
|
||||
Verzeichnisstruktur der Sourcen
|
||||
===================
|
||||
|
@ -913,8 +1019,8 @@ ip_mon/ TCP/IP-Monitorprogramm nebst Streamstreiber/Modul.
|
|||
isdn_2/ Schicht-2-Treiber für ISDN (D-Kanalsteuerung, B-Kanal-Routing).
|
||||
isdn_3/ Schicht-3-Treiber (1TR6 etc.).
|
||||
isdn_4/ Steuerprogramm (besagter wilder Hack).
|
||||
ksupport/ Supportkram für den Kernel, diverse Streamsmodule.
|
||||
strppp/ PPP-Supportmodul, unfertig
|
||||
ksupport/ Supportkram für den Kernel, diverse Streamsmodule,
|
||||
Supportcode für die ISDN-Protokollhandler.
|
||||
reconnect/ Streamsmodul zum dynamischen Wiederaufbau einer Verbindung.
|
||||
strslip/ Streamsmodul für SLIP-Framing.
|
||||
str_if/ Streamsmodul für Anbindung an TCP/IP.
|
||||
|
@ -970,38 +1076,36 @@ Kontrollprogramm f
|
|||
"slip"-Modul via ML-Zeile explizit eingesetzt werden.
|
||||
|
||||
-d eine "Default"-Route zur Gegenseite wird eingerichtet.
|
||||
-L Standleitungsbetrieb; protokolliert den Dialog zum Modem.
|
||||
-l Debugging; setzt qinfo-Modul ein.
|
||||
-l zusätzlich count-Modul.
|
||||
-l zusätzlich strlog-Modul.
|
||||
-M Standleitungsbetrieb; setzt IP-Monitor-Modul ein.
|
||||
-S Standleitungs/Dialupbetrieb auf synchroner Leitung: verwende kein
|
||||
"slip"-Modul.
|
||||
-m mtu setzt die MTU auf den angegebenen Wert. (Die MRU ist auf 4000 Bytes
|
||||
begrenzt.)
|
||||
-o Standleitungsbetrieb; schickt ATA zur Leitung und wartet auf CONNECT.
|
||||
-p dev Standleitungs- oder Dialupbetrieb; öffnet Device "dev". (/dev/tty
|
||||
für stdin/out)
|
||||
-v schaltet Van-Jacobsen-Headerkompression ein.
|
||||
-f schaltet Cisco-HDLC-Header ein.
|
||||
-R ip die IP-Nummer "ip" wird zur Gegenseite geroutet. (route -host)
|
||||
-r ip Das IP-Netz "ip" wird zur Gegenseite geroutet. (route -net)
|
||||
-r ip:nm Das IP-Netz "ip" wird mit der Netmask "nm" zur Gegenseite geroutet.
|
||||
ip_loc lokale IP-Nummer.
|
||||
Es muß sich dabei nicht unbedingt um die IP-Nummer handeln, die
|
||||
die Gegenstelle von uns erwartet; es reicht, wenn die Gegenseite
|
||||
die verwendete Nummer zu uns routet und die dort konfigurierte Nummer
|
||||
lokal erkannt wird. Um das zu erreichen, ist der Befehl
|
||||
% ifconfig lo0 alias <Erwartete_IP_Nr>
|
||||
(BSD), bzw.
|
||||
% ifconfig dummyX <IP-Nr> ; route add <IP-Nr>
|
||||
(Linux) sehr hilfreich.
|
||||
ip_rem IP-Nummer der Gegenstelle
|
||||
Es muß sich dabei nicht unbedingt um die IP-Nummer handeln, die
|
||||
die Gegenseite auf ihrem Interface konfiguriert hat; es reicht,
|
||||
wenn es eine ist, die irgendwo am anderen Ende der Leitung existiert.
|
||||
Solche 'wilden' Konfigurationen sollte man zwar vermeiden, aber...
|
||||
|
||||
Die folgenden Optionen werden _nicht_ im ISDN-Betrieb verwendet, sondern im
|
||||
Standalonebetrieb mit anderen Streams-Treibern. Im ISDN-Betrieb müssen
|
||||
stattdessen die entsprechenden Module auf der ML-Konfigurationszeile
|
||||
eingetragen werden.
|
||||
|
||||
-L protokolliert den Dialog zum Modem.
|
||||
-l Debugging: setzt qinfo-Modul ein.
|
||||
-ll zusätzlich count-Modul.
|
||||
-lll zusätzlich strlog-Modul.
|
||||
-M setzt IP-Monitor-Modul ein.
|
||||
-S Betrieb auf synchroner Leitung: verwende kein "slip"-Modul.
|
||||
-E Autoenable; wenn slipto auf einer bestehenden Verbindung gestartet
|
||||
wird.
|
||||
-o schickt ATA zur Leitung und wartet auf CONNECT.
|
||||
-p dev öffnet Device "dev". (Man verwende "/dev/tty" für stdin/out.)
|
||||
-v verwende Van-Jacobsen-Headerkompression.
|
||||
-f verwende Cisco-HDLC-Header.
|
||||
|
||||
Die folgenden Parameter müssen immer angegeben werden:
|
||||
|
||||
ip_loc lokale IP-Nummer.
|
||||
Kann auch auf anderen Interfaces (Ethernet) verwendet werden!
|
||||
ip_rem IP-Nummer der Gegenstelle.
|
||||
Die beiden Nummern muessen nicht im gleichen Netz sein!
|
||||
|
||||
Hackers Corner
|
||||
==============
|
||||
|
|
52
Makefile
52
Makefile
|
@ -1,17 +1,47 @@
|
|||
|
||||
all: isdn
|
||||
# config and include are first, final is last
|
||||
DIRS = config compat streams include bin support isdn_3 isdn_4 \
|
||||
ksupport isdn_2 str_if van_j cards x75 alaw \
|
||||
v110 pr_on strslip fakeh t70 rate timer reconnect ip_mon final
|
||||
ADIRS = config include bin support isdn_3 isdn_4 str_if ip_mon alaw tools
|
||||
KDIRS = config compat streams include ksupport isdn_2 str_if van_j cards x75 \
|
||||
alaw v110 pr_on strslip fakeh t70 rate timer reconnect ip_mon final
|
||||
# dumbmgr portman port_m
|
||||
|
||||
isdn: dummy
|
||||
make -C isdn
|
||||
SYSTEMS = linux
|
||||
#SYSTEMS = aux sco svr4 linux
|
||||
|
||||
depend dep:
|
||||
make -C isdn depend
|
||||
all prog:: .depend
|
||||
|
||||
load:
|
||||
make -C isdn load
|
||||
.depend:
|
||||
make depend
|
||||
touch .depend
|
||||
|
||||
clean:
|
||||
make -C isdn clean
|
||||
-rm .toldem
|
||||
all update load::
|
||||
set -e;for i in $(KDIRS);do echo "make $@ in $$i:" && make -C $$i $@ ; done
|
||||
|
||||
prog::
|
||||
set -e;for i in $(ADIRS);do echo "make $@ in $$i:" && make -C $$i $@ ; done
|
||||
|
||||
depend clean indent::
|
||||
set -e;for i in $(DIRS);do echo "make $@ in $$i:" && make -C $$i $@ ; done
|
||||
|
||||
install: all
|
||||
make -C final doinstall
|
||||
|
||||
conf:
|
||||
cd config ; make
|
||||
|
||||
clean::
|
||||
@for i in $(ALLDIRS) ; do ( cd $$i; \
|
||||
for j in $(SYSTEMS) ; do echo $$i/$$j ; \
|
||||
sh ../iftrue.sh "-d $$j" "cd $$j ; make clean" ; done \
|
||||
) ; done
|
||||
find . -name .depend -print|xargs rm -f
|
||||
|
||||
iprog: prog
|
||||
cd final && make install.bin
|
||||
|
||||
|
||||
dep: depend
|
||||
|
||||
dummy:
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
[ This is a German version. An English version is in the works. ]
|
||||
|
||||
Die Anleitung und der ganze Kram findet sich in der Datei DOKU, oder
|
||||
README.isdn in den Kernelsourcen.
|
||||
|
||||
|
||||
*** 1995-09-31
|
||||
|
||||
Release 13.
|
||||
|
||||
Wenn es immer noch Probleme beim ISDN-Login gibt: am Anfang von
|
||||
streams/streams_io das #undef in ein #define ändern, isdn_2.o mit
|
||||
"mod2=0x05" installieren, nochmal testen, mir den Syslog-Output schicken
|
||||
(*.debug, NICHT *.=debug !!!). Vorsicht, Paßwörter etc. stehen in diesem
|
||||
Log mit drin!
|
||||
|
||||
Wegen eines Fehlers im GNU-Make kann es passieren, daß "make" oder "make -w"
|
||||
nicht funktioniert. In diesem Fall "make --warn" verwenden.
|
||||
|
||||
|
||||
Die folgenden neuen Features sind noch mehr oder weniger ungetestet:
|
||||
SIGIO-Support.
|
||||
TTY-Code repariert.
|
||||
Starten beliebiger Programme bei Zustandsänderungen (RP-Zeile in der Konfig).
|
||||
Ethertype-Support (noch nicht vollständig).
|
||||
Callback wenn möglich auf derselben Leitung.
|
||||
Callback auf Leitung B, wenn ein Ruf auf A ankommt, dort aber besetzt ist.
|
||||
|
||||
Einigermaßen getestet:
|
||||
Callback. (War das ein Nerv. Manche ISDN-Vermittlungen sind _doof_.)
|
||||
|
||||
Fehlermeldungen reorganisiert.
|
||||
|
||||
|
||||
*** 1995-07-22
|
||||
|
||||
isdn_4/master.c aufgesplittet, Verzeichnisstruktur leicht umgebaut,
|
||||
deshalb leider keine Diffs.
|
||||
|
||||
|
||||
*** 1995-06-12
|
||||
|
||||
Wieder ein paar Bugs weniger.
|
||||
|
||||
Der "arnet"-Treiber ist fuer die synchronen Karten dieser Firma gedacht und
|
||||
noch nicht 100% ausgetestet.
|
||||
|
||||
Wenn jemand Uebermittlung von Gebuehreninformationen waehrend der
|
||||
Verbindung im Euro-ISDN aktiviert hat -> Mail an mich.
|
||||
|
||||
Support fuer Standleitungen: Restart klemmt manchmal.
|
||||
|
||||
Die Patches basieren auf aelteren Kernelversionen und sind nicht besonders
|
||||
sauber...
|
||||
|
||||
Support fuer Kernel 1.3 ist in Arbeit.
|
||||
|
||||
|
||||
*** 1995-02-04
|
||||
|
||||
Euro-ISDN! Relativ rudimentär, sollte aber erstmal tun.
|
||||
(In der Doku steht was von FINGER WEG. Vorsicht -- ich garantiere nicht,
|
||||
daß sich der Kram nicht total danebenbenimmt. Ich wage es aber zu
|
||||
bezweifeln, daß mein Treiber dazu führt, daß der Anschluß gesperrt wird...)
|
||||
|
||||
Support für 128kBit-Standleitungen.
|
||||
|
||||
rm -rf streams/isdn isdn/cards/leonardo (für Leute, die den Patch
|
||||
verwenden).
|
||||
|
||||
|
||||
*** 1995-01-18
|
||||
|
||||
Na endlich... modularisierte Version, basierend auf 1.1.83.
|
||||
_Ohne_ Spezialkram (OK, ein kleines bißchen ;-) nachdem das Linux-TCP/IP
|
||||
endlich einen brauchbaren Status erreicht zu haben scheint.
|
||||
|
||||
|
||||
*** 1994-10-27
|
||||
|
||||
Interimsrelease, basierend auf 1.1.57.
|
||||
In libc.tar.gz beginden sich die letzten 4.5.26-Libraries und Include-
|
||||
dateien, angepaßt auf meinen Kernel. (Die nächste Version, basierend auf
|
||||
4.6.xx, ist weit weniger schlimm.)
|
||||
|
||||
In kernel.tar.gz sind die Quellen fuer den angepassten Kernel, komplett.
|
||||
|
||||
Konfiguration:
|
||||
CONFIG_SCHEDULER_BSD Y
|
||||
CONFIG_INET_BSD N
|
||||
CONFIG_MALLOC_TRACE Y
|
||||
CONFIG_DEBUG_LATENCY N
|
||||
|
||||
Alles andere (fast) wie gewohnt. Ohne MALLOC-TRACE gibt es Probleme mit
|
||||
der Speicherverwaltung; wenn jemand den Fehler findet, immer nur her mit
|
||||
einem Patch.
|
||||
|
||||
INET_BSD braucht BSD-Utilities für die Konfiguration, die ich momentan
|
||||
nicht im Source habe (Plattenfehler).
|
||||
|
||||
Die Übersetzung des Streams-Teils liefert haufenweise Warnings; ignorieren.
|
||||
|
||||
|
||||
*** 1994-08-07
|
||||
|
||||
Die Datei /usr/include/sys/conf.h muss die folgende Zeile enthalten:
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
Sorry; dieser Fehler wird mit dem naechsten Update behoben.
|
||||
|
||||
|
||||
*** 1994-08-03
|
||||
|
||||
Patch 38 passt sauber in den Kern.
|
||||
Festverbindungen tun; Patch (inkl. Update auf -38) folgt demnaechst.
|
||||
|
||||
|
||||
*** 1994-08-01
|
||||
|
||||
CONFIG_MALLOC_TRACE funktioniert nicht korrekt (Speicherverluste). Ich
|
||||
arbeite dran.
|
||||
|
||||
|
||||
*** 1994-07-31
|
||||
|
||||
Festverbindungen werden unterstützt.
|
||||
Diffs auf PL37 generiert.
|
||||
Networking-Code generiert.
|
||||
include- und libc-Diffs generiert.
|
||||
|
||||
|
||||
*** 1994-07-29
|
||||
|
||||
In der Datei streams/isdn/config/config.data muss die Variable STR_IN von
|
||||
"in2" auf "linux" geaendert werden, wenn mit Linux-Networking gearbeitet
|
||||
werden soll.
|
||||
|
||||
|
||||
*** 1994-07-27
|
||||
|
||||
Patch 36 läßt sich problemlos einspielen.
|
||||
|
||||
|
||||
*** 1994-07-26
|
||||
|
||||
Die Datei "kernel-1.1.35.diff.gz" enthält die Diffs zu meinem Kernel.
|
||||
"streams-1.1.35.tar.gz" enthält den Streams-Teil (notwendig!).
|
||||
|
||||
Warnung: Da ich selber leicht modifizierte Includedateien unter
|
||||
/usr/include einsetze, kann es sein, daß die Kompilation nicht
|
||||
durchläuft... in diesem Fall bitte Mail an mich.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
Euro-ISDN
|
||||
Hauptprogramm gewaltig aufraeumen
|
||||
PPP einbauen.
|
||||
Hauptprogramm weiter aufraeumen
|
||||
Protokollstack vom Hauptmodul aus aufbauen
|
||||
Anklinken anderer Treiber (intelligente ISDN-Karten, serielle Schnittstellen)
|
||||
Mehr Features fuer 1TR6
|
||||
|
@ -9,7 +9,6 @@ proto-Treiber um Signalisierung erweitern
|
|||
DOKU verbessern (jaja...)
|
||||
|
||||
Bekannte Fehler:
|
||||
Gelegentlich vergisst das System, eine L3-Connection freizugeben
|
||||
Das Handling von knappen Streams-Datenbloecken ist verbesserungsbeduerftig.
|
||||
|
||||
Moegliche Probleme:
|
|
@ -4,15 +4,15 @@ MAKE = make
|
|||
P =
|
||||
|
||||
## =()<CCU = @<CCU>@>()=
|
||||
CCU = gcc-elf -g
|
||||
CCU = gcc
|
||||
## =()<CC = @<CC>@>()=
|
||||
CC = gcc
|
||||
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
|
||||
CFLAGS = -O2 -Wall $(DEFS)
|
||||
## =()<DEFSN = @<DEFS>@ >()=
|
||||
DEFSN = -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd
|
||||
DEFSN = -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd
|
||||
## =()<NCFLAGS = @<CFLAGS>@ $(DEFSN)>()=
|
||||
NCFLAGS = -O2 -Wall $(DEFSN)
|
||||
## =()<LIBS = @<LIBS>@>()=
|
||||
|
@ -57,7 +57,7 @@ clean:
|
|||
depend: Makefile $(SOURCES)
|
||||
$(CC) -M $(DEFS) $(SOURCES) > .depend
|
||||
|
||||
load: all
|
||||
load:
|
||||
insmod alaw.o
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
|
@ -27,12 +27,7 @@
|
|||
/*
|
||||
* Standard Streams stuff.
|
||||
*/
|
||||
static struct module_info alaw_minfo_w =
|
||||
{
|
||||
0, "alaw", 0, INFPSZ, 4000, 1000
|
||||
};
|
||||
|
||||
static struct module_info alaw_minfo_r =
|
||||
static struct module_info alaw_minfo =
|
||||
{
|
||||
0, "alaw", 0, INFPSZ, 10000, 2000
|
||||
};
|
||||
|
@ -44,12 +39,12 @@ static qf_srv alaw_rsrv, alaw_wsrv;
|
|||
|
||||
static struct qinit alaw_rinit =
|
||||
{
|
||||
alaw_rput, alaw_rsrv, alaw_open, alaw_close, NULL, &alaw_minfo_r, NULL
|
||||
alaw_rput, alaw_rsrv, alaw_open, alaw_close, NULL, &alaw_minfo, NULL
|
||||
};
|
||||
|
||||
static struct qinit alaw_winit =
|
||||
{
|
||||
alaw_wput, alaw_wsrv, NULL, NULL, NULL, &alaw_minfo_w, NULL
|
||||
alaw_wput, alaw_wsrv, NULL, NULL, NULL, &alaw_minfo, NULL
|
||||
};
|
||||
|
||||
struct streamtab alawinfo =
|
||||
|
@ -91,9 +86,10 @@ alaw_proto (queue_t * q, mblk_t * mp)
|
|||
struct alaw_ *alaw = (struct alaw_ *) q->q_ptr;
|
||||
streamchar *origmp = mp->b_rptr;
|
||||
ushort_t id;
|
||||
int error = 0;
|
||||
|
||||
/* In case we want to printf("%s") this... */
|
||||
if (mp->b_wptr < mp->b_datap->db_lim)
|
||||
if (mp->b_wptr < DATA_END(mp))
|
||||
*mp->b_wptr = '\0';
|
||||
if (m_getid (mp, &id) != 0) {
|
||||
mp->b_rptr = origmp;
|
||||
|
@ -107,53 +103,50 @@ alaw_proto (queue_t * q, mblk_t * mp)
|
|||
|
||||
while (mp != NULL && m_getsx (mp, &id) == 0)
|
||||
switch (id) {
|
||||
err:
|
||||
printf (" :Err %s\n", mp->b_rptr);
|
||||
mp->b_rptr = origmp;
|
||||
freemsg (mp);
|
||||
mp = NULL;
|
||||
default:
|
||||
goto err;
|
||||
case PROTO_MODULE:
|
||||
break;
|
||||
case ALAW_LAW:
|
||||
printf ("ALAW: Only A-Law supported\n");
|
||||
goto err;
|
||||
case ALAW_RVCO_ON:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if (z < 0 || z > 127)
|
||||
goto err;
|
||||
alaw->r.on = z;
|
||||
break;
|
||||
case ALAW_RVCO_OFF:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if (z < 0 || z > 127)
|
||||
goto err;
|
||||
alaw->r.off = z;
|
||||
break;
|
||||
case ALAW_RVCO_CNT:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if (z < 50 || z > 65535)
|
||||
goto err;
|
||||
alaw->r.count = z;
|
||||
break;
|
||||
case ALAW_XVCO_ON:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if (z < 0 || z > 127)
|
||||
goto err;
|
||||
alaw->w.on = z;
|
||||
break;
|
||||
case ALAW_XVCO_OFF:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if (z < 0 || z > 127)
|
||||
goto err;
|
||||
alaw->w.off = z;
|
||||
break;
|
||||
case ALAW_XVCO_CNT:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if (z < 50 || z > 65535)
|
||||
goto err;
|
||||
|
@ -173,6 +166,10 @@ alaw_proto (queue_t * q, mblk_t * mp)
|
|||
mp->b_rptr = origmp;
|
||||
putnext (q, mp);
|
||||
}
|
||||
return;
|
||||
err:
|
||||
mp->b_rptr = origmp;
|
||||
m_reply (q, mp, error ? error : -EINVAL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -205,7 +202,7 @@ alaw_mute (mblk_t * mb, struct _vco *vco)
|
|||
|
||||
if (mz != NULL) {
|
||||
short sz;
|
||||
mz->b_datap->db_type = mb->b_datap->db_type;
|
||||
DATA_TYPE(mz) = DATA_TYPE(mb);
|
||||
|
||||
bcopy (mb->b_rptr, mz->b_wptr, (sz = blkend - (uchar_t *) mb->b_rptr));
|
||||
mz->b_wptr += sz;
|
||||
|
@ -282,17 +279,13 @@ static char cswap[256] =
|
|||
|
||||
/* Streams code to open the driver. */
|
||||
static int
|
||||
alaw_open (queue_t * q, dev_t dev, int flag, int sflag
|
||||
#ifdef DO_ADDERROR
|
||||
,int *err
|
||||
#endif
|
||||
)
|
||||
alaw_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
|
||||
{
|
||||
register struct alaw_ *alaw;
|
||||
|
||||
alaw = malloc(sizeof(*alaw));
|
||||
if(alaw == NULL)
|
||||
return OPENFAIL;
|
||||
ERR_RETURN(-ENOMEM);
|
||||
memset(alaw,0,sizeof(*alaw));
|
||||
|
||||
WR (q)->q_ptr = (char *) alaw;
|
||||
|
@ -301,9 +294,6 @@ alaw_open (queue_t * q, dev_t dev, int flag, int sflag
|
|||
alaw->q = q;
|
||||
alaw__init (alaw);
|
||||
|
||||
if (0)
|
||||
printf ("ALAW pseudo-driver %d opened.\n", dev);
|
||||
|
||||
MORE_USE;
|
||||
return 0;
|
||||
}
|
||||
|
@ -318,8 +308,7 @@ alaw_close (queue_t * q, int dummy)
|
|||
|
||||
flushq (q, FLUSHALL);
|
||||
flushq (WR (q), FLUSHALL);
|
||||
if (0)
|
||||
printf ("ALAW driver closed.\n");
|
||||
|
||||
free(alaw);
|
||||
LESS_USE;
|
||||
return;
|
||||
|
@ -330,20 +319,18 @@ alaw_close (queue_t * q, int dummy)
|
|||
static void
|
||||
alaw_wput (queue_t * q, mblk_t * mp)
|
||||
{
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
putq (q, mp);
|
||||
break;
|
||||
case M_FLUSH:
|
||||
if (*mp->b_rptr & FLUSHW)
|
||||
flushq (q, FLUSHDATA);
|
||||
/* FALL THRU */
|
||||
default:
|
||||
putnext (q, mp);
|
||||
break;
|
||||
default:{
|
||||
putnext (q, mp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -356,11 +343,12 @@ alaw_wsrv (queue_t * q)
|
|||
mblk_t *mp;
|
||||
|
||||
while ((mp = getq (q)) != NULL) {
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
alaw_proto (q, mp);
|
||||
break;
|
||||
CASE_DATA {
|
||||
case CASE_DATA:
|
||||
{
|
||||
mblk_t *mr;
|
||||
|
||||
if (!canput (q->q_next)) {
|
||||
|
@ -388,7 +376,7 @@ alaw_wsrv (queue_t * q)
|
|||
flushq (q, FLUSHDATA);
|
||||
/* FALL THRU */
|
||||
default:
|
||||
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
|
||||
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
|
||||
putnext (q, mp);
|
||||
continue;
|
||||
} else {
|
||||
|
@ -404,7 +392,7 @@ alaw_wsrv (queue_t * q)
|
|||
static void
|
||||
alaw_rput (queue_t * q, mblk_t * mp)
|
||||
{
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
|
||||
case M_FLUSH:
|
||||
if (*mp->b_rptr & FLUSHR) {
|
||||
|
@ -413,7 +401,7 @@ alaw_rput (queue_t * q, mblk_t * mp)
|
|||
putnext (q, mp); /* send it along too */
|
||||
break;
|
||||
case MSG_PROTO:
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
putq (q, mp); /* queue it for my service routine */
|
||||
break;
|
||||
|
||||
|
@ -433,11 +421,12 @@ alaw_rsrv (queue_t * q)
|
|||
register struct alaw_ *alaw = (struct alaw_ *) q->q_ptr;
|
||||
|
||||
while ((mp = getq (q)) != NULL) {
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
alaw_proto (q, mp);
|
||||
break;
|
||||
CASE_DATA {
|
||||
case CASE_DATA:
|
||||
{
|
||||
mblk_t *mr;
|
||||
|
||||
if (!canput (q->q_next)) {
|
||||
|
@ -459,12 +448,13 @@ alaw_rsrv (queue_t * q)
|
|||
}
|
||||
if ((mr = alaw_mute (mp, &alaw->r)) != NULL)
|
||||
putnext (q, mr);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
case M_HANGUP:
|
||||
case M_ERROR:
|
||||
/* FALL THRU */
|
||||
default:
|
||||
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
|
||||
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
|
||||
putnext (q, mp);
|
||||
continue;
|
||||
} else {
|
|
@ -4,6 +4,7 @@ all prog:
|
|||
rm -f slipto; ln -s ../str_if/slipto .
|
||||
rm -f toalaw; ln -s ../alaw/toalaw .
|
||||
rm -f tosnd; ln -s ../alaw/tosnd .
|
||||
rm -f cardname; ln -s ../tools/cardname .
|
||||
|
||||
clean:
|
||||
rm -f master
|
||||
|
@ -11,7 +12,8 @@ clean:
|
|||
rm -f slipto
|
||||
rm -f toalaw
|
||||
rm -f tosnd
|
||||
rm -f cardname
|
||||
|
||||
install update depend indent load:
|
||||
echo "Nothing to be done."
|
||||
@echo "Nothing to be done."
|
||||
|
|
@ -35,7 +35,8 @@ if test -d $in ; then
|
|||
done
|
||||
thefile=$in/$pid.$file
|
||||
cd ..
|
||||
tee $thefile | ( set +e; tosnd 3 mac.smurf.noris.de ; cat >/dev/null )
|
||||
cat > $thefile
|
||||
#tee $thefile | ( set +e; tosnd 3 mac.smurf.noris.de ; cat >/dev/null )
|
||||
if test -s $thefile ; then
|
||||
echo "Phone call: $thefile" | mail -s "Phone call" $(ls -l $thefile|awk '{print $3;}' )
|
||||
else
|
|
@ -0,0 +1,5 @@
|
|||
## =()<CARDS = @<CARDS>@>()=
|
||||
CARDS = dumb
|
||||
|
||||
all lib clean depend install update indent load:
|
||||
@set -e; for i in $(CARDS) ; do $(MAKE) $(MAKEFLAGS) -C $$i $@ ; done
|
|
@ -5,8 +5,8 @@ P =
|
|||
|
||||
## =()<CC = @<CC>@>()=
|
||||
CC = gcc
|
||||
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
## =()<DEFS = @<DEFCARDS>@ @<KERNEL>@ -I../../include >()=
|
||||
DEFS = -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../../include
|
||||
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
|
||||
CFLAGS = -O2 -Wall $(DEFS)
|
||||
## =()<RANLIB = @<RANLIB>@>()=
|
||||
|
@ -34,7 +34,7 @@ indent:
|
|||
depend: Makefile $(SOURCES)
|
||||
$(CC) -M $(DEFS) $(SOURCES) > .depend
|
||||
|
||||
load: all
|
||||
load:
|
||||
insmod arnet.o
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
|
@ -0,0 +1,2 @@
|
|||
Diese "arnet"-Karten sind keine ISDN-Karten, sondern Karten mit synchronen
|
||||
seriellen Ports und einem Haufen RAM, um on-board-DMA zu machen.
|
|
@ -1339,8 +1339,8 @@ arnet_init1(struct arnet_info *arn)
|
|||
uchar_t inb3, inb4, inb5, inb6, inbc;
|
||||
unsigned short x;
|
||||
struct arnet_port *arp;
|
||||
ldprintf(".%d.",__LINE__);
|
||||
printf("AR: ");
|
||||
|
||||
printf("Arnet: ");
|
||||
|
||||
arn->usage = 99;
|
||||
bzero(&arn->queue,sizeof(arn->queue));
|
||||
|
@ -1359,12 +1359,10 @@ ldprintf(".%d.",__LINE__);
|
|||
printf("*** region 0x%x..0x%x blocked\n",arn->ioaddr,arn->ioaddr+15);
|
||||
return 0;
|
||||
}
|
||||
request_region(arn->ioaddr,16,"arnet");
|
||||
arn->memsize = 1<<(((inb3&0x1C)>>2)+16);
|
||||
printf("cf %02x: %d kByte, memory at %p, bus %d, adapter %s; %d ports; rev %02x; ", inb3, arn->memsize>>10, arn->membase, inb3&3, astr(inb3>>5), inb5, inb4);
|
||||
if((unsigned long)arn->membase & 0xFF003FFF) {
|
||||
printf("*** invalid membase: 0x%p\n",arn->membase);
|
||||
release_region(arn->ioaddr,16);
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
|
@ -1379,6 +1377,10 @@ ldprintf(".%d.",__LINE__);
|
|||
|
||||
}
|
||||
arn->nports = inb5;
|
||||
if(arn->nports != 2 && arn->nports != 4) {
|
||||
printf("huh? card with %d ports?\n",arn->nports);
|
||||
return 0;
|
||||
}
|
||||
arn->handshake = inb6;
|
||||
if(inb6 == 0)
|
||||
printf("no control/status lines; ");
|
||||
|
@ -1420,12 +1422,6 @@ ldprintf(".%d.",__LINE__);
|
|||
case 15: inbc = 7; break;
|
||||
default:
|
||||
printf("*** unknown IRQ %d\n",arn->irq);
|
||||
release_region(arn->ioaddr,16);
|
||||
return 0;
|
||||
}
|
||||
if((arn->irq != 0) && request_irq(arn->irq,arnet_intr,0 /* SA_INTERRUPT */,"arnet")) {
|
||||
printf("*** IRQ %d not available\n",arn->irq);
|
||||
release_region(arn->ioaddr,16);
|
||||
return 0;
|
||||
}
|
||||
inbc <<= 1;
|
||||
|
@ -1459,29 +1455,27 @@ ldprintf(".%d.",__LINE__);
|
|||
if(MEM(char,arn,0x33) != 0xAA) {
|
||||
if((arn->nports <= 2) || (MEM(char,arn,0x33) != 0x5A)) {
|
||||
printf("ERROR: Readback A, %02x\n", MEM(char,arn,0x33));
|
||||
goto GetOut;
|
||||
return 0;
|
||||
}
|
||||
printf("ERROR: second chip unselectable A, %02x\n", MEM(char,arn,0x33));
|
||||
arn->nports -= 1;
|
||||
return 0;
|
||||
}
|
||||
if(MEM(char,arn,0x53) != 0x55) {
|
||||
if((arn->nports <= 2) || (MEM(char,arn,0x53) != 0xA5)) {
|
||||
printf("ERROR: Readback B, %02x\n", MEM(char,arn,0x53));
|
||||
goto GetOut;
|
||||
return 0;
|
||||
}
|
||||
printf("ERROR: second chip unselectable B, %02x\n", MEM(char,arn,0x53));
|
||||
arn->nports -= 1;
|
||||
return 0;
|
||||
}
|
||||
if(arn->nports == 3)
|
||||
arn->nports --;
|
||||
if(arn->nports > 2) {
|
||||
arnet_page(arn,ADDR_SCA1);
|
||||
if(MEM(char,arn,0x33) != 0x5A) {
|
||||
printf("ERROR: Readback C, %02x\n", MEM(char,arn,0x33));
|
||||
arn->nports -= 2;
|
||||
return 0;
|
||||
} else if(MEM(char,arn,0x53) != 0xA5) {
|
||||
printf("ERROR: Readback D, %02x\n", MEM(char,arn,0x53));
|
||||
arn->nports -= 2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1494,15 +1488,14 @@ ldprintf(".%d.",__LINE__);
|
|||
MEM(char,arn,0x53) = 0xFF;
|
||||
}
|
||||
|
||||
if((arn->irq != 0) && request_irq(arn->irq,arnet_intr,0 /* SA_INTERRUPT */,"arnet")) {
|
||||
printf("*** IRQ %d not available\n",arn->irq);
|
||||
return 0;
|
||||
}
|
||||
request_region(arn->ioaddr,16,"arnet");
|
||||
printf("\n");
|
||||
arn->usage = 0;
|
||||
return 1;
|
||||
|
||||
GetOut:
|
||||
if(arn->irq != 0)
|
||||
free_irq(arn->irq);
|
||||
release_region(arn->ioaddr,16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1542,14 +1535,7 @@ ddprintf("l ");
|
|||
|
||||
/* Streams code to open the driver. */
|
||||
static int
|
||||
arnet_open (queue_t * q, dev_t dev, int flag, int sflag
|
||||
#ifdef DO_ADDERROR
|
||||
,int *err
|
||||
#define U_ERROR *err
|
||||
#else
|
||||
#define U_ERROR u.u_error
|
||||
#endif
|
||||
)
|
||||
arnet_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
|
||||
{
|
||||
struct arnet_info *arn = arnet_list;
|
||||
struct arnet_port *arp;
|
||||
|
@ -1567,8 +1553,7 @@ ddprintf("n ");
|
|||
mdev --;
|
||||
}
|
||||
if(mdev == 0) {
|
||||
U_ERROR = ENXIO;
|
||||
return OPENFAIL;
|
||||
ERR_RETURN(-ENXIO);
|
||||
}
|
||||
arn->usage++;
|
||||
arp = &arn->port[cdev];
|
||||
|
@ -1593,8 +1578,7 @@ ddprintf("n ");
|
|||
q->q_ptr = NULL;
|
||||
WR(q)->q_ptr = NULL;
|
||||
arp->q = NULL;
|
||||
U_ERROR = -err;
|
||||
return OPENFAIL;
|
||||
ERR_RETURN(err);
|
||||
}
|
||||
arn->usage = 0;
|
||||
if(0)arnet_memdump(arn,"Open");
|
||||
|
@ -1657,9 +1641,9 @@ ldprintf(".%d.",__LINE__);
|
|||
freemsg(mp);
|
||||
return;
|
||||
}
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATATYPE(mp)) {
|
||||
case M_IOCTL:
|
||||
mp->b_datap->db_type = M_IOCNAK;
|
||||
DATA_TYPE(mp) = M_IOCNAK;
|
||||
((struct iocblk *)mp->b_rptr)->ioc_error = EINVAL;
|
||||
qreply (q, mp);
|
||||
break;
|
||||
|
@ -1679,7 +1663,7 @@ ldprintf(".%d.",__LINE__);
|
|||
break;
|
||||
default:
|
||||
log_printmsg (NULL, "Strange ARNET", mp, KERN_WARNING);
|
||||
/* putctl1(RD(q)->b_next, M_ERROR, ENXIO); */
|
||||
/* putctl1(RD(q)->b_next, M_ERROR, -ENXIO); */
|
||||
freemsg (mp);
|
||||
break;
|
||||
}
|
||||
|
@ -1767,7 +1751,7 @@ if(dodebug>1)ddprintf("q ");
|
|||
freemsg (mp);
|
||||
continue;
|
||||
}
|
||||
if (mp->b_datap->db_type >= QPCTL || canput (q->q_next)) {
|
||||
if (DATA_TYPE(mp) >= QPCTL || canput (q->q_next)) {
|
||||
putnext (q, mp);
|
||||
continue;
|
||||
} else {
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,93 @@
|
|||
|
||||
SHELL = /bin/sh
|
||||
MAKE = make
|
||||
## =()<P = @<P>@>()=
|
||||
P =
|
||||
|
||||
## =()<CC = @<CC>@>()=
|
||||
CC = gcc
|
||||
## =()<DEFS = @<DEFCARDS>@ @<KERNEL>@ -I../../include >()=
|
||||
DEFS = -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../../include
|
||||
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
|
||||
CFLAGS = -O2 -Wall $(DEFS)
|
||||
## =()<LD = @<LD>@>()=
|
||||
LD = ld
|
||||
## =()<DUMBCARDS = @<DUMBCARDS>@>()=
|
||||
DUMBCARDS = teles
|
||||
|
||||
## =()<SYS = @<SYS>@>()=
|
||||
SYS = linux
|
||||
|
||||
SOURCES = avm_io.c bsc_io.c teles_io.c ncp_io.c ncp16_io.c shell.c insert.c
|
||||
|
||||
OBJ =
|
||||
ALL = teles.o avm.o bsc.o ncp.o ncp16.o \
|
||||
d_teles.o d_avm.o d_bsc.o d_ncp.o d_ncp16.o
|
||||
|
||||
all: $(foreach c,${DUMBCARDS},$c.o) $(foreach c,${DUMBCARDS},d_$c.o)
|
||||
|
||||
load: $(foreach c,${DUMBCARDS},ins-$c)
|
||||
|
||||
|
||||
avm.o: insert.c
|
||||
$(CC) $(CFLAGS) -DCARDTYPE=avm -o avm.o -c insert.c
|
||||
bsc.o: insert.c
|
||||
$(CC) $(CFLAGS) -DCARDTYPE=bsc -o bsc.o -c insert.c
|
||||
ncp16.o: insert.c
|
||||
$(CC) $(CFLAGS) -DCARDTYPE=ncp16 -o ncp16.o -c insert.c
|
||||
ncp.o: insert.c
|
||||
$(CC) $(CFLAGS) -DCARDTYPE=ncp -o ncp.o -c insert.c
|
||||
teles.o: insert.c
|
||||
$(CC) $(CFLAGS) -DCARDTYPE=teles -o teles.o -c insert.c
|
||||
|
||||
d_avm.o: shell.c avm_io.c
|
||||
$(CC) $(CFLAGS) -D_avm_ -o d_avm.o -c shell.c
|
||||
d_bsc.o: shell.c bsc_io.c
|
||||
$(CC) $(CFLAGS) -D_bsc_ -o d_bsc.o -c shell.c
|
||||
d_ncp16.o: shell.c ncp16_io.c
|
||||
$(CC) $(CFLAGS) -D_ncp16_ -DWIDE -o d_ncp16.o -c shell.c
|
||||
d_ncp.o: shell.c ncp_io.c
|
||||
$(CC) $(CFLAGS) -D_ncp_ -o d_ncp.o -c shell.c
|
||||
d_teles.o: shell.c teles_io.c
|
||||
$(CC) $(CFLAGS) -D_teles_ -o d_teles.o -c shell.c
|
||||
|
||||
ins-avm:
|
||||
insmod d_avm.o
|
||||
insmod avm.o
|
||||
ins-bsc:
|
||||
insmod d_bsc.o
|
||||
insmod bsc.o
|
||||
ins-teles:
|
||||
insmod d_teles.o
|
||||
insmod teles.o
|
||||
ins-ncp:
|
||||
insmod d_ncp.o
|
||||
insmod ncp.o
|
||||
ins-ncp16:
|
||||
insmod d_ncp16.o
|
||||
insmod ncp16.o
|
||||
|
||||
lib:
|
||||
|
||||
indent:
|
||||
../../indent.sh $(SOURCES)
|
||||
|
||||
depend: Makefile $(SOURCES)
|
||||
cp /dev/null .depend
|
||||
for i in avm ncp teles bsc ; do $(CC) -D_$${i}_ -M $(DEFS) shell.c |\
|
||||
sed -e "s/shell\.o/X$${i}.o/" >> .depend ; done
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(ALL)
|
||||
|
||||
install: all
|
||||
@sh ../../iftrue.sh "-d $(SYS)" "cd $(SYS); make"
|
||||
|
||||
update: all
|
||||
@sh ../../iftrue.sh "-d $(SYS)" "cd $(SYS); make update"
|
||||
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
|
|
@ -50,6 +50,9 @@ static int Init(struct _dumb * dumb) {
|
|||
Byte foo;
|
||||
unsigned int step = 0;
|
||||
|
||||
if(dumb->ioaddr == 0)
|
||||
return -EINVAL;
|
||||
dumb->numHSCX = 2;
|
||||
save_flags(flags);
|
||||
sti();
|
||||
timout = jiffies+1;
|
||||
|
@ -104,7 +107,7 @@ static int Init(struct _dumb * dumb) {
|
|||
default:
|
||||
def:
|
||||
printf(" AIRQR %02x, step %d ",foo,step);
|
||||
return 0;
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
Exit:
|
||||
|
@ -121,7 +124,7 @@ static int Init(struct _dumb * dumb) {
|
|||
|
||||
ByteOut(dumb->ioaddr+0x1800,0x04);
|
||||
ByteOut(dumb->ioaddr+0x1800,0x08);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void InitISAC(struct _dumb * dumb)
|
|
@ -28,6 +28,9 @@ static int Init(struct _dumb * dumb) {
|
|||
int timout;
|
||||
long flags;
|
||||
|
||||
if(dumb->ioaddr == 0)
|
||||
return -EINVAL;
|
||||
dumb->numHSCX = 2;
|
||||
save_flags(flags);
|
||||
timout = jiffies+(HZ/20)+1;
|
||||
ByteOut(dumb->ioaddr,0x80);
|
||||
|
@ -37,7 +40,7 @@ static int Init(struct _dumb * dumb) {
|
|||
timout = jiffies+(HZ/20)+1;
|
||||
while(jiffies <= timout) ;
|
||||
restore_flags(flags);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static void InitISAC(struct _dumb * dumb)
|
||||
{
|
|
@ -0,0 +1,56 @@
|
|||
#include "f_module.h"
|
||||
#include "isdn_limits.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef linux
|
||||
#include <linux/sched.h>
|
||||
#endif
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
#ifndef CARDTYPE
|
||||
#error "You have to define CARDTYPE for this to work."
|
||||
#endif
|
||||
|
||||
#define xxappxx(a,b) a##b
|
||||
#define NAME(a,b) xxappxx(a,b) /* isn't C wonderful */
|
||||
#define xxstrxx(a) #a
|
||||
#define STRING(a) xxstrxx(a) /* ditto */
|
||||
|
||||
extern int NAME(CARDTYPE,init)(struct _dumb *dumb);
|
||||
extern void NAME(CARDTYPE,exit)(struct _dumb *dumb);
|
||||
|
||||
struct _dumb dumb;
|
||||
|
||||
int irq = 0;
|
||||
int mem = 0;
|
||||
int io = 0;
|
||||
int ipl = 0;
|
||||
int name = 0;
|
||||
int debug = 0;
|
||||
|
||||
#ifdef MODULE
|
||||
static int do_init_module(void)
|
||||
{
|
||||
if(name == 0) {
|
||||
printf("You must name this card: insmod xxx.o name=$(name Foo0)\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dumb.irq = irq;
|
||||
dumb.ipl = ipl;
|
||||
dumb.ioaddr = io;
|
||||
dumb.memaddr = mem;
|
||||
dumb.ID = name;
|
||||
dumb.debug = debug;
|
||||
return NAME(CARDTYPE,init)(&dumb);
|
||||
}
|
||||
|
||||
static int do_exit_module(void)
|
||||
{
|
||||
NAME(CARDTYPE,exit)(&dumb);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#error "This can only be used as a module!"
|
||||
#endif
|
||||
|
|
@ -30,6 +30,9 @@ static int Init(struct _dumb * dumb) {
|
|||
long flags;
|
||||
char iflag;
|
||||
|
||||
if(dumb->ioaddr == 0)
|
||||
return -EINVAL;
|
||||
dumb->numHSCX = 2;
|
||||
save_flags(flags);
|
||||
timout = jiffies+(HZ/20)+1;
|
||||
ByteOut(dumb->ioaddr,0xF0);
|
||||
|
@ -43,7 +46,7 @@ static int Init(struct _dumb * dumb) {
|
|||
case 0: break;
|
||||
default:
|
||||
printf (" unknown card code %d ",ByteIn(dumb->ioaddr) >> 5);
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
}
|
||||
switch(dumb->irq) {
|
||||
case 3: iflag = 0; break;
|
||||
|
@ -57,10 +60,10 @@ static int Init(struct _dumb * dumb) {
|
|||
case 0: iflag = 7; break;
|
||||
default:
|
||||
printf (" impossible irq %d ",dumb->irq);
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
ByteOut(dumb->ioaddr,(iflag<<5));
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void InitISAC(struct _dumb * dumb)
|
|
@ -29,6 +29,9 @@ static int Init(struct _dumb * dumb) {
|
|||
long flags;
|
||||
char iflag;
|
||||
|
||||
if(dumb->ioaddr == 0)
|
||||
return -EINVAL;
|
||||
dumb->numHSCX = 2;
|
||||
save_flags(flags);
|
||||
timout = jiffies+(HZ/20)+1;
|
||||
ByteOut(dumb->ioaddr,0xF0);
|
||||
|
@ -42,7 +45,7 @@ static int Init(struct _dumb * dumb) {
|
|||
case 0: break;
|
||||
default:
|
||||
printf (" unknown card code %d ",ByteIn(dumb->ioaddr) >> 5);
|
||||
return 0;
|
||||
return -EIO;
|
||||
}
|
||||
switch(dumb->irq) {
|
||||
case 3: iflag = 0; break;
|
||||
|
@ -55,10 +58,10 @@ static int Init(struct _dumb * dumb) {
|
|||
case 0: iflag = 7; break;
|
||||
default:
|
||||
printf (" impossible irq %d ",dumb->irq);
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
ByteOut(dumb->ioaddr,(iflag<<5));
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void InitISAC(struct _dumb * dumb)
|
|
@ -31,7 +31,6 @@ ADF1 00
|
|||
MOCR 00
|
||||
SQXR 20
|
||||
CMDR 41
|
||||
|
||||
*/
|
||||
#ifdef linux
|
||||
#define SLOW_IO_BY_JUMPING
|
||||
|
@ -46,6 +45,7 @@ CMDR 41
|
|||
#include "isdn_12.h"
|
||||
#include "smallq.h"
|
||||
#include "isdn_limits.h"
|
||||
#include "isdn_proto.h"
|
||||
#include <sys/stream.h>
|
||||
#include "streamlib.h"
|
||||
#include <sys/errno.h>
|
||||
|
@ -85,7 +85,7 @@ CMDR 41
|
|||
|
||||
#define FIFO(x) fifo[(x,0)] /* keep side effects but address at offset zero */
|
||||
|
||||
#include "Config.h"
|
||||
#include "shell.h"
|
||||
|
||||
typedef struct _isac {
|
||||
union {
|
||||
|
@ -200,6 +200,8 @@ typedef struct _hscx {
|
|||
#include "teles_io.c"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define DUMBTIME 300 /* poll: times per second */
|
||||
|
||||
#define xxappxx(a,b) a##b
|
||||
|
@ -212,6 +214,12 @@ void NAME(CARDTYPE,poll)(struct _dumb *dumb);
|
|||
void NAME(CARDTYPE,poll)(void *);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static struct _dumb *dumbmap[16] = { NULL, };
|
||||
|
||||
|
||||
|
||||
static void toggle_off(struct _dumb * dumb)
|
||||
{
|
||||
int i;
|
||||
|
@ -240,8 +248,8 @@ static void toggle_on(struct _dumb * dumb)
|
|||
ByteOutISAC(dumb,MASK,0x00);
|
||||
}
|
||||
|
||||
static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
|
||||
char listen)
|
||||
static int
|
||||
dumb_mode (struct _isdn1_card * card, short channel, char mode, char listen)
|
||||
{
|
||||
struct _dumb * dumb = (struct _dumb *) card;
|
||||
unsigned long ms = SetSPL(dumb->ipl);
|
||||
|
@ -249,7 +257,7 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
|
|||
|
||||
switch(channel) {
|
||||
case 0:
|
||||
DEBUG(info) printf(KERN_INFO "ISDN%d ISAC %s<%d>%s\n",dumb-dumbdata,mode?(mode==1?"standby":"up"):"down",mode,listen?" listen":"");
|
||||
DEBUG(info) printf(KERN_INFO "ISDN ISAC %s<%d>%s\n",mode?(mode==1?"standby":"up"):"down",mode,listen?" listen":"");
|
||||
ISAC_mode(dumb,mode,listen);
|
||||
if(mode == M_OFF) {
|
||||
int j;
|
||||
|
@ -259,12 +267,12 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
|
|||
break;
|
||||
default:
|
||||
if(channel > 0 && channel <= dumb->numHSCX) {
|
||||
DEBUG(info) printf(KERN_INFO "ISDN%d HSCX%d %s<%d>%s\n",dumb-dumbdata,channel,mode?"up":"down",mode,listen?" listen":"");
|
||||
DEBUG(info) printf(KERN_INFO "ISDN HSCX%d %s<%d>%s\n",channel,mode?"up":"down",mode,listen?" listen":"");
|
||||
err = HSCX_mode(dumb,channel,mode,listen);
|
||||
if (err < 0) {
|
||||
printf(KERN_WARNING "ISDN err %d %d\n",channel, err);
|
||||
splx(ms);
|
||||
return -err;
|
||||
return err;
|
||||
}
|
||||
|
||||
dumb->chan[channel].nblk = 0;
|
||||
|
@ -273,7 +281,7 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
|
|||
} else {
|
||||
printf(KERN_WARNING "ISDN badChan %d\n",channel);
|
||||
splx(ms);
|
||||
return EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
NAME(CARDTYPE,poll)(dumb);
|
||||
|
@ -281,15 +289,50 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int dumb_prot (struct _isdn1_card * card, short channel, mblk_t * proto)
|
||||
static int
|
||||
dumb_prot (struct _isdn1_card * card, short channel, mblk_t * mp, int flags)
|
||||
{
|
||||
return EINVAL;
|
||||
struct _dumb * dumb = (struct _dumb *)card;
|
||||
streamchar *origmp = mp->b_rptr;
|
||||
ushort_t id;
|
||||
int error = 0;
|
||||
|
||||
DEBUG(info)printf("Prot chan %d flags 0%o\n",channel,flags);
|
||||
|
||||
if(!(flags & ~CHP_FROMSTACK)) {
|
||||
if ((error = m_getid (mp, &id)) != 0)
|
||||
goto err;
|
||||
switch (id) {
|
||||
default:
|
||||
break;
|
||||
case PROTO_OFFSET:
|
||||
{
|
||||
long z;
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if (z < 0 || z >= 1024) {
|
||||
error = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
if(flags & CHP_FROMSTACK) /* down */
|
||||
dumb->chan[channel].offset = z;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
err:
|
||||
if(mp != NULL) {
|
||||
if (origmp != NULL)
|
||||
mp->b_rptr = origmp;
|
||||
}
|
||||
return (error ? error : isdn2_chprot(card,channel,mp,flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if buffer space is available
|
||||
*/
|
||||
static int dumb_candata (struct _isdn1_card * card, short channel)
|
||||
static int
|
||||
dumb_candata (struct _isdn1_card * card, short channel)
|
||||
{
|
||||
struct _dumb * dumb = (struct _dumb *)card;
|
||||
return (dumb->chan[channel].q_out.nblocks < 4);
|
||||
|
@ -298,7 +341,8 @@ static int dumb_candata (struct _isdn1_card * card, short channel)
|
|||
/*
|
||||
* Enqueue the data.
|
||||
*/
|
||||
static int dumb_data (struct _isdn1_card * card, short channel, mblk_t * data)
|
||||
static int
|
||||
dumb_data (struct _isdn1_card * card, short channel, mblk_t * data)
|
||||
{
|
||||
struct _dumb * dumb = (struct _dumb *)card;
|
||||
S_enqueue(&dumb->chan[channel].q_out, data);
|
||||
|
@ -309,43 +353,45 @@ static int dumb_data (struct _isdn1_card * card, short channel, mblk_t * data)
|
|||
/*
|
||||
* Flush the send queue.
|
||||
*/
|
||||
static int dumb_flush (struct _isdn1_card * card, short channel)
|
||||
static int
|
||||
dumb_flush (struct _isdn1_card * card, short channel)
|
||||
{
|
||||
struct _dumb * dumb = (struct _dumb *)card;
|
||||
S_flush(&dumb->chan[channel].q_out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ISACpresent(struct _dumb *dumb)
|
||||
static int
|
||||
ISACpresent(struct _dumb *dumb)
|
||||
{
|
||||
unsigned char Bt;
|
||||
if(((Bt = ByteInISAC(dumb,STAR)) & ~0x4F) != 0) {
|
||||
printf("<STAR %02x> ",Bt);
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
}
|
||||
if(((Bt = ByteInISAC(dumb,EXIR)) & ~0x10) != 0) {
|
||||
printf("<EXIR %02x> ",Bt);
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
}
|
||||
if(((Bt = ByteInISAC(dumb,RBCH)) & 0x8F) != 0x00) {
|
||||
printf("<RBCH %02x> ",Bt);
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
}
|
||||
ByteOutISAC(dumb,MODE,0xD1);
|
||||
if((Bt = ByteInISAC(dumb,MODE)) != 0xD1) {
|
||||
printf("<MODE %02x> ",Bt);
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
}
|
||||
#if 0
|
||||
if((Bt = ByteInISAC(dumb,RBCL)) != 0) {
|
||||
printf("<RBCL %02x> ",Bt);
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
}
|
||||
#endif
|
||||
ByteOutISAC(dumb,MODE,0xC1);
|
||||
if((Bt = ByteInISAC(dumb,MODE)) != 0xC1) {
|
||||
printf("<MODE %02x> ",Bt);
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -364,7 +410,7 @@ static void ISAC_kick(struct _dumb * dumb)
|
|||
uchar_t *sendp = NULL;
|
||||
|
||||
unsigned long ms = SetSPL(dumb->ipl);
|
||||
DEBUG(isac) printf(KERN_DEBUG "K%d ",dumb-dumbdata);
|
||||
DEBUG(isac) printf(KERN_DEBUG "K ");
|
||||
if(dumb->chan[0].locked) {
|
||||
DEBUG(isac) printf("lck ");
|
||||
splx(ms);
|
||||
|
@ -438,6 +484,8 @@ static void ISAC_kick(struct _dumb * dumb)
|
|||
DEBUG(isac) printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* inline */
|
||||
#endif
|
||||
|
@ -448,7 +496,7 @@ static void HSCX_kick(struct _dumb * dumb, u_char hscx)
|
|||
hdlc_buf bufp = &dumb->chan[hscx];
|
||||
|
||||
unsigned long ms = SetSPL(dumb->ipl);
|
||||
DEBUG(hscxout) printf(KERN_DEBUG "K%d.%d ",dumb-dumbdata,hscx);
|
||||
DEBUG(hscxout) printf(KERN_DEBUG "K.%d ",hscx);
|
||||
if(bufp->locked) {
|
||||
DEBUG(hscxout) { printf("Lck\n"); }
|
||||
splx(ms);
|
||||
|
@ -530,7 +578,7 @@ static void HSCX_kick(struct _dumb * dumb, u_char hscx)
|
|||
ByteInHSCX(dumb,hscx,EXIR)&0x40
|
||||
#endif
|
||||
) { /* XDU */
|
||||
DEBUG(info) printf(KERN_DEBUG "Underrun HSCX %d.%d\n",dumb-dumbdata,hscx);
|
||||
DEBUG(info) printf(KERN_DEBUG "Underrun HSCX.%d\n",hscx);
|
||||
ByteOutHSCX(dumb,hscx,CMDR,0x01);
|
||||
bufp->m_out_run = bufp->m_out;
|
||||
bufp->p_out = bufp->m_out->b_rptr;
|
||||
|
@ -595,6 +643,7 @@ static void HSCX_kick(struct _dumb * dumb, u_char hscx)
|
|||
bufp->locked = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* inline */
|
||||
#endif
|
||||
|
@ -609,9 +658,9 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
|
|||
hdlc_buf bufp = &dumb->chan[hscx];
|
||||
|
||||
#ifdef WIDE
|
||||
DEBUG(hscx) { printf(KERN_DEBUG "%c%d.%d %02x:%02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',dumb-dumbdata,hscx, isr0,isr1); }
|
||||
DEBUG(hscx) { printf(KERN_DEBUG "%c.%d %02x:%02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',hscx, isr0,isr1); }
|
||||
#else
|
||||
DEBUG(hscx) { printf(KERN_DEBUG "%c%d.%d %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',dumb-dumbdata,hscx, Reason); }
|
||||
DEBUG(hscx) { printf(KERN_DEBUG "%c.%d %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',hscx, Reason); }
|
||||
if (hasEX)
|
||||
#endif
|
||||
{
|
||||
|
@ -626,7 +675,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
|
|||
EXIR & 0x80
|
||||
#endif
|
||||
) { /* XMR */
|
||||
DEBUG(info) { printf(KERN_DEBUG "Msg Repeat HSCX %d.%d\n",dumb-dumbdata,hscx); }
|
||||
DEBUG(info) { printf(KERN_DEBUG "Msg Repeat HSCX.%d\n",hscx); }
|
||||
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
|
||||
if (ByteInHSCX(dumb,hscx,STAR) & 0x40) { /* XFW */
|
||||
#ifdef WIDE
|
||||
|
@ -651,7 +700,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
|
|||
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
|
||||
if (bufp->mode >= M_HDLC) {
|
||||
DEBUG(info) {
|
||||
printf(KERN_DEBUG "Xmit Underrun HSCX %d.%d\n",dumb-dumbdata,hscx); }
|
||||
printf(KERN_DEBUG "Xmit Underrun HSCX.%d\n",hscx); }
|
||||
#if NEW_XMIT
|
||||
ByteOutHSCX(dumb,hscx,CMDR, 0x01); /* XRES */
|
||||
#ifdef WIDE
|
||||
|
@ -713,7 +762,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
|
|||
EXIR & 0x10
|
||||
#endif
|
||||
) { /* RFO */
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv overflow HSCX %d.%d\n",dumb-dumbdata,hscx); }
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv overflow HSCX.%d\n",hscx); }
|
||||
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
|
||||
if(
|
||||
#ifdef WIDE
|
||||
|
@ -765,7 +814,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
|
|||
ByteOutHSCX(dumb,hscx,CMDR, 0x80); /* RMC */
|
||||
} else {
|
||||
if ((recvb = bufp->m_in_run) != NULL) {
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + blen > (uchar_t *)recvb->b_datap->db_lim)
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + blen > (uchar_t *)DATA_END(recvb))
|
||||
recvb = NULL;
|
||||
}
|
||||
if (recvb == NULL) {
|
||||
|
@ -804,7 +853,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%02x) HSCX %d.%d\n", RSTA,dumb-dumbdata,hscx); }
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%02x) HSCX.%d\n", RSTA,hscx); }
|
||||
if(bufp->m_in != NULL) {
|
||||
freemsg(bufp->m_in);
|
||||
bufp->m_in = bufp->m_in_run = NULL;
|
||||
|
@ -823,21 +872,27 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
|
|||
mblk_t *recvb;
|
||||
|
||||
if ((recvb = bufp->m_in_run) != NULL) {
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + HSCX_R_FIFO_SIZE > (uchar_t *)recvb->b_datap->db_lim)
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + HSCX_R_FIFO_SIZE > (uchar_t *)DATA_END(recvb))
|
||||
recvb = NULL;
|
||||
}
|
||||
if(0)DEBUG(hscx)printf(":");
|
||||
if (recvb == NULL) {
|
||||
recvb = allocb(HSCX_R_FIFO_SIZE*4,BPRI_MED);
|
||||
if(recvb != NULL) {
|
||||
recvp = recvb->b_wptr;
|
||||
if(bufp->m_in_run == NULL) {
|
||||
bufp->m_in = bufp->m_in_run = recvb;
|
||||
} else {
|
||||
linkb(bufp->m_in_run, recvb);
|
||||
bufp->m_in_run = recvb;
|
||||
if(bufp->m_in_run == NULL) { /* first block */
|
||||
recvb = allocb(HSCX_R_FIFO_SIZE*2+bufp->offset,BPRI_MED);
|
||||
if(recvb != NULL) {
|
||||
recvb->b_wptr += bufp->offset;
|
||||
recvb->b_rptr += bufp->offset;
|
||||
recvp = recvb->b_wptr;
|
||||
bufp->m_in = bufp->m_in_run = recvb;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
recvb = allocb(HSCX_R_FIFO_SIZE*4,BPRI_MED);
|
||||
if(recvb != NULL) {
|
||||
recvp = recvb->b_wptr;
|
||||
linkb(bufp->m_in_run, recvb);
|
||||
bufp->m_in_run = recvb;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(recvb == NULL) {
|
||||
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
|
||||
|
@ -909,7 +964,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
Byte Reason;
|
||||
|
||||
while((Reason = ByteInISAC(dumb,ISTA))) {
|
||||
DEBUG(isac) { printf(KERN_DEBUG "%c%d %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',dumb-dumbdata, Reason); }
|
||||
DEBUG(isac) { printf(KERN_DEBUG "%c %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',Reason); }
|
||||
if (Reason & 0x04) { /* CISQ */
|
||||
Byte CIR = ByteInISAC(dumb,CIR0);
|
||||
|
||||
|
@ -950,7 +1005,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
Byte EXIR = ByteInISAC(dumb,EXIR);
|
||||
DEBUG(isac) { printf(". %x", EXIR); }
|
||||
if (EXIR & 0x80) { /* XMR */
|
||||
DEBUG(info) { printf(KERN_DEBUG "MsgRepeat ISAC %d\n",dumb-dumbdata); }
|
||||
DEBUG(info) { printf(KERN_DEBUG "MsgRepeat ISAC\n"); }
|
||||
CEC(ByteInISAC(dumb,STAR) & 0x04);
|
||||
if (ByteInISAC(dumb,STAR) & 0x40) { /* XFW */
|
||||
Reason |= 0x10; /* also set XPR bit */
|
||||
|
@ -964,7 +1019,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
if (EXIR & 0x40) { /* XDU */
|
||||
CEC(ByteInISAC(dumb,STAR) & 0x04);
|
||||
if (dumb->chan[0].mode >= M_HDLC) {
|
||||
DEBUG(info) { printf(KERN_DEBUG "Xmit Underrun ISAC %d\n",dumb-dumbdata); }
|
||||
DEBUG(info) { printf(KERN_DEBUG "Xmit Underrun ISAC\n"); }
|
||||
#if NEW_XMIT
|
||||
ByteOutISAC(dumb,CMDR, 0x01); /* XRES */
|
||||
Reason |= 0x10;
|
||||
|
@ -986,7 +1041,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
DEBUG(info) { printf(KERN_WARNING "ISDN .PCE\n"); }
|
||||
}
|
||||
if (EXIR & 0x10) { /* RFO */
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv overflow ISAC %d (%02x)\n",dumb-dumbdata, EXIR); }
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv overflow ISAC (%02x)\n", EXIR); }
|
||||
CEC(ByteInISAC(dumb,STAR) & 0x04);
|
||||
if(Reason & 0xC0) {
|
||||
ByteOutISAC(dumb,CMDR, 0xC0); /* RMC|RHR */
|
||||
|
@ -1018,6 +1073,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
blen = (xblen & (ISAC_R_FIFO_SIZE-1));
|
||||
xblen += (ByteInISAC(dumb,RBCH) & 0x0F) << 8;
|
||||
if(blen == 1) {
|
||||
DEBUG(isac) printf(KERN_DEBUG ".R-%d\n",xblen);
|
||||
if((recvb = dumb->chan[0].m_in_run) != NULL) {
|
||||
mblk_t *msg = dumb->chan[0].m_in;
|
||||
dumb->chan[0].m_in = dumb->chan[0].m_in_run = NULL;
|
||||
|
@ -1030,10 +1086,10 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
} else {
|
||||
if(blen == 0)
|
||||
blen = ISAC_R_FIFO_SIZE;
|
||||
DEBUG(isac) printf(KERN_DEBUG ".R %d\n",xblen);
|
||||
DEBUG(isac) printf(KERN_DEBUG ".R=%d\n",xblen);
|
||||
if ((recvb = dumb->chan[0].m_in_run) != NULL) {
|
||||
DEBUG(isac)printf("a%d ",dsize(dumb->chan[0].m_in));
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + blen-1 > (uchar_t *)recvb->b_datap->db_lim)
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + blen > (uchar_t *)DATA_END(recvb))
|
||||
recvb = NULL;
|
||||
}
|
||||
if (recvb == NULL) {
|
||||
|
@ -1052,6 +1108,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
short i;
|
||||
mblk_t *msg = dumb->chan[0].m_in;
|
||||
dumb->chan[0].m_in = dumb->chan[0].m_in_run = NULL;
|
||||
DEBUG(isac) printf(">%p",recvp);
|
||||
for(i=0;i < blen; i++)
|
||||
*recvp++ = ByteInISAC(dumb,FIFO(i));
|
||||
recvb->b_wptr = recvp;
|
||||
|
@ -1068,7 +1125,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%x) %d\n",RSTA,dumb-dumbdata); }
|
||||
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%x)\n",RSTA); }
|
||||
if(dumb->chan[0].m_in != NULL) {
|
||||
freemsg(dumb->chan[0].m_in);
|
||||
dumb->chan[0].m_in = dumb->chan[0].m_in_run = NULL;
|
||||
|
@ -1081,7 +1138,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
mblk_t *recvb;
|
||||
|
||||
if ((recvb = dumb->chan[0].m_in_run) != NULL) {
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + ISAC_R_FIFO_SIZE > (uchar_t *)recvb->b_datap->db_lim)
|
||||
if ((recvp = (uchar_t *)recvb->b_wptr) + ISAC_R_FIFO_SIZE > (uchar_t *)DATA_END(recvb))
|
||||
recvb = NULL;
|
||||
}
|
||||
if (recvb == NULL) {
|
||||
|
@ -1133,7 +1190,6 @@ static void IRQ_ISAC(struct _dumb * dumb)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
inline
|
||||
#endif
|
||||
|
@ -1165,14 +1221,12 @@ static void IRQ_HSCX(struct _dumb * dumb)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef linux
|
||||
|
||||
static void
|
||||
dumbintr(int irq, struct pt_regs *regs)
|
||||
{
|
||||
struct _dumb *dumb;
|
||||
|
||||
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
|
||||
for(dumb=dumbmap[irq];dumb != NULL;dumb = dumb->next) {
|
||||
if(dumb->irq == irq) {
|
||||
dumb->polled --;
|
||||
IRQ_HSCX(dumb);
|
||||
|
@ -1182,7 +1236,7 @@ dumbintr(int irq, struct pt_regs *regs)
|
|||
toggle_off(dumb);
|
||||
}
|
||||
}
|
||||
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
|
||||
for(dumb=dumbmap[irq];dumb != NULL;dumb = dumb->next) {
|
||||
if(dumb->irq == irq) {
|
||||
toggle_on(dumb);
|
||||
}
|
||||
|
@ -1190,23 +1244,6 @@ dumbintr(int irq, struct pt_regs *regs)
|
|||
}
|
||||
|
||||
|
||||
#else
|
||||
void NAME(CARDTYPE,intr)(int x)
|
||||
{
|
||||
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
|
||||
if(dumb->irq == x) {
|
||||
dumb->polled --;
|
||||
IRQ_HSCX(dumb);
|
||||
IRQ_ISAC(dumb);
|
||||
dumb->polled ++;
|
||||
toggle_off(dumb);
|
||||
toggle_on(dumb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef linux
|
||||
void NAME(CARDTYPE,poll)(struct _dumb *dumb)
|
||||
#else
|
||||
|
@ -1249,9 +1286,8 @@ static void dumbtimer(struct _dumb *dumb)
|
|||
{
|
||||
NAME(CARDTYPE,poll)(dumb);
|
||||
#if 0
|
||||
if(dumb->countme++ > 10) {
|
||||
dumb->countme = 0;
|
||||
printf(" -%d:%02x %02x %02x- ",dumb-dumbdata,ByteInISAC(dumb,STAR),ByteInISAC(dumb,ISTA),ByteInISAC(dumb,CIR0));
|
||||
if(dumb->countme++ < 10) {
|
||||
printf(" -(%d):%02x %02x %02x- ",dumb->irq,ByteInISAC(dumb,STAR),ByteInISAC(dumb,ISTA),ByteInISAC(dumb,CIR0));
|
||||
}
|
||||
#endif
|
||||
#ifdef NEW_TIMEOUT
|
||||
|
@ -1261,131 +1297,122 @@ static void dumbtimer(struct _dumb *dumb)
|
|||
}
|
||||
#endif
|
||||
|
||||
void NAME(CARDTYPE,init)(void)
|
||||
int NAME(CARDTYPE,init)(struct _dumb *dumb)
|
||||
{
|
||||
extern caddr_t sptalloc();
|
||||
struct _dumb *dumb;
|
||||
int err;
|
||||
|
||||
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
|
||||
dumb->card.nr_chans = dumb->numHSCX * 2;
|
||||
dumb->card.ctl = dumb;
|
||||
dumb->card.chan = NULL;
|
||||
dumb->card.modes = (1<<M_HDLC)| (1<<M_HDLC_7H)| (1<<M_HDLC_7L)| (1<<M_TRANSPARENT)| (1<<M_TRANS_ALAW)| (1<<M_TRANS_V110)| (1<<M_TRANS_HDLC);
|
||||
dumb->card.ch_mode = dumb_mode;
|
||||
dumb->card.ch_prot = dumb_prot;
|
||||
dumb->card.send = dumb_data;
|
||||
dumb->card.flush = dumb_flush;
|
||||
dumb->card.cansend = dumb_candata;
|
||||
dumb->polled = -1;
|
||||
dumb->card.ctl = dumb;
|
||||
dumb->card.modes = (1<<M_HDLC)| (1<<M_HDLC_7H)| (1<<M_HDLC_7L)| (1<<M_TRANSPARENT)| (1<<M_TRANS_ALAW)| (1<<M_TRANS_V110)| (1<<M_TRANS_HDLC);
|
||||
dumb->card.ch_mode = dumb_mode;
|
||||
dumb->card.ch_prot = dumb_prot;
|
||||
dumb->card.send = dumb_data;
|
||||
dumb->card.flush = dumb_flush;
|
||||
dumb->card.cansend = dumb_candata;
|
||||
dumb->card.poll = NULL;
|
||||
dumb->polled = -1;
|
||||
|
||||
printf("ISDN: " STRING(CARDTYPE) " at mem %lx io 0x%x irq %d: ",dumb->memaddr,dumb->ioaddr,dumb->irq);
|
||||
printf("ISDN: " STRING(CARDTYPE) " at mem %lx io 0x%x irq %d: ",dumb->memaddr,dumb->ioaddr,dumb->irq);
|
||||
|
||||
if(!Init(dumb)) {
|
||||
printf("Card not initializable.\n");
|
||||
continue;
|
||||
}
|
||||
InitHSCX(dumb);
|
||||
InitISAC(dumb);
|
||||
InitHSCX(dumb);
|
||||
if((err = Init(dumb)) < 0) {
|
||||
printf("Card not initializable.\n");
|
||||
if(err == 0)
|
||||
err = -EIO;
|
||||
return err;
|
||||
}
|
||||
dumb->card.nr_chans = dumb->numHSCX;
|
||||
|
||||
if(!ISACpresent(dumb)) {
|
||||
printf("Card not responding.\n");
|
||||
continue;
|
||||
}
|
||||
InitHSCX(dumb);
|
||||
InitISAC(dumb);
|
||||
InitHSCX(dumb);
|
||||
|
||||
if((err = ISACpresent(dumb)) < 0) {
|
||||
printf("Card not responding.\n");
|
||||
return err;
|
||||
}
|
||||
#ifndef M_UNIX
|
||||
#ifdef linux
|
||||
if((dumb->irq != 0) && request_irq(dumb->irq,dumbintr,SA_INTERRUPT,"ISDN")) {
|
||||
printf("IRQ not available.\n");
|
||||
continue;
|
||||
}
|
||||
if((dumb->irq != 0) && request_irq(dumb->irq,dumbintr,SA_INTERRUPT,"ISDN")) {
|
||||
printf("IRQ not available.\n");
|
||||
return -EEXIST;
|
||||
}
|
||||
#endif
|
||||
NAME(CARDTYPE,poll)(dumb);
|
||||
if((err = isdn2_register(&dumb->card, dumb->ID)) != 0) {
|
||||
printf("not installed (ISDN_2), err %d\n",err);
|
||||
continue;
|
||||
}
|
||||
NAME(CARDTYPE,poll)(dumb);
|
||||
if((err = isdn2_register(&dumb->card, dumb->ID)) != 0) {
|
||||
printf("not installed (ISDN_2), err %d\n",err);
|
||||
return err;
|
||||
}
|
||||
|
||||
dumb->polled = 1;
|
||||
dumb->polled = 1;
|
||||
#ifdef linux
|
||||
if(dumb->irq == 0) {
|
||||
printf("polling; ");
|
||||
if(dumb->irq == 0) {
|
||||
printf("polling; ");
|
||||
}
|
||||
#endif
|
||||
printf("installed at ");
|
||||
if(dumb->memaddr != 0)
|
||||
printf("mem 0x%lx ",dumb->memaddr);
|
||||
if(dumb->ioaddr != 0)
|
||||
printf("io 0x%x ",dumb->ioaddr);
|
||||
if(dumb->irq != 0)
|
||||
printf("irq %d.\n",dumb->irq);
|
||||
else
|
||||
printf("polled.\n");
|
||||
dumb->next = dumbmap[dumb->irq];
|
||||
dumbmap[dumb->irq] = dumb;
|
||||
#ifdef linux
|
||||
dumbtimer(dumb);
|
||||
#endif
|
||||
#endif /* M_UNIX */
|
||||
MOD_INC_USE_COUNT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NAME(CARDTYPE,exit)(struct _dumb *dumb)
|
||||
{
|
||||
int j;
|
||||
unsigned long ms = SetSPL(dumb->ipl);
|
||||
struct _dumb **ndumb = &dumbmap[dumb->irq];
|
||||
while(*ndumb != NULL) {
|
||||
if(*ndumb == dumb) {
|
||||
*ndumb = dumb->next;
|
||||
break;
|
||||
}
|
||||
dumbtimer(dumb);
|
||||
#endif
|
||||
printf("installed at ");
|
||||
if(dumb->memaddr != 0)
|
||||
printf("mem 0x%lx ",dumb->memaddr);
|
||||
if(dumb->ioaddr != 0)
|
||||
printf("io 0x%x ",dumb->ioaddr);
|
||||
if(dumb->irq != 0)
|
||||
printf("irq %d.\n",dumb->irq);
|
||||
else
|
||||
printf("polled.\n");
|
||||
#endif
|
||||
ndumb = &((*ndumb)->next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef M_UNIX
|
||||
void NAME(CARDTYPE,start)(void)
|
||||
{
|
||||
extern caddr_t sptalloc();
|
||||
short i;
|
||||
struct _dumb *dumb;
|
||||
int err;
|
||||
|
||||
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
|
||||
if((err = isdn2_register(&dumb->card, dumb->ID)) == 0)
|
||||
printcfg("dumb",0,dumb->ioaddr,dumb->irq,i, "unit %d",i);
|
||||
else
|
||||
printf("ISDN Driver %d/%d/%x not installed, err %d.\n",i,dumb->irq,dumb->ioaddr,err);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void NAME(CARDTYPE,halt)(void)
|
||||
{
|
||||
struct _dumb *dumb;
|
||||
|
||||
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
|
||||
int j;
|
||||
unsigned long ms = SetSPL(dumb->ipl);
|
||||
if(dumb->polled > 0) {
|
||||
#ifdef NEW_TIMEOUT
|
||||
untimeout(dumb->timer);
|
||||
untimeout(dumb->timer);
|
||||
#else
|
||||
untimeout(dumbtimer,dumb);
|
||||
untimeout(dumbtimer,dumb);
|
||||
#endif
|
||||
ByteOutISAC(dumb,MASK,0xFF);
|
||||
for(j=1; j<=dumb->numHSCX;j++) {
|
||||
ByteOutISAC(dumb,MASK,0xFF);
|
||||
for(j=1; j<=dumb->numHSCX;j++) {
|
||||
#ifdef WIDE
|
||||
ByteOutHSCX(dumb,j,IMR0,0xFF);
|
||||
ByteOutHSCX(dumb,j,IMR1,0xFF);
|
||||
ByteOutHSCX(dumb,j,IMR0,0xFF);
|
||||
ByteOutHSCX(dumb,j,IMR1,0xFF);
|
||||
#else
|
||||
ByteOutHSCX(dumb,j,MASK,0xFF);
|
||||
ByteOutHSCX(dumb,j,MASK,0xFF);
|
||||
#endif
|
||||
}
|
||||
if(dumb->irq > 0)
|
||||
free_irq(dumb->irq);
|
||||
isdn2_unregister(&dumb->card);
|
||||
}
|
||||
splx(ms);
|
||||
}
|
||||
}
|
||||
if(dumb->irq > 0)
|
||||
free_irq(dumb->irq);
|
||||
isdn2_unregister(&dumb->card);
|
||||
splx(ms);
|
||||
MOD_DEC_USE_COUNT;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
static int do_init_module(void)
|
||||
{
|
||||
NAME(CARDTYPE,init)();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_exit_module(void)
|
||||
{
|
||||
NAME(CARDTYPE,halt)();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
#ifndef CONF_H
|
||||
#define CONF_H
|
||||
#include "isdn_limits.h"
|
||||
#include "isdn_12.h"
|
||||
#include "smallq.h"
|
||||
|
@ -25,24 +27,25 @@ typedef struct _hdlc_buf {
|
|||
unsigned char *p_out;
|
||||
Byte mode;
|
||||
Byte locked,listen;
|
||||
u_short nblk,maxblk;
|
||||
u_short nblk,maxblk,offset;
|
||||
} *hdlc_buf;
|
||||
|
||||
typedef struct _dumb {
|
||||
struct _isdn1_card card;
|
||||
struct _isdn1_card card; /* must be first */
|
||||
|
||||
long memaddr;
|
||||
short ioaddr;
|
||||
char irq, ipl, numHSCX;
|
||||
long ID;
|
||||
int debug;
|
||||
unsigned char irq, ipl, numHSCX;
|
||||
unsigned long ID;
|
||||
unsigned int debug;
|
||||
|
||||
struct _hdlc_buf chan[MAX_B+1];
|
||||
#ifdef NEW_TIMEOUT
|
||||
long timer;
|
||||
#endif
|
||||
struct _dumb *next;
|
||||
long countme; signed char polled; char circ;
|
||||
} *__dumb;
|
||||
|
||||
extern struct _dumb dumbdata[];
|
||||
|
||||
#endif
|
|
@ -19,12 +19,15 @@ static inline Byte Slot(struct _dumb * dumb, u_char hscx) {
|
|||
return (hscx&1) ? 0x03 : 0x03; /* was 3 / 7 */
|
||||
}
|
||||
|
||||
static int Init(struct _dumb * dumb) {
|
||||
static int
|
||||
Init(struct _dumb * dumb) {
|
||||
int timout;
|
||||
long flags;
|
||||
|
||||
if(dumb->memaddr == 0)
|
||||
return -EINVAL;
|
||||
dumb->numHSCX = 2;
|
||||
save_flags(flags);
|
||||
|
||||
if(dumb->ipl) {
|
||||
int ioaddr;
|
||||
Byte cfval;
|
||||
|
@ -36,7 +39,7 @@ static int Init(struct _dumb * dumb) {
|
|||
case 4: ioaddr = 0xc80; break; /* may cause conflicts (motherboard range) */
|
||||
}
|
||||
switch(dumb->irq) {
|
||||
default: printk("irq %d not possible: ",dumb->irq); return 0;
|
||||
default: printk("irq %d not possible: ",dumb->irq); return -EINVAL;
|
||||
case 2: cfval = 0x00; break;
|
||||
case 3: cfval = 0x02; break;
|
||||
case 4: cfval = 0x04; break;
|
||||
|
@ -70,10 +73,11 @@ static int Init(struct _dumb * dumb) {
|
|||
timout = jiffies+(HZ/5)+1;
|
||||
while(jiffies <= timout) ;
|
||||
restore_flags(flags);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ISAC_mode(struct _dumb * dumb, Byte mode, Byte listen)
|
||||
static void
|
||||
ISAC_mode(struct _dumb * dumb, Byte mode, Byte listen)
|
||||
{
|
||||
unsigned long ms = SetSPL(dumb->ipl);
|
||||
static Byte xmode = 0xFF;
|
||||
|
@ -130,7 +134,8 @@ static Byte xmode = 0xFF;
|
|||
xmode = mode;
|
||||
}
|
||||
|
||||
static int HSCX_mode(struct _dumb * dumb, u_char hscx, Byte mode, Byte listen)
|
||||
static int
|
||||
HSCX_mode(struct _dumb * dumb, u_char hscx, Byte mode, Byte listen)
|
||||
{
|
||||
unsigned long ms = SetSPL(dumb->ipl);
|
||||
if(dumb->chan[hscx].m_in != NULL) {
|
||||
|
@ -210,7 +215,8 @@ static int HSCX_mode(struct _dumb * dumb, u_char hscx, Byte mode, Byte listen)
|
|||
splx(ms);
|
||||
return 0;
|
||||
}
|
||||
static void InitISAC(struct _dumb * dumb)
|
||||
static void
|
||||
InitISAC(struct _dumb * dumb)
|
||||
{
|
||||
dumb->chan[0].mode = M_OFF;
|
||||
dumb->chan[0].listen = 0;
|
||||
|
@ -225,7 +231,8 @@ static void InitISAC(struct _dumb * dumb)
|
|||
ByteOutISAC(dumb, MASK, 0x00);
|
||||
}
|
||||
|
||||
static void InitHSCX_(struct _dumb * dumb, u_char hscx)
|
||||
static void
|
||||
InitHSCX_(struct _dumb * dumb, u_char hscx)
|
||||
{
|
||||
ByteOutHSCX(dumb,hscx,CCR2, 0x30); /* 0x38 */
|
||||
ByteOutHSCX(dumb,hscx,TSAX, Slot(dumb,hscx));
|
|
@ -21,7 +21,7 @@ ALL = test.o
|
|||
|
||||
all: test.o
|
||||
|
||||
load: all
|
||||
load:
|
||||
insmod test.o
|
||||
|
||||
test.o: test.c
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* Testing driver which registers a device for loopback, and so on.
|
||||
*
|
||||
*/
|
||||
|
||||
#define UAREA
|
||||
|
||||
#include "f_module.h"
|
||||
#include "primitives.h"
|
||||
#include <sys/time.h>
|
||||
#include "f_signal.h"
|
||||
#include "f_malloc.h"
|
||||
#include <sys/sysmacros.h>
|
||||
#include "streams.h"
|
||||
#include <sys/stropts.h>
|
||||
/* #ifdef DONT_ADDERROR */
|
||||
#include "f_user.h"
|
||||
/* #endif */
|
||||
#include <sys/errno.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include "streamlib.h"
|
||||
#include "lap.h"
|
||||
#include <sys/termios.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/tqueue.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
extern void log_printmsg (void *log, const char *text, mblk_t * mp, const char*);
|
||||
extern void logh_printmsg (void *log, const char *text, mblk_t * mp);
|
||||
|
||||
#define ddprintf(xx) printf(xx),({int x;for(x=0;x<1000;x++) udelay(1000);})
|
||||
#define ldprintf if(0)printf
|
||||
#if 1
|
||||
#if 1
|
||||
#define dprintf printf
|
||||
#else
|
||||
#define dprintf ({int x;for(x=0;x<300;x++) udelay(1000);}),printf
|
||||
#endif
|
||||
#else
|
||||
#define dprintf if(0)printf
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Standard Streams driver information.
|
||||
*/
|
||||
static struct module_info itest_minfo =
|
||||
{
|
||||
0, "itest", 0, INFPSZ, 8000, 3000
|
||||
};
|
||||
|
||||
static qf_open itest_open;
|
||||
static qf_close itest_close;
|
||||
static qf_srv itest_wsrv, itest_rsrv;
|
||||
static qf_put itest_wput;
|
||||
|
||||
static struct qinit itest_rinit =
|
||||
{
|
||||
NULL, NULL, itest_open, itest_close, NULL, &itest_minfo, NULL
|
||||
};
|
||||
|
||||
static struct qinit itest_winit =
|
||||
{
|
||||
itest_wput, itest_wsrv, NULL, NULL, NULL, &itest_minfo, NULL
|
||||
};
|
||||
|
||||
struct streamtab itest_info =
|
||||
{&itest_rinit, &itest_winit, NULL, NULL};
|
||||
|
||||
#define NCARDS 2
|
||||
#define NBCHAN 3
|
||||
|
||||
struct testcard {
|
||||
struct _isdn1_card *card;
|
||||
struct testchannel {
|
||||
struct testcard *card;
|
||||
queue_t *q;
|
||||
} port[NBCHAN+1];
|
||||
} test_card[NCARDS];
|
||||
|
||||
|
||||
static int test_poll (struct _isdn1_card * card, short channel)
|
||||
{
|
||||
struct testcard *test_card = (struct testcad *)card;
|
||||
struct testchannel *testport;
|
||||
|
||||
if(channel < 0 || channel >= NBCHAN)
|
||||
return -EIO;
|
||||
testport = &testcard.port[channel];
|
||||
if(testport->q == NULL)
|
||||
return -ENXIO;
|
||||
if(WR(testport->q)->q_first == NULL)
|
||||
return -EAGAIN;
|
||||
qenable(WR(testport->q));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_candata (struct _isdn1_card * card, short channel)
|
||||
{
|
||||
struct testcard *test_card = (struct testcad *)card;
|
||||
struct testchannel *testport;
|
||||
|
||||
if(channel < 0 || channel >= NBCHAN)
|
||||
return 0;
|
||||
testport = &testcard.port[channel];
|
||||
if(testport->q == NULL)
|
||||
return 0;
|
||||
return canput(testport->q->q_next);
|
||||
}
|
||||
|
||||
static int test_data (struct _isdn1_card * card, short channel, mblk_t * data)
|
||||
{
|
||||
struct testcard *test_card = (struct testcad *)card;
|
||||
struct testchannel *testport;
|
||||
|
||||
if(channel < 0 || channel >= NBCHAN)
|
||||
return -EIO;
|
||||
testport = &testcard.port[channel];
|
||||
if(testport->q == NULL)
|
||||
return -ENXIO;
|
||||
if(!canput(testport->q->q_next))
|
||||
return -EAGAIN;
|
||||
putnext(testport->q,data);
|
||||
}
|
||||
|
||||
data
|
||||
candata
|
||||
|
||||
static int test_flush (struct _isdn1_card * card, short channel)
|
||||
{
|
||||
struct testcard *test_card = (struct testcad *)card;
|
||||
struct testchannel *testport;
|
||||
|
||||
if(channel < 0 || channel >= NBCHAN)
|
||||
return -EIO;
|
||||
testport = &testcard.port[channel];
|
||||
if(testport->q == NULL)
|
||||
return -ENXIO;
|
||||
putctlx1(testport->q,M_FLUSH,FLUSHR|FLUSHW);
|
||||
}
|
||||
|
||||
static int test_prot (struct _isdn1_card * card, short channel, mblk_t * proto)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
static int test_mode (struct _isdn1_card * card, short channel, char mode,
|
||||
char listen)
|
||||
{
|
||||
struct testcard *test_card = (struct testcad *)card;
|
||||
struct testchannel *testport;
|
||||
|
||||
if(channel < 0 || channel >= NBCHAN)
|
||||
return -EIO;
|
||||
testport = &testcard.port[channel];
|
||||
if(testport->q == NULL)
|
||||
return -ENXIO;
|
||||
if(mode == MODE_OFF)
|
||||
putctlx1(testport->q,M_HANGUP);
|
||||
}
|
||||
|
||||
|
||||
/* Streams code to open the driver. */
|
||||
static int
|
||||
itest_open (queue_t * q, dev_t dev, int flag, int sflag
|
||||
#ifdef DO_ADDERROR
|
||||
,int *err
|
||||
#define U_ERROR *err
|
||||
#else
|
||||
#define U_ERROR u.u_error
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct testcard *test_card;
|
||||
struct testchannel *testport;
|
||||
int mdev = 0;
|
||||
int cdev;
|
||||
int err;
|
||||
|
||||
dev = minor (dev);
|
||||
cdev = dev & 0x0F;
|
||||
mdev = cdev / (NBCHAN+1);
|
||||
cdev %= (NBCHAN+1);
|
||||
|
||||
if(mdev >= NCARDS) {
|
||||
U_ERROR = ENXIO;
|
||||
return OPENFAIL;
|
||||
}
|
||||
testcard = test_card[mdev];
|
||||
testport = &testcard->port[cdev];
|
||||
if(testport->q != NULL) {
|
||||
printf("itest dev 0x%x: already open, %p\n",dev,testport->q);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MORE_USE;
|
||||
|
||||
if(cdev == 0) {
|
||||
int theID = CHAR4('T','s','t','A'+mdev);
|
||||
|
||||
testcard->card.nr_chans = NBCHAN;
|
||||
testcard->card.ctl = testcard;
|
||||
testcard->card.chan = NULL;
|
||||
testcard->card.modes = (1<<M_HDLC)| (1<<M_TRANSPARENT)| (1<<M_TRANS_ALAW)| (1<<M_TRANS_V110)| (1<<M_TRANS_HDLC);
|
||||
testcard->card.ch_mode = test_mode;
|
||||
testcard->card.ch_prot = test_prot;
|
||||
testcard->card.send = test_data;
|
||||
testcard->card.flush = test_flush;
|
||||
testcard->card.cansend = test_candata;
|
||||
testcard->card.poll = test_poll;
|
||||
|
||||
if((err = isdn2_register(&testcard->card, theID)) != 0) {
|
||||
U_ERROR = err;
|
||||
LESS_USE;
|
||||
return OPENFAIL;
|
||||
}
|
||||
}
|
||||
|
||||
testport->card = testcard;
|
||||
testport->q = q;
|
||||
|
||||
WR (q)->q_ptr = (caddr_t) testport;
|
||||
q->q_ptr = (caddr_t) testport;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/* Streams code to close the driver. */
|
||||
static void
|
||||
itest_close (queue_t *q, int dummy)
|
||||
{
|
||||
struct testchannel *testport = (struct testchannel *) q->q_ptr;
|
||||
struct testcard *test_card = testport->card;
|
||||
|
||||
if(testport->q == NULL)
|
||||
return;
|
||||
if(testport == &testcard->port[0])
|
||||
isdn2_unregister(&testcard->card);
|
||||
|
||||
testport->q = NULL;
|
||||
|
||||
LESS_USE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Streams code to write data. */
|
||||
static void
|
||||
itest_wput (queue_t *q, mblk_t *mp)
|
||||
{
|
||||
struct testchannel *testport = (struct testchannel *) q->q_ptr;
|
||||
struct testcard *test_card = testport->card;
|
||||
ldprintf(".%d.",__LINE__);
|
||||
|
||||
#ifdef CONFIG_DEBUG_STREAMS
|
||||
if(msgdsize(mp) < 0)
|
||||
return;
|
||||
#endif
|
||||
if(testport->q == NULL) {
|
||||
freemsg(mp);
|
||||
return;
|
||||
}
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case M_IOCTL:
|
||||
DATA_TYPE(mp) = M_IOCNAK;
|
||||
((struct iocblk *)mp->b_rptr)->ioc_error = EINVAL;
|
||||
qreply (q, mp);
|
||||
break;
|
||||
CASE_DATA
|
||||
putq (q, mp);
|
||||
break;
|
||||
case M_FLUSH:
|
||||
if (*mp->b_rptr & FLUSHW)
|
||||
flushq (q, 0);
|
||||
|
||||
if (*mp->b_rptr & FLUSHR) {
|
||||
flushq (RD (q), 0);
|
||||
*mp->b_rptr &= ~FLUSHW;
|
||||
qreply (q, mp);
|
||||
} else
|
||||
freemsg (mp);
|
||||
break;
|
||||
default:
|
||||
log_printmsg (NULL, "Strange itest", mp, KERN_WARNING);
|
||||
/* putctl1(RD(q)->b_next, M_ERROR, ENXIO); */
|
||||
freemsg (mp);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Streams code to scan the write queue. */
|
||||
static void
|
||||
itest_wsrv (queue_t *q)
|
||||
{
|
||||
struct testchannel *testport = (struct testchannel *) q->q_ptr;
|
||||
struct testcard *testcard;
|
||||
mblk_t *mp;
|
||||
int chan;
|
||||
|
||||
if(testport == NULL || testport->q == NULL) {
|
||||
flushq(q,FLUSHALL);
|
||||
return;
|
||||
}
|
||||
testcard = testport->card;
|
||||
chan = testport - testcard->port;
|
||||
|
||||
while (q->q_first != NULL) {
|
||||
int err = isdn2_canrecv(&testcard->card, chan);
|
||||
if(err != 0)
|
||||
break;
|
||||
mp = getq (q)) != NULL);
|
||||
if(mp != NULL) {
|
||||
err = isdn2_recv(&testcard->card, chan,mp);
|
||||
if(err != 0)
|
||||
freemsg(mp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
static int devmajor1 = 0;
|
||||
|
||||
static int do_init_module(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
bzero(test_card,sizeof(test_card));
|
||||
|
||||
err = register_strdev(0,&itest_info,0);
|
||||
if(err < 0) {
|
||||
return err;
|
||||
}
|
||||
devmajor1 = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_exit_module(void)
|
||||
{
|
||||
int err1;
|
||||
int i;
|
||||
|
||||
err1 = unregister_strdev(devmajor1,&itest_info,0);
|
||||
return err1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
54
isdn/cf → cf
54
isdn/cf → cf
|
@ -35,7 +35,7 @@ ML login * * * -,3 frame x75
|
|||
P cept cept * * RFX :vB 8890 :vL 9090A9D1E7 :vH 91D2 :sv 0F00
|
||||
MP cept * * * - x75 :nk 1
|
||||
MP cept * * * - proto :sg 0 :ca 2 :bk 0
|
||||
ML cept * * * -,0 frame x75
|
||||
ML cept * * * -,0 frame x75 t70
|
||||
D cept cept * * o -01910
|
||||
|
||||
# Sample CEPT session, old standard. Untested.
|
||||
|
@ -43,7 +43,7 @@ D cept cept * * o -01910
|
|||
P btx btx * * RFX :vB 8890 :vL 9090A9D1EA :sv 0500
|
||||
MP btx * * * - x75 :nk 1
|
||||
MP btx * * * - proto :sg 0 :ca 2 :bk 0
|
||||
ML btx * * * -,0 frame x75
|
||||
ML btx * * * -,0 frame x75 t70
|
||||
D btx btx * * o -01910
|
||||
|
||||
|
||||
|
@ -55,29 +55,45 @@ R tcp somebody * * root 1RUp slipto -r <remote_network> <local_IP> <remote_IP>
|
|||
# Use -R for host routes. Use -r network:netmask for subnets or supernets.
|
||||
# Use -d for the default route.
|
||||
|
||||
P tcp somebody * * R :nr .1
|
||||
P tcp * * * MFX :lr /2 :vB 8890 :sv 0700
|
||||
P tcp somebody * * R :nr .1
|
||||
P tcp * * * MFX :lr /2 :vB 8890 :sv 0700
|
||||
ML tcp somebody * * -,3 frame timer reconn str_if
|
||||
|
||||
MP tcp somebody * * - timer :tr 60 :tw 60 :ti 360 :to 360 :tI :lo
|
||||
MP tcp * * * - proto :sg 1 :ca 1 :bk 0
|
||||
MP tcp somebody * * - timer :tr 60 :tw 60 :ti 360 :to 360 :tI :lo
|
||||
MP tcp * * * - proto :sg 1 :ca 1 :bk 0
|
||||
|
||||
## example for dialup-TCP; demand-only and outgoing-only.
|
||||
# If you need dynamic address assignment, call slipto
|
||||
# from an appropriate chat script.
|
||||
# Dynamic address assignment via PPP will be here, too ... someday.
|
||||
|
||||
#R dtcp somebody * * root 1RUd slipto -E -r <remote_network> <local_IP> <remote_IP>
|
||||
#P dtcp somebody * * R :nr .1
|
||||
#P dtcp * * * MFX :lr /2 :vB 8890 :sv 0700
|
||||
#ML dtcp somebody * * -,3 frame slip timer str_if
|
||||
|
||||
#MP dtcp somebody * * - timer :tr 60 :tw 60 :ti 360 :to 360 :tI :lo
|
||||
#MP dtcp * * * - proto :sg 0 :ca 1 :bk 0
|
||||
|
||||
|
||||
# Remote phone numbers.
|
||||
# The "unknown" entry is used when no number is transmitted.
|
||||
# Note that you need a matching entry with "o" flag (or no "i" flag)
|
||||
# if you want to ATDnumber.
|
||||
|
||||
D * somebody A * - +49=911-234567.
|
||||
|
||||
D * x-de-nbg X * i +49=911-*
|
||||
D * x-de Y * i +49=*
|
||||
D * x-intl Z * i +*
|
||||
D * unknown U * i +*
|
||||
D * unknown U * - +*
|
||||
|
||||
|
||||
# Local numbers.
|
||||
#DL Tel0 +49=911-959913/[1-3] :pr 0 :sp 8 :pr 63
|
||||
DL Tel0 +49=911-919402/ :pr 0 :sp 65 :pr 63
|
||||
## :pr 65 -- leased lines ONLY.
|
||||
## :pr 64 -- leased lines ONLY.
|
||||
## :pr 65 -- cards with CAPI interface ONLY.
|
||||
## :pr 0 -- the normal circuit-mode D channel protocol
|
||||
## :sp 65 -- German 1TR6
|
||||
## :sp 8 -- European DSS-1
|
||||
|
@ -88,17 +104,35 @@ DL Tel0 +49=911-919402/ :pr 0 :sp 65 :pr 63
|
|||
# Use the second line if you're using a PBX which doesn't prefix external
|
||||
# numbers with the PBX' dialout prefix.
|
||||
DP * +00=0-
|
||||
#DP * +00=0- +000=00-0
|
||||
|
||||
#DP * +000=00-0 +00=0-
|
||||
|
||||
# Card modes. Don't change the numbers, the driver knows about them.
|
||||
CM ???? 2 transalaw
|
||||
CM ???? 3 transv110
|
||||
CM ???? 4 trans
|
||||
CM ???? 10 frame
|
||||
CM ???? 14 frameb
|
||||
|
||||
|
||||
# Limit how many B channel connections may be opened.
|
||||
# Override the limit with :il in the P line.
|
||||
CL * 2
|
||||
|
||||
|
||||
## Load cards
|
||||
LF Bin? 2048 /etc/isdn/boot.68k
|
||||
|
||||
## The following is a complete example on how to do a leased line.
|
||||
#
|
||||
#P tcp foo A Tel3 RX :dI :pr 64 :sp 0 :bc 1 :Ft
|
||||
#ML tcp foo * Tel3 -,3 frame xstrlog fakeh reconn str_if
|
||||
#MP tcp foo * Tel3 - proto :sg 1 :ca 1 :bk 0 :on
|
||||
#R tcp foo * Tel3 root 1RUBf slipto -d 10.1.1.1 10.1.1.2
|
||||
#D * foo A Tel3 f -
|
||||
#DL Tel3 - :pr 64
|
||||
#CM Tel3 10 frame
|
||||
#CM Tel3 14 frameb
|
||||
#MP tcp * * * - proto :sg 1 :ca 1 :bk 0
|
||||
#MP * * * * i proto :sg 0 :ca 1 :bk 0
|
||||
|
||||
# END
|
|
@ -8,7 +8,7 @@ P =
|
|||
## =()<CC = @<CC>@>()=
|
||||
CC = gcc
|
||||
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
|
||||
CFLAGS = -O2 -Wall $(DEFS)
|
||||
|
||||
|
@ -42,7 +42,7 @@ depend: Makefile $(SOURCES)
|
|||
ln -s . linux
|
||||
$(CC) -M $(DEFS) $(SOURCES) > .depend
|
||||
|
||||
load: all
|
||||
load:
|
||||
insmod compat.o
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
|
@ -6,6 +6,7 @@
|
|||
* Copyright 1994: Matthias Urlichs <urlichs@smurf.noris.de>
|
||||
*/
|
||||
#ifdef MODULE
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
@ -15,9 +16,11 @@
|
|||
#include <asm/delay.h>
|
||||
|
||||
/*
|
||||
* syscompat.c -- provide compatibility code for stuff written for non-Linux kernels
|
||||
* compat.c
|
||||
*
|
||||
* Version 0.1 by Matthias Urlichs <urlichs@smurf.sub.org>
|
||||
* provides some compatibility code for stuff written for non-Linux kernels
|
||||
*
|
||||
* Version 0.3 by Matthias Urlichs <urlichs@smurf.noris.de>
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
|
@ -32,78 +35,12 @@
|
|||
unsigned long block_mask = 0;
|
||||
const char *xdeb_file; unsigned int xdeb_line;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Completely untested code.
|
||||
* Just rewrite the stuff to use sleep_on and wake_up;
|
||||
* they're better anyway...
|
||||
* Standard Unix-kernel timeout code. Two versions -- the new version
|
||||
* returns a pointer to its internal data, the old version doesn't, which
|
||||
* means we have to scan for the thing in an internal list when
|
||||
* deallocating the timer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* I freely admit that the implementation below can be improved
|
||||
* tremendously, but IMHO there are better things to do with my time.
|
||||
* YMMV. -M.U-
|
||||
*/
|
||||
static struct event_list {
|
||||
struct event_list *next;
|
||||
struct wait_queue *queue;
|
||||
caddr_t event;
|
||||
} *event_list;
|
||||
static char block_events;
|
||||
static struct wait_queue *block_queue;
|
||||
|
||||
/* sleep is supposed to be written so that wakeup can run from an interrupt
|
||||
without running off the queue. */
|
||||
|
||||
int sleep(caddr_t event, int prio) {
|
||||
unsigned long flags;
|
||||
struct event_list *ev = event_list;
|
||||
|
||||
save_flags(flags);
|
||||
cli();
|
||||
while(block_events)
|
||||
sleep_on(&block_queue);
|
||||
block_events = 1;
|
||||
while(ev != NULL && ev->event != event) {
|
||||
if(ev->next->queue == NULL) {
|
||||
struct event_list *ev2 = ev->next;
|
||||
ev->next = ev2->next;
|
||||
kfree_s(ev2, sizeof(struct event_list));
|
||||
} else {
|
||||
ev = ev->next;
|
||||
}
|
||||
}
|
||||
if(ev == NULL) {
|
||||
ev = (struct event_list *)kmalloc(sizeof(struct event_list),GFP_KERNEL);
|
||||
ev->queue = NULL;
|
||||
ev->event = event;
|
||||
ev->next = event_list;
|
||||
event_list = ev->next;
|
||||
}
|
||||
block_events = 0;
|
||||
wake_up(&block_queue);
|
||||
if(prio & PZERO)
|
||||
interruptible_sleep_on(&ev->queue);
|
||||
else
|
||||
sleep_on(&ev->queue);
|
||||
restore_flags(flags);
|
||||
return ((current->signal & ~current->blocked) != 0);
|
||||
}
|
||||
|
||||
void wakeup(caddr_t event) {
|
||||
struct event_list *ev = event_list;
|
||||
|
||||
while(ev != NULL && ev->event != event) {
|
||||
ev = ev->next;
|
||||
}
|
||||
if(ev != NULL) {
|
||||
wake_up(&ev->queue);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
struct timing {
|
||||
struct timer_list tim;
|
||||
void (*proc)(void *);
|
||||
|
@ -112,6 +49,7 @@ struct timing {
|
|||
|
||||
struct timing_old {
|
||||
struct timing tim;
|
||||
struct timing_old *prev;
|
||||
struct timing_old *next;
|
||||
};
|
||||
static struct timing_old *start = NULL;
|
||||
|
@ -130,14 +68,18 @@ static void dotimer(void *arg)
|
|||
|
||||
static void droptimer_old(void (*func)(void *), void *arg, char del)
|
||||
{
|
||||
struct timing_old **head = &start;
|
||||
struct timing_old *tim;
|
||||
unsigned long flags;
|
||||
save_flags(flags);
|
||||
cli();
|
||||
while(*head != NULL) {
|
||||
if((*head)->tim.proc == func && (*head)->tim.arg == arg) {
|
||||
struct timing_old *tim = *head;
|
||||
*head = tim->next;
|
||||
for(tim = start; tim != NULL; tim = tim->next) {
|
||||
if(tim->tim.proc == func && tim->tim.arg == arg) {
|
||||
if(tim->next != NULL)
|
||||
tim->next->prev = tim->prev;
|
||||
if(tim->prev != NULL)
|
||||
tim->prev->next = tim->next;
|
||||
else
|
||||
start = tim->next;
|
||||
restore_flags(flags);
|
||||
if(del) {
|
||||
del_timer(&tim->tim.tim);
|
||||
|
@ -147,8 +89,7 @@ static void droptimer_old(void (*func)(void *), void *arg, char del)
|
|||
MOD_DEC_USE_COUNT;
|
||||
#endif
|
||||
return;
|
||||
} else
|
||||
head = &(*head)->next;
|
||||
}
|
||||
}
|
||||
restore_flags(flags);
|
||||
printk("Timer %p:%p not found\n", func,arg);
|
||||
|
@ -188,7 +129,11 @@ int timeout(void (*func)(void *), void *arg, int expire)
|
|||
timer->proc = func;
|
||||
timer->arg = arg;
|
||||
timer->tim.data = (unsigned long)timer;
|
||||
timer->tim.expires = expire;
|
||||
timer->tim.expires = expire
|
||||
#if LINUX_VERSION_CODE >= 66304 /* 1.3.0 -- is that right ?? */
|
||||
+ jiffies;
|
||||
#endif
|
||||
;
|
||||
#ifdef MODULE
|
||||
MOD_INC_USE_COUNT;
|
||||
#endif
|
||||
|
@ -220,11 +165,18 @@ void timeout_old(void (*func)(void *), void *arg, int expire)
|
|||
timer->tim.arg = arg;
|
||||
timer->tim.tim.function = (fct)dotimer_old;
|
||||
timer->tim.tim.data = (unsigned long)timer;
|
||||
timer->tim.tim.expires = expire;
|
||||
s = spl6();
|
||||
timer->tim.tim.expires = expire
|
||||
#if LINUX_VERSION_CODE >= 66304 /* 1.3.0 -- is that right ?? */
|
||||
+ jiffies;
|
||||
#endif
|
||||
;
|
||||
save_flags(s); cli();
|
||||
if(start != NULL)
|
||||
start->prev = timer;
|
||||
timer->next = start;
|
||||
timer->prev = NULL;
|
||||
start = timer;
|
||||
splx(s);
|
||||
restore_flags(s);
|
||||
#ifdef MODULE
|
||||
MOD_INC_USE_COUNT;
|
||||
#endif
|
||||
|
@ -385,7 +337,7 @@ char kernel_version[] = UTS_RELEASE;
|
|||
|
||||
int init_module(void)
|
||||
{
|
||||
#ifdef __ELF__
|
||||
#if defined(__ELF__) || LINUX_VERSION_CODE >= 66304 /* 1.3.0. Is that right??? */
|
||||
#define U
|
||||
#else
|
||||
#define U "_"
|
|
@ -0,0 +1,355 @@
|
|||
#define COMPAT_C
|
||||
|
||||
/*
|
||||
* Compatibility stuff for Streams-ish drivers and other stuff.
|
||||
*
|
||||
* Copyright 1994: Matthias Urlichs <urlichs@smurf.noris.de>
|
||||
*/
|
||||
#ifdef MODULE
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
/*
|
||||
* compat.c
|
||||
*
|
||||
* provides some compatibility code for stuff written for non-Linux kernels
|
||||
*
|
||||
* Version 0.3 by Matthias Urlichs <urlichs@smurf.noris.de>
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/malloc.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
unsigned long block_mask = 0;
|
||||
const char *xdeb_file; unsigned int xdeb_line;
|
||||
|
||||
/*
|
||||
* Standard Unix-kernel timeout code. Two versions -- the new version
|
||||
* returns a pointer to its internal data, the old version doesn't, which
|
||||
* means we have to scan for the thing in an internal list when
|
||||
* deallocating the timer.
|
||||
*/
|
||||
struct timing {
|
||||
struct timer_list tim;
|
||||
void (*proc)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
struct timing_old {
|
||||
struct timing tim;
|
||||
struct timing_old *prev;
|
||||
struct timing_old *next;
|
||||
};
|
||||
static struct timing_old *start = NULL;
|
||||
|
||||
static void dotimer(void *arg)
|
||||
{
|
||||
struct timing *tim = (struct timing *)arg;
|
||||
|
||||
(*tim->proc)(tim->arg);
|
||||
sti();
|
||||
kfree_s(tim,sizeof(struct timing));
|
||||
#ifdef MODULE
|
||||
MOD_DEC_USE_COUNT;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void droptimer_old(void (*func)(void *), void *arg, char del)
|
||||
{
|
||||
struct timing_old *tim;
|
||||
unsigned long flags;
|
||||
save_flags(flags);
|
||||
cli();
|
||||
for(tim = start; tim != NULL; tim = tim->next) {
|
||||
if(tim->tim.proc == func && tim->tim.arg == arg) {
|
||||
if(tim->next != NULL)
|
||||
tim->next->prev = tim->prev;
|
||||
if(tim->prev != NULL)
|
||||
tim->prev->next = tim->next;
|
||||
else
|
||||
start = tim->next;
|
||||
restore_flags(flags);
|
||||
if(del) {
|
||||
del_timer(&tim->tim.tim);
|
||||
kfree_s(tim,sizeof(struct timing_old));
|
||||
}
|
||||
#ifdef MODULE
|
||||
MOD_DEC_USE_COUNT;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
restore_flags(flags);
|
||||
printk("Timer %p:%p not found\n", func,arg);
|
||||
}
|
||||
|
||||
static void dotimer_old(void *arg)
|
||||
{
|
||||
struct timing_old *tim = (struct timing_old *)arg;
|
||||
|
||||
droptimer_old(tim->tim.proc,tim->tim.arg,0);
|
||||
(*tim->tim.proc)(tim->tim.arg);
|
||||
|
||||
sti();
|
||||
kfree_s(tim,sizeof(*tim));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MALLOC_NAMES
|
||||
int deb_timeout(const char *deb_file, unsigned int deb_line, void (*func)(void *), void *arg, int expire)
|
||||
#else
|
||||
int timeout(void (*func)(void *), void *arg, int expire)
|
||||
#endif
|
||||
{
|
||||
typedef void (*fct)(unsigned long);
|
||||
struct timing *timer;
|
||||
|
||||
#ifdef CONFIG_MALLOC_NAMES
|
||||
timer = (struct timing *)deb_kmalloc(deb_file,deb_line, sizeof(struct timing), GFP_ATOMIC);
|
||||
#else
|
||||
timer = (struct timing *)kmalloc(sizeof(struct timing), GFP_ATOMIC);
|
||||
#endif
|
||||
if(timer == NULL) {
|
||||
printf(" *!* No Timeout!\n");
|
||||
return (int)NULL;
|
||||
}
|
||||
init_timer(&timer->tim);
|
||||
timer->tim.function = (fct)dotimer;
|
||||
timer->proc = func;
|
||||
timer->arg = arg;
|
||||
timer->tim.data = (unsigned long)timer;
|
||||
timer->tim.expires = expire
|
||||
#if LINUX_VERSION_CODE >= 66318 /* 1.3.14 -- is that right ?? */
|
||||
+ jiffies;
|
||||
#endif
|
||||
;
|
||||
#ifdef MODULE
|
||||
MOD_INC_USE_COUNT;
|
||||
#endif
|
||||
add_timer(&timer->tim);
|
||||
return (int)timer;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MALLOC_NAMES
|
||||
void deb_timeout_old(const char *deb_file, unsigned int deb_line, void (*func)(void *), void *arg, int expire)
|
||||
#else
|
||||
void timeout_old(void (*func)(void *), void *arg, int expire)
|
||||
#endif
|
||||
{
|
||||
typedef void (*fct)(unsigned long);
|
||||
struct timing_old *timer;
|
||||
int s;
|
||||
|
||||
#ifdef CONFIG_MALLOC_NAMES
|
||||
timer = (struct timing_old *)deb_kmalloc(deb_file,deb_line, sizeof(struct timing_old), GFP_ATOMIC);
|
||||
#else
|
||||
timer = (struct timing_old *)kmalloc(sizeof(struct timing_old), GFP_ATOMIC);
|
||||
#endif
|
||||
if(timer == NULL) {
|
||||
printf(" *!* No Timeout!\n");
|
||||
return;
|
||||
}
|
||||
init_timer(&timer->tim.tim);
|
||||
timer->tim.proc = func;
|
||||
timer->tim.arg = arg;
|
||||
timer->tim.tim.function = (fct)dotimer_old;
|
||||
timer->tim.tim.data = (unsigned long)timer;
|
||||
timer->tim.tim.expires = expire
|
||||
#if LINUX_VERSION_CODE >= 66318 /* 1.3.14 -- is that right ?? */
|
||||
+ jiffies;
|
||||
#endif
|
||||
;
|
||||
save_flags(s); cli();
|
||||
if(start != NULL)
|
||||
start->prev = timer;
|
||||
timer->next = start;
|
||||
timer->prev = NULL;
|
||||
start = timer;
|
||||
restore_flags(s);
|
||||
#ifdef MODULE
|
||||
MOD_INC_USE_COUNT;
|
||||
#endif
|
||||
add_timer(&timer->tim.tim);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MALLOC_NAMES
|
||||
void deb_untimeout(const char *deb_file, unsigned int deb_line, int timer)
|
||||
#else
|
||||
void untimeout(int timer)
|
||||
#endif
|
||||
{
|
||||
del_timer(&((struct timing *)timer)->tim);
|
||||
#ifdef CONFIG_MALLOC_NAMES
|
||||
deb_kfree_s(deb_file,deb_line, (void *)timer,sizeof(struct timing));
|
||||
#else
|
||||
kfree_s((void *)timer,sizeof(struct timing));
|
||||
#endif
|
||||
#ifdef MODULE
|
||||
MOD_DEC_USE_COUNT;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MALLOC_NAMES
|
||||
void deb_untimeout_old(const char *deb_file, unsigned int deb_line, void (*func)(void *), void *arg)
|
||||
#else
|
||||
void untimeout_old(void (*func)(void *), void *arg)
|
||||
#endif
|
||||
{
|
||||
droptimer_old(func,arg,1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int crash_time = 300; /* Five minutes until reboot */
|
||||
|
||||
#define get_seg_long(seg,addr) ({ \
|
||||
register unsigned long __res; \
|
||||
__asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \
|
||||
:"=a" (__res):"0" (seg),"m" (*(addr))); \
|
||||
__res;})
|
||||
|
||||
|
||||
void sysdump(const char *msg, struct pt_regs *regs, unsigned long err)
|
||||
{
|
||||
int i,nlim=9;
|
||||
unsigned long flags;
|
||||
unsigned long esp;
|
||||
unsigned short ss;
|
||||
unsigned int dodump=100;
|
||||
|
||||
#if 1
|
||||
static unsigned long lticks = 0;
|
||||
|
||||
if(jiffies-lticks < HZ) {
|
||||
printk("."); return;
|
||||
}
|
||||
#endif
|
||||
save_flags(flags); cli();
|
||||
if(err != 0xf00fdead) {
|
||||
|
||||
if(regs == NULL)
|
||||
esp = (unsigned long) &msg;
|
||||
else
|
||||
esp = (unsigned long) ®s->esp;
|
||||
ss = KERNEL_DS;
|
||||
|
||||
printk(KERN_DEBUG "\n");
|
||||
if(msg != NULL)
|
||||
printk(KERN_EMERG "%s: %08lx\n", msg, err);
|
||||
else
|
||||
nlim += 4;
|
||||
if(regs != NULL) {
|
||||
printk(KERN_EMERG "EIP: %04x:%08lx EFLAGS: %08lx\n", 0xffff & regs->cs,regs->eip,regs->eflags);
|
||||
printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
|
||||
regs->eax, regs->ebx, regs->ecx, regs->edx);
|
||||
printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
|
||||
regs->esi, regs->edi, regs->ebp, esp);
|
||||
printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
|
||||
regs->ds, regs->es, regs->fs, regs->gs, ss);
|
||||
if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page)
|
||||
printk(KERN_EMERG "Corrupted stack page\n");
|
||||
else
|
||||
nlim += 1;
|
||||
|
||||
} else
|
||||
nlim += 5;
|
||||
store_TR(i);
|
||||
if(current != NULL) {
|
||||
printk(KERN_EMERG "Process %s (pid: %d, process nr: %d, stackpage=%08lx)\n",
|
||||
current->comm, current->pid, 0xffff & i, current->kernel_stack_page);
|
||||
} else {
|
||||
printk(KERN_EMERG "No current process\n");
|
||||
}
|
||||
{
|
||||
int nlines = 0, linepos = 0;
|
||||
printk(KERN_EMERG "");
|
||||
for (i=0; dodump && nlines < nlim; i++) {
|
||||
u_long xx = get_seg_long(ss,(i+(unsigned long *)esp));
|
||||
if(dodump > 1 && (xx & 0xfff00000) == 0xbff00000)
|
||||
dodump = 4;
|
||||
#define WRAP(n) do { if((linepos+=(n))>=80) { dodump--; nlines++; linepos=(n); printk("\n" KERN_EMERG); } } while(0)
|
||||
if (xx & 0xFF000000UL) { WRAP(9); printk("%08lx ",xx); }
|
||||
else if(xx & 0x00FF0000UL) { WRAP(7); printk("%06lx ",xx); }
|
||||
else if(xx & 0x0000FF00UL) { WRAP(5); printk("%04lx ",xx); }
|
||||
else { WRAP(3); printk("%02lx ",xx); }
|
||||
#undef WRAP
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
}
|
||||
dodump=0;
|
||||
if(err == 0xDEADBEEF)
|
||||
dodump=0;
|
||||
else if(err == 0xF00DDEAD || err == 0xf00fdead)
|
||||
dodump=(crash_time ? crash_time : 60);
|
||||
else if(jiffies < 60*HZ)
|
||||
dodump=9999999;
|
||||
else
|
||||
dodump=crash_time;
|
||||
if(dodump>0) {
|
||||
if(dodump < 10000) {
|
||||
int j;
|
||||
|
||||
printk(KERN_EMERG "Crash & Burn...");
|
||||
for(j=dodump;j>0;j--) {
|
||||
int i;
|
||||
if((j%30 == 0) || (j%5 == 0 && j < 60) || j < 10) printk("%d...",j);
|
||||
for(i=0;i<9990;i++) udelay(100);
|
||||
}
|
||||
panic("now.");
|
||||
} else {
|
||||
printk(KERN_EMERG "Kernel halted.");
|
||||
for(;;);
|
||||
}
|
||||
}
|
||||
restore_flags(flags);
|
||||
}
|
||||
|
||||
|
||||
void do_i_sleep_on(struct wait_queue **p)
|
||||
{
|
||||
long s = splx(~0);
|
||||
interruptible_sleep_on(p);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void do_sleep_on(struct wait_queue **p)
|
||||
{
|
||||
long s = splx(~0);
|
||||
sleep_on(p);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
char kernel_version[] = UTS_RELEASE;
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
#if defined(__ELF__) || LINUX_VERSION_CODE >= 66304 /* 1.3.0. Is that right??? */
|
||||
#define U
|
||||
#else
|
||||
#define U "_"
|
||||
#endif
|
||||
rename_module_symbol(U "do_i_sleep_on",U "interruptible_sleep_on");
|
||||
rename_module_symbol(U "do_sleep_on",U "sleep_on");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cleanup_module(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,8 +19,14 @@
|
|||
#include <asm/segment.h>
|
||||
|
||||
#ifndef COMPAT_C
|
||||
#ifdef interruptible_sleep_on
|
||||
#undef interruptible_sleep_on
|
||||
extern void interruptible_sleep_on(struct wait_queue ** p);
|
||||
#endif
|
||||
#ifdef sleep_on
|
||||
#undef sleep_on
|
||||
extern void sleep_on(struct wait_queue ** p);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
|
@ -18,7 +18,7 @@ DESTDIR /usr/local/isdn
|
|||
##
|
||||
## What to name the lockfiles.
|
||||
#### =()<LOCKNAME @<LOCKNAME>@>()=
|
||||
LOCKNAME /var/spool/uucp/LCK..%s
|
||||
LOCKNAME /var/lock/LCK..%s
|
||||
##
|
||||
|
||||
## Name of the "KERNEL" flag in system include files (KERNEL, _KERNEL, INKERNEL)
|
||||
|
@ -53,13 +53,13 @@ MLEVEL 3
|
|||
P
|
||||
## C pre-processor flags for normal programs.
|
||||
#### =()<DEFS @<DEFS>@>()=
|
||||
DEFS -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd
|
||||
DEFS -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd
|
||||
## C pre-processor flags for kernel code.
|
||||
## Don't include any KERNEL flags.
|
||||
#### =()<DEFKERNEL @<DEFKERNEL>@>()=
|
||||
DEFKERNEL -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer
|
||||
DEFKERNEL -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer
|
||||
## C pre-processor flags for ISDN card support
|
||||
#### =()<DEFSCARDS @<DEFCARDS>@>()=
|
||||
#### =()<DEFCARDS @<DEFCARDS>@>()=
|
||||
DEFCARDS -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops
|
||||
###
|
||||
## C compiler for the kernel
|
||||
|
@ -67,8 +67,8 @@ DEFCARDS -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops
|
|||
CC gcc
|
||||
###
|
||||
## C compiler for the utilities
|
||||
#### =()<CC @<CC>@>()=
|
||||
CCU gcc -g
|
||||
#### =()<CCU @<CCU>@>()=
|
||||
CCU gcc
|
||||
##
|
||||
## common C compiler flags
|
||||
#### =()<CFLAGS @<CFLAGS>@>()=
|
||||
|
@ -161,48 +161,18 @@ DEBUGGING DO
|
|||
CONF_MOD2 0x00
|
||||
## 0x00, 0x33
|
||||
#### =()<CONF_DEBUG @<CONF_DEBUG>@>()=
|
||||
CONF_DEBUG 0x5006
|
||||
CONF_DEBUG 0x0000
|
||||
## 0x5006, 0xf3df
|
||||
|
||||
|
||||
### ISDN configuration options
|
||||
|
||||
## One TEI per B channel? Seems to be required for US National-1.
|
||||
## DO or DONT.
|
||||
## DO or DONT. DO is currently not supported by the L3 driver.
|
||||
#### =()<MULTI_TEI @<MULTI_TEI>@>()=
|
||||
MULTI_TEI DONT
|
||||
##
|
||||
## Take down Level 2 if idle? (Some PBXes don't like this.)
|
||||
#### =()<L2_DOWN @<L2_DOWN>@>()=
|
||||
L2_DOWN DO
|
||||
##
|
||||
## Grab a TEI when starting up?
|
||||
## Turn this on if the first incoming call is answered too late.
|
||||
## The standards say not to get a TEI at startup, but we may be too slow
|
||||
## otherwise.
|
||||
#### =()<TEI_IMMEDIATE @<TEI_IMMEDIATE>@>()=
|
||||
TEI_IMMEDIATE DONT
|
||||
##
|
||||
## Use a "frozen" random number for TEI assignment, and try a fixed TEI
|
||||
## if assignment of a variable TEI fails?
|
||||
## Necessary with some PBXes; doesn't seem to hurt anywhere.
|
||||
#### =()<TEI_FIXED @<TEI_FIXED>@>()=
|
||||
TEI_FIXED DO
|
||||
##
|
||||
## Immediately answer when an incoming call is detected?
|
||||
## Turn this on if some incoming calls are answered too late.
|
||||
## (Useful for slow systems with lots of debugging, or if things are
|
||||
## run over NFS.)
|
||||
## The standards say not to do this.
|
||||
#### =()<ANSWER_IMMEDIATE @<ANSWER_IMMEDIATE>@>()=
|
||||
ANSWER_IMMEDIATE DONT
|
||||
|
||||
##
|
||||
## Delay when establishing a connection. Range: 1..HZ*2.
|
||||
## Use this when the ISDN switch has problems with accepting data
|
||||
## immediately after establishing a connection.
|
||||
#### =()<UP_DELAY @<UP_DELAY>@>()=
|
||||
UP_DELAY (HZ / 2)
|
||||
### the other configuration stuff is now per-card, see DOKU.
|
||||
|
||||
##
|
||||
## What to call protocol stuff. M_EXPROTO or (M_PROTO+0x40)
|
||||
|
@ -210,7 +180,7 @@ UP_DELAY (HZ / 2)
|
|||
MSG_PROTO M_EXPROTO
|
||||
##
|
||||
## What to call hopefully-expedited data stuff. M_EXDATA or (M_DATA+0x40).
|
||||
#### =()<MSG_DATA @<MSG_DATA>@>()=
|
||||
#### =()<MSG_EXDATA @<MSG_EXDATA>@>()=
|
||||
MSG_EXDATA M_EXDATA
|
||||
##
|
||||
## What to call normal data stuff. M_DATA
|
|
@ -49,7 +49,7 @@ CFLAGS $(DEFS) -g -O2 -W -Wreturn-type -Wshadow -Wcomment
|
|||
#CFLAGS $(DEFS) -g -W -Wreturn-type -Wshadow -Wcomment -D_BSD_SOURCE -D_SYSV_SOURCE
|
||||
## Flags for the "cc -o" line; e.g., -Bstatic on SunOS4.x while debugging.
|
||||
#### =()<LDFLAGS @<LDFLAGS>@>()=
|
||||
LDFLAGS
|
||||
LDFLAGS
|
||||
##
|
||||
## If you need to link in other libraries, add them here
|
||||
#### =()<LIBS @<LIBS>@>()=
|
|
@ -1,14 +1,17 @@
|
|||
;; List of isdn files that are fed to subst.
|
||||
;; Lines beginning with a semi-colon are comment lines.
|
||||
../arnet/Makefile
|
||||
../rate/Makefile
|
||||
../alaw/Makefile
|
||||
../compat/Makefile
|
||||
../streams/Makefile
|
||||
;; ../cards/leonardo/Makefile
|
||||
;; ../ppp_if/Makefile
|
||||
../cards/Makefile
|
||||
../cards/arnet/Makefile
|
||||
../cards/dumb/Makefile
|
||||
../cards/bintec/Makefile
|
||||
../config/Makefile
|
||||
../tools/Makefile
|
||||
../include/config.h
|
||||
../include/f_strings.h
|
||||
../include/f_termio.h
|
||||
|
@ -23,7 +26,7 @@
|
|||
;; ../portman/Makefile
|
||||
../pr_on/Makefile
|
||||
../str_if/Makefile
|
||||
../strppp/Makefile
|
||||
;; ../strppp/Makefile
|
||||
../strslip/Makefile
|
||||
../support/Makefile
|
||||
../timer/Makefile
|
|
@ -1,3 +1,5 @@
|
|||
/* This is from INN. */
|
||||
|
||||
/* $Revision: 1.10 $
|
||||
**
|
||||
** A C version of Henry Spencer's "subst" script.
|
|
@ -6,11 +6,11 @@ P =
|
|||
## =()<CC = @<CC>@>()=
|
||||
CC = gcc
|
||||
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
|
||||
CFLAGS = -O2 -Wall $(DEFS)
|
||||
## =()<DEFSN = @<DEFS>@ >()=
|
||||
DEFSN = -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd
|
||||
DEFSN = -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd
|
||||
## =()<CFLAGSN = @<CFLAGS>@ $(DEFSN)>()=
|
||||
CFLAGSN = -O2 -Wall $(DEFSN)
|
||||
|
||||
|
@ -43,7 +43,7 @@ clean:
|
|||
@sh ../iftrue.sh "-d $(SYS)" "cd $(SYS); make clean"
|
||||
|
||||
|
||||
load: all
|
||||
load:
|
||||
insmod fakeh.o
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
|
@ -1,6 +1,8 @@
|
|||
/**
|
||||
** Streams FAKEH module
|
||||
** Streams FAKEH module, used to pretend we're a Cisco box.
|
||||
** Do turn off keepalives at the other end!
|
||||
**/
|
||||
#undef DO_KEEPALIVES /* not yet..! */
|
||||
|
||||
#include "f_module.h"
|
||||
#include "primitives.h"
|
||||
|
@ -52,18 +54,22 @@ struct fakeh_ {
|
|||
queue_t *qptr;
|
||||
ushort_t offset;
|
||||
|
||||
unsigned connected:1;
|
||||
unsigned do_ethertype:1;
|
||||
#ifdef DO_KEEPALIVES
|
||||
int timer;
|
||||
#ifdef NEW_TIMEOUT
|
||||
int timeout;
|
||||
#endif
|
||||
unsigned connected:1;
|
||||
unsigned long last_a;
|
||||
unsigned long last_b;
|
||||
unsigned long last_c;
|
||||
unsigned long last_d;
|
||||
unsigned char lastmap[4];
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef DO_KEEPALIVES
|
||||
static void
|
||||
fake_h_timer (struct fakeh_ *fakeh)
|
||||
{
|
||||
|
@ -111,27 +117,25 @@ fake_h_timer (struct fakeh_ *fakeh)
|
|||
timeout ((void *)fake_h_timer, fakeh, fakeh->timer * HZ);
|
||||
splx(s);
|
||||
}
|
||||
#endif /* DO_KEEPALIVES */
|
||||
|
||||
|
||||
/* Streams code to open the driver. */
|
||||
static int
|
||||
fakeh_open (queue_t * q, dev_t dev, int flag, int sflag
|
||||
#ifdef DO_ADDERROR
|
||||
,int *err
|
||||
#endif
|
||||
)
|
||||
fakeh_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
|
||||
{
|
||||
register struct fakeh_ *fakeh;
|
||||
|
||||
fakeh = malloc(sizeof(*fakeh));
|
||||
if(fakeh == NULL)
|
||||
return OPENFAIL;
|
||||
ERR_RETURN(-ENOMEM);
|
||||
memset(fakeh,0,sizeof(*fakeh));
|
||||
WR (q)->q_ptr = (char *) fakeh;
|
||||
q->q_ptr = (char *) fakeh;
|
||||
|
||||
fakeh->qptr = q;
|
||||
fakeh->connected = 0;
|
||||
#ifdef DO_KEEPALIVES
|
||||
fakeh->last_a = 0;
|
||||
fakeh->last_b = 0;
|
||||
fakeh->last_c = 0;
|
||||
|
@ -140,6 +144,7 @@ fakeh_open (queue_t * q, dev_t dev, int flag, int sflag
|
|||
fakeh->lastmap[1] = 2;
|
||||
fakeh->lastmap[2] = 1;
|
||||
fakeh->lastmap[3] = 0;
|
||||
#endif
|
||||
|
||||
MORE_USE;
|
||||
return 0;
|
||||
|
@ -157,6 +162,7 @@ fakeh_close (queue_t * q, int dummy)
|
|||
flushq (WR (q), FLUSHALL);
|
||||
fakeh->qptr = NULL;
|
||||
|
||||
#ifdef DO_KEEPALIVES
|
||||
if (fakeh->connected & (fakeh->timer > 0)) {
|
||||
#ifdef NEW_TIMEOUT
|
||||
untimeout (fakeh->timeout);
|
||||
|
@ -164,6 +170,7 @@ fakeh_close (queue_t * q, int dummy)
|
|||
untimeout (fake_h_timer, ipmon);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
free(fakeh);
|
||||
|
||||
LESS_USE;
|
||||
|
@ -177,6 +184,7 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
|
|||
register struct fakeh_ *fakeh = (struct fakeh_ *) q->q_ptr;
|
||||
streamchar *origmp = mp->b_rptr;
|
||||
ushort_t id;
|
||||
int error = 0;
|
||||
|
||||
if (m_getid (mp, &id) != 0) {
|
||||
mp->b_rptr = origmp;
|
||||
|
@ -194,26 +202,32 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
|
|||
goto err;
|
||||
if(!down) {
|
||||
fakeh->offset = z;
|
||||
z += 4;
|
||||
if(fakeh->do_ethertype)
|
||||
z += 2;
|
||||
else
|
||||
z += 4;
|
||||
freemsg(mp);
|
||||
if((mp = allocb(10,BPRI_MED)) != NULL) {
|
||||
m_putid(mp,PROTO_OFFSET);
|
||||
m_puti(mp,z);
|
||||
mp->b_datap->db_type = MSG_PROTO;
|
||||
DATA_TYPE(mp) = MSG_PROTO;
|
||||
origmp = NULL;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case PROTO_CONNECTED:
|
||||
fakeh->connected = 1;
|
||||
#ifdef DO_KEEPALIVES
|
||||
if (fakeh->timer > 0) {
|
||||
#ifdef NEW_TIMEOUT
|
||||
fakeh->timeout =
|
||||
#endif
|
||||
timeout ((void *)fake_h_timer, fakeh, fakeh->timer * HZ);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case PROTO_DISCONNECT:
|
||||
#ifdef DO_KEEPALIVES
|
||||
if(fakeh->connected && (fakeh->timer > 0)) {
|
||||
#ifdef NEW_TIMEOUT
|
||||
untimeout (fakeh->timeout);
|
||||
|
@ -221,32 +235,44 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
|
|||
untimeout (fake_h_timer, ipmon);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
fakeh->connected = 0;
|
||||
break;
|
||||
case PROTO_MODULE:
|
||||
if (strnamecmp (q, mp)) { /* Config information for me. */
|
||||
#ifdef DO_KEEPALIVES
|
||||
long z;
|
||||
#endif
|
||||
|
||||
while (mp != NULL && m_getsx (mp, &id) == 0) {
|
||||
switch (id) {
|
||||
default:
|
||||
goto err;
|
||||
case PROTO_MODULE:
|
||||
break;
|
||||
case PROTO_TYPE_NONE:
|
||||
fakeh->do_ethertype = 0;
|
||||
break;
|
||||
case PROTO_TYPE_ETHER:
|
||||
fakeh->do_ethertype = 1;
|
||||
break;
|
||||
#ifdef DO_KEEPALIVES
|
||||
case FAKEH_SETMAP:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
fakeh->lastmap[0] = z;
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
fakeh->lastmap[1] = z;
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
fakeh->lastmap[2] = z;
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
fakeh->lastmap[3] = z;
|
||||
break;
|
||||
case FAKEH_TIMEOUT:
|
||||
if (m_geti (mp, &z) != 0)
|
||||
if ((error = m_geti (mp, &z)) != 0)
|
||||
goto err;
|
||||
if ((z < 4 || z >= 4090) && (z != 0))
|
||||
goto err;
|
||||
|
@ -257,6 +283,7 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
|
|||
timeout ((void *)fake_h_timer, fakeh, fakeh->timer * HZ);
|
||||
fakeh->timer = z;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (mp != NULL) {
|
||||
|
@ -274,7 +301,7 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
|
|||
return;
|
||||
err:
|
||||
mp->b_rptr = origmp;
|
||||
m_reply (q, mp, EINVAL);
|
||||
m_reply (q, mp, error ? error : -EINVAL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -282,9 +309,9 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
|
|||
static void
|
||||
fakeh_wput (queue_t * q, mblk_t * mp)
|
||||
{
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
putq (q, mp);
|
||||
break;
|
||||
case M_FLUSH:
|
||||
|
@ -307,33 +334,43 @@ fakeh_wsrv (queue_t * q)
|
|||
mblk_t *mp;
|
||||
|
||||
while ((mp = getq (q)) != NULL) {
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
fakeh_proto (q, mp, 1);
|
||||
break;
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
{
|
||||
mblk_t *mh;
|
||||
short offlen;
|
||||
|
||||
if (!canput (q->q_next)) {
|
||||
putbq (q, mp);
|
||||
return;
|
||||
}
|
||||
if (/* XXX */ 0 || mp->b_datap->db_ref > 1 ||
|
||||
mp->b_datap->db_base > mp->b_rptr - 4) {
|
||||
mh = allocb(fakeh->offset+4,BPRI_LO);
|
||||
if(fakeh->do_ethertype)
|
||||
offlen = 2;
|
||||
else
|
||||
offlen = 4;
|
||||
if (/* XXX */ 0 || DATA_REFS(mp) > 1 ||
|
||||
DATA_START(mp) > mp->b_rptr - offlen) {
|
||||
mh = allocb(fakeh->offset+offlen,BPRI_LO);
|
||||
if(mh == NULL) {
|
||||
putbqf(q,mp);
|
||||
return;
|
||||
}
|
||||
mh->b_datap->db_type = mp->b_datap->db_type;
|
||||
mh->b_rptr += fakeh->offset+4;
|
||||
mh->b_wptr += fakeh->offset+4;
|
||||
DATA_TYPE(mh) = DATA_TYPE(mp);
|
||||
mh->b_rptr += fakeh->offset+offlen;
|
||||
mh->b_wptr += fakeh->offset+offlen;
|
||||
linkb (mh, mp);
|
||||
mp = mh;
|
||||
}
|
||||
mp->b_rptr -= 4;
|
||||
*(long *)mp->b_rptr = htonl(0x0F000800);
|
||||
if(fakeh->do_ethertype) {
|
||||
mp->b_rptr -= 2;
|
||||
*(short *)mp->b_rptr = htons(0x0F00);
|
||||
} else {
|
||||
mp->b_rptr -= 4;
|
||||
*(long *)mp->b_rptr = htonl(0x0F000800);
|
||||
}
|
||||
putnext (q, mp);
|
||||
}
|
||||
break;
|
||||
|
@ -342,7 +379,7 @@ fakeh_wsrv (queue_t * q)
|
|||
flushq (q, FLUSHDATA);
|
||||
/* FALL THRU */
|
||||
default:
|
||||
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
|
||||
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
|
||||
putnext (q, mp);
|
||||
continue;
|
||||
} else {
|
||||
|
@ -358,7 +395,7 @@ fakeh_wsrv (queue_t * q)
|
|||
static void
|
||||
fakeh_rput (queue_t * q, mblk_t * mp)
|
||||
{
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
|
||||
case M_FLUSH:
|
||||
if (*mp->b_rptr & FLUSHR) {
|
||||
|
@ -367,7 +404,7 @@ fakeh_rput (queue_t * q, mblk_t * mp)
|
|||
putnext (q, mp); /* send it along too */
|
||||
break;
|
||||
case MSG_PROTO:
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
putq (q, mp); /* queue it for my service routine */
|
||||
break;
|
||||
|
||||
|
@ -385,11 +422,11 @@ fakeh_rsrv (queue_t * q)
|
|||
register struct fakeh_ *fakeh = (struct fakeh_ *) q->q_ptr;
|
||||
|
||||
while ((mp = getq (q)) != NULL) {
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
fakeh_proto (q, mp, 0);
|
||||
break;
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
{
|
||||
unsigned long xhdr;
|
||||
short tlen = dsize (mp);
|
||||
|
@ -409,20 +446,32 @@ fakeh_rsrv (queue_t * q)
|
|||
return;
|
||||
}
|
||||
mp = mq;
|
||||
xhdr = *(long *)mp->b_rptr & ntohl(0xFF00FFFF);
|
||||
mp->b_rptr += 4;
|
||||
if (xhdr != ntohl(0x0F000800)) {
|
||||
if(fakeh->do_ethertype) {
|
||||
xhdr = *(short *)mp->b_rptr & htons(0xFF00);
|
||||
mp->b_rptr += 2;
|
||||
} else {
|
||||
xhdr = *(long *)mp->b_rptr & htonl(0xFF00FFFF);
|
||||
mp->b_rptr += 4;
|
||||
}
|
||||
if (xhdr != (fakeh->do_ethertype ? htons(0x0F00) : htonl(0x0F000800))) {
|
||||
#ifdef DO_KEEPALIVES
|
||||
if(fakeh->do_ethertype) {
|
||||
mp->b_rptr -= 2;
|
||||
xhdr = *(long *)mp->b_rptr & htonl(0xFF00FFFF);
|
||||
mp->b_rptr += 4;
|
||||
}
|
||||
if(xhdr == ntohl(0x8F008035)) {
|
||||
mq = pullupm(mp,12);
|
||||
if (mq == NULL) {
|
||||
freemsg (mp);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
mp = mq;
|
||||
fakeh->last_a = *(long *)mp->b_rptr++;
|
||||
fakeh->last_b = *(long *)mp->b_rptr++;
|
||||
fakeh->last_c = *(long *)mp->b_rptr++;
|
||||
}
|
||||
#endif
|
||||
freemsg(mp);
|
||||
continue;
|
||||
}
|
||||
|
@ -433,7 +482,7 @@ fakeh_rsrv (queue_t * q)
|
|||
case M_ERROR:
|
||||
/* FALL THRU */
|
||||
default:
|
||||
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
|
||||
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
|
||||
putnext (q, mp);
|
||||
continue;
|
||||
} else {
|
|
@ -6,9 +6,9 @@ SYS = linux
|
|||
## =()<CC = @<CC>@>()=
|
||||
CC = gcc
|
||||
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ >()=
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE
|
||||
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
|
||||
CFLAGS = -O2 -Wall $(DEFS)
|
||||
CFLAGS = -g -O2 -Wall $(DEFS)
|
||||
|
||||
## =()<SYS = @<SYS>@>()=
|
||||
SYS = linux
|
||||
|
@ -18,10 +18,10 @@ DESTDIR = /usr/local/isdn
|
|||
SOURCES = x75.c
|
||||
|
||||
doinstall:
|
||||
@cd .. && make install
|
||||
#@$(MAKE) $(MAKEFLAGS) -C .. install
|
||||
|
||||
install.sys:
|
||||
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && make install \
|
||||
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && $(MAKE) $(MAKEFLAGS) install \
|
||||
CFLAGS=\"$(CFLAGS)\" CC=\"$(CC)\""
|
||||
if test ! -d ${DESTDIR} ; then mkdir ${DESTDIR} ; else true ; fi
|
||||
if test ! -d ${DESTDIR}/bin ; then mkdir ${DESTDIR}/bin ; else true ; fi
|
||||
|
@ -41,10 +41,10 @@ install.bin:
|
|||
install: install.sys
|
||||
|
||||
clean:
|
||||
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && make clean"
|
||||
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && $(MAKE) $(MAKEFLAGS) clean"
|
||||
|
||||
run:
|
||||
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && make run"
|
||||
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && $(MAKE) $(MAKEFLAGS) run"
|
||||
|
||||
lib:
|
||||
|
|
@ -13,9 +13,6 @@
|
|||
typedef unsigned char streamchar;
|
||||
#endif
|
||||
|
||||
/* =()<#define UP_DELAY @<UP_DELAY>@>()= */
|
||||
#define UP_DELAY (HZ / 2)
|
||||
|
||||
#ifdef KERNEL
|
||||
/* =()<#define @<NEED_SPL>@_NEED_SPL>()= */
|
||||
#define DONT_NEED_SPL
|
||||
|
@ -45,7 +42,7 @@ typedef unsigned char streamchar;
|
|||
/* =()<#define CONF_MOD2 @<CONF_MOD2>@>()= */
|
||||
#define CONF_MOD2 0x00
|
||||
/* =()<#define CONF_DEBUG @<CONF_DEBUG>@>()= */
|
||||
#define CONF_DEBUG 0x5006
|
||||
#define CONF_DEBUG 0x0000
|
||||
#else
|
||||
#ifdef DO_DEBUGGING
|
||||
|
||||
|
@ -87,18 +84,6 @@ extern char *strdup (const char *xx);
|
|||
extern int writev(int fd, struct iovec *vp, int vpcount);
|
||||
#endif
|
||||
|
||||
/* =()<#define @<ANSWER_IMMEDIATE>@_ANSWER_IMMEDIATE>()= */
|
||||
#define DONT_ANSWER_IMMEDIATE
|
||||
|
||||
/* =()<#define @<TEI_FIXED>@_TEI_FIXED>()= */
|
||||
#define DO_TEI_FIXED
|
||||
|
||||
/* =()<#define @<TEI_IMMEDIATE>@_TEI_IMMEDIATE>()= */
|
||||
#define DONT_TEI_IMMEDIATE
|
||||
|
||||
/* =()<#define @<L2_DOWN>@_L2_DOWN>()= */
|
||||
#define DO_L2_DOWN
|
||||
|
||||
/* =()<#define @<MULTI_TEI>@_MULTI_TEI>()= */
|
||||
#define DONT_MULTI_TEI
|
||||
|
||||
|
@ -106,6 +91,6 @@ extern int writev(int fd, struct iovec *vp, int vpcount);
|
|||
#define ROUTE_PATH "/sbin/route"
|
||||
|
||||
/* =()<#define LOCKNAME "@<LOCKNAME>@">()= */
|
||||
#define LOCKNAME "/var/lock/uucp/LCK..%s"
|
||||
#define LOCKNAME "/var/lock/LCK..%s"
|
||||
|
||||
#endif /* _CONFIG_H */
|
|
@ -55,6 +55,7 @@
|
|||
#include <linux/icmp.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#define ADR(x) x /* in struct ip */
|
||||
#define _F_DONE
|
||||
#endif
|
|
@ -2,6 +2,7 @@
|
|||
#if defined (linux) && defined(__KERNEL__) && defined(MODULE)
|
||||
#define _HAS_MODULE
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
|
@ -19,10 +20,7 @@ int init_module(void)
|
|||
}
|
||||
|
||||
void cleanup_module( void) {
|
||||
if (MOD_IN_USE)
|
||||
printk(KERN_INFO "module is in use, remove delayed\n");
|
||||
else
|
||||
do_exit_module();
|
||||
do_exit_module();
|
||||
}
|
||||
#endif
|
||||
#define MORE_USE MOD_INC_USE_COUNT
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
struct _isdn1_card;
|
||||
|
||||
/*
|
||||
* Download boot code.
|
||||
*/
|
||||
typedef int (*C_boot)(struct _isdn1_card * card, int step, int offset, mblk_t *data);
|
||||
/*
|
||||
* Initiate mode changes. For the D channel, zero means to turn off L1; one
|
||||
* turns L1 back on. For the B channels, see M_*. "listen" on the B
|
||||
|
@ -39,8 +43,13 @@ typedef int (*C_ch_mode) (struct _isdn1_card * card, short channel, char mode,
|
|||
* driver program.
|
||||
*/
|
||||
typedef int (*C_ch_prot) (struct _isdn1_card * card, short channel, mblk_t * proto, int flags);
|
||||
#define CHP_BACKCHAN 01 /* Back channel from the stack to the card */
|
||||
#define CHP_MODLIST 02 /* includes a module list */
|
||||
#define CHP_FROMSTACK 01 /* travels from the channel to the master */
|
||||
#define CHP_MODLIST 02 /* module list */
|
||||
|
||||
/*
|
||||
* Check if the card has data for us.
|
||||
*/
|
||||
typedef int (*C_poll) (struct _isdn1_card * card, short channel);
|
||||
|
||||
/*
|
||||
* Check if buffer space is available
|
||||
|
@ -62,7 +71,9 @@ struct _isdn1_card {
|
|||
* one. */
|
||||
void *ctl; /* Pointer for L1 data structures, card
|
||||
* drivers must not touch this. */
|
||||
#if 0
|
||||
struct _isdn_chan *chan; /* Pointer to array. First is the D channel. */
|
||||
#endif
|
||||
ulong_t modes; /* Modes available on this card. */
|
||||
#define CHM_INTELLIGENT 01 /* If this bit is set, the card is clever and modes>>1 has the ID of the high-level driver. */
|
||||
|
||||
|
@ -71,6 +82,8 @@ struct _isdn1_card {
|
|||
C_data send;
|
||||
C_flush flush;
|
||||
C_candata cansend;
|
||||
C_poll poll; /* check if the card can send more data */
|
||||
C_boot boot;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -93,8 +106,6 @@ extern int isdn2_unregister (struct _isdn1_card *card);
|
|||
*/
|
||||
extern void isdn2_new_state (struct _isdn1_card *card, char state);
|
||||
|
||||
extern void isdn2_new_proto (struct _isdn1_card *card, short channel, mblk_t * proto);
|
||||
|
||||
/*
|
||||
* Callback to test availability of queue space. Cards are not required to call
|
||||
* this.
|
||||
|
@ -117,7 +128,7 @@ extern int isdn2_recv (struct _isdn1_card *card, short channel, mblk_t * data);
|
|||
extern int isdn2_backenable (struct _isdn1_card *card, short channel);
|
||||
|
||||
/*
|
||||
* Callback for mode setup.
|
||||
* Callback for protocol setup.
|
||||
*/
|
||||
extern int isdn2_chprot (struct _isdn1_card * card, short channel, mblk_t * proto, int flags);
|
||||
|
|
@ -27,7 +27,9 @@ enum M_state {
|
|||
typedef struct _isdn2_chan {
|
||||
queue_t *qptr; /* read queue (i.e. going up) for Streams */
|
||||
struct _isdn2_card *card; /* NULL if not assigned to a card */
|
||||
#if 0
|
||||
struct _isdn_chan *chan; /* B channel: data buffer */
|
||||
#endif
|
||||
mblk_t *bufx;
|
||||
#ifdef NEW_TIMEOUT
|
||||
int timer_unblock;
|
||||
|
@ -55,7 +57,7 @@ enum C_state {
|
|||
typedef struct _isdn2_card {
|
||||
struct _isdn1_card *card;
|
||||
struct _isdn2_card *next;
|
||||
struct _isdn2_chan *chan[MAXCHAN]; /* pointer to B/D channels */
|
||||
struct _isdn2_chan *chan[MAXCHAN+1]; /* pointer to B/D channels */
|
||||
#ifdef DO_MULTI_TEI
|
||||
struct _isdn2_state *state[MAX_B];
|
||||
#else
|
|
@ -97,6 +97,8 @@ typedef struct _isdn23_hdr {
|
|||
* compared */
|
||||
uchar_t card; /* Card ID. Counting up from zero. */
|
||||
uchar_t bchans;
|
||||
uchar_t flags; /* Some stuff */
|
||||
#define HDR_CARD_PP 01
|
||||
long id; /* Unique ID of this card, for hardware
|
||||
* config. Usually the first three characters
|
||||
* identify the card and the last is a serial
|
||||
|
@ -146,11 +148,6 @@ typedef struct _isdn23_hdr {
|
|||
/* invalid isdn23_hdr follows */
|
||||
} _hdr_inval; /* Note: There's usually no need to analyze
|
||||
* the errors. */
|
||||
#ifdef DO_BOOT
|
||||
struct { /* Report an error: invalid command */
|
||||
int doboot;
|
||||
} _hdr_boot;
|
||||
#endif
|
||||
struct { /* Get/Set the TEI for a card */
|
||||
uchar_t card;
|
||||
uchar_t TEI; /* TEI_BROADCAST means the TEI is unassigned */
|
||||
|
@ -161,6 +158,11 @@ typedef struct _isdn23_hdr {
|
|||
* feature. However, the implementation gets
|
||||
* somewhat cleaner if the TEI negotiation
|
||||
* handler is just another L3 protocol */
|
||||
struct {
|
||||
uchar_t card;
|
||||
int seqnum;
|
||||
int foffset;
|
||||
} _hdr_load; /* download some code to the card */
|
||||
/*
|
||||
* Setting the TEI to TEI_BROADCAST does the Right Thing WRT to
|
||||
* protocol handlers.
|
||||
|
@ -187,9 +189,7 @@ typedef struct _isdn23_hdr {
|
|||
#define hdr_notify sel._hdr_notify /* I */
|
||||
#define hdr_inval sel._hdr_inval /* Z */
|
||||
#define hdr_tei sel._hdr_tei /* K */
|
||||
#ifdef DO_BOOT
|
||||
#define hdr_boot sel._hdr_boot /* B */
|
||||
#endif
|
||||
#define hdr_load sel._hdr_load /* L */
|
||||
|
||||
/* Magic numbers. */
|
||||
|
||||
|
@ -210,9 +210,7 @@ typedef struct _isdn23_hdr {
|
|||
#define HDR_INVAL 15
|
||||
#define HDR_TEI 16
|
||||
#define HDR_PROTOCMD 17
|
||||
#ifdef DO_BOOT
|
||||
#define HDR_BOOT 18
|
||||
#endif
|
||||
#define HDR_LOAD 18
|
||||
|
||||
#define HDR_FLAGS 0x80
|
||||
#define HDR_NOERROR 0x80
|
|
@ -214,6 +214,7 @@ typedef struct _isdn3_conn {
|
|||
#define MS_DELAYING 040000 /* Wait a bit */
|
||||
#define MS_INITPROTO 0100000 /* card protocols set */
|
||||
#define MS_INITPROTO_SENT 0200000 /* asked for setup */
|
||||
#define MS_NOMINOR 0400000
|
||||
/*
|
||||
* if set and ms->delay == zero, we got killconn. This is a hack but there are
|
||||
* no more bits free.
|
||||
|
@ -374,6 +375,24 @@ void isdn3_repeat (isdn3_conn conn, ushort_t id, mblk_t * data);
|
|||
*/
|
||||
void conn_info (isdn3_conn conn, mblk_t * mb);
|
||||
|
||||
/*
|
||||
* Extract flags from conn info.
|
||||
*/
|
||||
long isdn3_flags(mblk_t *info, uchar_t protocol, uchar_t subprot);
|
||||
#define FL_UPDELAY 017
|
||||
#define FL_UPDELAY_SHIFT 3
|
||||
|
||||
#define FL_L2KEEP 020 /* default is to close L2 */
|
||||
#define FL_TEI_IMMED 040 /* default is to do that later */
|
||||
|
||||
#define FL_POINTOPOINT 0100 /* point-to-point */
|
||||
#define FL_MULTIPOINT1 0200 /* variable ID */
|
||||
#define FL_MULTIPOINT2 0000 /* fixed ID; special -> default */
|
||||
#define FL_MULTIPOINT3 0300 /* fixed TEI */
|
||||
#define FL_POINTMASK 0300
|
||||
|
||||
#define FL_ANS_IMMED 0400 /* default is to delay */
|
||||
|
||||
/**
|
||||
* Convenience macros for handling connection timeouts.
|
||||
*
|
||||
|
@ -394,7 +413,7 @@ void conn_info (isdn3_conn conn, mblk_t * mb);
|
|||
#define timer(T,c) TIMER(T,c,T,VAL_##T,RUN_##T)
|
||||
#define FTIMER(T,c,w,v,f) do { if(!((c)->timerflags & f)) { timeout(w,(c),v); (c)->timerflags |= f; } } while(0)
|
||||
#define ftimer(T,c) FTIMER(T,c,T,VAL_##T,RUN_##T)
|
||||
#define RTIMER(T,c,w,v,f) do { if((c)->timerflags & f) { timeout(w,(c),v); } } while(0)
|
||||
#define RTIMER(T,c,w,v,f) do { if((c)->timerflags & f) { untimeout(w,(c)); timeout(w,(c),v); } } while(0)
|
||||
#define rtimer(T,c) RTIMER(T,c,T,VAL_##T,RUN_##T)
|
||||
|
||||
#endif /* _ISDN_3 */
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#define PREF_NOERR '=' /* Prefix to disable error replies */
|
||||
|
||||
#define CMD_LOADFILE CHAR2('l','F') /* download part of a file */
|
||||
|
||||
#define CMD_FAKEOPEN CHAR2('f','o') /* Indicate that a /dev/isdn device has
|
||||
* been opened. This is used to avoid a
|
||||
* possible race condition */
|
||||
|
@ -91,15 +93,14 @@
|
|||
#define IND_NOCARD CHAR2 ('C','n') /* Card going offline. IND_NOCARD
|
||||
* arg_card. */
|
||||
|
||||
#ifdef DO_BOOT
|
||||
#define IND_BOOT CHAR2('B','T')
|
||||
#endif
|
||||
/*
|
||||
* Arguments. short,long,uchar are encoded decimally, ushort and ulong as
|
||||
* unsigned hex, ident as four letters, strings as-is.
|
||||
*/
|
||||
#define ARG_PREFOUT CHAR2('x','i') /* drop an incoming call */
|
||||
#define ARG_FORCEOUT CHAR2('y','i') /* not implemented yet */
|
||||
#define ARG_PREFOUT CHAR2('x','i') /* drop an incoming call if we're also calling out */
|
||||
#define ARG_FORCEOUT CHAR2('y','i') /* always call back instead of accepting */
|
||||
#define ARG_BACKCALL CHAR2('b','i') /* call back if incoming call rejected because busy */
|
||||
#define ARG_NOREJECT CHAR2('n','j') /* don't send REJ code */
|
||||
#define ARG_FASTDROP CHAR2('f','X')
|
||||
#define ARG_FASTREDIAL CHAR2('f','r')
|
||||
#define ARG_IGNORELIMIT CHAR2('i','l')
|
||||
|
@ -133,6 +134,10 @@
|
|||
#define ARG_OUTNUMS CHAR2 ('o','m') /* outgoing, for build */
|
||||
#define ARG_INNUMS CHAR2 ('i','m') /* incoming, for match */
|
||||
#define ARG_BOTHNUMS CHAR2 ('b','m') /* in+out, default */
|
||||
#define ARG_NEEDLOCAL CHAR2('v','l') /* local numer required, incoming */
|
||||
#define ARG_NEEDREMOTE CHAR2('v','r') /* remote numer required, incoming */
|
||||
#define ARG_NEEDNOLOCAL CHAR2('V','l') /* local numer missing; incoming */
|
||||
#define ARG_NEEDNOREMOTE CHAR2('V','r') /* remote numer missing; incoming */
|
||||
#define ARG_SERVICE CHAR2 ('s','v') /* ulong service type. */
|
||||
#define ARG_BEARER CHAR2 ('v','B') /* vector Bearer Capability. */
|
||||
#define ARG_LLC CHAR2 ('v','L') /* vector Lower Level Compat. */
|
||||
|
@ -154,6 +159,26 @@
|
|||
#define ARG_UID CHAR2('u','i') /* uid of whoever opened the device */
|
||||
#define ARG_GID CHAR2('g','i') /* gid of whoever opened the device */
|
||||
#define ARG_CHARGE CHAR2('C','I') /* what's it cost */
|
||||
|
||||
#define ARG_SEQNUM CHAR2('s','N') /* number of the file */
|
||||
#define ARG_OFFSET CHAR2('o','F') /* offset within the file */
|
||||
|
||||
#define ARG_UPDELAY CHAR2('u','d') /* Delay the data exchange */
|
||||
|
||||
#define ARG_POINTOPOINT CHAR2('p','p') /* point-to-point link */
|
||||
#define ARG_MULTIPOINT1 CHAR2('m','p') /* multipoint link, variable ID */
|
||||
#define ARG_MULTIPOINT2 CHAR2('m','f') /* multipoint link, fixed ID */
|
||||
#define ARG_MULTIPOINT3 CHAR2('m','t') /* multipoint link, fixed TEI */
|
||||
|
||||
#define ARG_ANSWER_IMMED CHAR2('a','i') /* grab the TEI on startup */
|
||||
#define ARG_ANSWER_DELAY CHAR2('a','d') /* grab the TEI when needed */
|
||||
|
||||
#define ARG_TEI_IMMED CHAR2('t','i') /* grab the TEI on startup */
|
||||
#define ARG_TEI_DELAY CHAR2('t','d') /* grab the TEI when needed */
|
||||
|
||||
#define ARG_L2KEEP CHAR2('k','l') /* keep L2 open */
|
||||
#define ARG_L2CLOSE CHAR2('c','l') /* close L2 when no connection is pending */
|
||||
|
||||
/* Other arguments are protocol dependent. See the appropriate include files. */
|
||||
|
||||
#define LISTARG_CONN CHAR2 ('L','C')
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#define MINOR_MAX 240
|
||||
|
||||
#define MAX_B 2 /* max # of B channels per card */
|
||||
#define MAX_B 31 /* max # of B channels per card */
|
||||
#define MAX_D 3 /* max # D channel data connections, i.e. X25 */
|
||||
#define MAXCHAN (MAX_B+MAX_D)
|
||||
#define NMINOR MINOR_MAX
|
|
@ -39,6 +39,9 @@
|
|||
#define PROTO_OUTGOING CHAR2('o','u') /* Outgoing call. */
|
||||
|
||||
#define PROTO_OFFSET CHAR2('o','s') /* do mblk preallocation */
|
||||
#define PROTO_TICK CHAR2('t','k') /* sync the timers */
|
||||
#define PROTO_DATA_IN CHAR2('d','I') /* data are flowing in; for external measuerment */
|
||||
#define PROTO_DATA_OUT CHAR2('d','O') /* data are flowing out; for external measuerment */
|
||||
|
||||
#define PROTO_AT CHAR2('a','t') /* Command. "*at ATD9612521". */
|
||||
#define PROTO_MODULE CHAR2('m','s') /* Setup for a protocol */
|
||||
|
@ -84,4 +87,17 @@
|
|||
* taking down the connection.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
** Common per-module arguments.
|
||||
**/
|
||||
|
||||
#define PROTO_TYPE_NONE CHAR2('.','N')
|
||||
#define PROTO_TYPE_ETHER CHAR2('.','E')
|
||||
#define PROTO_TYPE_PPP CHAR2('.','P')
|
||||
/*
|
||||
* Set the encapsulation type. PROTO_TYPE_NONE means either no networking
|
||||
* data, or IP only.
|
||||
*/
|
||||
|
||||
#endif /* _ISDN_PROTO */
|
|
@ -20,17 +20,17 @@
|
|||
#if MSG_DATA != MSG_EXDATA
|
||||
|
||||
#if M_DATA != MSG_DATA
|
||||
#define CASE_DATA case M_DATA: case MSG_DATA: case MSG_EXDATA: case M_EXDATA:
|
||||
#define CASE_DATA M_DATA: case MSG_DATA: case MSG_EXDATA: case M_EXDATA
|
||||
#else
|
||||
#define CASE_DATA case MSG_DATA: case MSG_EXDATA: case M_EXDATA:
|
||||
#define CASE_DATA MSG_DATA: case MSG_EXDATA: case M_EXDATA
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if M_DATA != MSG_DATA
|
||||
#define CASE_DATA case M_DATA: case MSG_DATA: case M_EXDATA:
|
||||
#define CASE_DATA M_DATA: case MSG_DATA: case M_EXDATA
|
||||
#else
|
||||
#define CASE_DATA case M_DATA: case M_EXDATA:
|
||||
#define CASE_DATA M_DATA: case M_EXDATA
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -38,17 +38,17 @@
|
|||
#if MSG_DATA != MSG_EXDATA
|
||||
|
||||
#if M_DATA != MSG_DATA
|
||||
#define CASE_DATA case M_DATA: case MSG_DATA: case MSG_EXDATA:
|
||||
#define CASE_DATA M_DATA: case MSG_DATA: case MSG_EXDATA
|
||||
#else
|
||||
#define CASE_DATA case MSG_DATA: case MSG_EXDATA:
|
||||
#define CASE_DATA MSG_DATA: case MSG_EXDATA
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if M_DATA != MSG_DATA
|
||||
#define CASE_DATA case M_DATA: case MSG_DATA:
|
||||
#define CASE_DATA M_DATA: case MSG_DATA
|
||||
#else
|
||||
#define CASE_DATA case M_DATA:
|
||||
#define CASE_DATA M_DATA
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -4,15 +4,15 @@ MAKE = make
|
|||
P =
|
||||
|
||||
## =()<CCU = @<CCU>@>()=
|
||||
CCU = gcc-elf -g
|
||||
CCU = gcc
|
||||
## =()<CC = @<CC>@>()=
|
||||
CC = gcc
|
||||
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
|
||||
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
|
||||
CFLAGS = -O2 -Wall $(DEFS)
|
||||
## =()<DEFSN = @<DEFS>@ -I../include >()=
|
||||
DEFSN = -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd -I../include
|
||||
DEFSN = -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd -I../include
|
||||
## =()<CFLAGSN = @<CFLAGS>@ $(DEFSN)>()=
|
||||
CFLAGSN = -O2 -Wall $(DEFSN)
|
||||
## =()<LIBS = @<LIBS>@>()=
|
||||
|
@ -54,7 +54,7 @@ indent:
|
|||
depend: Makefile $(SOURCES)
|
||||
$(CC) -M $(DEFS) $(SOURCES) > .depend
|
||||
|
||||
load: all
|
||||
load:
|
||||
insmod ip_mon.o
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
|
@ -22,6 +22,7 @@
|
|||
#include "streamlib.h"
|
||||
#include "isdn_proto.h"
|
||||
#include "vanj.h"
|
||||
#include "ppp.h"
|
||||
|
||||
static struct module_info ip_mon_minfo =
|
||||
{
|
||||
|
@ -58,7 +59,11 @@ struct _ip_mon {
|
|||
int timeout;
|
||||
#endif
|
||||
short nr;
|
||||
char hastimer;
|
||||
unsigned hastimer:1;
|
||||
unsigned encap:2;
|
||||
#define ENCAP_NONE 0
|
||||
#define ENCAP_ETHER 1
|
||||
#define ENCAP_PPP 2
|
||||
} ip_mon;
|
||||
|
||||
static mblk_t *ip_info[NIP_INFO];
|
||||
|
@ -156,6 +161,7 @@ ip_mon_proto (queue_t * q, mblk_t * mp, char senddown)
|
|||
register struct _ip_mon *ipmon = (struct _ip_mon *) q->q_ptr;
|
||||
char *origmp = mp->b_rptr;
|
||||
ushort_t id;
|
||||
int error = 0;
|
||||
|
||||
if (m_getid (mp, &id) != 0) {
|
||||
mp->b_rptr = origmp;
|
||||
|
@ -180,22 +186,25 @@ ip_mon_proto (queue_t * q, mblk_t * mp, char senddown)
|
|||
goto err;
|
||||
#endif
|
||||
while (mp != NULL && m_getsx (mp, &id) == 0) {
|
||||
int err = EINVAL;
|
||||
|
||||
switch (id) {
|
||||
err:
|
||||
mp->b_rptr = origmp;
|
||||
m_reply(q,mp,EINVAL);
|
||||
mp = NULL;
|
||||
default:
|
||||
goto err;
|
||||
case PROTO_MODULE:
|
||||
break;
|
||||
case PROTO_TYPE_NONE:
|
||||
ipmon->encap = ENCAP_NONE;
|
||||
break;
|
||||
case PROTO_TYPE_PPP:
|
||||
ipmon->encap = ENCAP_PPP;
|
||||
break;
|
||||
case PROTO_TYPE_ETHER:
|
||||
ipmon->encap = ENCAP_ETHER;
|
||||
break;
|
||||
case IP_MON_TIMEOUT:
|
||||
if (m_geti (mp, &x) != 0)
|
||||
if ((error = m_geti (mp, &x)) != 0)
|
||||
goto err;
|
||||
if (x < 2 || x > 99999) {
|
||||
err = EINVAL;
|
||||
if (x < 2 || x > 99999)
|
||||
goto err;
|
||||
}
|
||||
ipmon->timer = x;
|
||||
break;
|
||||
}
|
||||
|
@ -212,6 +221,10 @@ ip_mon_proto (queue_t * q, mblk_t * mp, char senddown)
|
|||
mp->b_rptr = origmp;
|
||||
putnext (q, mp);
|
||||
}
|
||||
return;
|
||||
err:
|
||||
mp->b_rptr = origmp;
|
||||
m_reply (q, mp, error ? error : -EINVAL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -240,14 +253,7 @@ ip_mon_timer (struct _ip_mon *ipmon)
|
|||
}
|
||||
|
||||
static int
|
||||
ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag
|
||||
#ifdef DO_ADDERROR
|
||||
,int *err
|
||||
#define U_ERROR *err
|
||||
#else
|
||||
#define U_ERROR u.u_error
|
||||
#endif
|
||||
)
|
||||
ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
|
||||
{
|
||||
struct _ip_mon *ipmon;
|
||||
static int nr = 1;
|
||||
|
@ -257,15 +263,13 @@ ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag
|
|||
if (sflag == MODOPEN) {
|
||||
ipmon = malloc(sizeof(*ipmon));
|
||||
if(ipmon == NULL)
|
||||
return OPENFAIL;
|
||||
ERR_RETURN(-ENOMEM);
|
||||
} else if (ip_mon.qptr != NULL) {
|
||||
printf ("IP_MON: Master already open\n");
|
||||
U_ERROR = EBUSY;
|
||||
return OPENFAIL;
|
||||
ERR_RETURN(-EBUSY);
|
||||
} else if (dev != 0 || sflag == CLONEOPEN) {
|
||||
printf ("IP_MON: Bad minor number: dev %d, sflag %d\n", dev, sflag);
|
||||
U_ERROR = ENXIO;
|
||||
return OPENFAIL;
|
||||
ERR_RETURN(-ENXIO);
|
||||
} else {
|
||||
ipmon = &ip_mon;
|
||||
do_timeout = (ip_mon.qptr == NULL);
|
||||
|
@ -295,9 +299,9 @@ ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag
|
|||
static void
|
||||
ip_mon_wput (queue_t * q, mblk_t * mp)
|
||||
{
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
putq (q, mp);
|
||||
break;
|
||||
case M_FLUSH:
|
||||
|
@ -312,7 +316,7 @@ ip_mon_wput (queue_t * q, mblk_t * mp)
|
|||
return;
|
||||
}
|
||||
|
||||
static mblk_t *count_packet (mblk_t *mp, char doswap)
|
||||
static mblk_t *count_packet (struct _ip_mon *ipmon, mblk_t *mp, char doswap)
|
||||
{
|
||||
mblk_t *mq;
|
||||
struct ip *ipp;
|
||||
|
@ -326,26 +330,38 @@ static mblk_t *count_packet (mblk_t *mp, char doswap)
|
|||
freemsg(mp);
|
||||
return NULL;
|
||||
}
|
||||
mq = pullupm (mp, sizeof (struct ip)); /* IP header */
|
||||
if(ipmon->encap) {
|
||||
short encap;
|
||||
mq = pullupm (mp, 2); /* encap header */
|
||||
|
||||
if (mq == NULL)
|
||||
return mp;
|
||||
encap = *(short *)(mq->b_rptr);
|
||||
if((ipmon->encap == ENCAP_PPP && encap != htons(PPP_IP)) ||
|
||||
(ipmon->encap == ENCAP_ETHER && encap != htons(ETH_P_IP)))
|
||||
return mq;
|
||||
mp = mq;
|
||||
}
|
||||
mq = pullupm (mp, sizeof (struct ip) + 2); /* IP header */
|
||||
|
||||
if (mq == NULL) {
|
||||
return mp; /* oh well -- don't count it */
|
||||
}
|
||||
ms = splstr();
|
||||
ipp = (struct ip *) mq->b_rptr;
|
||||
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
|
||||
|
||||
switch (ipp->ip_p) {
|
||||
default:
|
||||
localp = remotep = 0;
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct tcphdr));
|
||||
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct tcphdr)+2);
|
||||
|
||||
if (mp != NULL) {
|
||||
struct tcphdr *tcp;
|
||||
|
||||
mq = mp;
|
||||
ipp = (struct ip *) mq->b_rptr;
|
||||
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
|
||||
tcp = (struct tcphdr *) (((char *)ipp) + (ipp->ip_hl << 2));
|
||||
localp = tcp->th_sport;
|
||||
remotep = tcp->th_dport;
|
||||
|
@ -353,13 +369,13 @@ static mblk_t *count_packet (mblk_t *mp, char doswap)
|
|||
return mq;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct udphdr));
|
||||
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct udphdr)+2);
|
||||
|
||||
if (mp != NULL) {
|
||||
struct udphdr *udp;
|
||||
|
||||
mq = mp;
|
||||
ipp = (struct ip *) mq->b_rptr;
|
||||
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
|
||||
udp = (struct udphdr *) (((char *)ipp) + (ipp->ip_hl << 2));
|
||||
localp = udp->uh_sport;
|
||||
remotep = udp->uh_dport;
|
||||
|
@ -367,12 +383,12 @@ static mblk_t *count_packet (mblk_t *mp, char doswap)
|
|||
return mq;
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct icmp));
|
||||
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct icmp) + 2);
|
||||
if(mp != NULL) {
|
||||
struct icmp *icm;
|
||||
|
||||
mq = mp;
|
||||
ipp = (struct ip *) mq->b_rptr;
|
||||
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
|
||||
icm = (struct icmp *) (((char *)ipp) + (ipp->ip_hl << 2));
|
||||
if(doswap) {
|
||||
localp = htons(icm->icmp_code);
|
||||
|
@ -413,6 +429,7 @@ static void
|
|||
ip_mon_wsrv (queue_t * q)
|
||||
{
|
||||
mblk_t *mp;
|
||||
struct _ip_mon *ipmon = (struct _ip_mon *) q->q_ptr;
|
||||
|
||||
if (q == ip_mon.qptr) {
|
||||
while ((mp = getq (q)) != NULL) {
|
||||
|
@ -423,7 +440,7 @@ ip_mon_wsrv (queue_t * q)
|
|||
if (mp->b_rptr - mp->b_wptr != sizeof (struct _monitor)
|
||||
|| mp->b_cont != NULL) {
|
||||
freemsg (mp);
|
||||
putctlx1 (RD (q), M_ERROR, EIO);
|
||||
putctlerr (RD (q), -EIO);
|
||||
flushq (q, FLUSHDATA);
|
||||
splx (ms);
|
||||
return;
|
||||
|
@ -441,21 +458,23 @@ ip_mon_wsrv (queue_t * q)
|
|||
}
|
||||
} else {
|
||||
while ((mp = getq (q)) != NULL) {
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
ip_mon_proto (q, mp, 1);
|
||||
break;
|
||||
CASE_DATA {
|
||||
case CASE_DATA:
|
||||
{
|
||||
mblk_t *mq;
|
||||
|
||||
if(!canput(q->q_next)) {
|
||||
putbq(q,mp);
|
||||
return;
|
||||
}
|
||||
mq = count_packet(mp,0);
|
||||
mq = count_packet(ipmon, mp,0);
|
||||
if(mq != NULL)
|
||||
putnext (q, mq);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
case M_FLUSH:
|
||||
if (*mp->b_rptr & FLUSHW)
|
||||
flushq (q, FLUSHDATA);
|
||||
|
@ -498,7 +517,7 @@ ip_mon_close (queue_t * q, int dummy)
|
|||
static void
|
||||
ip_mon_rput (queue_t * q, mblk_t * mp)
|
||||
{
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
|
||||
case M_FLUSH:
|
||||
if (*mp->b_rptr & FLUSHR) {
|
||||
|
@ -508,7 +527,7 @@ ip_mon_rput (queue_t * q, mblk_t * mp)
|
|||
break;
|
||||
|
||||
case MSG_PROTO:
|
||||
CASE_DATA
|
||||
case CASE_DATA:
|
||||
putq (q, mp); /* queue it for my service routine */
|
||||
break;
|
||||
|
||||
|
@ -526,23 +545,26 @@ static void
|
|||
ip_mon_rsrv (queue_t * q)
|
||||
{
|
||||
mblk_t *mp;
|
||||
struct _ip_mon *ipmon = (struct _ip_mon *) q->q_ptr;
|
||||
|
||||
while ((mp = getq (q)) != NULL) {
|
||||
switch (mp->b_datap->db_type) {
|
||||
switch (DATA_TYPE(mp)) {
|
||||
case MSG_PROTO:
|
||||
ip_mon_proto (q, mp, 0);
|
||||
break;
|
||||
CASE_DATA {
|
||||
mblk_t *mq;
|
||||
case CASE_DATA:
|
||||
{
|
||||
mblk_t *mq;
|
||||
|
||||
if(!canput(q->q_next)) {
|
||||
putbq(q,mp);
|
||||
return;
|
||||
if(!canput(q->q_next)) {
|
||||
putbq(q,mp);
|
||||
return;
|
||||
}
|
||||
mq = count_packet(ipmon, mp,1);
|
||||
if(mq != NULL)
|
||||
putnext (q, mq);
|
||||
}
|
||||
mq = count_packet(mp,1);
|
||||
if(mq != NULL)
|
||||
putnext (q, mq);
|
||||
} break;
|
||||
break;
|
||||
default:
|
||||
putnext (q, mp);
|
||||
continue;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue