Changes in uspace/lib/drv/generic/driver.c [a996ae31:45059d6b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
ra996ae31 r45059d6b 63 63 64 64 /** Devices */ 65 LIST_INITIALIZE(devices);66 FIBRIL_MUTEX_INITIALIZE(devices_mutex);67 68 /** Functions */69 65 LIST_INITIALIZE(functions); 70 66 FIBRIL_MUTEX_INITIALIZE(functions_mutex); … … 80 76 81 77 static irq_code_t default_pseudocode = { 82 0,83 NULL,84 78 sizeof(default_cmds) / sizeof(irq_cmd_t), 85 79 default_cmds … … 88 82 static ddf_dev_t *create_device(void); 89 83 static void delete_device(ddf_dev_t *); 90 static void dev_add_ref(ddf_dev_t *);91 static void dev_del_ref(ddf_dev_t *);92 static void fun_add_ref(ddf_fun_t *);93 static void fun_del_ref(ddf_fun_t *);94 84 static remote_handler_t *function_get_default_handler(ddf_fun_t *); 95 85 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); … … 200 190 pseudocode = &default_pseudocode; 201 191 202 int res = irq_register(irq, dev->handle, ctx->id, pseudocode);192 int res = register_irq(irq, dev->handle, ctx->id, pseudocode); 203 193 if (res != EOK) { 204 194 remove_interrupt_context(&interrupt_contexts, ctx); … … 213 203 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts, 214 204 dev, irq); 215 int res = irq_unregister(irq, dev->handle);205 int res = unregister_irq(irq, dev->handle); 216 206 217 207 if (ctx != NULL) { … … 237 227 } 238 228 239 static ddf_dev_t *driver_get_device(devman_handle_t handle) 240 { 241 ddf_dev_t *dev = NULL; 242 243 assert(fibril_mutex_is_locked(&devices_mutex)); 244 245 list_foreach(devices, link) { 246 dev = list_get_instance(link, ddf_dev_t, link); 247 if (dev->handle == handle) 248 return dev; 249 } 229 static ddf_fun_t *driver_get_function(list_t *functions, devman_handle_t handle) 230 { 231 ddf_fun_t *fun = NULL; 232 233 fibril_mutex_lock(&functions_mutex); 234 235 list_foreach(*functions, link) { 236 fun = list_get_instance(link, ddf_fun_t, link); 237 if (fun->handle == handle) { 238 fibril_mutex_unlock(&functions_mutex); 239 return fun; 240 } 241 } 242 243 fibril_mutex_unlock(&functions_mutex); 250 244 251 245 return NULL; 252 246 } 253 247 254 static ddf_fun_t *driver_get_function(devman_handle_t handle) 255 { 256 ddf_fun_t *fun = NULL; 257 258 assert(fibril_mutex_is_locked(&functions_mutex)); 259 260 list_foreach(functions, link) { 261 fun = list_get_instance(link, ddf_fun_t, link); 262 if (fun->handle == handle) 263 return fun; 264 } 265 266 return NULL; 267 } 268 269 static void driver_dev_add(ipc_callid_t iid, ipc_call_t *icall) 248 static void driver_add_device(ipc_callid_t iid, ipc_call_t *icall) 270 249 { 271 250 char *dev_name = NULL; … … 273 252 274 253 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 275 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);254 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall); 276 255 277 256 ddf_dev_t *dev = create_device(); 278 279 /* Add one reference that will be dropped by driver_dev_remove() */280 dev_add_ref(dev);281 257 dev->handle = dev_handle; 282 258 … … 290 266 (void) parent_fun_handle; 291 267 292 res = driver->driver_ops->dev_add(dev); 293 294 if (res != EOK) { 295 dev_del_ref(dev); 296 async_answer_0(iid, res); 297 return; 298 } 299 300 fibril_mutex_lock(&devices_mutex); 301 list_append(&dev->link, &devices); 302 fibril_mutex_unlock(&devices_mutex); 268 res = driver->driver_ops->add_device(dev); 269 if (res != EOK) 270 delete_device(dev); 303 271 304 272 async_answer_0(iid, res); 305 }306 307 static void driver_dev_added(ipc_callid_t iid, ipc_call_t *icall)308 {309 fibril_mutex_lock(&devices_mutex);310 ddf_dev_t *dev = driver_get_device(IPC_GET_ARG1(*icall));311 fibril_mutex_unlock(&devices_mutex);312 313 if (dev != NULL && driver->driver_ops->device_added != NULL)314 driver->driver_ops->device_added(dev);315 }316 317 static void driver_dev_remove(ipc_callid_t iid, ipc_call_t *icall)318 {319 devman_handle_t devh;320 ddf_dev_t *dev;321 int rc;322 323 devh = IPC_GET_ARG1(*icall);324 325 fibril_mutex_lock(&devices_mutex);326 dev = driver_get_device(devh);327 if (dev != NULL)328 dev_add_ref(dev);329 fibril_mutex_unlock(&devices_mutex);330 331 if (dev == NULL) {332 async_answer_0(iid, ENOENT);333 return;334 }335 336 if (driver->driver_ops->dev_remove != NULL)337 rc = driver->driver_ops->dev_remove(dev);338 else339 rc = ENOTSUP;340 341 if (rc == EOK)342 dev_del_ref(dev);343 344 async_answer_0(iid, (sysarg_t) rc);345 }346 347 static void driver_dev_gone(ipc_callid_t iid, ipc_call_t *icall)348 {349 devman_handle_t devh;350 ddf_dev_t *dev;351 int rc;352 353 devh = IPC_GET_ARG1(*icall);354 355 fibril_mutex_lock(&devices_mutex);356 dev = driver_get_device(devh);357 if (dev != NULL)358 dev_add_ref(dev);359 fibril_mutex_unlock(&devices_mutex);360 361 if (dev == NULL) {362 async_answer_0(iid, ENOENT);363 return;364 }365 366 if (driver->driver_ops->dev_gone != NULL)367 rc = driver->driver_ops->dev_gone(dev);368 else369 rc = ENOTSUP;370 371 if (rc == EOK)372 dev_del_ref(dev);373 374 async_answer_0(iid, (sysarg_t) rc);375 }376 377 static void driver_fun_online(ipc_callid_t iid, ipc_call_t *icall)378 {379 devman_handle_t funh;380 ddf_fun_t *fun;381 int rc;382 383 funh = IPC_GET_ARG1(*icall);384 385 /*386 * Look the function up. Bump reference count so that387 * the function continues to exist until we return388 * from the driver.389 */390 fibril_mutex_lock(&functions_mutex);391 392 fun = driver_get_function(funh);393 if (fun != NULL)394 fun_add_ref(fun);395 396 fibril_mutex_unlock(&functions_mutex);397 398 if (fun == NULL) {399 async_answer_0(iid, ENOENT);400 return;401 }402 403 /* Call driver entry point */404 if (driver->driver_ops->fun_online != NULL)405 rc = driver->driver_ops->fun_online(fun);406 else407 rc = ENOTSUP;408 409 fun_del_ref(fun);410 411 async_answer_0(iid, (sysarg_t) rc);412 }413 414 static void driver_fun_offline(ipc_callid_t iid, ipc_call_t *icall)415 {416 devman_handle_t funh;417 ddf_fun_t *fun;418 int rc;419 420 funh = IPC_GET_ARG1(*icall);421 422 /*423 * Look the function up. Bump reference count so that424 * the function continues to exist until we return425 * from the driver.426 */427 fibril_mutex_lock(&functions_mutex);428 429 fun = driver_get_function(funh);430 if (fun != NULL)431 fun_add_ref(fun);432 433 fibril_mutex_unlock(&functions_mutex);434 435 if (fun == NULL) {436 async_answer_0(iid, ENOENT);437 return;438 }439 440 /* Call driver entry point */441 if (driver->driver_ops->fun_offline != NULL)442 rc = driver->driver_ops->fun_offline(fun);443 else444 rc = ENOTSUP;445 446 async_answer_0(iid, (sysarg_t) rc);447 273 } 448 274 … … 460 286 461 287 switch (IPC_GET_IMETHOD(call)) { 462 case DRIVER_DEV_ADD: 463 driver_dev_add(callid, &call); 464 break; 465 case DRIVER_DEV_ADDED: 466 async_answer_0(callid, EOK); 467 driver_dev_added(callid, &call); 468 break; 469 case DRIVER_DEV_REMOVE: 470 driver_dev_remove(callid, &call); 471 break; 472 case DRIVER_DEV_GONE: 473 driver_dev_gone(callid, &call); 474 break; 475 case DRIVER_FUN_ONLINE: 476 driver_fun_online(callid, &call); 477 break; 478 case DRIVER_FUN_OFFLINE: 479 driver_fun_offline(callid, &call); 288 case DRIVER_ADD_DEVICE: 289 driver_add_device(callid, &call); 480 290 break; 481 291 default: 482 async_answer_0(callid, ENO TSUP);292 async_answer_0(callid, ENOENT); 483 293 } 484 294 } … … 498 308 */ 499 309 devman_handle_t handle = IPC_GET_ARG2(*icall); 500 501 fibril_mutex_lock(&functions_mutex); 502 ddf_fun_t *fun = driver_get_function(handle); 503 fibril_mutex_unlock(&functions_mutex); 504 /* XXX Need a lock on fun */ 310 ddf_fun_t *fun = driver_get_function(&functions, handle); 505 311 506 312 if (fun == NULL) { … … 660 466 ddf_dev_t *dev; 661 467 662 dev = calloc(1,sizeof(ddf_dev_t));468 dev = malloc(sizeof(ddf_dev_t)); 663 469 if (dev == NULL) 664 470 return NULL; 665 471 472 memset(dev, 0, sizeof(ddf_dev_t)); 666 473 return dev; 667 474 } … … 691 498 static void delete_device(ddf_dev_t *dev) 692 499 { 693 if (dev->driver_data != NULL)694 free(dev->driver_data);695 500 free(dev); 696 501 } 697 502 698 /** Delete functionstructure.503 /** Delete device structure. 699 504 * 700 505 * @param dev The device structure. … … 703 508 { 704 509 clean_match_ids(&fun->match_ids); 705 if (fun->driver_data != NULL)706 free(fun->driver_data);707 510 if (fun->name != NULL) 708 511 free(fun->name); … … 710 513 } 711 514 712 /** Increase device reference count. */713 static void dev_add_ref(ddf_dev_t *dev)714 {715 atomic_inc(&dev->refcnt);716 }717 718 /** Decrease device reference count.719 *720 * Free the device structure if the reference count drops to zero.721 */722 static void dev_del_ref(ddf_dev_t *dev)723 {724 if (atomic_predec(&dev->refcnt) == 0)725 delete_device(dev);726 }727 728 /** Increase function reference count.729 *730 * This also increases reference count on the device. The device structure731 * will thus not be deallocated while there are some associated function732 * structures.733 */734 static void fun_add_ref(ddf_fun_t *fun)735 {736 dev_add_ref(fun->dev);737 atomic_inc(&fun->refcnt);738 }739 740 /** Decrease function reference count.741 *742 * Free the function structure if the reference count drops to zero.743 */744 static void fun_del_ref(ddf_fun_t *fun)745 {746 ddf_dev_t *dev = fun->dev;747 748 if (atomic_predec(&fun->refcnt) == 0)749 delete_function(fun);750 751 dev_del_ref(dev);752 }753 754 /** Allocate driver-specific device data. */755 extern void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size)756 {757 void *data;758 759 assert(dev->driver_data == NULL);760 761 data = calloc(1, size);762 if (data == NULL)763 return NULL;764 765 dev->driver_data = data;766 return data;767 }768 769 515 /** Create a DDF function node. 770 516 * … … 798 544 return NULL; 799 545 800 /* Add one reference that will be dropped by ddf_fun_destroy() */546 fun->bound = false; 801 547 fun->dev = dev; 802 fun_add_ref(fun);803 804 fun->bound = false;805 548 fun->ftype = ftype; 806 549 … … 814 557 } 815 558 816 /** Allocate driver-specific function data. */817 extern void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size)818 {819 void *data;820 821 assert(fun->bound == false);822 assert(fun->driver_data == NULL);823 824 data = calloc(1, size);825 if (data == NULL)826 return NULL;827 828 fun->driver_data = data;829 return data;830 }831 832 559 /** Destroy DDF function node. 833 560 * … … 840 567 { 841 568 assert(fun->bound == false); 842 843 /* 844 * Drop the reference added by ddf_fun_create(). This will deallocate 845 * the function as soon as all other references are dropped (i.e. 846 * as soon control leaves all driver entry points called in context 847 * of this function. 848 */ 849 fun_del_ref(fun); 569 delete_function(fun); 850 570 } 851 571 … … 894 614 * the function invisible to the system. 895 615 * 896 * @param fun Function to unbind616 * @param fun Function to bind 897 617 * @return EOK on success or negative error code 898 618 */ … … 903 623 assert(fun->bound == true); 904 624 625 add_to_functions_list(fun); 905 626 res = devman_remove_function(fun->handle); 906 627 if (res != EOK) … … 910 631 911 632 fun->bound = false; 912 return EOK;913 }914 915 /** Online function.916 *917 * @param fun Function to online918 * @return EOK on success or negative error code919 */920 int ddf_fun_online(ddf_fun_t *fun)921 {922 int res;923 924 assert(fun->bound == true);925 926 res = devman_drv_fun_online(fun->handle);927 if (res != EOK)928 return res;929 930 return EOK;931 }932 933 /** Offline function.934 *935 * @param fun Function to offline936 * @return EOK on success or negative error code937 */938 int ddf_fun_offline(ddf_fun_t *fun)939 {940 int res;941 942 assert(fun->bound == true);943 944 res = devman_drv_fun_offline(fun->handle);945 if (res != EOK)946 return res;947 948 633 return EOK; 949 634 } … … 972 657 973 658 match_id->id = str_dup(match_id_str); 974 match_id->score = match_score;659 match_id->score = 90; 975 660 976 661 add_match_id(&fun->match_ids, match_id); … … 1018 703 * incoming connections. 1019 704 */ 1020 async_set_client_connection(driver_connection); 1021 rc = devman_driver_register(driver->name); 705 rc = devman_driver_register(driver->name, driver_connection); 1022 706 if (rc != EOK) { 1023 707 printf("Error: Failed to register driver with device manager "
Note:
See TracChangeset
for help on using the changeset viewer.