Öffnen und Schließen

Unser Treiber kann eine Schnittstelle beim Laden des Moduls oder beim Hochfahren des Kernels suchen. Bevor die Schnittstelle Pakete transportieren kann, muß der Kernel sie aber öffnen und ihr eine Adresse zuweisen. Dies geschieht als Reaktion auf einen ifconfig-Aufruf.

Wenn ifconfig verwendet wird, um einer Schnittstelle eine Adresse zuzuweisen, erledigt es zwei Aufgaben. Zunächst weist es die Adresse der Schnittstelle mit Hilfe des ioctl-Befehls SIOCSIFADDR (Socket I/O Control Set Interface ADDRess) zu und dann setzt es das IFF_UP-Bit in dev->flag durch den ioctl-Befehl SIOCSIFFLAGS (Socket I/O Control Set Interface FLAGS), um die Schnittstelle zu aktivieren.

Was das Gerät angeht, macht ioctl(SIOCSIFADDR) nichts. Es wird keine Treiberfunktion aufgerufen — die Aufgabe ist geräteunabhängig und wird vom Kernel erledigt. Der zweite ioctl-Befehl (SIOCSIFFLAGS) ruft dann allerdings die open-Methode für das Gerät auf.

Entsprechend ruft ifconfig beim Herunterfahren einer Schnittstelle ioctl(SIOCSIFFLAGS) auf, um das Flag IFF_UP zu löschen. Anschließend wird die stop-Methode aufgerufen.

Beide Gerätemethoden geben im Erfolgsfall 0 und den üblichen negativen Wert bei Fehlern zurück.

Was den eigentlichen Code angeht, muß der Treiber in vielerlei Hinsicht das gleiche machen, wie auch bei Zeichen- und Block-Treibern. open fordert alle benötigten Systemressourcen an und teilt der Schnittstelle mit, jetzt aktiv zu sein; stop fährt die Schnittstelle herunter und gibt die Systemressourcen frei. Es sind allerdings noch eine Reihe weiterer Schritte durchzuführen.

Zunächst muß die Hardware-Adresse aus dem Hardware-Gerät nach dev->dev_addr kopiert werden, bevor die Schnittstelle mit der Außenwelt kommunizieren kann. Die Hardware-Adresse kann je nach Geschmack des Treibers beim Suchen nach dem Gerät oder beim Öffnen zugewiesen werden. Die Software-Schnittstelle snull macht das in open; hier wird einfach eine Hardware-Nummer vorgetäuscht, indem ein ASCII-String der Länge ETH_ALEN verwendet wird (also der Länge von Ethernet-Hardware-Adressen).

Die Methode open sollte auch die Übertragungswarteschlange der Schnittstelle starten (und damit Pakete zur Übertragung akzeptieren), sobald die Schnittstelle zum Senden von Daten bereit ist. Der Kernel stellt dafür eine Funktion bereit:


voidnetif_start_queue(structnet_device*dev);

Der Code von open in snull sieht so aus:


intsnull_open(structnet_device*dev)
{
MOD_INC_USE_COUNT;

/*request_region(),request_irq(),....(wiefops->open)*/

/*
*DieHardware-AdressederKartezuweisen:Wirverwenden
*"\0SNULx",wobeix0oder1ist.DasersteByteist'\0',um
*Multicast-Adressenzuvermeiden(dasersteBytein
*Multicast-Adressenistungerade).
*/
memcpy(dev->dev_addr,"\0SNUL0",ETH_ALEN);
dev->dev_addr[ETH_ALEN-1]+=(dev-snull_devs);/*dieNummer*/

netif_start_queue(dev);
return0;
}

Wie Sie sehen, muß man bei Abwesenheit echter Hardware in der open-Methode nur wenig tun. Das gleiche gilt auch für die stop-Methode; diese macht nur die Operationen von open rückgängig. Aus diesem Grund wird die Funktion, die stop implementiert, oft close oder release genannt.


intsnull_release(structnet_device*dev)
{
/*Ports,IRQusw.freigeben--wiefops->close*/

netif_stop_queue(dev);/*keineUebertragungmehrmoeglich*/
MOD_DEC_USE_COUNT;
return0;
}

Die Funktion


voidnetif_stop_queue(structnet_device*dev);

ist das Gegenstück zu netif_start_queue; sie markiert das Gerät als nicht mehr übertragungsfähig. Diese Funktion muß aufgerufen werden, wenn die Schnittstelle geschlossen wird (was in der Methode stop geschieht), kann aber auch dazu verwendet werden, die Übertragung vorübergehend anzuhalten, was im nächsten Abschnitt erläutert wird.