Annotation of driverkit/libDriver/Kernel/IOTokenRing.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*     Copyright (c) 1993 NeXT Computer, Inc.  All rights reserved. 
                     25:  *
                     26:  * TokenRing.m - TokenRing device-independent abstract superclass
                     27:  *
                     28:  *     The TokenRing superclass contains the device-independent functions
                     29:  *     that are common to most token-ring drivers.  The hardware-specific
                     30:  *     driver should be a subclass of TokenRing.
                     31:  *
                     32:  * HISTORY
                     33:  * 25-Jan-93 Joel Greenblatt at NeXT 
                     34:  *     created
                     35:  *      
                     36:  */
                     37: 
                     38:  
                     39: #define MACH_USER_API  1
                     40:  
                     41: 
                     42: #import <mach/mach_types.h>
                     43: #import <mach/message.h>
                     44: #import <machkit/NXLock.h>
                     45: #import <driverkit/generalFuncs.h>
                     46: #import <driverkit/interruptMsg.h>
                     47: #import <driverkit/kernelDriver.h>
                     48: #import <netinet/in.h>
                     49: #import <kernserv/prototypes.h>
                     50: #import <net/tokensr.h>
                     51: #import <sys/errno.h>
                     52: 
                     53: #import <driverkit/IOTokenRing.h>
                     54: 
                     55: static void TokenRingTimeout(IOTokenRing *device);
                     56: 
                     57: static char    TRDeviceName[] = "tr";
                     58: static char    TRDeviceType[] = "TokenRing";
                     59: static int     TRDeviceCount = 0;
                     60: 
                     61: extern int ipforwarding; // flag in kernel to control ip lan-to-lan routing
                     62: 
                     63: /*
                     64:  * Attach virtual drivers
                     65:  */
                     66: extern void vtrip_config(int unit, int flags, int mtu, int tokpri);
                     67: 
                     68: #define IP_SRCROUTING          0x1     /* enable IP source routing */
                     69: 
                     70: 
                     71: /*
                     72:  * Configuration strings in Instance.table
                     73:  */
                     74: static const char ITRingSpeed[] =              "Ring Speed";
                     75: static const char ITNodeAddress[] =            "Node Address";
                     76: static const char ITGroupAddress[] =           "Group Address";
                     77: static const char ITFunctionalAddress[] =      "Functional Address";
                     78: static const char ITEarlyToken[] =             "16Mb Early Token";
                     79: static const char ITAutoRecovery[] =           "Auto Recovery";
                     80: static const char ITIPAttach[] =               "IP Attach";
                     81: static const char ITIPMtu[] =                  "IP Mtu";
                     82: static const char ITIPTokenPriority[] =        "IP Token Priority";
                     83: static const char ITIPSourceRouting[] =        "IP 802.5 Source Routing";
                     84: 
                     85: static const char ITipFowarding[] =            "IP LAN-to-LAN Routing";
                     86: 
                     87: 
                     88: @interface DriverCmdtr:Object
                     89: {
                     90: @private
                     91:     port_t     _driverPort_kern;
                     92:     id         _interLock;
                     93: #define OPDONE         1
                     94: #define BUSY           2
                     95: #define IDLE           3
                     96:     int                _oper;
                     97: #define RESET_ON       1
                     98: #define RESET_OFF      2
                     99: #define TERMINATE      4
                    100:     int                _ret;
                    101: }
                    102: @end
                    103: 
                    104: @implementation DriverCmdtr
                    105: 
                    106: - initPort:(port_t)port
                    107: {
                    108:     [super init];
                    109: 
                    110:     _interLock = [[NXConditionLock alloc] initWith:IDLE];
                    111:     _driverPort_kern = IOGetKernPort(port);
                    112:     
                    113:     return self;
                    114: }
                    115: 
                    116:  
                    117: - free
                    118: {
                    119:     [_interLock free];
                    120:     
                    121:     port_release(_driverPort_kern);
                    122:     
                    123:     return [super free];
                    124: }
                    125: 
                    126: - (int)oper
                    127: {
                    128:     return (_oper);
                    129: }
                    130: 
                    131: - (void)done:(int)ret
                    132: {
                    133:     if ([_interLock condition] == BUSY) {
                    134:        [_interLock lock];
                    135:        _ret = ret;
                    136:        [_interLock unlockWith:OPDONE];
                    137:     }
                    138: }
                    139: 
                    140: - (int)send:(int)oper
                    141: {
                    142:     msg_header_t       msg = { 0 };
                    143:     int                        result;
                    144:     
                    145:     [_interLock lockWhen:IDLE];
                    146:         
                    147:     _oper = oper;
                    148:     
                    149:     msg.msg_size = sizeof (msg);
                    150:     msg.msg_remote_port = _driverPort_kern;
                    151:     msg.msg_id =  IO_COMMAND_MSG;
                    152:     
                    153:     [_interLock unlockWith:BUSY];
                    154:     
                    155:     result = msg_send_from_kernel(&msg, MSG_OPTION_NONE, 0);
                    156:     if (result == SEND_SUCCESS) {
                    157:        [_interLock lockWhen:OPDONE];
                    158:        result = _ret;
                    159:     }
                    160:     else
                    161:        [_interLock lock];
                    162:     
                    163:     [_interLock unlockWith:IDLE];
                    164:     
                    165:     return (result);
                    166: }
                    167: 
                    168: @end
                    169: 
                    170: @implementation IOTokenRing
                    171: 
                    172: /*
                    173:  * Private Methods
                    174:  */
                    175:  
                    176: /*
                    177:  * Set maximum packet size based on ring speed.  Unfortunately, there may
                    178:  * be different interpretations for token-ring.  Subclass can override if it
                    179:  * disagrees, or must reduce due to implementation limitations.
                    180:  */
                    181: -(void)_set8025FrameSizes
                    182: {
                    183:     /*
                    184:      * The maximum allowable packet size is a function of ring speed 
                    185:      * (per IEEE 802.5 standard). 
                    186:      */
                    187:     if(_ringSpeed == 4) {
                    188:        _maxInfoFieldSize = MAC_INFO_4MB; 
                    189:     }   
                    190:     if(_ringSpeed == 16) {
                    191:        _maxInfoFieldSize = MAC_INFO_16MB;
                    192:     }
                    193: }
                    194: 
                    195: /*
                    196:  * Get info from Instance.table (some params are just saved for
                    197:  * optional subclass use).
                    198:  */
                    199: - (int)_getInstanceTable:(IODeviceDescription *)devDesc
                    200: {
                    201: 
                    202:     IOConfigTable      *confTable;
                    203:     const char         *s;
                    204: 
                    205:     confTable = [devDesc configTable];
                    206:     if(confTable == nil) {
                    207:        IOLog("%s: couldn't get Instance%d.table\n",
                    208:            [self name], [self unit]);
                    209:        return 1;
                    210:     }
                    211: 
                    212:     /*
                    213:        * MAC layer parms ...
                    214:        */
                    215: 
                    216:     s = [confTable valueForStringKey: ITRingSpeed];            // ring speed
                    217:     if (!strcmp(s, "4")) 
                    218:        _ringSpeed = 4;
                    219:     else if (strcmp(s, "16") == 0) 
                    220:        _ringSpeed = 16;
                    221:     else {
                    222:        IOLog("%s: invalid ring speed in Instance.table\n", [self name]);
                    223:        _ringSpeed = 16;
                    224:     }
                    225:     [confTable freeString:s];
                    226: 
                    227:     s = [confTable valueForStringKey: ITNodeAddress];  // Node address
                    228: #if 0
                    229:     /*
                    230:      * Unsupported for now.  The subclass is free to access the config
                    231:      * table directly to read the node address and use it.
                    232:      */
                    233:     if (strcmp(s, "")) {
                    234:        //_nodeAddress
                    235:        IOLog("%s: cannot override burned-in addr\n", [self name]);
                    236:     } 
                    237:     else 
                    238:        IOLog("%s: will use burned-in node address\n", [self name]);
                    239: #endif
                    240:     [confTable freeString:s];
                    241: 
                    242: #if 0
                    243:     s = [confTable valueForStringKey: ITGroupAddress]; // Group addr
                    244:     if (strcmp(s, "")) {
                    245:        //_groupAddress 
                    246:        IOLog("%s: cannot set Group addr\n", [self name]);
                    247:     } 
                    248:     else 
                    249:        IOLog("%s: no Group Addresses enabled\n", [self name]);
                    250:     [confTable freeString:s];
                    251: 
                    252:     s = [confTable valueForStringKey: ITFunctionalAddress];    // Func addr
                    253:     if (strcmp(s, "")) {
                    254:        //_functionalAddress
                    255:        IOLog("%s: cannot set Functional addr\n", [self name]);
                    256:     } 
                    257:     else 
                    258:        IOLog("%s: no Functional Addresses enabled\n", [self name]);
                    259:     [confTable freeString:s];
                    260: #endif 0
                    261: 
                    262:     s = [confTable valueForStringKey: ITEarlyToken];   // early token
                    263:     if (!strcmp(s, "YES")) 
                    264:        _flags._isEarlyTokenEnabled = 1;
                    265:     else 
                    266:        _flags._isEarlyTokenEnabled = 0;
                    267:     [confTable freeString:s];
                    268: 
                    269:     s = [confTable valueForStringKey: ITAutoRecovery]; // auto recov
                    270:     if (!strcmp(s, "YES")) 
                    271:        _flags._shouldAutoRecover = 1;
                    272:     else 
                    273:        _flags._shouldAutoRecover = 0;
                    274:     [confTable freeString:s];
                    275: 
                    276: #if 0
                    277:     /*
                    278:      * IP params ...
                    279:      */
                    280: 
                    281:     s = [confTable valueForStringKey: ITIPAttach];             // attach i/f
                    282:     if (!strcmp(s, "YES")) 
                    283:        _flags._shouldAttachIP = 1;
                    284:     else 
                    285:        _flags._shouldAttachIP = 0;
                    286:     [confTable freeString:s];
                    287: 
                    288:     s = [confTable valueForStringKey: ITIPMtu];                // mtu
                    289:     _ipMtu = strtol(s, 0, 10);
                    290:     [confTable freeString:s];
                    291: 
                    292:     s = [confTable valueForStringKey: ITIPTokenPriority];      // token pri
                    293:     if (!strcmp(s, "DEFAULT")) 
                    294:        _ipTokenPriority = 8;
                    295:     else 
                    296:        _ipTokenPriority = strtol(s, 0, 10);
                    297:     [confTable freeString:s];
                    298: 
                    299:     s = [confTable valueForStringKey: ITIPSourceRouting];      // source rtng
                    300:     if (!strcmp(s, "YES")) 
                    301:        _flags._doesIPSourceRouting = 1;
                    302:     else 
                    303:        _flags._doesIPSourceRouting = 0;
                    304:     [confTable freeString:s];
                    305: 
                    306:     /*
                    307:      * Allow fowarding of packets between interfaces in a multi-homed
                    308:      * host (a don't care for hosts with single i-faces).  Note that
                    309:      * if no param is specified we don't touch ipforwarding (as of
                    310:      * this writing this parameter is left out of our Default.table).
                    311:      */
                    312:     s = [confTable valueForStringKey: ITipFowarding]; 
                    313:     if (!strcmp(s, "YES")) 
                    314:        ipforwarding = 1;
                    315:     if (!strcmp(s, "NO")) 
                    316:        ipforwarding = 0;
                    317:     [confTable freeString:s];
                    318: #endif 0
                    319:   
                    320:     /*
                    321:      * Set these defaults here for now.  We'll support them in the instance
                    322:      * table eventually.
                    323:      */
                    324:     _flags._shouldAttachIP = 1;
                    325:     _ipMtu = 8100;
                    326:     _ipTokenPriority = 8;
                    327:     _flags._doesIPSourceRouting = 1;
                    328:     ipforwarding = 0;
                    329: 
                    330:     return 0;
                    331: }
                    332: 
                    333: 
                    334: /*
                    335:  * Public Methods
                    336:  */
                    337: 
                    338: /*
                    339:  * Normally invoked from subclass method of same name.
                    340:  */
                    341: - initFromDeviceDescription:(IODeviceDescription *)devDesc
                    342: {
                    343:     char       devName[8];
                    344:     int        unit;
                    345:     
                    346:     if ([super initFromDeviceDescription:devDesc] == nil)
                    347:        return nil;
                    348: 
                    349:     if ([self startIOThread] != IO_R_SUCCESS) {
                    350:        [self free]; 
                    351:        return nil;
                    352:     }
                    353:     
                    354:     unit = TRDeviceCount++;
                    355:   
                    356:     sprintf(devName, "%s%d", TRDeviceName, unit);
                    357:     [self setName:devName];
                    358:     [self setDeviceKind:TRDeviceType];
                    359:     [self setUnit:unit];
                    360: 
                    361:     if([self _getInstanceTable:devDesc]) {
                    362:        [self free]; 
                    363:        return nil;
                    364:     }
                    365: 
                    366:     _driverCmd = [[DriverCmdtr alloc] initPort:[self interruptPort]];
                    367: 
                    368:     [self _set8025FrameSizes]; 
                    369:     
                    370:     return self;
                    371: }
                    372: 
                    373: - free
                    374: {
                    375:     [self clearTimeout];
                    376:     if (_driverCmd) {
                    377:        [_driverCmd send:TERMINATE];
                    378:        [_driverCmd free];
                    379:     }
                    380:     if (_netif)
                    381:        [_netif free];
                    382:     return [super free];
                    383: }
                    384: 
                    385: /*
                    386:  * Subclass must invoke this method to attach our networking interfaces
                    387:  * (typically done after successful hardware init).
                    388:  */
                    389: - (IONetwork *)attachToNetworkWithAddress:(token_addr_t)addrs
                    390: {
                    391:     int        vtripf = 0; 
                    392:     int                i;
                    393: 
                    394:     [self registerDevice];
                    395: 
                    396:     _nodeAddress = addrs;
                    397:     
                    398:     /*
                    399:      * Netif for "real" (hdw) driver interface.
                    400:      */
                    401:     _netif = [[IONetwork alloc] initForNetworkDevice:self
                    402:        name:TRDeviceName unit:[self unit]
                    403:        type:IFTYPE_TOKENRING
                    404:        maxTransferUnit:_maxInfoFieldSize   
                    405:        flags:0];
                    406: 
                    407:     /*
                    408:      * Netif for IP to get to us.
                    409:      */
                    410:     if(_flags._shouldAttachIP) {
                    411:        if(_flags._doesIPSourceRouting) vtripf |= IP_SRCROUTING;
                    412:        vtrip_config([self unit], vtripf, _ipMtu, _ipTokenPriority);
                    413:     }
                    414: 
                    415:     /*
                    416:      * Emit the node address
                    417:      */
                    418:      IOLog("%s: Token Ring Node address %02x:%02x:%02x:%02x:%02x:%02x\n",
                    419:        [self name],
                    420:        _nodeAddress.ta_byte[0],_nodeAddress.ta_byte[1],
                    421:        _nodeAddress.ta_byte[2],_nodeAddress.ta_byte[3],
                    422:        _nodeAddress.ta_byte[4],_nodeAddress.ta_byte[5]);
                    423:     
                    424: #if 0
                    425:     /*
                    426:      * Emit the group address, if non-zero
                    427:      */
                    428:     for (i = 2 ; i < 4 ; ++i) {
                    429:        if (_groupAddress.ta_byte[i]) {
                    430:            IOLog("%s: Token Ring Group address "
                    431:                "%02x:%02x:%02x,%02x:%02x:%02x\n",
                    432:                [self name],
                    433:                _groupAddress.ta_byte[0], _groupAddress.ta_byte[1],
                    434:                _groupAddress.ta_byte[2], _groupAddress.ta_byte[3],
                    435:                _groupAddress.ta_byte[4], _groupAddress.ta_byte[5]);
                    436:            break;
                    437:        }
                    438:     }
                    439:     
                    440:     /*
                    441:      * Emit the functional address, if non-zero
                    442:      */
                    443:     
                    444:     for (i = 2 ; i < 4 ; ++i) {
                    445:        if (_functionalAddress.ta_byte[i]) {
                    446:            IOLog("%s: Token Ring Functional address "
                    447:                "%02x:%02x:%02x,%02x:%02x:%02x\n",
                    448:                [self name],
                    449:                _functionalAddress.ta_byte[0], _functionalAddress.ta_byte[1],
                    450:                _functionalAddress.ta_byte[2], _functionalAddress.ta_byte[3],
                    451:                _functionalAddress.ta_byte[4], _functionalAddress.ta_byte[5]);
                    452:            break;
                    453:        }
                    454:     }
                    455: #endif 0
                    456:     return _netif;
                    457: }
                    458: 
                    459: - (IONetwork *)networkInterface
                    460: {
                    461:     return _netif;
                    462: }
                    463: 
                    464: - (BOOL)isRunning
                    465: {
                    466:     return (BOOL)_flags._isRunning;
                    467: }
                    468: 
                    469: - (void)setRunning:(BOOL)running
                    470: {
                    471:     _flags._isRunning = running;
                    472: }
                    473: 
                    474: /*
                    475:  * Implement driver timeouts.
                    476:  */
                    477:  
                    478: - (unsigned int)relativeTimeout
                    479: {
                    480:     ns_time_t                  timestamp;
                    481: 
                    482:     if (_absTimeout == 0)      
                    483:        return (0);
                    484:     
                    485:     IOGetTimestamp(&timestamp);
                    486:     
                    487:     if (_absTimeout <= timestamp) {
                    488:        _absTimeout = 0; return (0);
                    489:     }
                    490:        
                    491:     return ((unsigned int) ((_absTimeout - timestamp) / (1000 * 1000)));
                    492: }
                    493: 
                    494: - (void)setRelativeTimeout:(unsigned int)timeout
                    495: {
                    496:     if (_absTimeout > 0)
                    497:        (void)ns_untimeout((func)TokenRingTimeout, self);
                    498: 
                    499:     IOGetTimestamp(&_absTimeout);
                    500:     
                    501:     _absTimeout += ((ns_time_t)timeout * (1000 * 1000));
                    502:     
                    503:     ns_abstimeout((func)TokenRingTimeout, self, 
                    504:        _absTimeout, CALLOUT_PRI_THREAD);
                    505: }
                    506: 
                    507: - (void)clearTimeout
                    508: {
                    509:     if (_absTimeout > 0) {
                    510:        (void)ns_untimeout((func)TokenRingTimeout, self);
                    511:        _absTimeout = 0;
                    512:     }
                    513: }
                    514: 
                    515: - (BOOL)earlyTokenEnabled
                    516: {
                    517:     return (BOOL)_flags._isEarlyTokenEnabled;
                    518: }
                    519: 
                    520: - (BOOL)shouldAutoRecover
                    521: {
                    522:     return (BOOL)_flags._shouldAutoRecover;
                    523: }
                    524: 
                    525: - (unsigned)ringSpeed
                    526: {
                    527:     return _ringSpeed;
                    528: } 
                    529: 
                    530: - (unsigned)maxInfoFieldSize
                    531: {
                    532:     return _maxInfoFieldSize;
                    533: }
                    534: 
                    535: - (void)setMaxInfoFieldSize:(unsigned)size
                    536: {
                    537:     //sanity check?
                    538:     _maxInfoFieldSize = size;
                    539: }
                    540: 
                    541: /*
                    542:  * Hardware Address Methods
                    543:  */
                    544: 
                    545: - (token_addr_t)nodeAddress
                    546: {
                    547:     return _nodeAddress;
                    548: }
                    549: 
                    550: #if 0
                    551: 
                    552: - (token_addr_t)groupAddress
                    553: {
                    554:     return _groupAddress;
                    555: }
                    556: 
                    557: - (token_addr_t)functionalAddress
                    558: {
                    559:     return _functionalAddress;
                    560: }
                    561: 
                    562: #endif 0
                    563: 
                    564: /*
                    565:  * Implement the IONetworkDeviceMethods protocol
                    566:  */
                    567:  
                    568: - (int)finishInitialization
                    569: {
                    570:     int        result = 0;
                    571: 
                    572:     if (!_flags._isRunning)
                    573:        result = [_driverCmd send:RESET_ON];
                    574: 
                    575:     return (result);
                    576: }
                    577: 
                    578: - (BOOL)resetAndEnable:(BOOL)enable
                    579: {
                    580:     return YES;
                    581: }
                    582: 
                    583: - (void)transmit:(netbuf_t)pkt
                    584: {
                    585:     nb_free(pkt);
                    586: }
                    587: 
                    588: 
                    589: /*
                    590:  * Token-ring transmit.  Invokes [self transmit] in subclass 
                    591:  * to do actual hardware-specific transmission.
                    592:  */
                    593: - (int)outputPacket :(netbuf_t)nb address:(void *)dest_addr
                    594: {
                    595: 
                    596:     int                maclen;
                    597:     tokenHeader_t      *th = (tokenHeader_t *)dest_addr;
                    598: 
                    599:     /* 
                    600:      * Bail out if our hardware is down.
                    601:      */
                    602:     if(!_flags._isRunning) {
                    603:        nb_free(nb);
                    604:        return TRINGDOWN;
                    605:     }
                    606: 
                    607:     /* 
                    608:      * Return error if data-field too large (shouldn't happen by
                    609:      * well behaved code, but we include for safety).
                    610:      */
                    611:     if(nb_size(nb) > _maxInfoFieldSize) {
                    612:        IOLog("%s: netOutput bad frame size=%d\n",
                    613:            [self name], nb_size(nb));
                    614:        nb_free(nb);
                    615:        return TBADFSIZE; 
                    616:     }
                    617: 
                    618:     /*
                    619:      * Get the callers MAC header length (which is variable, due
                    620:      * to the source routing field).
                    621:      */
                    622:     maclen = get_8025_hdr_len(th); 
                    623:     if(maclen < 0) {
                    624:        IOLog("%s: bad mac header\n", [self name]);
                    625:        nb_free(nb);
                    626:        return TBADFSIZE;  
                    627:     }
                    628: 
                    629:     /*
                    630:      * Add the 802.5 MAC header to the net buffer.  Note that when
                    631:      * we allocate buffers we reserve MAC_HDR_MAX (the largest possible
                    632:      * MAC header).  Here we grow the buffer so that the actual MAC header
                    633:      * just fits.  The packet data is therefore contiguous (as opposed to
                    634:      * a gap between the unused portion of the MAC header and the data
                    635:      * field).  This saves the subclass from needing to deal with
                    636:      * fragmentation.  This is all great as long as the subclass
                    637:      * hardware only requires even-aligned data.  Otherwise the subclass
                    638:      * must implement its' own outputPacket method or copy the data
                    639:      * (sorry).
                    640:      */
                    641:     nb_grow_top(nb, maclen);  // grow buffer so that mac header just fits
                    642:     th = (tokenHeader_t *)nb_map(nb);
                    643:     bcopy(dest_addr, th, maclen); /* copy da to tx buf */
                    644:     th->ac &= 0xf0; /* mask all but token priority & mon bits */
                    645: 
                    646:     /*
                    647:      * Subclass does hdw-specific transmit.
                    648:      */
                    649:     [self transmit:nb];         
                    650: 
                    651:     return 0;
                    652: }
                    653: 
                    654: /*
                    655:  * Netif get-buffer method.   
                    656:  *
                    657:  * This generic version doesn't insure buffer alignment or prevent page
                    658:  * spanning.  Subclass should override if needed (as does TokenExpress).
                    659:  */
                    660: - (netbuf_t)allocateNetbuf
                    661: {
                    662:     netbuf_t nb;
                    663: 
                    664:     nb = nb_alloc(_maxInfoFieldSize + MAC_HDR_MAX);
                    665:     if (nb)
                    666:        nb_shrink_top(nb, MAC_HDR_MAX);  /* reserve space for max 802.5 hdr */
                    667:            
                    668:     return nb;         
                    669: }
                    670: 
                    671: /*
                    672:  * Netif command method.
                    673:  */
                    674: - (int)performCommand:(const char *)command data:(void *)data
                    675: {
                    676:     int        rtn = 0;
                    677: 
                    678:     if (strcmp(command, IFCONTROL_SETFLAGS) == 0) 
                    679:        return(rtn);
                    680: 
                    681:     else if (strcmp(command, IFCONTROL_GETADDR) == 0) {
                    682:        bcopy((void *)&_nodeAddress, data, sizeof(_nodeAddress));
                    683:     } 
                    684:     
                    685:     else {
                    686:        rtn = EINVAL;
                    687:     }
                    688: 
                    689:     return (rtn);
                    690: }
                    691: 
                    692: @end
                    693: 
                    694: @implementation IOTokenRing(PrivateMethods)
                    695: 
                    696: //
                    697: // Used to handle a synchronous
                    698: // command sent by another thread
                    699: // to the driver thread.
                    700: //
                    701: - (void)commandRequestOccurred
                    702: {
                    703:     int                oper = [_driverCmd oper];
                    704:     int                result = 0;
                    705: 
                    706:     switch (oper) {
                    707:     
                    708:     case RESET_ON:
                    709:        if (!_flags._isRunning) {
                    710:            if (![self resetAndEnable:TRUE])
                    711:                result = EIO;
                    712:        }
                    713:        [_driverCmd done:result];
                    714:        break;
                    715:     
                    716:     case RESET_OFF:
                    717:        [self resetAndEnable:FALSE];
                    718:        _flags._isRunning = FALSE;
                    719:        [_driverCmd done:result];
                    720:        break;
                    721: 
                    722:     case TERMINATE:
                    723:        [_driverCmd done:result];
                    724:        IOExitThread();
                    725:        break;
                    726:     }
                    727: }
                    728: 
                    729: @end
                    730: 
                    731: static void
                    732: TokenRingTimeout(IOTokenRing *device)
                    733: {
                    734:     msg_header_t       msg = { 0 };
                    735:     
                    736:     if (device->_absTimeout > 0) {     
                    737:        device->_absTimeout = 0;
                    738:        
                    739:     
                    740:        msg.msg_size = sizeof (msg);
                    741:        msg.msg_remote_port = IOGetKernPort([device interruptPort]);
                    742:        msg.msg_id =  IO_TIMEOUT_MSG;
                    743:        
                    744:        msg_send_from_kernel(&msg, MSG_OPTION_NONE, 0);
                    745:     }
                    746: }
                    747: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.