Annotation of kernel/driverkit/driverServerXXX.m, revision 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) 1992 NeXT Computer, Inc.
        !            27:  *
        !            28:  * Driverkit kernel support.
        !            29:  *
        !            30:  * HISTORY
        !            31:  *
        !            32:  * 15 Jan 1998    Martin Minow
        !            33:  *   Added kern_IOCreateMachPort
        !            34:  * 28 Aug 1992 Joe Pasqua
        !            35:  *     Use new interface to interrupt mechanism.
        !            36:  * 25 Aug 1992 Joe Pasqua
        !            37:  *     Added minimal implementations of kern{IOAttach|Detach}Interrupt,
        !            38:  *     kern_IOCreateDevicePort.
        !            39:  * 9 August 1992 ? at NeXT
        !            40:  *     Created.
        !            41:  */
        !            42: 
        !            43: #import <mach/mach_types.h>
        !            44: 
        !            45: #import <ipc/ipc_space.h>
        !            46: 
        !            47: #import <kern/kern_port.h>
        !            48: #import        <kern/task.h>
        !            49: 
        !            50: #import <vm/vm_kern.h>
        !            51: 
        !            52: #import <driverkit/generalFuncs.h>
        !            53: #import <driverkit/IODevice.h>
        !            54: #import <driverkit/IODeviceParams.h>
        !            55: #import <driverkit/i386/driverServer.h>
        !            56: #import <driverkit/KernDevice.h>
        !            57: #import <driverkit/KernDeviceDescription.h>
        !            58: #import <driverkit/KernBus.h>
        !            59: #import <driverkit/i386/EISAKernBus.h>
        !            60: #import <driverkit/interruptMsg.h>
        !            61: #import <driverkit/driverServerXXX.h>
        !            62: #import <driverkit/autoconfCommon.h>
        !            63: #import <driverkit/Device_ddm.h>
        !            64: #import <driverkit/kernelDriver.h>
        !            65: #import <driverkit/driverTypesPrivate.h>
        !            66: #import <driverkit/configTableKern.h>
        !            67: #import <sys/param.h>
        !            68: #import <sys/systm.h>
        !            69: #import <machkit/NXLock.h>
        !            70: #import <objc/List.h>
        !            71: 
        !            72: void
        !            73: dev_server_init(
        !            74:     void
        !            75: )
        !            76: {
        !            77: #if    i386
        !            78:     /*
        !            79:      * Initialize dma controller(s).
        !            80:      */
        !            81:     dma_initialize();
        !            82:     
        !            83:     /*
        !            84:      * Initialize DMA lock mechanism.
        !            85:      */
        !            86:     initDmaLock();
        !            87: #endif i386
        !            88: }
        !            89: 
        !            90: KernDevice *
        !            91: convert_port_to_dev(
        !            92:     port_t     dev_port
        !            93: )
        !            94: {
        !            95:     KernDevice         *kernDevice = nil;
        !            96:     kern_port_t                port = (kern_port_t)dev_port;
        !            97: 
        !            98:     if (port == IP_NULL)
        !            99:        return nil;
        !           100: 
        !           101:     ip_lock(port);
        !           102: 
        !           103:     if(ip_kotype(port) == IKOT_DEVICE)
        !           104:        kernDevice = (KernDevice *)port->ip_kobject;
        !           105: 
        !           106:     ip_unlock(port);
        !           107: 
        !           108:     return kernDevice;
        !           109: }
        !           110: 
        !           111: port_t
        !           112: create_dev_port(
        !           113:     KernDevice         *kernDevice
        !           114: )
        !           115: {
        !           116:     kern_port_t                devicePort;
        !           117:     if ((devicePort = ipc_port_alloc_kernel()) == IP_NULL)
        !           118:        return (PORT_NULL);
        !           119: 
        !           120:     ipc_kobject_set(devicePort, (unsigned int)kernDevice, IKOT_DEVICE);
        !           121:     
        !           122:     return (IOConvertPort((port_t)devicePort,
        !           123:                            IO_Kernel, IO_KernelIOTask));
        !           124: }
        !           125: 
        !           126: void
        !           127: destroy_dev_port(
        !           128:     port_t             port
        !           129: )
        !           130: {
        !           131:     kern_port_t                devicePort;
        !           132: 
        !           133:     if (port != PORT_NULL) {
        !           134:        devicePort = (kern_port_t)IOConvertPort(port,
        !           135:                                                IO_KernelIOTask, IO_Kernel);
        !           136:        ip_lock(devicePort);
        !           137:        ipc_port_destroy(devicePort);
        !           138:     }
        !           139: }
        !           140: 
        !           141: /*
        !           142:  * Determine deviceType and deviceName of specified objectNumber.
        !           143:  */
        !           144: IOReturn kern_IOLookupByObjectNumber(
        !           145:        host_t          device_master,
        !           146:        IOObjectNumber  objectNumber,
        !           147:        IOString        *deviceKind,            // returned
        !           148:        IOString        *deviceName)            // returned
        !           149: {
        !           150:        if (device_master == HOST_NULL)
        !           151:                return IO_R_PRIVILEGE;
        !           152: 
        !           153:        return  [IODevice lookupByObjectNumber:objectNumber
        !           154:                deviceKind:deviceKind
        !           155:                deviceName:deviceName];
        !           156: }
        !           157: 
        !           158: /*
        !           159:  * Determine deviceType and IOObjectNumber of specified IOString.
        !           160:  */
        !           161: IOReturn kern_IOLookupByDeviceName(
        !           162:        host_t          device_master,
        !           163:        IOString        deviceName,
        !           164:        IOObjectNumber  *objectNumber,          // returned
        !           165:        IOString        *deviceKind)            // returned
        !           166: {
        !           167:        if (device_master == HOST_NULL)
        !           168:                return IO_R_PRIVILEGE;
        !           169: 
        !           170:        return [IODevice lookupByDeviceName:deviceName
        !           171:                objectNumber:objectNumber
        !           172:                deviceKind:deviceKind];
        !           173: }
        !           174: 
        !           175: /*
        !           176:  * Get/set parameter RPCs. 
        !           177:  */
        !           178:  
        !           179: IOReturn kern_IOGetIntValues(
        !           180:        host_t          device_master,
        !           181:        IOObjectNumber  objectNumber,
        !           182:        IOParameterName parameterName,
        !           183:        unsigned int     maxCount,              // 0 means "as much as
        !           184:                                                //    possible"
        !           185:        unsigned int    *parameterArray,        // data returned here
        !           186:        unsigned int    *returnedCount)         // size returned here
        !           187: {      
        !           188:        IOReturn rtn;
        !           189:        unsigned count = maxCount;
        !           190:        
        !           191:        if (device_master == HOST_NULL)
        !           192:                return IO_R_PRIVILEGE;
        !           193: 
        !           194:        rtn = [IODevice getIntValues:parameterArray
        !           195:                forParameter:parameterName
        !           196:                objectNumber:objectNumber
        !           197:                count:&count];
        !           198:        *returnedCount = count;
        !           199:        return rtn;
        !           200: }
        !           201: 
        !           202: IOReturn kern_IOGetCharValues(
        !           203:        host_t          device_master,
        !           204:        IOObjectNumber  objectNumber,
        !           205:        IOParameterName parameterName,
        !           206:        unsigned int    maxCount,               // 0 means "as much as
        !           207:                                                //    possible"
        !           208:        unsigned char   *parameterArray,        // data returned here
        !           209:        unsigned int    *returnedCount)         // size returned here
        !           210: {      
        !           211:        IOReturn rtn;
        !           212:        unsigned count = maxCount;
        !           213:        
        !           214:        if (device_master == HOST_NULL)
        !           215:                return IO_R_PRIVILEGE;
        !           216: 
        !           217:        rtn = [IODevice getCharValues:parameterArray
        !           218:                forParameter:parameterName
        !           219:                objectNumber:objectNumber
        !           220:                count:&count];
        !           221:        *returnedCount = count;
        !           222:        return rtn;
        !           223: }
        !           224: 
        !           225: IOReturn kern_IOSetIntValues(
        !           226:        host_priv_t device_master,
        !           227:        IOObjectNumber objectNumber,
        !           228:        IOParameterName parameterName,
        !           229:        unsigned int *parameterArray,
        !           230:        unsigned int count)                     // size of parameterArray
        !           231: {      
        !           232:        if (device_master == HOST_NULL)
        !           233:                return IO_R_PRIVILEGE;
        !           234: 
        !           235:        return [IODevice setIntValues:parameterArray
        !           236:                forParameter:parameterName
        !           237:                objectNumber:objectNumber
        !           238:                count:count];
        !           239: }
        !           240: 
        !           241: IOReturn kern_IOSetCharValues(
        !           242:        host_t          device_master,
        !           243:        IOObjectNumber  objectNumber,
        !           244:        IOParameterName parameterName,
        !           245:        unsigned char   *parameterArray,
        !           246:        unsigned int    count)                  // size of parameterArray
        !           247: {      
        !           248:        if (device_master == HOST_NULL)
        !           249:                return IO_R_PRIVILEGE;
        !           250: 
        !           251:        return [IODevice setCharValues:parameterArray
        !           252:                forParameter:parameterName
        !           253:                objectNumber:objectNumber
        !           254:                count:count];
        !           255: }
        !           256: 
        !           257: IOReturn kern_IOLookUpByStringPropertyList(
        !           258:        host_priv_t     device_master,
        !           259:        unsigned char * values,
        !           260:        unsigned int    valuesLen,              // Mig added
        !           261:        unsigned char * results,
        !           262:        unsigned int    *returnedCount,         // size returned here
        !           263:        unsigned int    length)
        !           264: {
        !           265:        IOReturn        rtn;
        !           266: 
        !           267:        rtn =  [IODevice lookUpByStringPropertyList:(const char *)values
        !           268:                 results      : (char *)results
        !           269:                 maxLength    : (unsigned int)length];
        !           270: 
        !           271:        if( rtn == IO_R_SUCCESS)
        !           272:            *returnedCount = strlen( results) + 1;
        !           273: 
        !           274:        return( rtn);
        !           275: }
        !           276: 
        !           277: IOReturn kern_IOGetStringPropertyList(
        !           278:        host_priv_t     device_master,
        !           279:        IOObjectNumber  objectNumber,
        !           280:        unsigned char * names,
        !           281:        unsigned int    nameLen,                // Mig added
        !           282:        unsigned char * results,
        !           283:        unsigned int    *returnedCount,         // size returned here. Mig added
        !           284:        unsigned int    length)
        !           285: {
        !           286:         IOReturn       rtn;
        !           287: 
        !           288:        rtn =   [IODevice getStringPropertyList:objectNumber
        !           289:                 names        : (const char *)names
        !           290:                 results      : (char *)results
        !           291:                 maxLength    : (unsigned int)length];
        !           292: 
        !           293:        if( rtn == IO_R_SUCCESS)
        !           294:            *returnedCount = strlen( results) + 1;
        !           295: 
        !           296:        return( rtn);
        !           297: }
        !           298: 
        !           299: IOReturn kern_IOGetByteProperty(
        !           300:        host_priv_t     device_master,
        !           301:        IOObjectNumber  objectNumber,
        !           302:        unsigned char * name,
        !           303:        unsigned int    nameLen,                // Mig added
        !           304:        unsigned char * results,
        !           305:        unsigned int    *returnedCount,         // size returned here. Mig added
        !           306:        unsigned int    length)
        !           307: {
        !           308:         IOReturn       rtn;
        !           309:        *returnedCount = length;
        !           310: 
        !           311:        rtn =   [IODevice getByteProperty:objectNumber
        !           312:                 name         : (const char *)name
        !           313:                 results      : (char *)results
        !           314:                 maxLength    : (unsigned int *)returnedCount];
        !           315: 
        !           316:        return( rtn);
        !           317: }
        !           318: 
        !           319: IOReturn kern_IOServerConnect(
        !           320:        host_t          device_master,
        !           321:        IOObjectNumber  objectNumber,
        !           322:        ipc_port_t      taskIPCPort,
        !           323:        ipc_port_t     *serverIPCPort)
        !           324: {
        !           325:        extern task_t IOTask_kern;      // kernel internal version of IOTask
        !           326:        IOReturn rtn;
        !           327: 
        !           328:        if (device_master == HOST_NULL)
        !           329:                return IO_R_PRIVILEGE;
        !           330: 
        !           331:        rtn = [IODevice serverConnect: (port_t *) serverIPCPort
        !           332:                         objectNumber: objectNumber
        !           333:                             taskPort: (port_t) taskIPCPort];
        !           334:        if (MACH_PORT_VALID(*serverIPCPort))
        !           335:            (void) ipc_object_copyin_compat(IOTask_kern->itk_space,
        !           336:                        *serverIPCPort, MSG_TYPE_PORT, FALSE, serverIPCPort);
        !           337: 
        !           338:        return rtn;
        !           339: }
        !           340: 
        !           341: IOReturn kern_IOCallDeviceMethod(
        !           342:        host_priv_t     device_master,
        !           343:        IOObjectNumber  objectNumber,
        !           344:        char *          methodName,
        !           345:        unsigned char   *inputParams,
        !           346:        unsigned int    inputCount,             // size of parameterArray
        !           347:        unsigned int    *maxCount,              // caller's output buffer size
        !           348:                                                // on return the needed size
        !           349:        unsigned char   *outputParams,          // data returned here
        !           350:        unsigned int    *returnedCount)         // size to be returned here
        !           351: {      
        !           352:        IOReturn rtn;
        !           353:        unsigned count = *maxCount;
        !           354: 
        !           355:        rtn = [IODevice callDeviceMethod : methodName
        !           356:                        inputParams : inputParams
        !           357:                        inputCount : inputCount
        !           358:                        outputParams : outputParams
        !           359:                        outputCount : &count
        !           360:                        privileged : device_master
        !           361:                        objectNumber : objectNumber];
        !           362: 
        !           363:        if( count <= *maxCount)
        !           364:            *returnedCount = count;             // how much was returned
        !           365:        else
        !           366:            *returnedCount = *maxCount;
        !           367: 
        !           368:        *maxCount = count;                      // how much is available
        !           369: 
        !           370:        return rtn;
        !           371: }
        !           372: 
        !           373: #ifdef i386
        !           374: 
        !           375: IOReturn
        !           376: kern_IOGetEISADeviceConfig(
        !           377:     KernDevice                 *device,
        !           378:     IOEISAInterruptList                interrupts,
        !           379:     unsigned int               *interruptNum,
        !           380:     IOEISADMAChannelList       dmaChannels,
        !           381:     unsigned int               *dmaChannelNum,
        !           382:     IOEISAPortMap              ioRegions,
        !           383:     unsigned int               *ioRegionNum,
        !           384:     IOEISAMemoryMap            memoryRegions,
        !           385:     unsigned int               *memoryRegionNum
        !           386: )
        !           387: {
        !           388:     int                        i, num;
        !           389:     Range              range;
        !           390:     id                 list, deviceDescription;
        !           391: 
        !           392:     if (device == nil)
        !           393:        return IO_R_PRIVILEGE;
        !           394:        
        !           395:     deviceDescription = [device deviceDescription];
        !           396:     
        !           397:     list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
        !           398:     num = [list count];
        !           399:     if (num > IO_NUM_EISA_INTERRUPTS)
        !           400:        num = IO_NUM_EISA_INTERRUPTS;
        !           401:     for (i = 0; i < num; i++)
        !           402:        interrupts[i] = [[list objectAt:i] item];
        !           403:     *interruptNum = num;
        !           404: 
        !           405:     list = [deviceDescription resourcesForKey:DMA_CHANNELS_KEY];
        !           406:     num = [list count];
        !           407:     if (num > IO_NUM_EISA_DMA_CHANNELS)
        !           408:        num = IO_NUM_EISA_DMA_CHANNELS;
        !           409:     for (i = 0; i < num; i++)
        !           410:        dmaChannels[i] = [[list objectAt:i] item];
        !           411:     *dmaChannelNum = num;
        !           412: 
        !           413:     list = [deviceDescription resourcesForKey:IO_PORTS_KEY];
        !           414:     num = [list count];
        !           415:     if (num > IO_NUM_EISA_PORT_RANGES)
        !           416:        num = IO_NUM_EISA_PORT_RANGES;
        !           417:     for (i = 0; i < num; i++) {
        !           418:        range = [[list objectAt:i] range];
        !           419:        ioRegions[i].start = range.base;
        !           420:        ioRegions[i].size = range.length;
        !           421:     }
        !           422:     *ioRegionNum = num;
        !           423: 
        !           424:     list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
        !           425:     num = [list count];
        !           426:     if (num > IO_NUM_EISA_MEMORY_RANGES)
        !           427:        num = IO_NUM_EISA_MEMORY_RANGES;
        !           428:     for (i = 0; i < num; i++) {
        !           429:        range = [[list objectAt:i] range];
        !           430:        memoryRegions[i].start = range.base;
        !           431:        memoryRegions[i].size = range.length;
        !           432:     }
        !           433:     *memoryRegionNum = num;
        !           434:     
        !           435:     return IO_R_SUCCESS;
        !           436: }
        !           437: 
        !           438: IOReturn
        !           439: kern_IOMapEISADevicePorts(
        !           440:     KernDevice         *device,
        !           441:     thread_t           thread
        !           442: )
        !           443: {
        !           444:     IOReturn   rtn;
        !           445: 
        !           446:     if (device == nil)
        !           447:        return (IO_R_PRIVILEGE);
        !           448:        
        !           449:     if (thread->task->kernel_vm_space)
        !           450:        return (IO_R_SUCCESS);
        !           451:        
        !           452:     rtn = kern_dev_map_port_com(device, thread, FALSE);
        !           453:     
        !           454:     return (rtn);
        !           455: }
        !           456: 
        !           457: IOReturn
        !           458: kern_IOUnMapEISADevicePorts(
        !           459:     KernDevice         *device,
        !           460:     thread_t           thread
        !           461: )
        !           462: {
        !           463:     IOReturn   rtn;
        !           464: 
        !           465:     if (device == nil)
        !           466:        return (IO_R_PRIVILEGE);
        !           467:        
        !           468:     if (thread->task->kernel_vm_space)
        !           469:        return (IO_R_SUCCESS);
        !           470:        
        !           471:     rtn = kern_dev_map_port_com(device, thread, TRUE);
        !           472:     
        !           473:     return (rtn);
        !           474: }
        !           475: 
        !           476: IOReturn
        !           477: kern_IOMapEISADeviceMemory(
        !           478:     KernDevice         *device,
        !           479:     task_t             task,
        !           480:     vm_offset_t        phys,
        !           481:     vm_size_t          length,
        !           482:     vm_offset_t        *addr,                          // in/out
        !           483:     BOOL               anywhere,
        !           484:     IOCache    cache
        !           485: )
        !           486: {
        !           487:     IOReturn   rtn;
        !           488: 
        !           489:     if (device == nil)
        !           490:        return IO_R_PRIVILEGE;
        !           491:     
        !           492:     rtn = kern_dev_map_phys(
        !           493:                            device,
        !           494:                            task->map,
        !           495:                            phys,
        !           496:                            length,
        !           497:                            addr,
        !           498:                            anywhere,
        !           499:                            cache);
        !           500:     
        !           501:     return (rtn);
        !           502: }
        !           503: 
        !           504: IOReturn
        !           505: kern_dev_map_port_com(
        !           506:     KernDevice         *device,
        !           507:     thread_t           thread,
        !           508:     boolean_t          unmap
        !           509: )
        !           510: {
        !           511:     id                 list, deviceDescription;
        !           512:     Range              range;
        !           513:     int                        i, num;
        !           514:     
        !           515:     deviceDescription = [device deviceDescription];
        !           516:     
        !           517:     list = [deviceDescription resourcesForKey:IO_PORTS_KEY];
        !           518:     num = [list count];
        !           519: 
        !           520:     /*
        !           521:      * Determine what is the highest port
        !           522:      * number we need to map.
        !           523:      */
        !           524:     for (i = 0; i < num; i++) {
        !           525:        range = [[list objectAt:i] range];
        !           526:        (void) task_map_io_ports(thread->task, range.base, range.length, unmap);
        !           527:     }
        !           528:     
        !           529:     return (IO_R_SUCCESS);
        !           530: }
        !           531: 
        !           532: #endif
        !           533: 
        !           534: IOReturn
        !           535: kern_dev_map_phys(
        !           536:     KernDevice         *device,
        !           537:     vm_map_t           map,
        !           538:     vm_offset_t                phys,
        !           539:     vm_size_t          length,
        !           540:     vm_offset_t                *addr,
        !           541:     boolean_t          anywhere,
        !           542:     IOCache            cache
        !           543: )
        !           544: {
        !           545:     id                 list, deviceDescription;
        !           546:     kern_return_t      result;
        !           547:     vm_offset_t                vaddr;
        !           548:     Range              range;
        !           549:     int                        i, num;
        !           550:     cache_spec_t       caching;
        !           551:     
        !           552:     switch (cache) {
        !           553:     
        !           554:     case IO_CacheOff:
        !           555:        caching = cache_disable;
        !           556:        break;
        !           557:        
        !           558:     case IO_WriteThrough:
        !           559:        caching = cache_writethrough;
        !           560:        break;
        !           561:        
        !           562:     default:
        !           563:        caching = cache_default;
        !           564:        break;
        !           565:     }
        !           566:     
        !           567:     deviceDescription = [device deviceDescription];
        !           568:     
        !           569:     list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
        !           570:     num = [list count];
        !           571:     
        !           572:     for (i = 0; i < num; i++) {
        !           573:        range = [[list objectAt:i] range];
        !           574:        if (range.base <= phys &&
        !           575:            (range.base + range.length) >= (phys + length))
        !           576:            break;
        !           577:     }
        !           578:            
        !           579:     if (i == num)
        !           580:        return (IO_R_PRIVILEGE);
        !           581:        
        !           582:     if (anywhere)
        !           583:        *addr = vm_map_min(map);
        !           584:     else
        !           585:        *addr = trunc_page(*addr);
        !           586:        
        !           587:     if (map == kernel_map) {
        !           588:        if (!anywhere &&
        !           589:            *addr < 1*1024*1024)        // In the hole... (between 640K and 1M)
        !           590:            return (IO_R_SUCCESS);
        !           591:     }
        !           592:        
        !           593:     result = vm_map_find(
        !           594:                        map,
        !           595:                        VM_OBJECT_NULL, (vm_offset_t) 0,
        !           596:                        addr, length,
        !           597:                        anywhere);
        !           598: 
        !           599:     if (result != KERN_SUCCESS)
        !           600:        return (IO_R_NO_SPACE);
        !           601: 
        !           602:     vaddr = *addr;
        !           603:     vaddr = trunc_page(vaddr);
        !           604:     length = round_page(length);
        !           605:        
        !           606:     (void) vm_map_inherit(
        !           607:                        map,
        !           608:                        vaddr, vaddr + length,
        !           609:                        VM_INHERIT_NONE);
        !           610: 
        !           611:     phys = trunc_page(phys);
        !           612:     
        !           613:     while (length > 0) {
        !           614:        pmap_enter_cache_spec(
        !           615:                            map->pmap,
        !           616:                            vaddr,
        !           617:                            phys,
        !           618:                            VM_PROT_READ | VM_PROT_WRITE,
        !           619:                            TRUE,
        !           620:                            caching);
        !           621:                
        !           622:        vaddr += PAGE_SIZE; length -= PAGE_SIZE; phys += PAGE_SIZE;
        !           623:     }
        !           624:     
        !           625:     return (IO_R_SUCCESS);
        !           626: }
        !           627: 
        !           628: IOReturn
        !           629: kern_IOProbeDriver(host_priv_t device_master, 
        !           630:        unsigned char *configData, 
        !           631:        unsigned int count)
        !           632: {
        !           633:        struct probeDriverArgs  args;
        !           634:        NXConditionLock         *loadDeviceLock;
        !           635:        char                    *configString;
        !           636: 
        !           637:        if (device_master == HOST_NULL)
        !           638:                return IO_R_PRIVILEGE;
        !           639: 
        !           640:        configString = IOMalloc(count + 1);
        !           641:        if (configString == NULL)
        !           642:            return IO_R_NO_SPACE;
        !           643:        bcopy(configData, configString, count);
        !           644:        configString[count] = '\0';
        !           645: 
        !           646:        /*
        !           647:         *  We need to configure the driver from the IOTask context, so...
        !           648:         */
        !           649: 
        !           650:        /*
        !           651:         * Set up a lock so we know when autoconf is complete.
        !           652:         */
        !           653:        loadDeviceLock = [NXConditionLock alloc];
        !           654:        [loadDeviceLock initWith:NO];
        !           655: 
        !           656:        args.waitLock = loadDeviceLock;
        !           657:        args.configData = configString;
        !           658:        IOForkThread((IOThreadFunc) configureThread, (void *) &args);
        !           659:        
        !           660:        [loadDeviceLock lockWhen:YES];
        !           661:        [loadDeviceLock free];
        !           662:        IOFree(configString, count + 1);
        !           663: 
        !           664:        return (args.rtn ? IO_R_SUCCESS : IO_R_NO_DEVICE);
        !           665: }
        !           666: 
        !           667: extern const char *findBootConfigString(int n);
        !           668: 
        !           669: IOReturn kern_IOGetDriverConfig(host_t device_master,
        !           670:        unsigned driverNum,
        !           671:        unsigned maxDataSize,
        !           672:        IOConfigData configData,
        !           673:        unsigned int *configDataCnt)
        !           674: {
        !           675:        int configLength;
        !           676:        const char *configString;
        !           677:        
        !           678:        if (device_master == HOST_NULL)
        !           679:                return IO_R_PRIVILEGE;
        !           680: 
        !           681:        if(maxDataSize > (IO_CONFIG_TABLE_SIZE - 1)) {
        !           682:                maxDataSize = IO_CONFIG_TABLE_SIZE - 1;
        !           683:        }
        !           684:        configString = findBootConfigString(driverNum);
        !           685:        if (configString == NULL) {
        !           686:            return IO_R_NO_DEVICE;
        !           687:        }
        !           688:        configLength = strlen(configString);
        !           689:        if(maxDataSize > configLength) {
        !           690:                maxDataSize = configLength;
        !           691:        }
        !           692:        bcopy(configString, configData, maxDataSize);
        !           693:        configData[maxDataSize] = '\0';
        !           694:        *configDataCnt = maxDataSize + 1;
        !           695:        return IO_R_SUCCESS;
        !           696: }
        !           697: 
        !           698: IOReturn kern_IOGetSystemConfig(host_t device_master,
        !           699:        unsigned maxDataSize,
        !           700:        IOConfigData configData,
        !           701:        unsigned int *configDataCnt)
        !           702: {
        !           703:        return kern_IOGetDriverConfig(
        !           704:            device_master,
        !           705:            0,
        !           706:            maxDataSize,
        !           707:            configData,
        !           708:            configDataCnt);
        !           709: }
        !           710: 
        !           711: IOReturn kern_IOUnloadDriver(host_t device_master,
        !           712:        IOConfigData configData,
        !           713:        unsigned int configDataSize)
        !           714: {
        !           715:        const char      *className;
        !           716:        IOConfigTable   *configTable = nil;
        !           717:        Class           theClass;
        !           718: 
        !           719:        if (device_master == HOST_NULL)
        !           720:                return IO_R_PRIVILEGE;
        !           721: 
        !           722:        configTable = [IOConfigTable newForConfigData:configData];
        !           723:        className = [configTable valueForStringKey:"Driver Name"];
        !           724:        theClass = objc_getClass(className);
        !           725:        if (theClass == nil) {
        !           726:                IOLog("IOUnloadDriver: Couldn't find class named %s\n", 
        !           727:                        className);
        !           728:                if(configTable)
        !           729:                        [configTable free];
        !           730:                return IO_R_INVALID_ARG;
        !           731:        }
        !           732:        
        !           733:        [theClass unregisterClass: theClass];
        !           734:        if (configTable)
        !           735:                [configTable free];
        !           736:        // FIXME: should we do [theClass free] here?
        !           737:        return IO_R_SUCCESS;
        !           738: }
        !           739: 
        !           740: #if defined(hppa) || defined(sparc) /* [*/
        !           741: 
        !           742: static int mapfun(
        !           743:        dev_t           dev,
        !           744:        vm_offset_t     addr,
        !           745:        int             prot
        !           746: )
        !           747: {
        !           748:        vm_offset_t phys = pmap_extract(kernel_pmap, addr);
        !           749:        return(atop(phys));
        !           750: }
        !           751: 
        !           752: IOReturn kern_IOMapLockShmem(
        !           753:        KernDevice  *device,
        !           754:        task_t       task,
        !           755:        vm_size_t    size,
        !           756:        vm_offset_t *shmem)
        !           757: {
        !           758:     vm_object_t vmobject;
        !           759:     vm_map_t    task_map;
        !           760: 
        !           761:     task_map = task->map;
        !           762:     if (task_map == VM_MAP_NULL)
        !           763:        return(IO_R_VM_FAILURE);
        !           764:     size = round_page(size);
        !           765:     
        !           766:     /* Create a fake object to "hold" these pages for user mapping. */
        !           767:     vmobject = (vm_object_t)vm_object_special(0, mapfun, 0, *shmem, size);
        !           768: 
        !           769:     /*
        !           770:     ** Find some memory of the same size in 'task'.  We use vm_map_find()
        !           771:     ** to do this. vm_map_find inserts the found memory object in the
        !           772:     ** target task's map as a side effect.  Ensure that the addresses
        !           773:     ** are equivalently mapped to avoid aliasing problems.
        !           774:     */
        !           775:     if (vm_map_find(task_map, vmobject, 0, shmem, size, FALSE))
        !           776:     { // OK, can't get that, so let it find memory 
        !           777:        if (vm_map_find(task_map, vmobject, 0, shmem, size, TRUE))
        !           778:            return(IO_R_NO_MEMORY);
        !           779:     }
        !           780: 
        !           781:     return(IO_R_SUCCESS); 
        !           782: }
        !           783: 
        !           784: IOReturn kern_IOUnMapLockShmem(
        !           785:        KernDevice  *device,
        !           786:        task_t       task,
        !           787:        vm_size_t    size,
        !           788:        vm_offset_t *shmem)
        !           789: {
        !           790:     vm_offset_t off;
        !           791:     kern_return_t krtn;
        !           792:     vm_map_t           task_map;
        !           793: 
        !           794:     task_map = task->map;
        !           795:     if (task_map == VM_MAP_NULL)
        !           796:        return(IO_R_VM_FAILURE);
        !           797:     size = round_page(size);
        !           798: 
        !           799:     // Pull the shared pages out of the task map
        !           800:     for ( off = 0; off < size; off += PAGE_SIZE )
        !           801:     {
        !           802:        pmap_remove(task_map->pmap, *shmem + off, *shmem + off + PAGE_SIZE);
        !           803:     }
        !           804:     // Free the former shmem area in the task
        !           805:     krtn = vm_map_remove(task_map, *shmem, *shmem + size );
        !           806:     if (krtn)
        !           807:     {
        !           808:        IOLog("IOUnMapLockShmem: vm_map_remove() returned %d\n", krtn);
        !           809:     }
        !           810:    
        !           811:     // This deallocate is commented out because it caused some strange
        !           812:     // kernel hang -- Should be looked into some time.
        !           813:     // Possibly the ref_cnt is not properly incremented.
        !           814: //    vm_map_deallocate(task_map);     // discard our reference
        !           815:     return(krtn);
        !           816: }
        !           817: #endif /*]*/
        !           818: 
        !           819: IOReturn
        !           820: kern_IOMapDeviceMemory(
        !           821:     KernDevice         *device,
        !           822:     task_t             task,
        !           823:     vm_offset_t        phys,
        !           824:     vm_size_t          length,
        !           825:     vm_offset_t        *addr,                          // in/out
        !           826:     BOOL               anywhere,
        !           827:     IOCache    cache
        !           828: )
        !           829: {
        !           830:     IOReturn   rtn;
        !           831: 
        !           832:     if (device == nil)
        !           833:        return IO_R_PRIVILEGE;
        !           834:     
        !           835:     rtn = kern_dev_map_phys(
        !           836:                            device,
        !           837:                            task->map,
        !           838:                            phys,
        !           839:                            length,
        !           840:                            addr,
        !           841:                            anywhere,
        !           842:                            cache);
        !           843:     
        !           844:     return (rtn);
        !           845: }
        !           846: 
        !           847: #if hppa /* [ */
        !           848: IOReturn
        !           849: kern_IOGetDeviceConfig(
        !           850:     KernDevice                 *device,
        !           851:     IOHPPAInterruptList                interrupts,
        !           852:     unsigned int               *interruptNum,
        !           853:     IOHPPAMemoryMap            memoryRegions,
        !           854:     unsigned int               *memoryRegionNum
        !           855: )
        !           856: {
        !           857:     int                        i, num;
        !           858:     Range              range;
        !           859:     id                 list, deviceDescription;
        !           860: 
        !           861:     if (device == nil)
        !           862:        return IO_R_PRIVILEGE;
        !           863:        
        !           864:     deviceDescription = [device deviceDescription];
        !           865:     
        !           866:     list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
        !           867:     num = [list count];
        !           868:     if (num > IO_NUM_HPPA_INTERRUPTS)
        !           869:        num = IO_NUM_HPPA_INTERRUPTS;
        !           870:     for (i = 0; i < num; i++)
        !           871:        interrupts[i] = [[list objectAt:i] item];
        !           872:     *interruptNum = num;
        !           873: 
        !           874:     list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
        !           875:     num = [list count];
        !           876:     if (num > IO_NUM_HPPA_MEMORY_RANGES)
        !           877:        num = IO_NUM_HPPA_MEMORY_RANGES;
        !           878:     for (i = 0; i < num; i++) {
        !           879:        range = [[list objectAt:i] range];
        !           880:        memoryRegions[i].start = range.base;
        !           881:        memoryRegions[i].size = range.length;
        !           882:     }
        !           883:     *memoryRegionNum = num;
        !           884:     
        !           885:     return IO_R_SUCCESS;
        !           886: }
        !           887: #endif /* ] */
        !           888: 
        !           889: #if sparc /*[*/
        !           890: 
        !           891: IOReturn
        !           892: kern_IOMapSparcDeviceMemory(
        !           893:     KernDevice         *device,
        !           894:     task_t             task,
        !           895:     vm_offset_t        phys,
        !           896:     vm_size_t          length,
        !           897:     vm_offset_t        *addr,                          // in/out
        !           898:     BOOL               anywhere,
        !           899:     IOCache    cache
        !           900: )
        !           901: {
        !           902:     IOReturn   rtn;
        !           903:     id                 list, deviceDescription;
        !           904:     kern_return_t      result;
        !           905:     vm_offset_t                vaddr;
        !           906:        vm_map_t        map;
        !           907:     Range              range;
        !           908:     int                        i, num;
        !           909:     cache_spec_t       caching;
        !           910:        unsigned int paddr,spaceid;
        !           911:     
        !           912:      if (device == nil)
        !           913:        return IO_R_PRIVILEGE;
        !           914:        map = task->map;
        !           915:     if (anywhere)
        !           916:        *addr = vm_map_min(map);
        !           917:     else
        !           918:        *addr = trunc_page(*addr);
        !           919: #if 0  
        !           920: // needed only for intel
        !           921:     if (map == kernel_map) {
        !           922:        if (!anywhere &&
        !           923:            *addr < 1*1024*1024)        // In the hole... (between 640K and 1M)
        !           924:            return (IO_R_SUCCESS);
        !           925:     }
        !           926: #endif
        !           927:     result = vm_map_find(
        !           928:                        map,
        !           929:                        VM_OBJECT_NULL, (vm_offset_t) 0,
        !           930:                        addr, length,
        !           931:                        anywhere);
        !           932: 
        !           933:     if (result != KERN_SUCCESS)
        !           934:        return (IO_R_NO_SPACE);
        !           935:     vaddr = *addr;
        !           936:     vaddr = trunc_page(vaddr);
        !           937:     length = round_page(length);
        !           938:        
        !           939:     (void) vm_map_inherit(
        !           940:                        map,
        !           941:                        vaddr, vaddr + length,
        !           942:                        VM_INHERIT_NONE);
        !           943:        // Mapping the frame buffer in user context
        !           944:        spaceid = (phys ) & 0x0f;       // 4bits space id which is packed in bits 24-31;
        !           945:        paddr = ((unsigned int)(phys & 0xffffff00));
        !           946:        pmap_enter_range( map->pmap,
        !           947:                           vaddr, paddr,
        !           948:                           spaceid, length,
        !           949:                           VM_PROT_READ | VM_PROT_WRITE, FALSE, TRUE );
        !           950:     return (IO_R_SUCCESS);
        !           951: 
        !           952: 
        !           953: }
        !           954: 
        !           955: IOReturn
        !           956: kern_IOGetDeviceConfig(
        !           957:     KernDevice                 *device,
        !           958:     IOSPARCInterruptList               interrupts,
        !           959:     unsigned int               *interruptNum,
        !           960:     IOSPARCMemoryMap           memoryRegions,
        !           961:     unsigned int               *memoryRegionNum
        !           962: )
        !           963: {
        !           964:     int                        i, num;
        !           965:     Range              range;
        !           966:     id                 list, deviceDescription;
        !           967: 
        !           968:     if (device == nil)
        !           969:        return IO_R_PRIVILEGE;
        !           970:        
        !           971:     deviceDescription = [device deviceDescription];
        !           972:     
        !           973:     list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
        !           974:     num = [list count];
        !           975:     if (num > IO_NUM_SPARC_INTERRUPTS)
        !           976:        num = IO_NUM_SPARC_INTERRUPTS;
        !           977:     for (i = 0; i < num; i++)
        !           978:        interrupts[i] = [[list objectAt:i] item];
        !           979:     *interruptNum = num;
        !           980: 
        !           981:     list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
        !           982:     num = [list count];
        !           983:     if (num > IO_NUM_SPARC_MEMORY_RANGES)
        !           984:        num = IO_NUM_SPARC_MEMORY_RANGES;
        !           985:     for (i = 0; i < num; i++) {
        !           986:        range = [[list objectAt:i] range];
        !           987:        memoryRegions[i].start = range.base;
        !           988:        memoryRegions[i].size = range.length;
        !           989:     }
        !           990:     *memoryRegionNum = num;
        !           991:     
        !           992:     return IO_R_SUCCESS;
        !           993: }
        !           994: 
        !           995: 
        !           996: #endif /*]*/
        !           997: 
        !           998: #if ppc /* [ */
        !           999: IOReturn
        !          1000: kern_IOGetDeviceConfig(
        !          1001:     KernDevice                 *device,
        !          1002:     IOPPCInterruptList         interrupts,
        !          1003:     unsigned int               *interruptNum,
        !          1004: #ifdef notyet 
        !          1005:     IOPPCDMAChannelList        dmaChannels,
        !          1006:     unsigned int               *dmaChannelNum,
        !          1007: #endif
        !          1008:     IOPPCMemoryMap             memoryRegions,
        !          1009:     unsigned int               *memoryRegionNum
        !          1010: )
        !          1011: {
        !          1012:     int                        i, num;
        !          1013:     Range              range;
        !          1014:     id                 list, deviceDescription;
        !          1015: 
        !          1016:     if (device == nil)
        !          1017:        return IO_R_PRIVILEGE;
        !          1018:        
        !          1019:     deviceDescription = [device deviceDescription];
        !          1020:     
        !          1021:     list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
        !          1022:     num = [list count];
        !          1023:     if (num > IO_NUM_PPC_INTERRUPTS)
        !          1024:        num = IO_NUM_PPC_INTERRUPTS;
        !          1025:     for (i = 0; i < num; i++)
        !          1026:        interrupts[i] = [[list objectAt:i] item];
        !          1027:     *interruptNum = num;
        !          1028: 
        !          1029: #ifdef notyet 
        !          1030:    list = [deviceDescription resourcesForKey:DMA_CHANNELS_KEY];
        !          1031:     num = [list count];
        !          1032:     if (num > IO_NUM_PPC_DMA_CHANNELS)
        !          1033:        num = IO_NUM_PPC_DMA_CHANNELS;
        !          1034:     for (i = 0; i < num; i++)
        !          1035:        dmaChannels[i] = [[list objectAt:i] item];
        !          1036:     *dmaChannelNum = num;
        !          1037: #endif
        !          1038:     list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
        !          1039:     num = [list count];
        !          1040:     if (num > IO_NUM_PPC_MEMORY_RANGES)
        !          1041:        num = IO_NUM_PPC_MEMORY_RANGES;
        !          1042:     for (i = 0; i < num; i++) {
        !          1043:        range = [[list objectAt:i] range];
        !          1044:        memoryRegions[i].start = range.base;
        !          1045:        memoryRegions[i].size = range.length;
        !          1046:     }
        !          1047:     *memoryRegionNum = num;
        !          1048: 
        !          1049: 
        !          1050:     
        !          1051:     return IO_R_SUCCESS;
        !          1052: }
        !          1053: #endif /* ] */

unix.superglobalmegacorp.com

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