Copyright ã1995 by NeXT Computer, Inc.  All Rights Reserved.

IOTokenRing

Inherits From:	IODirectDevice : IODevice : Object

Conforms To:	IONetworkDeviceMethods

Declared In:	driverkit/IOTokenRing.h

Class Description

IOTokenRing is an abstract class for controlling Token Ring devices. It provides a framework for sending and receiving packets (also known as frames), handling interrupts, and setting and detecting timeouts. It also provides an IONetwork instance that connects the driver with the kernel networking subsystem, as well as an I/O thread from which most of the IOTokenRing instance methods are invoked. To write a Token Ring driver, you create a subclass of IOTokenRing.

Implementing a Subclass

Your subclass of IOTokenRing must do the following:

·	Implement probe: and initFromDeviceDescription:. These let your driver create instances of itself. The implementation of probe: should allocate an instance, if necessary, and invoke initFromDeviceDescription:. See the IODevice specification for more information on implementing probe:.

·	Implement resetAndEnable:, and interruptOccurred. (interruptOccurred is documented in the IODirectDevice specification.)

·	Implement either transmit: or outputPacket:address:.

IONetwork Method Usage

When your driver invokes IONetwork's method handleInputPacket:extra: to hand off a packet to the kernel, it needs to pass a valid pointer to a tokenHeader_t struct as the extra: argument. Passing 0 for this argument (as ethernet drivers do) won't suffice.

IONetworkDeviceMethods Protocol Implementation

In IOEthernet's implementation, finishInitialization invokes resetAndEnable:YES if [self isRunning] == YES.

Recommended Reading

Besides the documentation for your hardware, see the references in the ªNetwork Driversº section of ªSuggested Readingº in the Appendix to help you write a Token Ring driver.

Instance Variables

None declared in this class.

Adopted Protocols

IONetworkDeviceMethods	- allocateNetbuf
- finishInitialization
- outputPacket:address:
- performCommand:data:

Method Types

Creating and destroying IOTokenRing instances	
- free
- initFromDeviceDescription:
- attachToNetworkWithAddress:

Transmitting packets	- transmit:

Setting and handling hardware timeouts	
- setRelativeTimeout:
- relativeTimeout
- clearTimeout

Setting and getting the state of the hardware	
- setRunning:
- isRunning
- resetAndEnable:

Setting and getting maximum sizes
- setMaxInfoFieldSize:
- maxInfoFieldSize

Getting other configuration information	
- earlyTokenEnabled
- nodeAddress
- ringSpeed
- shouldAutoRecover

Instance Methods

attachToNetworkWithAddress:

- (IONetwork *)attachToNetworkWithAddress:(token_addr_t)address

Invokes registerDevice, sets the node address to address, creates an IONetwork instance, and attaches to the network subsystem by sending the IONetwork an initForNetworkDevice:... message. Besides starting up the IP protocol stack for the device, this method also starts up an 802.2-compliant Null SAP interface. Finally, this method logs a message stating the node address. Returns the IONetwork instance just created.

To determine the value to specify for address, first invoke nodeAddress. If nodeAddress returns a nonzero value, use that value. Otherwise, use the hardware's burnt-in address. 

You invoke this method at the end of your implementation of initFromDeviceDescription:. You must invoke resetAndEnable:NO before invoking this method, as described under initFromDeviceDescription:, later in this specification.

clearTimeout

- (void)clearTimeout

If a transmission timeout is scheduled, unschedules the timeout. This method is normally invoked from a subclass's implementation of interruptOccurred.

See also:  - setRelativeTimeout:, - relativeTimeout

earlyTokenEnabled

- (BOOL)earlyTokenEnabled

Returns YES if Early Token Release (ETR) is supported by the station; otherwise, returns NO. Stations that support ETR can co-exist with non-ETR stations in the ring. The value returned by this method is set by initFromDeviceDescription:.

free

- free

Frees the IOTokenRing instance and its resources and returns nil.

initFromDeviceDescription:

- initFromDeviceDescription:(IODeviceDescription *)devDesc 

Invokes the superclass implementation, starts an I/O thread (using startIOThread), and sets the device name, kind, and unit. 

Next, it examines the device configuration table for such parameters as ring speed and early token enablement. It then sets the maximum packet size, based on the ring speed. If the ring speed is 4 megabits per second, the maximum info field size is MAC_INFO_4MB. If the ring speed is 16, the maximum info field size is MAC_INFO_16MB. (The maximum packet size is the maximum info field size plus MAC_HDR_MAX.) These constants are defined in the header file bsd/net/tokendefs.h.

Subclasses of IOTokenRing should implement this method so that it invokes the superclass version of initFromDeviceDescription:, makes sure the configuration is correct, invokes setMaxInfoFieldSize:, does any other device-specific software and hardware initialization, and invokes attachToNetworkWithAddress:. 

This method should free the instance and return nil on failure; otherwise, it should return self. A rough example of implementing this method is below.

