Changeset 38b3baf in mainline for uspace/srv/devman/main.c
- Timestamp:
- 2010-10-23T07:16:14Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7e66a5ec
- Parents:
- 032e0bb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/main.c
r032e0bb r38b3baf 63 63 static class_list_t class_list; 64 64 65 /** 66 * Register running driver. 67 */ 68 static driver_t * devman_driver_register(void) 69 { 65 /** Register running driver. */ 66 static driver_t *devman_driver_register(void) 67 { 70 68 printf(NAME ": devman_driver_register \n"); 71 69 … … 81 79 char *drv_name = NULL; 82 80 83 / / Get driver name84 int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);81 /* Get driver name. */ 82 int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0); 85 83 if (rc != EOK) { 86 84 ipc_answer_0(iid, rc); 87 85 return NULL; 88 86 } 89 printf(NAME ": the %s driver is trying to register by the service.\n", drv_name); 90 91 // Find driver structure 87 printf(NAME ": the %s driver is trying to register by the service.\n", 88 drv_name); 89 90 /* Find driver structure. */ 92 91 driver = find_driver(&drivers_list, drv_name); 93 92 … … 103 102 drv_name = NULL; 104 103 105 / / Create connection to the driver106 printf(NAME ": creating connection to the %s driver.\n", driver->name); 104 /* Create connection to the driver. */ 105 printf(NAME ": creating connection to the %s driver.\n", driver->name); 107 106 ipc_call_t call; 108 ipc_callid_t callid = async_get_call(&call); 107 ipc_callid_t callid = async_get_call(&call); 109 108 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { 110 109 ipc_answer_0(callid, ENOTSUP); … … 113 112 } 114 113 115 / / remember driver's phone114 /* Remember driver's phone. */ 116 115 set_driver_phone(driver, IPC_GET_ARG5(call)); 117 116 118 printf(NAME ": the %s driver was successfully registered as running.\n", driver->name);119 120 ipc_answer_0(callid, EOK);121 117 printf(NAME ": the %s driver was successfully registered as running.\n", 118 driver->name); 119 120 ipc_answer_0(callid, EOK); 122 121 ipc_answer_0(iid, EOK); 123 122 … … 125 124 } 126 125 127 /** 128 * Receive device match ID from the device's parent driver and add it to the list of devices match ids. 129 * 130 * @param match_ids the list of the device's match ids. 131 * 132 * @return 0 on success, negative error code otherwise. 133 */ 134 static int devman_receive_match_id(match_id_list_t *match_ids) { 135 126 /** Receive device match ID from the device's parent driver and add it to the 127 * list of devices match ids. 128 * 129 * @param match_ids The list of the device's match ids. 130 * @return Zero on success, negative error code otherwise. 131 */ 132 static int devman_receive_match_id(match_id_list_t *match_ids) 133 { 136 134 match_id_t *match_id = create_match_id(); 137 135 ipc_callid_t callid; … … 141 139 callid = async_get_call(&call); 142 140 if (DEVMAN_ADD_MATCH_ID != IPC_GET_METHOD(call)) { 143 printf(NAME ": ERROR: devman_receive_match_id - invalid protocol.\n"); 141 printf(NAME ": ERROR: devman_receive_match_id - invalid " 142 "protocol.\n"); 144 143 ipc_answer_0(callid, EINVAL); 145 144 delete_match_id(match_id); … … 148 147 149 148 if (NULL == match_id) { 150 printf(NAME ": ERROR: devman_receive_match_id - failed to allocate match id.\n"); 149 printf(NAME ": ERROR: devman_receive_match_id - failed to " 150 "allocate match id.\n"); 151 151 ipc_answer_0(callid, ENOMEM); 152 152 return ENOMEM; … … 158 158 159 159 char *match_id_str; 160 rc = async_data_write_accept((void **) &match_id_str, true, 0, 0, 0, 0);160 rc = async_data_write_accept((void **) &match_id_str, true, 0, 0, 0, 0); 161 161 match_id->id = match_id_str; 162 162 if (EOK != rc) { 163 163 delete_match_id(match_id); 164 printf(NAME ": devman_receive_match_id - failed to receive match id string.\n"); 164 printf(NAME ": devman_receive_match_id - failed to receive " 165 "match id string.\n"); 165 166 return rc; 166 167 } … … 168 169 list_append(&match_id->link, &match_ids->ids); 169 170 170 printf(NAME ": received match id '%s', score = %d \n", match_id->id, match_id->score); 171 printf(NAME ": received match id '%s', score = %d \n", 172 match_id->id, match_id->score); 171 173 return rc; 172 174 } 173 175 174 /** 175 * Receive device match IDs from the device's parent driver 176 * and add them to the list of devices match ids. 177 * 178 * @param match_count the number of device's match ids to be received. 179 * @param match_ids the list of the device's match ids. 180 * 181 * @return 0 on success, negative error code otherwise. 182 */ 183 static int devman_receive_match_ids(ipcarg_t match_count, match_id_list_t *match_ids) 184 { 176 /** Receive device match IDs from the device's parent driver and add them to the 177 * list of devices match ids. 178 * 179 * @param match_count The number of device's match ids to be received. 180 * @param match_ids The list of the device's match ids. 181 * @return Zero on success, negative error code otherwise. 182 */ 183 static int 184 devman_receive_match_ids(ipcarg_t match_count, match_id_list_t *match_ids) 185 { 185 186 int ret = EOK; 186 187 size_t i; 188 187 189 for (i = 0; i < match_count; i++) { 188 if (EOK != (ret = devman_receive_match_id(match_ids))) {190 if (EOK != (ret = devman_receive_match_id(match_ids))) 189 191 return ret; 190 }191 192 } 192 193 return ret; 193 194 } 194 195 195 /** Handle child device registration. 196 * 196 /** Handle child device registration. 197 * 197 198 * Child devices are registered by their parent's device driver. 198 199 */ 199 200 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call) 200 201 { 201 //printf(NAME ": devman_add_child\n");202 203 202 device_handle_t parent_handle = IPC_GET_ARG1(*call); 204 203 ipcarg_t match_count = IPC_GET_ARG2(*call); … … 215 214 216 215 char *dev_name = NULL; 217 int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0); 216 int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0); 218 217 if (EOK != rc) { 219 218 fibril_rwlock_write_unlock(&tree->rwlock); … … 221 220 return; 222 221 } 223 //printf(NAME ": newly added child device's name is '%s'.\n", dev_name);224 222 225 223 node_t *node = create_dev_node(); … … 236 234 devman_receive_match_ids(match_count, &node->match_ids); 237 235 238 / / return device handle to parent's driver236 /* Return device handle to parent's driver. */ 239 237 ipc_answer_1(callid, EOK, node->handle); 240 238 241 / / try to find suitable driver and assign it to the device242 assign_driver(node, &drivers_list, &device_tree); 239 /* Try to find suitable driver and assign it to the device. */ 240 assign_driver(node, &drivers_list, &device_tree); 243 241 } 244 242 245 243 static void devmap_register_class_dev(dev_class_info_t *cli) 246 244 { 247 / / create devmap path and name for the device245 /* Create devmap path and name for the device. */ 248 246 char *devmap_pathname = NULL; 249 asprintf(&devmap_pathname, "%s/%s%c%s", DEVMAP_CLASS_NAMESPACE, cli->dev_class->name, DEVMAP_SEPARATOR, cli->dev_name); 250 if (NULL == devmap_pathname) { 251 return; 252 } 253 254 // register the device by the device mapper and remember its devmap handle 255 devmap_device_register(devmap_pathname, &cli->devmap_handle); 256 257 // add device to the hash map of class devices registered by device mapper 247 asprintf(&devmap_pathname, "%s/%s%c%s", DEVMAP_CLASS_NAMESPACE, 248 cli->dev_class->name, DEVMAP_SEPARATOR, cli->dev_name); 249 if (NULL == devmap_pathname) 250 return; 251 252 /* 253 * Register the device by the device mapper and remember its devmap 254 * handle. 255 */ 256 devmap_device_register(devmap_pathname, &cli->devmap_handle); 257 258 /* 259 * Add device to the hash map of class devices registered by device 260 * mapper. 261 */ 258 262 class_add_devmap_device(&class_list, cli); 259 263 260 free(devmap_pathname); 264 free(devmap_pathname); 261 265 } 262 266 … … 265 269 device_handle_t handle = IPC_GET_ARG1(*call); 266 270 267 / / Get class name271 /* Get class name. */ 268 272 char *class_name; 269 int rc = async_data_write_accept((void **)&class_name, true, 0, 0, 0, 0); 273 int rc = async_data_write_accept((void **) &class_name, true, 274 0, 0, 0, 0); 270 275 if (rc != EOK) { 271 276 ipc_answer_0(callid, rc); … … 280 285 281 286 dev_class_t *cl = get_dev_class(&class_list, class_name); 282 283 287 dev_class_info_t *class_info = add_device_to_class(dev, cl, NULL); 284 288 285 / / register the device's class alias by devmapper289 /* Register the device's class alias by devmapper. */ 286 290 devmap_register_class_dev(class_info); 287 291 288 printf(NAME ": device '%s' added to class '%s', class name '%s' was asigned to it\n", dev->pathname, class_name, class_info->dev_name);289 290 ipc_answer_0(callid, EOK);291 } 292 293 /** 294 295 * 296 * The initialization is done in a separate fibril to avoid deadlocks 297 * (if the driver needed to be served by devman during the driver's initialization).292 printf(NAME ": device '%s' added to class '%s', class name '%s' was " 293 "asigned to it\n", dev->pathname, class_name, class_info->dev_name); 294 295 ipc_answer_0(callid, EOK); 296 } 297 298 /** Initialize driver which has registered itself as running and ready. 299 * 300 * The initialization is done in a separate fibril to avoid deadlocks (if the 301 * driver needed to be served by devman during the driver's initialization). 298 302 */ 299 303 static int init_running_drv(void *drv) 300 304 { 301 driver_t *driver = (driver_t *)drv; 302 initialize_running_driver(driver, &device_tree); 303 printf(NAME ": the %s driver was successfully initialized. \n", driver->name); 305 driver_t *driver = (driver_t *) drv; 306 307 initialize_running_driver(driver, &device_tree); 308 printf(NAME ": the %s driver was successfully initialized. \n", 309 driver->name); 304 310 return 0; 305 311 } 306 312 307 /** Function for handling connections from a driver to the device manager. 308 */ 313 /** Function for handling connections from a driver to the device manager. */ 309 314 static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall) 310 { 311 /* Accept the connection */315 { 316 /* Accept the connection. */ 312 317 ipc_answer_0(iid, EOK); 313 318 … … 316 321 return; 317 322 318 // Initialize the driver as running (e.g. pass assigned devices to it) in a separate fibril; 319 // the separate fibril is used to enable the driver 320 // to use devman service during the driver's initialization. 323 /* 324 * Initialize the driver as running (e.g. pass assigned devices to it) 325 * in a separate fibril; the separate fibril is used to enable the 326 * driver to use devman service during the driver's initialization. 327 */ 321 328 fid_t fid = fibril_create(init_running_drv, driver); 322 329 if (fid == 0) { 323 printf(NAME ": Error creating fibril for the initialization of the newly registered running driver.\n"); 330 printf(NAME ": Error creating fibril for the initialization of " 331 "the newly registered running driver.\n"); 324 332 return; 325 333 } 326 334 fibril_add_ready(fid); 327 328 /*thread_id_t tid;329 if (0 != thread_create(init_running_drv, driver, "init_running_drv", &tid)) {330 printf(NAME ": failed to start the initialization of the newly registered running driver.\n");331 }*/332 335 333 336 ipc_callid_t callid; … … 354 357 } 355 358 356 /** Find handle for the device instance identified by the device's path in the device tree.357 * /359 /** Find handle for the device instance identified by the device's path in the 360 * device tree. */ 358 361 static void devman_device_get_handle(ipc_callid_t iid, ipc_call_t *icall) 359 362 { 360 char *pathname; 361 int rc = async_data_write_accept((void **)&pathname, true, 0, 0, 0, 0); 363 char *pathname; 364 365 int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0); 362 366 if (rc != EOK) { 363 367 ipc_answer_0(iid, rc); … … 365 369 } 366 370 367 node_t * dev = find_dev_node_by_path(&device_tree, pathname); 371 node_t * dev = find_dev_node_by_path(&device_tree, pathname); 368 372 369 373 free(pathname); … … 378 382 379 383 380 /** Function for handling connections from a client to the device manager. 381 */ 384 /** Function for handling connections from a client to the device manager. */ 382 385 static void devman_connection_client(ipc_callid_t iid, ipc_call_t *icall) 383 386 { 384 /* Accept connection */387 /* Accept connection. */ 385 388 ipc_answer_0(iid, EOK); 386 389 … … 404 407 } 405 408 406 static void devman_forward(ipc_callid_t iid, ipc_call_t *icall, bool drv_to_parent) { 407 409 static void 410 devman_forward(ipc_callid_t iid, ipc_call_t *icall, bool drv_to_parent) 411 { 408 412 device_handle_t handle = IPC_GET_ARG2(*icall); 409 // printf(NAME ": devman_forward - trying to forward connection to device with handle %x.\n", handle);410 413 411 414 node_t *dev = find_dev_node(&device_tree, handle); 412 415 if (NULL == dev) { 413 printf(NAME ": devman_forward error - no device with handle %x was found.\n", handle); 416 printf(NAME ": devman_forward error - no device with handle %x " 417 "was found.\n", handle); 414 418 ipc_answer_0(iid, ENOENT); 415 419 return; … … 419 423 420 424 if (drv_to_parent) { 421 if (NULL != dev->parent) { 422 driver = dev->parent->drv; 423 } 425 if (NULL != dev->parent) 426 driver = dev->parent->drv; 424 427 } else if (DEVICE_USABLE == dev->state) { 425 driver = dev->drv; 428 driver = dev->drv; 426 429 assert(NULL != driver); 427 430 } 428 431 429 if (NULL == driver) { 430 printf(NAME ": devman_forward error - the device is not in usable state.\n", handle); 432 if (NULL == driver) { 433 printf(NAME ": devman_forward error - the device is not in " 434 "usable state.\n", handle); 431 435 ipc_answer_0(iid, ENOENT); 432 return; 433 } 434 435 int method; 436 if (drv_to_parent) {436 return; 437 } 438 439 int method; 440 if (drv_to_parent) 437 441 method = DRIVER_DRIVER; 438 } else {442 else 439 443 method = DRIVER_CLIENT; 440 }441 444 442 445 if (driver->phone <= 0) { 443 printf(NAME ": devman_forward: cound not forward to driver %s ", driver->name); 446 printf(NAME ": devman_forward: cound not forward to driver %s ", 447 driver->name); 444 448 printf("the driver's phone is %x).\n", driver->phone); 445 449 ipc_answer_0(iid, EINVAL); 446 450 return; 447 451 } 448 printf(NAME ": devman_forward: forward connection to device %s to driver %s.\n",449 450 ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 451 } 452 453 /** Function for handling connections from a client forwarded by the device mapper to the device manager.454 * /452 printf(NAME ": devman_forward: forward connection to device %s to " 453 "driver %s.\n", dev->pathname, driver->name); 454 ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 455 } 456 457 /** Function for handling connections from a client forwarded by the device 458 * mapper to the device manager. */ 455 459 static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall) 456 460 { 457 461 dev_handle_t devmap_handle = IPC_GET_METHOD(*icall); 462 458 463 node_t *dev = find_devmap_tree_device(&device_tree, devmap_handle); 459 if (NULL == dev) {464 if (NULL == dev) 460 465 dev = find_devmap_class_device(&class_list, devmap_handle); 461 }462 466 463 467 if (NULL == dev || NULL == dev->drv) { … … 471 475 } 472 476 473 printf(NAME ": devman_connection_devmapper: forward connection to device %s to driver %s.\n", 474 dev->pathname, dev->drv->name); 475 ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0, IPC_FF_NONE); 476 } 477 478 /** Function for handling connections to device manager. 479 * 480 */ 477 printf(NAME ": devman_connection_devmapper: forward connection to " 478 "device %s to driver %s.\n", dev->pathname, dev->drv->name); 479 ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0, 480 IPC_FF_NONE); 481 } 482 483 /** Function for handling connections to device manager. */ 481 484 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall) 482 { 483 // Silly hack to enable the device manager to register as a driver by the device mapper. 484 // If the ipc method is not IPC_M_CONNECT_ME_TO, this is not the forwarded connection from naming service, 485 // so it must be a connection from the devmapper which thinks this is a devmapper-style driver. 486 // So pretend this is a devmapper-style driver. 487 // (This does not work for device with handle == IPC_M_CONNECT_ME_TO, 488 // because devmapper passes device handle to the driver as an ipc method.) 489 if (IPC_M_CONNECT_ME_TO != IPC_GET_METHOD(*icall)) { 485 { 486 /* 487 * Silly hack to enable the device manager to register as a driver by 488 * the device mapper. If the ipc method is not IPC_M_CONNECT_ME_TO, this 489 * is not the forwarded connection from naming service, so it must be a 490 * connection from the devmapper which thinks this is a devmapper-style 491 * driver. So pretend this is a devmapper-style driver. (This does not 492 * work for device with handle == IPC_M_CONNECT_ME_TO, because devmapper 493 * passes device handle to the driver as an ipc method.) 494 */ 495 if (IPC_M_CONNECT_ME_TO != IPC_GET_METHOD(*icall)) 490 496 devman_connection_devmapper(iid, icall); 491 } 492 493 // ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection from naming service 494 // by which we registered as device manager, so be device manager 495 496 // Select interface 497 498 /* 499 * ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection 500 * from naming service by which we registered as device manager, so be 501 * device manager. 502 */ 503 504 /* Select interface. */ 497 505 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { 498 506 case DEVMAN_DRIVER: … … 503 511 break; 504 512 case DEVMAN_CONNECT_TO_DEVICE: 505 / / Connect client to selected device513 /* Connect client to selected device. */ 506 514 devman_forward(iid, icall, false); 507 515 break; 508 516 case DEVMAN_CONNECT_TO_PARENTS_DEVICE: 509 / / Connect client to selected device517 /* Connect client to selected device. */ 510 518 devman_forward(iid, icall, true); 511 break; 519 break; 512 520 default: 513 521 /* No such interface */ … … 516 524 } 517 525 518 /** Initialize device manager internal structures. 519 */ 520 static bool devman_init() 521 { 522 printf(NAME ": devman_init - looking for available drivers. \n"); 523 524 // initialize list of available drivers 526 /** Initialize device manager internal structures. */ 527 static bool devman_init(void) 528 { 529 printf(NAME ": devman_init - looking for available drivers.\n"); 530 531 /* Initialize list of available drivers. */ 525 532 init_driver_list(&drivers_list); 526 if (0 == lookup_available_drivers(&drivers_list, DRIVER_DEFAULT_STORE)) { 533 if (0 == lookup_available_drivers(&drivers_list, 534 DRIVER_DEFAULT_STORE)) { 527 535 printf(NAME " no drivers found."); 528 536 return false; 529 537 } 530 printf(NAME ": devman_init - list of drivers has been initialized. 531 532 / / create root device node538 printf(NAME ": devman_init - list of drivers has been initialized.\n"); 539 540 /* Create root device node. */ 533 541 if (!init_device_tree(&device_tree, &drivers_list)) { 534 542 printf(NAME " failed to initialize device tree."); 535 return false; 543 return false; 536 544 } 537 545 538 546 init_class_list(&class_list); 539 547 540 // !!! devman_connection ... as the device manager is not a real devmap driver 541 // (it uses a completely different ipc protocol than an ordinary devmap driver) 542 // forwarding a connection from client to the devman by devmapper would not work 543 devmap_driver_register(NAME, devman_connection); 548 /* 549 * !!! devman_connection ... as the device manager is not a real devmap 550 * driver (it uses a completely different ipc protocol than an ordinary 551 * devmap driver) forwarding a connection from client to the devman by 552 * devmapper would not work. 553 */ 554 devmap_driver_register(NAME, devman_connection); 544 555 545 556 return true; … … 555 566 } 556 567 557 / / Set a handler of incomming connections568 /* Set a handler of incomming connections. */ 558 569 async_set_client_connection(devman_connection); 559 570 560 / / Register device manager at naming service571 /* Register device manager at naming service. */ 561 572 ipcarg_t phonead; 562 573 if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0) … … 566 577 async_manager(); 567 578 568 / / Never reached579 /* Never reached. */ 569 580 return 0; 570 581 }
Note:
See TracChangeset
for help on using the changeset viewer.