|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.