- initFromDeviceDescription:(IODeviceDescription *)devDesc
{
    if([super initFromDeviceDescription:devDesc] == nil) 
        return nil;

    /* Perform any 1-time hardware initialization. */

    /* Finish initializing the hardware. */
    [self resetAndEnable:NO];  

    /* Do any additional software initialization; set the max info 
     * field size; get the node address (as described in the 
     * documentation of attachToNetworkWithAddress: */

    IOLog("%s: Token-Ring at port=%x irq=%d dma=%d speed=%d\n",
        [self name], base, myIrq, myDmaChan, [self ringSpeed]);

    network = [super attachToNetworkWithAddress:myNodeAddress];
    return self;
}

isRunning

- (BOOL)isRunning

Returns YES if the hardware is currently inserted in the ring; otherwise, returns NO.

See also:  - setRunning:

maxInfoFieldSize

- (unsigned int)maxInfoFieldSize

Returns the maximum size of the info field. This value is used by allocateNetbuf. It's also used as the maximum transfer unit specified to the network subsystem.

See also:  - setMaxInfoFieldSize:

nodeAddress

- (token_addr_t)nodeAddress

Returns the node address for this station. Currently, only burnt-in addresses are supported. In the future, however, IOTokenRing will be able to initialize the node address from the device configuration table. The value returned by this method is set by attachToNetworkWithAddress:.

relativeTimeout

- (unsigned int)relativeTimeout

Returns the number of milliseconds until a transmission timeout will occur. If no transmission timeout is currently scheduled, this method returns zero.

See also:  - clearTimeout, - setRelativeTimeout:

resetAndEnable:

- (BOOL)resetAndEnable:(BOOL)enable 

Does nothing and returns YES. Subclasses of IOTokenRing must implement this method so that it resets and initializes the hardware. This method should invoke setRunning: to record the basic state of the device.

If enable is YES and the station is already in the ring, this method should do nothing but invoke setRunning: with a YES argument and return YES. If enable is YES and the station isn't in the ring, interrupts should be enabled and the station inserted in the ring; setRunning: should be used to update the device running status to YES or NO, depending on the success of the insertion. If enable is NO, interrupts should be left disabled, the station should be removed from the ring, and setRunning: should be invoked with a NO argument. 

This method should return YES if it encounters no errors (no matter what value enable has); if it encounters errors, it should return NO. For example, the result from resetAndEnable:NO should be YES if the reset is successful.

The only time this method is invoked, with the exception of any invocations from your IOTokenRing subclass implementation, is during initialization. Specifically, resetAndEnable:YES is invoked once in the I/O thread after attachToNetworkWithAddress: is invoked. 

See also:  - setRunning:

ringSpeed

- (unsigned int)ringSpeed

Returns the speed of the Token Ring, in megabits per second. This value, which is either 4 or 16, is set to the amount specified by the ªRing Speedº key in the device configuration table. If the value is missing or invalid, the ring speed is set to 16.

setMaxInfoFieldSize:

- (void)setMaxInfoFieldSize:(unsigned int)size 

Sets the maximum size of the info field. This value is used by allocateNetbuf. It's also used as the maximum transfer unit specified to the network subsystem. Your subclass should invoke this method in its implementation of initFromDeviceDescription:.

See also:  - maxInfoFieldSize

setRelativeTimeout:

- (void)setRelativeTimeout:(unsigned int)timeout 

Schedules a timeout to occur in timeout milliseconds. When timeout milliseconds pass without the timeout being cleared (with clearTimeout), timeoutOccurred is invoked. 

See also:  - clearTimeout, - relativeTimeout, - timeoutOccurred (IODirectDevice)

setRunning:

- (void)setRunning:(BOOL)running 

Sets whether the hardware is inserted into the ring. The value of running should be YES to indicate that the hardware is inserted; otherwise, it should be NO. This method is invoked only by methods in IOTokenRing subclassesÐnot by IOTokenRing's own method implementations. You should invoke this method in your implementation of resetAndEnable:.

See also:  - isRunning

shouldAutoRecover

- (BOOL)shouldAutoRecover

Returns YES if the device should try to recover from a failed attempt at inserting itself into the ring or from an unexpected removal from the ring; otherwise, returns NO. IOTokenRing sets this value depending on the value of the ªAuto Recoveryº key in the device configuration table. This method is provided as a convenience for IOTokenRing subclasses that support automatic recovery.

transmit:

- (void)transmit:(netbuf_t)packet 

Does nothing except free packet, using the nb_free() function. This method is invoked by the kernel networking subsystem when the hardware should transmit a packet. 

Subclasses of IOTokenRing can implement this method or they can reimplement the method that invokes it: outputPacket:address:.   To determine the number of bytes of data to be transmitted, use the nb_size() function. To get a pointer to the data, use nb_map(). After getting the information you need from packet, you should free it with nb_free().

See also:  - outputPacket:address: (IONetworkDeviceMethods protocol)