Annotation of kernel/driverkit/KernBus.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: 
                     25: /*
                     26:  * Copyright (c) 1993, 1994 NeXT Computer, Inc.
                     27:  *
                     28:  * Kernel Bus Resource Object(s).
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * 1 Jul 1994 ? at NeXT
                     33:  *     Modifications to support shared interrupts.
                     34:  * 16 Mar 1994 ? at NeXT
                     35:  *     Added range mapping.
                     36:  * 24 Feb 1994 ? at NeXT
                     37:  *     Major rewrite.
                     38:  * 31 Oct 1993 ? at NeXT
                     39:  *     Created.
                     40:  */
                     41: 
                     42: #import <mach/mach_types.h>
                     43: 
                     44: #import <objc/HashTable.h>
                     45: 
                     46: #import <driverkit/KernBus.h>
                     47: #import <driverkit/KernBusPrivate.h>
                     48: #import <driverkit/KernDeviceDescription.h>
                     49: 
                     50: @implementation KernBusItemResource
                     51: 
                     52: - initWithItemCount:   (unsigned int)count
                     53:            itemBase:   (unsigned int)base
                     54:            itemKind:   kind
                     55:            owner:      owner
                     56: {
                     57:     [super init];
                     58: 
                     59:     /*
                     60:      * Check for base wrap
                     61:      * and invalid count.
                     62:      */
                     63:     if (count > 1024 || (base + count) <= base)
                     64:        return [self free];
                     65: 
                     66:     _owner = owner;
                     67:     _kind = (kind == nil)? [KernBusItem class]: kind;
                     68:     _items = (void *)IOMalloc(count * sizeof (KernBusItem *));
                     69:     _itemCount = 0;
                     70:     bzero(_items, count * sizeof (KernBusItem *));
                     71:     _count = count; _base = base;
                     72: 
                     73:     return self;
                     74: }
                     75: 
                     76: - initWithItemCount:   (unsigned int)count
                     77:            itemKind:   kind
                     78:            owner:      owner
                     79: {
                     80:     return [self initWithItemCount:count itemBase:0 itemKind:kind owner:owner];
                     81: }
                     82: 
                     83: - init
                     84: {
                     85:     return [self free];
                     86: }
                     87: 
                     88: - free
                     89: {
                     90:     if (_itemCount > 0)
                     91:        return self;
                     92: 
                     93:     if (_count > 0 && _items)
                     94:        IOFree(_items, sizeof (_count * sizeof (KernBusItem *)));
                     95: 
                     96:     return [super free];
                     97: }
                     98: 
                     99: - reserveItem: (unsigned int)item
                    100: {
                    101:     KernBusItem                **items = _items;
                    102:     id                 *object;
                    103: 
                    104:     /*
                    105:      * Check for invalid
                    106:      * item.
                    107:      */ 
                    108:     if (item < _base || item >= (_base + _count))
                    109:        return nil;
                    110:        
                    111:     object = &items[item - _base];
                    112: 
                    113:     if (*object == nil) {
                    114:        if ((*object = [[_kind alloc]
                    115:                                initForResource:self
                    116:                                            item:item
                    117:                                        shareable:NO]) != nil) {
                    118:            if (_itemCount++ == 0)
                    119:                [_owner _resourceActive];
                    120:        }
                    121:     }
                    122:     else
                    123:        return nil;
                    124:     
                    125:     return *object;
                    126: }
                    127: 
                    128: - shareItem:   (unsigned int)item
                    129: {
                    130:     KernBusItem                **items = _items;
                    131:     id                 *object;
                    132: 
                    133:     /*
                    134:      * Check for invalid
                    135:      * item.
                    136:      */ 
                    137:     if (item < _base || item >= (_base + _count))
                    138:        return nil;
                    139:        
                    140:     object = &items[item - _base];
                    141:        
                    142:     if (*object == nil)        {
                    143:        if ((*object = [[_kind alloc]
                    144:                                initForResource:self
                    145:                                            item:item
                    146:                                        shareable:YES]) != nil) {
                    147:            if (_itemCount++ == 0)
                    148:                [_owner _resourceActive];
                    149:        }
                    150:     }
                    151:     else
                    152:        return [*object share];
                    153:        
                    154:     return *object;
                    155: }
                    156: 
                    157: #ifdef notdef
                    158: - reserveAnyItem
                    159: {
                    160:     id                 *object = _items;
                    161:     int                        i;
                    162:     
                    163:     if (_itemCount >= _count)
                    164:        return nil;
                    165: 
                    166:     for (i = 0; i < _count; i++, object++) {
                    167:        if (*object == nil) {
                    168:            if ((*object = [[_kind alloc]
                    169:                                    initForResource:self
                    170:                                                item:i
                    171:                                            shareable:NO]) != nil) {
                    172:                if (_itemCount++ == 0)
                    173:                    [_owner _resourceActive];
                    174: 
                    175:                return *object;
                    176:            }
                    177:        }
                    178:     }
                    179:        
                    180:     return nil;
                    181: }
                    182: 
                    183: - shareAnyItem
                    184: {
                    185:     id                 *object = _items;
                    186:     int                        i;
                    187:     
                    188:     for (i = 0; i < _count; i++, object++) {
                    189:        if (*object == nil) {
                    190:            if ((*object = [[_kind alloc]
                    191:                                    initForResource:self
                    192:                                                item:i
                    193:                                            shareable:YES]) != nil) {
                    194:                if (_itemCount++ == 0)
                    195:                    [_owner _resourceActive];
                    196: 
                    197:                return *object;
                    198:            }
                    199:        }
                    200:        else if ([*object share])
                    201:            return *object;
                    202:     }
                    203:     
                    204:     return nil;
                    205: }
                    206: #endif
                    207: 
                    208: - (unsigned int) findFreeItem
                    209: {
                    210:     KernBusItem                **items = _items;
                    211:     unsigned int       i;
                    212: 
                    213:     for (i = 0; i < _count; i++)
                    214:        if (items[i] == nil)
                    215:            break;
                    216: 
                    217:     /*
                    218:      * If there are no free items, we return an invalid item.
                    219:      */
                    220:     return i + _base;
                    221: }
                    222: 
                    223: @end
                    224: 
                    225: @implementation KernBusItemResource(Private)
                    226: 
                    227: - _destroyItem:                object
                    228: {
                    229:     KernBusItem                **item, **items = _items;
                    230:     KernBusItem_       *iv = (KernBusItem_ *)object;
                    231:     
                    232:     if (![object isKindOf:_kind])
                    233:        return nil;
                    234:        
                    235:     item = &items[iv->_item - _base];
                    236:     if (*item == nil)
                    237:        return nil;
                    238:        
                    239:     *item = nil;
                    240:     if (--_itemCount == 0)
                    241:        [_owner _resourceInactive];
                    242:     
                    243:     return [object dealloc];
                    244: }
                    245: 
                    246: @end
                    247: 
                    248: @implementation KernBusItem
                    249: 
                    250: - initForResource:     resource
                    251:        item:           (unsigned int)item
                    252:        shareable:      (BOOL)shareable
                    253: {
                    254:     if (resource == nil)
                    255:        return [super free];
                    256: 
                    257:     [super init];
                    258: 
                    259:     _resource = resource;
                    260:     _item = item;
                    261:     _useCount = 1;
                    262:     _shareable = shareable;
                    263:     
                    264:     return self;
                    265: }
                    266: 
                    267: - init
                    268: {
                    269:     return [super free];
                    270: }
                    271: 
                    272: - free
                    273: {
                    274:     if (--_useCount > 0)
                    275:        return nil;
                    276:        
                    277:     return [_resource _destroyItem:self];
                    278: }
                    279: 
                    280: - dealloc
                    281: {
                    282:     if (_useCount > 0)
                    283:        return self;
                    284: 
                    285:     return [super free];
                    286: }
                    287: 
                    288: - share
                    289: {
                    290:     if (!_shareable)
                    291:        return nil;
                    292:        
                    293:     _useCount++;
                    294:     
                    295:     return self;
                    296: }
                    297: 
                    298: - (unsigned int)item
                    299: {
                    300:     return _item;
                    301: }
                    302: 
                    303: @end
                    304: 
                    305: @implementation KernBusRangeResource
                    306: 
                    307: - initWithExtent:      (Range)extent
                    308:            kind:       kind
                    309:            owner:      owner
                    310: {
                    311:     unsigned int       end = extent.base + extent.length;
                    312:     
                    313:     [super init];
                    314: 
                    315:     /*
                    316:      * Check for wraparound.
                    317:      */        
                    318:     if (!rangeIsValid(extent))
                    319:        return [self free];
                    320: 
                    321:     _owner = owner;
                    322:     _kind = (kind == nil)? [KernBusRange class]: kind;
                    323:     _rangeCount = 0;
                    324:     _ranges = 0;
                    325:     _end = end; _base = extent.base;
                    326:     
                    327:     return self;
                    328: }
                    329: 
                    330: - free
                    331: {
                    332:     if (_rangeCount > 0)
                    333:        return self;
                    334:     
                    335:     return [super free];
                    336: }
                    337: 
                    338: - reserveRange:        (Range)range
                    339: {
                    340:     unsigned int       base = range.base;
                    341:     unsigned int       end = base + range.length;
                    342:     void               **prevnext = &_ranges;
                    343:     KernBusRange_      *new, *next;
                    344:     id                 object = nil;
                    345: 
                    346:     /*
                    347:      * Check region for wrap.
                    348:      */        
                    349:     if (!rangeIsValid(range))
                    350:        return nil;
                    351: 
                    352:     /*
                    353:      * Check region against
                    354:      * address space.
                    355:      */
                    356:     if (base < _base || (_end > 0 && end > _end))
                    357:        return nil;
                    358: 
                    359:     /*
                    360:      * Add range if no overlap
                    361:      * with existing regions.
                    362:      */        
                    363:     while (TRUE) {
                    364:        if ((next = *prevnext) == 0 || end <= next->_base) {
                    365:            if ((object = [[_kind alloc]
                    366:                                    initForResource:self
                    367:                                                range:range
                    368:                                                shareable:NO]) != nil) {
                    369:                new = (KernBusRange_ *)object;
                    370:                new->_next = next;
                    371:                *prevnext = new;
                    372:                if (_rangeCount++ == 0)
                    373:                    [_owner _resourceActive];
                    374:            }
                    375:            break;
                    376:        }
                    377:        else if (next->_end > base)
                    378:            break;
                    379:        
                    380:        prevnext = &next->_next;
                    381:     }
                    382:     
                    383:     return object;
                    384: }
                    385: 
                    386: - shareRange:  (Range)range
                    387: {
                    388:     unsigned int       base = range.base;
                    389:     unsigned int       end = base + range.length;
                    390:     void               **prevnext = &_ranges;
                    391:     KernBusRange_      *new, *next;
                    392:     id                 object = nil;
                    393: 
                    394:     /*
                    395:      * Check region for wrap.
                    396:      */        
                    397:     if (!rangeIsValid(range))
                    398:        return nil;
                    399: 
                    400:     /*
                    401:      * Check region against
                    402:      * address space.
                    403:      */
                    404:     if (base < _base || (_end > 0 && end > _end))
                    405:        return nil;
                    406: 
                    407:     /*
                    408:      * Add range if no overlap
                    409:      * with existing regions.
                    410:      */        
                    411:     while (TRUE) {
                    412:        if ((next = *prevnext) == 0 || end <= next->_base) {
                    413:            if ((object = [[_kind alloc]
                    414:                                    initForResource:self
                    415:                                        range:range
                    416:                                        shareable:YES]) != nil) {
                    417:                new = (KernBusRange_ *)object;
                    418:                new->_next = next;
                    419:                *prevnext = new;
                    420:                if (_rangeCount++ == 0)
                    421:                    [_owner _resourceActive];
                    422:            }
                    423:            break;
                    424:        }
                    425: #if !ppc
                    426:        else if (base >= next->_base && end <= next->_end) {
                    427:            object = (KernBusRange *)next; object = [object share];
                    428:            break;
                    429:        }
                    430:        else if (next->_end > base)
                    431:            break;
                    432: #endif
                    433:        prevnext = &next->_next;
                    434:     }
                    435:     
                    436:     return object;
                    437: }
                    438: 
                    439: - (Range)findFreeRangeWithSize:(unsigned int)size
                    440:         alignment:(unsigned int)align
                    441: {
                    442:     Range              result;
                    443:     unsigned int       base;
                    444:     unsigned int       end;
                    445:     void               **prevnext = &_ranges;
                    446:     KernBusRange_      *new, *next;
                    447:     id                 object = nil;
                    448: 
                    449:     base = _base;
                    450:     end = base + size;
                    451:     result.base = result.length = 0;
                    452: 
                    453:     /*
                    454:      * Add range if no overlap
                    455:      * with existing regions.
                    456:      */
                    457:     for (base = _base, end = base + size;
                    458:          base < _end;
                    459:         base += align, end += align) {
                    460:        while (TRUE) {
                    461:            if ((next = *prevnext) == 0 || end <= next->_base) {
                    462:                result.base = base;
                    463:                result.length = end - base;
                    464:                break;
                    465:            }
                    466:            else if (next->_end > base)
                    467:                break;
                    468:            
                    469:            prevnext = &next->_next;
                    470:        }
                    471:        
                    472:        if (result.length)
                    473:            break;
                    474:     }
                    475:     
                    476:     return result;
                    477: }
                    478: 
                    479: @end
                    480: 
                    481: @implementation KernBusRangeResource(Private)
                    482: 
                    483: - _destroyRange:       object
                    484: {
                    485:     void               **prevnext = &_ranges;
                    486:     KernBusRange_      *next;
                    487:     
                    488:     // Should check class of object
                    489:     
                    490:     if (![object isKindOf:_kind])
                    491:        return nil;
                    492:        
                    493:     while ((next = *prevnext) != 0) {
                    494:        if (next == (KernBusRange_ *)object) {
                    495:            *prevnext = next->_next;
                    496:            if (--_rangeCount == 0)
                    497:                [_owner _resourceInactive];
                    498: 
                    499:            return [object dealloc];
                    500:        }
                    501:        
                    502:        prevnext = &next->_next;
                    503:     }
                    504:     
                    505:     return nil;
                    506: }
                    507: 
                    508: @end
                    509: 
                    510: @implementation KernBusRange
                    511: 
                    512: - initForResource:     resource
                    513:        range:          (Range)range
                    514:        shareable:      (BOOL)shareable
                    515: {
                    516:     if (resource == nil)
                    517:        return [super free];
                    518: 
                    519:     [super init];
                    520: 
                    521:     _resource = resource;
                    522:     _base = range.base;
                    523:     _end = _base + range.length;
                    524:     _useCount = 1;
                    525:     _shareable = shareable;
                    526:     _mappingCount = 0;
                    527:     
                    528:     return self;
                    529: }
                    530: 
                    531: - init
                    532: {
                    533:     return [super free];
                    534: }
                    535: 
                    536: - free
                    537: {
                    538:     if (_mappingCount > 0)
                    539:        return self;
                    540: 
                    541:     if (--_useCount > 0)
                    542:        return nil;
                    543:        
                    544:     return [_resource _destroyRange:self];
                    545: }
                    546: 
                    547: - dealloc
                    548: {
                    549:     if (_useCount > 0)
                    550:        return self;
                    551: 
                    552:     return [super free];
                    553: }
                    554: 
                    555: - share
                    556: {
                    557:     if (!_shareable)
                    558:        return nil;
                    559:        
                    560:     _useCount++;
                    561:     
                    562:     return self;
                    563: }
                    564: 
                    565: - (Range)range
                    566: {
                    567:     Range      range;
                    568:     
                    569:     range.base = _base;
                    570:     range.length = _end - _base;
                    571:     
                    572:     return range;
                    573: }
                    574: 
                    575: @end
                    576: 
                    577: @implementation KernBusRange(Private)
                    578: 
                    579: - _addMapping
                    580: {
                    581:     _mappingCount++;
                    582:     
                    583:     return self;
                    584: }
                    585: 
                    586: - _destroyMapping:     object
                    587: {
                    588:     _mappingCount--;
                    589:     
                    590:     return [object free];
                    591: }
                    592: 
                    593: @end
                    594: 
                    595: @implementation KernBusRangeMapping
                    596: 
                    597: - initWithRange:       range
                    598:        subRange:       (Range)subRange
                    599: {
                    600:     Range              resourceRange;
                    601:     unsigned int       resourceBase, resourceEnd;
                    602:     unsigned int       mappedBase, mappedEnd;
                    603: 
                    604:     if (range == nil)
                    605:        return [self free];
                    606: 
                    607:     [super init];
                    608: 
                    609:     if (!rangeIsValid(subRange))
                    610:        return [self free];
                    611: 
                    612:     /*
                    613:      * Convert range into
                    614:      * endpoints.
                    615:      */
                    616:     resourceRange = [range range];
                    617:     resourceBase = resourceRange.base;
                    618:     resourceEnd = resourceBase + resourceRange.length;
                    619: 
                    620:     /*
                    621:      * Convert subrange into
                    622:      * absolute endpoints.
                    623:      */        
                    624:     mappedBase = resourceBase + subRange.base;
                    625:     mappedEnd = resourceBase + subRange.base + subRange.length;
                    626: 
                    627:     /*
                    628:      * Check subrange against
                    629:      * range.
                    630:      */
                    631:     if (mappedBase < resourceBase ||
                    632:                (resourceEnd > 0 && mappedEnd > resourceEnd))
                    633:        return [self free];
                    634: 
                    635:     _range = range;
                    636:     _mappedRange.base = mappedBase;
                    637:     _mappedRange.length = subRange.length;
                    638: 
                    639:     [range _addMapping];
                    640: 
                    641:     return self;
                    642: }
                    643: 
                    644: - free
                    645: {
                    646:     id                 range = _range;
                    647: 
                    648:     if (range == nil)
                    649:        return [super free];
                    650:        
                    651:     _range = nil;
                    652: 
                    653:     return [range _destroyMapping:self];
                    654: }
                    655: 
                    656: - (Range)mappedRange
                    657: {
                    658:     return _mappedRange;
                    659: }
                    660: 
                    661: @end
                    662: 
                    663: @implementation KernBus
                    664: 
                    665: static HashTable       *_busClasses, *_busInstances;
                    666: 
                    667: + initialize
                    668: {
                    669:     if (_busClasses == nil) {
                    670:        _busClasses = [[HashTable alloc] initKeyDesc:"*"];
                    671:     }
                    672:     if (_busInstances == nil) {
                    673:        _busInstances = [[HashTable alloc] initKeyDesc:"*"];
                    674:     }
                    675:     
                    676:     return self;
                    677: }
                    678: 
                    679: + registerBusClass:busClass name:(char *)className
                    680: {
                    681:     [_busClasses insertKey:className value:busClass];
                    682:     
                    683:     return busClass;
                    684: }
                    685: 
                    686: + registerBusInstance:busInstance name:(char *)busName  busId:(int)index
                    687: {
                    688:     HashTable *t;
                    689:     
                    690:     t = [_busInstances valueForKey:busName];
                    691:     if (t == NULL) {
                    692:        t = [[HashTable alloc] initKeyDesc:"i"];
                    693:        [_busInstances insertKey:busName value:t];
                    694:     }
                    695:     [t insertKey:(void *)index value:busInstance];
                    696:     return busInstance;
                    697: }
                    698: 
                    699: + lookupBusClassWithName:(char *)busName
                    700: {
                    701:     return [_busClasses valueForKey:busName];
                    702: }
                    703: 
                    704: + lookupBusInstanceWithName:(char *)busName busId:(int)index
                    705: {
                    706:     HashTable *t;
                    707:     id obj = nil;
                    708:     
                    709:     t = [_busInstances valueForKey:busName];
                    710:     if (t) {
                    711:        obj = [t valueForKey:(void *)index];
                    712:     }
                    713:     return obj;
                    714: }
                    715: 
                    716: - init
                    717: {
                    718:     [super init];
                    719:     
                    720:     if (_resources == nil)
                    721:        _resources = [[HashTable alloc] initKeyDesc:"*"];
                    722: 
                    723:     return self;
                    724: }
                    725: 
                    726: - free
                    727: {
                    728:     if (_activeResourceCount > 0)
                    729:        return self;
                    730:        
                    731:     return [super free];
                    732: }
                    733: 
                    734: - (BOOL)areResourcesActive
                    735: {
                    736:     return _activeResourceCount > 0;
                    737: }
                    738: 
                    739: + deviceDescriptionFromConfigTable:table
                    740: {
                    741:     return [[KernDeviceDescription alloc] initFromConfigTable:table];
                    742: }
                    743: 
                    744: /*
                    745:  * Allocate resources for bus.
                    746:  * Return nil if there is an error allocating a resource.
                    747:  */
                    748: - allocateResourcesForDeviceDescription:descr
                    749: {
                    750:     const char **names;
                    751:     
                    752:     for (names = [self resourceNames]; names && *names; names++) {
                    753:        if ([descr allocateResourcesForKey:*names] == nil)
                    754:            return nil;
                    755:     }
                    756:     return descr;
                    757: }
                    758: 
                    759: - _insertResource:     object
                    760:        withKey:        (const char *)key
                    761: {
                    762:     HashTable  *resources = (HashTable *)_resources;
                    763:     
                    764:     if ([resources isKey:key])
                    765:        return nil;
                    766:        
                    767:     [resources insertKey:key value:object];
                    768:     
                    769:     return object;
                    770: }
                    771: 
                    772: - _deleteResourceWithKey:      (const char *)key
                    773: {
                    774:     HashTable  *resources = (HashTable *)_resources;
                    775:     id         object;
                    776: 
                    777:     if ((object = [resources valueForKey:key]) == nil)
                    778:        return nil;
                    779:        
                    780:     [resources removeKey:key];
                    781:     
                    782:     return object;
                    783: }
                    784: 
                    785: - _lookupResourceWithKey:      (const char *)key
                    786: {
                    787:     HashTable  *resources = (HashTable *)_resources;
                    788: 
                    789:     return [resources valueForKey:key];
                    790: }
                    791: 
                    792: - (const char **)resourceNames
                    793: {
                    794:     static const char *names[1];
                    795: 
                    796:     return names;
                    797: }
                    798: 
                    799: + (BOOL)configureDriverWithTable:configTable
                    800: {
                    801:     return NO;
                    802: }
                    803: 
                    804: - (int)busId
                    805: {
                    806:     return _busId;
                    807: }
                    808: 
                    809: - (void)setBusId:(int)busId
                    810: {
                    811:     _busId = busId;
                    812: }
                    813: 
                    814: + (BOOL)probeBus:configTable
                    815: {
                    816:     [[self alloc] init];
                    817:     return YES;
                    818: }
                    819: 
                    820: @end
                    821: 
                    822: @implementation KernBus(Private)
                    823: 
                    824: - (void)_resourceActive
                    825: {
                    826:     _activeResourceCount++;
                    827: }
                    828: 
                    829: - (void)_resourceInactive
                    830: {
                    831:     _activeResourceCount--;
                    832: }
                    833: 
                    834: @end

unix.superglobalmegacorp.com

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