Changeset 0f0f8bc in mainline
- Timestamp:
- 2011-08-29T18:46:37Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4d94002d
- Parents:
- 8cc4ddb
- Location:
- uspace/lib/drv
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r8cc4ddb r0f0f8bc 86 86 static ddf_dev_t *create_device(void); 87 87 static void delete_device(ddf_dev_t *); 88 static void dev_add_ref(ddf_dev_t *); 89 static void dev_del_ref(ddf_dev_t *); 90 static void fun_add_ref(ddf_fun_t *); 91 static void fun_del_ref(ddf_fun_t *); 88 92 static remote_handler_t *function_get_default_handler(ddf_fun_t *); 89 93 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); … … 261 265 } 262 266 263 static void driver_ add_device(ipc_callid_t iid, ipc_call_t *icall)267 static void driver_dev_add(ipc_callid_t iid, ipc_call_t *icall) 264 268 { 265 269 char *dev_name = NULL; … … 270 274 271 275 ddf_dev_t *dev = create_device(); 276 277 /* Add one reference that will be dropped by driver_dev_remove() */ 278 dev_add_ref(dev); 272 279 dev->handle = dev_handle; 273 280 … … 282 289 283 290 res = driver->driver_ops->add_device(dev); 284 if (res != EOK) 285 delete_device(dev); 291 292 if (res != EOK) { 293 dev_del_ref(dev); 294 async_answer_0(iid, res); 295 return; 296 } 286 297 287 298 fibril_mutex_lock(&devices_mutex); … … 303 314 fibril_mutex_lock(&devices_mutex); 304 315 dev = driver_get_device(devh); 316 dev_add_ref(dev); 305 317 fibril_mutex_unlock(&devices_mutex); 306 /* XXX need lock on dev */307 318 308 319 if (dev == NULL) { … … 316 327 rc = ENOTSUP; 317 328 329 if (rc == EOK) 330 dev_del_ref(dev); 331 318 332 async_answer_0(iid, (sysarg_t) rc); 319 333 } … … 326 340 327 341 funh = IPC_GET_ARG1(*icall); 342 343 /* 344 * Look up the function. Bump reference count so that 345 * the function continues to exist until we return 346 * from the driver. 347 */ 328 348 fibril_mutex_lock(&functions_mutex); 349 329 350 fun = driver_get_function(funh); 351 if (fun != NULL) 352 fun_add_ref(fun); 353 330 354 fibril_mutex_unlock(&functions_mutex); 331 /* XXX Need lock on fun */332 355 333 356 if (fun == NULL) { … … 336 359 } 337 360 361 /* Call driver entry point */ 338 362 if (driver->driver_ops->fun_online != NULL) 339 363 rc = driver->driver_ops->fun_online(fun); … … 341 365 rc = ENOTSUP; 342 366 367 fun_del_ref(fun); 368 343 369 async_answer_0(iid, (sysarg_t) rc); 344 370 } … … 351 377 352 378 funh = IPC_GET_ARG1(*icall); 379 380 /* 381 * Look up the function. Bump reference count so that 382 * the function continues to exist until we return 383 * from the driver. 384 */ 353 385 fibril_mutex_lock(&functions_mutex); 386 354 387 fun = driver_get_function(funh); 388 if (fun != NULL) 389 fun_add_ref(fun); 390 355 391 fibril_mutex_unlock(&functions_mutex); 356 /* XXX Need lock on fun */357 392 358 393 if (fun == NULL) { … … 361 396 } 362 397 398 /* Call driver entry point */ 363 399 if (driver->driver_ops->fun_offline != NULL) 364 400 rc = driver->driver_ops->fun_offline(fun); … … 383 419 switch (IPC_GET_IMETHOD(call)) { 384 420 case DRIVER_DEV_ADD: 385 driver_ add_device(callid, &call);421 driver_dev_add(callid, &call); 386 422 break; 387 423 case DRIVER_DEV_REMOVE: … … 575 611 ddf_dev_t *dev; 576 612 577 dev = malloc(sizeof(ddf_dev_t));613 dev = calloc(1, sizeof(ddf_dev_t)); 578 614 if (dev == NULL) 579 615 return NULL; 580 616 581 memset(dev, 0, sizeof(ddf_dev_t));582 617 return dev; 583 618 } … … 610 645 } 611 646 612 /** Delete devicestructure.647 /** Delete function structure. 613 648 * 614 649 * @param dev The device structure. … … 622 657 } 623 658 659 /** Increase device reference count. */ 660 static void dev_add_ref(ddf_dev_t *dev) 661 { 662 atomic_inc(&dev->refcnt); 663 } 664 665 /** Decrease device reference count. 666 * 667 * Free the device structure if the reference count drops to zero. 668 */ 669 static void dev_del_ref(ddf_dev_t *dev) 670 { 671 if (atomic_predec(&dev->refcnt) == 0) 672 delete_device(dev); 673 } 674 675 /** Increase function reference count. */ 676 static void fun_add_ref(ddf_fun_t *fun) 677 { 678 atomic_inc(&fun->refcnt); 679 } 680 681 /** Decrease function reference count. 682 * 683 * Free the function structure if the reference count drops to zero. 684 */ 685 static void fun_del_ref(ddf_fun_t *fun) 686 { 687 if (atomic_predec(&fun->refcnt) == 0) 688 delete_function(fun); 689 } 690 624 691 /** Create a DDF function node. 625 692 * … … 652 719 if (fun == NULL) 653 720 return NULL; 721 722 /* Add one reference that will be dropped by ddf_fun_destroy() */ 723 fun_add_ref(fun); 654 724 655 725 fun->bound = false; … … 676 746 { 677 747 assert(fun->bound == false); 678 delete_function(fun); 748 749 /* 750 * Drop the reference added by ddf_fun_create(). This will deallocate 751 * the function as soon as all other references are dropped (i.e. 752 * as soon control leaves all driver entry points called in context 753 * of this function. 754 */ 755 fun_del_ref(fun); 679 756 } 680 757 -
uspace/lib/drv/include/ddf/driver.h
r8cc4ddb r0f0f8bc 81 81 */ 82 82 devman_handle_t handle; 83 /** Reference count */ 84 atomic_t refcnt; 83 85 84 86 /** … … 104 106 /** Function indentifier (asigned by device manager) */ 105 107 devman_handle_t handle; 108 /** Reference count */ 109 atomic_t refcnt; 106 110 107 111 /** Device which this function belogs to */
Note:
See TracChangeset
for help on using the changeset viewer.