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

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright (c) 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.