Annotation of kernel/driverkit/driverServerXXX.m, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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