Annotation of driverkit/Config/ConfigUtils.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
                     25:  *
                     26:  * ConfigUtils.c - common utility functions for Config server.
                     27:  *
                     28:  * HISTORY
                     29:  * 12-Apr-91    Doug Mitchell at NeXT
                     30:  *      Created.
                     31:  */
                     32: 
                     33: #import <bsd/sys/types.h>
                     34: #import <bsd/libc.h>
                     35: #import <mach/mach_types.h>
                     36: #import <driverkit/userConfigServer.h>
                     37: #import "ConfigPrivate.h"
                     38: #import "ConfigUtils.h"
                     39: #import <mach/kern_return.h>
                     40: #import <mach/mach.h>
                     41: #import <mach/mach_error.h>
                     42: #import <kernserv/queue.h>
                     43: #import <driverkit/generalFuncs.h>
                     44: 
                     45: IONamedValue search_keys[] = {
                     46:        {SK_DRIVER_PORT,        "Driver Port"           },
                     47:        {SK_DEV_PORT,           "Device Port"           },
                     48:        {SK_SIG_PORT,           "Driver Sig Port"       },
                     49:        {SK_DEVNUM,             "dev_number"            },      
                     50:        {SK_FID,                "FID"                   },      
                     51:        {SK_DEV_INDEX,          "deviceIndex"           },      
                     52:        {0,                     NULL                    },
                     53: };
                     54: 
                     55: IONamedValue dev_returns[] = {
                     56:        {IO_R_SUCCESS,          "Success"                               },
                     57:        {IO_R_PRIVILEGE,        "port/device access denied"             },
                     58:        {IO_R_NO_CHANNELS,      "no DMA channels available"             },
                     59:        {IO_R_NO_SPACE,         "no address space available for mapping"},
                     60:        {IO_R_NO_DEVICE,        "no more dev_numbers"                   },
                     61:        {0,                     NULL                                    },
                     62: };
                     63: 
                     64: IONamedValue config_returns[] = {
                     65:        {IO_CNF_SUCCESS,        "Success"                               },
                     66:        {IO_CNF_NOT_REGISTERED, "port not registered"                   },
                     67:        {IO_CNF_NOT_FOUND,      "slot_id/dev_type not found"            },
                     68:        {IO_CNF_BUSY,           "Config Busy"                           },
                     69:        {IO_CNF_REGISTERED,     "driver_port already registered"        },
                     70:        {IO_CNF_RESOURCE,       "System Resource Shortage"              },
                     71:        {IO_CNF_ACCESS,         "Device Access Denied"                  },
                     72:        {0,                     NULL                                    },
                     73: };
                     74: 
                     75: /*
                     76:  * Get a driver_entry_t (and possibly a dev_entry_t) from driver_list 
                     77:  * matching the specified parameter. *dev_entry is only returned if the
                     78:  * specified search_key necessitates searching through a driver_entry's
                     79:  * dev_list.
                     80:  * Returns NULL if specified driver_entry not found.
                     81:  * driver_list_lock must be held on entry.
                     82:  */
                     83: driver_entry_t *get_driver_entry(
                     84:        dev_search_key_t search_key,
                     85:        port_t search_port,
                     86:        IODeviceNumber dev_number,
                     87:        file_id_t fid,
                     88:        IODeviceType device_type,       // only deviceIndex is used
                     89:        IOSlotId slot_id,
                     90:        dev_entry_t **dev_entry_pp)
                     91: {
                     92:        driver_entry_t *driver_entry;
                     93:        boolean_t found = FALSE;
                     94:        dev_entry_t *dev_entry;
                     95:        
                     96: #if    DDM_DEBUG
                     97:        xpr_common("get_driver_port: search key %s\n", 
                     98:                IOFindNameForValue(search_key, search_keys), 2,3,4,5);
                     99: #endif DDM_DEBUG
                    100:        driver_entry = (driver_entry_t *)queue_first(&driver_list);
                    101:        while(!queue_end(&driver_list, (queue_t)driver_entry)) {
                    102:                switch(search_key) {
                    103:                    case SK_DRIVER_PORT:
                    104:                        if(driver_entry->driver_port == search_port) 
                    105:                                found = TRUE;
                    106:                        break;
                    107:                    case SK_DEV_PORT:
                    108:                    case SK_DEVNUM:
                    109:                    case SK_DEV_INDEX:
                    110:                        /*
                    111:                         * Search this driver's dev_list for this dev_port
                    112:                         * or dev_number.
                    113:                         */
                    114:                        dev_entry = get_dev_entry(
                    115:                                search_key,
                    116:                                driver_entry,
                    117:                                search_port,
                    118:                                dev_number,
                    119:                                device_type,
                    120:                                slot_id);
                    121:                        if(dev_entry != NULL) {
                    122:                                found = TRUE;
                    123:                                if(dev_entry) {
                    124:                                        *dev_entry_pp = dev_entry;
                    125:                                }
                    126:                        }
                    127:                        break;
                    128:                        
                    129:                    case SK_SIG_PORT:
                    130:                        if(driver_entry->driver_sig_port == search_port)
                    131:                                found = TRUE;
                    132:                        break;
                    133:                        
                    134:                    case SK_FID:
                    135:                        if(driver_entry->executable_fid == fid)
                    136:                                found = TRUE;
                    137:                        break;
                    138:                        
                    139:                    default:
                    140:                        printf("BOGUS SEARCH KEY IN get_driver_entry()\n");
                    141:                        driver_entry = NULL;
                    142:                        found = TRUE;
                    143:                        break;
                    144:                }
                    145:                if(found)
                    146:                        break;
                    147:                /*
                    148:                 * Try next entry.
                    149:                 */
                    150:                driver_entry = (driver_entry_t *)driver_entry->link.next;
                    151:        }
                    152:        if(found) {
                    153:                xpr_common("get_driver_port: found driver_entry 0x%x\n", 
                    154:                        driver_entry, 2,3,4,5);
                    155:                if(driver_entry->filename) {
                    156:                        xpr_common("    filename = %s\n", 
                    157:                                IOCopyString(driver_entry->filename), 2,3,4,5);
                    158:                }
                    159:        }
                    160:        else {
                    161:                driver_entry = NULL;
                    162:                xpr_common("get_driver_port: driver_entry not found\n", 
                    163:                        1,2,3,4,5);
                    164:        }
                    165:        return(driver_entry);
                    166: }
                    167: 
                    168: /*
                    169:  * Get a dev_entry_t from specified driver_entry's dev_list matching the
                    170:  * specified parameter.
                    171:  * Returns NULL if dev_entry not found.
                    172:  * driver_list_lock must be held on entry.
                    173:  */
                    174: dev_entry_t *get_dev_entry(
                    175:        dev_search_key_t search_key,
                    176:        driver_entry_t *driver_entry,
                    177:        port_t search_port,
                    178:        IODeviceNumber dev_number,
                    179:        IODeviceType dev_type,
                    180:        IOSlotId slot_id)
                    181: {
                    182:        dev_entry_t *dev_entry;
                    183:        boolean_t found = FALSE;
                    184:        
                    185:        dev_entry = (dev_entry_t *)queue_first(&driver_entry->dev_list);
                    186:        while(!queue_end(&driver_entry->dev_list, (queue_t)dev_entry)) {
                    187:                switch(search_key) {
                    188:                    case SK_DEV_PORT:
                    189:                        if(dev_entry->dev_port == search_port) 
                    190:                                found = TRUE;
                    191:                        break;
                    192:                    case SK_DEVNUM:
                    193:                        if(dev_entry->dev_number == dev_number)
                    194:                                found = TRUE;
                    195:                        break;
                    196:                    case SK_DEV_INDEX:
                    197:                        if((dev_entry->dev_type == dev_type) &&
                    198:                           (dev_entry->slot_id == slot_id)) {
                    199:                                found = TRUE;   
                    200:                        }
                    201:                        break;
                    202:                    default:
                    203:                        printf("get_dev_entry: BOGUS SEARCH_KEY\n");
                    204:                        dev_entry = NULL;
                    205:                        found = TRUE;
                    206:                        break;
                    207:                }
                    208:                if(found)
                    209:                        break;
                    210:                        
                    211:                /*
                    212:                 * Try next dev_entry.
                    213:                 */
                    214:                dev_entry = (dev_entry_t *)dev_entry->link.next;
                    215:        }
                    216:        if(found)
                    217:                return(dev_entry);
                    218:        else
                    219:                return(NULL);
                    220: }
                    221: 
                    222: /*
                    223:  * Create a new driver_entry_t, add it to driver_list. Caller must hold
                    224:  * driver_list_lock. No ports are allocated here (that's done in 
                    225:  * exec_driver().
                    226:  */
                    227: driver_entry_t *create_driver_entry(
                    228:        file_id_t fid,
                    229:        filename_t filename)
                    230: {
                    231:        driver_entry_t *driver_entry;
                    232:        
                    233:        xpr_common("create_driver_entry: filename %s\n", 
                    234:                IOCopyString(filename), 2,3,4,5);
                    235:        driver_entry = malloc(sizeof(*driver_entry));
                    236:        queue_init(&driver_entry->dev_list);
                    237:        driver_entry->executable_fid = fid;
                    238:        strncpy(driver_entry->filename, filename, FILENAME_SIZE);
                    239:        driver_entry->driver_port = PORT_NULL;
                    240:        driver_entry->driver_sig_port = PORT_NULL;
                    241:        driver_entry->boot_requestor = PORT_NULL;
                    242:        driver_entry->running = FALSE;
                    243:        queue_enter(&driver_list,
                    244:                driver_entry,
                    245:                driver_entry_t *,
                    246:                link);
                    247:        return(driver_entry);
                    248: }
                    249: 
                    250: /*
                    251:  * Release all state associated with specified driver_entry_t. Inform kernel 
                    252:  * that all associated dev_ports are to be destroyed.
                    253:  *
                    254:  * This is used by driver_delete() and upon port death notification of a
                    255:  * driver_port.
                    256:  *
                    257:  * driver_list_lock must be held on entry.
                    258:  */
                    259: IOConfigReturn free_driver_entry(
                    260:        driver_entry_t *driver_entry)
                    261: {
                    262:        dev_entry_t *dev_entry, *dev_entry_next;
                    263:        IOConfigReturn crtn = IO_CNF_SUCCESS;
                    264:        
                    265:        xpr_common("free_driver_entry driver_entry 0x%x\n", 
                    266:                driver_entry, 2,3,4,5);
                    267:        xpr_common("  filename %s\n", 
                    268:                IOCopyString(driver_entry->filename), 2,3,4,5);
                    269:        dev_entry = (dev_entry_t *)queue_first(&driver_entry->dev_list);
                    270:        
                    271:        /*
                    272:         * First delete all of this driver's dev_ports.
                    273:         */
                    274:        while(!queue_end(&driver_entry->dev_list, (queue_t)dev_entry)) {
                    275:                dev_entry_next = (dev_entry_t *)dev_entry->link.next;
                    276:                if(free_dev_entry(dev_entry))
                    277:                        crtn = IO_CNF_ACCESS;
                    278:                dev_entry = dev_entry_next;
                    279:        }
                    280: 
                    281:        /*
                    282:         * Now free up internal state.
                    283:         */
                    284:        if(driver_entry->driver_sig_port != PORT_NULL)
                    285:                port_deallocate(task_self(), driver_entry->driver_sig_port);
                    286:        if(driver_entry->boot_requestor != PORT_NULL)
                    287:                port_deallocate(task_self(), driver_entry->boot_requestor);
                    288:        queue_remove(&driver_list,
                    289:                driver_entry,
                    290:                driver_entry_t *,
                    291:                link);
                    292:        free(driver_entry);
                    293:        return(crtn);
                    294: }
                    295: 
                    296: /*
                    297:  * Create a new dev_entry_t, add it to driver_entry's dev_list. This is the 
                    298:  * only place where we ask the kernel to create a dev_port.
                    299:  */
                    300: dev_entry_t *create_dev_entry(
                    301:        driver_entry_t *driver_entry, 
                    302:        IODeviceNumber dev_number,
                    303:        IODeviceType dev_type, 
                    304:        IOSlotId slot_id)
                    305: {      
                    306:        dev_entry_t *dev_entry;
                    307:        IOReturn drtn;
                    308:        
                    309:        xpr_common("create_dev_entry: dev_number %d dev_type 0x%x\n",
                    310:                dev_number, dev_type, 3,4,5);
                    311:        xpr_common("   slot_id 0x%x filename %s\n", 
                    312:                slot_id, IOCopyString(driver_entry->filename), 3,4,5);
                    313:        dev_entry = malloc(sizeof(*dev_entry));
                    314:        drtn = _IOCreateDevicePort(device_master_port,
                    315:                task_self(),
                    316:                dev_number,
                    317:                &dev_entry->dev_port);
                    318:        if(drtn) {
                    319:                IOLog("Config: _IOCreateDevicePort() returned %s\n",
                    320:                        IOFindNameForValue(drtn, dev_returns), 2,3,4,5);
                    321:                free(dev_entry);
                    322:                return(NULL);
                    323:        }
                    324:        dev_entry->dev_type = dev_type;
                    325:        dev_entry->slot_id = slot_id;
                    326:        dev_entry->dev_number = dev_number;
                    327:        dev_entry->driver_entry = driver_entry;
                    328:        queue_enter(&driver_entry->dev_list,
                    329:                dev_entry,
                    330:                dev_entry_t *,
                    331:                link);
                    332:        return(dev_entry);
                    333: }
                    334: 
                    335: 
                    336: /*
                    337:  * Destroy state associated with specified dev_entry.
                    338:  */
                    339: IOConfigReturn free_dev_entry(
                    340:        dev_entry_t *dev_entry)
                    341: {
                    342:        IOReturn drtn;
                    343:        IOConfigReturn crtn = IO_CNF_SUCCESS;
                    344:        
                    345:        xpr_common("deleting dev_entry 0x%x\n", dev_entry, 2,3,4,5);
                    346:        xpr_common("   dev_type 0x%x  slot_id 0x%x\n", 
                    347:                dev_entry->dev_type, dev_entry->slot_id, 3,4,5);
                    348:        if(dev_entry->dev_port != PORT_NULL) {
                    349:                drtn = _IODestroyDevicePort(device_master_port,
                    350:                        dev_entry->dev_port);
                    351:                if(drtn) {
                    352:                        xpr_common("free_dev_entry: _IODestroyDevicePort() "
                    353:                                "returned %s\n", 
                    354:                                IOFindNameForValue(drtn, dev_returns),
                    355:                                2,3,4,5);
                    356:                        crtn = IO_CNF_ACCESS;
                    357:                }
                    358:        }
                    359:                
                    360:        /*
                    361:         * Delete the dev_entry_t itself.
                    362:         */
                    363:        queue_remove(&dev_entry->driver_entry->dev_list,
                    364:                dev_entry,
                    365:                dev_entry_t *,
                    366:                link);
                    367:        free(dev_entry);
                    368:        return(crtn);
                    369: }
                    370: 
                    371: /*
                    372:  * Get/release driver_list_lock as a sleep lock.
                    373:  */
                    374: void get_driver_list_lock()
                    375: {
                    376:        mutex_lock(driver_list_lock);
                    377:        while(driver_list_locked)
                    378:                condition_wait(driver_list_cond, driver_list_lock);
                    379:        driver_list_locked = TRUE;
                    380:        mutex_unlock(driver_list_lock);
                    381: }
                    382: 
                    383: void release_driver_list_lock()
                    384: {
                    385:        mutex_lock(driver_list_lock);
                    386:        driver_list_locked = FALSE;
                    387:        condition_signal(driver_list_cond);
                    388:        mutex_unlock(driver_list_lock);
                    389: }
                    390: 

unix.superglobalmegacorp.com

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