Changes in uspace/lib/drv/generic/driver.c [609243f4:77ad86c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r609243f4 r77ad86c 70 70 FIBRIL_MUTEX_INITIALIZE(functions_mutex); 71 71 72 /** Interrupts */73 static interrupt_context_list_t interrupt_contexts;74 75 static irq_cmd_t default_cmds[] = {76 {77 .cmd = CMD_ACCEPT78 }79 };80 81 static irq_code_t default_pseudocode = {82 sizeof(default_cmds) / sizeof(irq_cmd_t),83 default_cmds84 };85 86 72 static ddf_dev_t *create_device(void); 87 73 static void delete_device(ddf_dev_t *); … … 93 79 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); 94 80 95 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)96 {97 int id = (int)IPC_GET_IMETHOD(*icall);98 interrupt_context_t *ctx;99 100 ctx = find_interrupt_context_by_id(&interrupt_contexts, id);101 if (ctx != NULL && ctx->handler != NULL)102 (*ctx->handler)(ctx->dev, iid, icall);103 }104 105 interrupt_context_t *create_interrupt_context(void)106 {107 interrupt_context_t *ctx;108 109 ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));110 if (ctx != NULL)111 memset(ctx, 0, sizeof(interrupt_context_t));112 113 return ctx;114 }115 116 void delete_interrupt_context(interrupt_context_t *ctx)117 {118 if (ctx != NULL)119 free(ctx);120 }121 122 void init_interrupt_context_list(interrupt_context_list_t *list)123 {124 memset(list, 0, sizeof(interrupt_context_list_t));125 fibril_mutex_initialize(&list->mutex);126 list_initialize(&list->contexts);127 }128 129 void130 add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)131 {132 fibril_mutex_lock(&list->mutex);133 ctx->id = list->curr_id++;134 list_append(&ctx->link, &list->contexts);135 fibril_mutex_unlock(&list->mutex);136 }137 138 void remove_interrupt_context(interrupt_context_list_t *list,139 interrupt_context_t *ctx)140 {141 fibril_mutex_lock(&list->mutex);142 list_remove(&ctx->link);143 fibril_mutex_unlock(&list->mutex);144 }145 146 interrupt_context_t *147 find_interrupt_context_by_id(interrupt_context_list_t *list, int id)148 {149 interrupt_context_t *ctx;150 151 fibril_mutex_lock(&list->mutex);152 153 list_foreach(list->contexts, link) {154 ctx = list_get_instance(link, interrupt_context_t, link);155 if (ctx->id == id) {156 fibril_mutex_unlock(&list->mutex);157 return ctx;158 }159 }160 161 fibril_mutex_unlock(&list->mutex);162 return NULL;163 }164 165 interrupt_context_t *166 find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)167 {168 interrupt_context_t *ctx;169 170 fibril_mutex_lock(&list->mutex);171 172 list_foreach(list->contexts, link) {173 ctx = list_get_instance(link, interrupt_context_t, link);174 if (ctx->irq == irq && ctx->dev == dev) {175 fibril_mutex_unlock(&list->mutex);176 return ctx;177 }178 }179 180 fibril_mutex_unlock(&list->mutex);181 return NULL;182 }183 184 185 int186 register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,187 irq_code_t *pseudocode)188 {189 interrupt_context_t *ctx = create_interrupt_context();190 191 ctx->dev = dev;192 ctx->irq = irq;193 ctx->handler = handler;194 195 add_interrupt_context(&interrupt_contexts, ctx);196 197 if (pseudocode == NULL)198 pseudocode = &default_pseudocode;199 200 int res = register_irq(irq, dev->handle, ctx->id, pseudocode);201 if (res != EOK) {202 remove_interrupt_context(&interrupt_contexts, ctx);203 delete_interrupt_context(ctx);204 }205 206 return res;207 }208 209 int unregister_interrupt_handler(ddf_dev_t *dev, int irq)210 {211 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,212 dev, irq);213 int res = unregister_irq(irq, dev->handle);214 215 if (ctx != NULL) {216 remove_interrupt_context(&interrupt_contexts, ctx);217 delete_interrupt_context(ctx);218 }219 220 return res;221 }222 223 81 static void add_to_functions_list(ddf_fun_t *fun) 224 82 { … … 267 125 static void driver_dev_add(ipc_callid_t iid, ipc_call_t *icall) 268 126 { 269 char *dev_name = NULL;270 int res;271 272 127 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 273 128 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall); 274 129 275 130 ddf_dev_t *dev = create_device(); 276 131 277 132 /* Add one reference that will be dropped by driver_dev_remove() */ 278 133 dev_add_ref(dev); 279 134 dev->handle = dev_handle; 280 135 136 char *dev_name = NULL; 281 137 async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0); 282 138 dev->name = dev_name; 283 139 284 140 /* 285 141 * Currently not used, parent fun handle is stored in context … … 288 144 (void) parent_fun_handle; 289 145 290 res = driver->driver_ops->add_device(dev);146 int res = driver->driver_ops->dev_add(dev); 291 147 292 148 if (res != EOK) { … … 303 159 } 304 160 305 static void driver_dev_added(ipc_callid_t iid, ipc_call_t *icall) 306 { 161 static void driver_dev_remove(ipc_callid_t iid, ipc_call_t *icall) 162 { 163 devman_handle_t devh = IPC_GET_ARG1(*icall); 164 307 165 fibril_mutex_lock(&devices_mutex); 308 ddf_dev_t *dev = driver_get_device(IPC_GET_ARG1(*icall)); 309 fibril_mutex_unlock(&devices_mutex); 310 311 if (dev != NULL && driver->driver_ops->device_added != NULL) 312 driver->driver_ops->device_added(dev); 313 } 314 315 static void driver_dev_remove(ipc_callid_t iid, ipc_call_t *icall) 316 { 317 devman_handle_t devh; 318 ddf_dev_t *dev; 319 int rc; 320 321 devh = IPC_GET_ARG1(*icall); 322 323 fibril_mutex_lock(&devices_mutex); 324 dev = driver_get_device(devh); 166 ddf_dev_t *dev = driver_get_device(devh); 325 167 if (dev != NULL) 326 168 dev_add_ref(dev); … … 331 173 return; 332 174 } 175 176 int rc; 333 177 334 178 if (driver->driver_ops->dev_remove != NULL) … … 345 189 static void driver_dev_gone(ipc_callid_t iid, ipc_call_t *icall) 346 190 { 347 devman_handle_t devh; 348 ddf_dev_t *dev; 349 int rc; 350 351 devh = IPC_GET_ARG1(*icall); 191 devman_handle_t devh = IPC_GET_ARG1(*icall); 352 192 353 193 fibril_mutex_lock(&devices_mutex); 354 d ev = driver_get_device(devh);194 ddf_dev_t *dev = driver_get_device(devh); 355 195 if (dev != NULL) 356 196 dev_add_ref(dev); … … 361 201 return; 362 202 } 203 204 int rc; 363 205 364 206 if (driver->driver_ops->dev_gone != NULL) … … 375 217 static void driver_fun_online(ipc_callid_t iid, ipc_call_t *icall) 376 218 { 377 devman_handle_t funh; 378 ddf_fun_t *fun; 379 int rc; 380 381 funh = IPC_GET_ARG1(*icall); 219 devman_handle_t funh = IPC_GET_ARG1(*icall); 382 220 383 221 /* … … 388 226 fibril_mutex_lock(&functions_mutex); 389 227 390 fun = driver_get_function(funh);228 ddf_fun_t *fun = driver_get_function(funh); 391 229 if (fun != NULL) 392 230 fun_add_ref(fun); … … 400 238 401 239 /* Call driver entry point */ 240 int rc; 241 402 242 if (driver->driver_ops->fun_online != NULL) 403 243 rc = driver->driver_ops->fun_online(fun); … … 412 252 static void driver_fun_offline(ipc_callid_t iid, ipc_call_t *icall) 413 253 { 414 devman_handle_t funh; 415 ddf_fun_t *fun; 416 int rc; 417 418 funh = IPC_GET_ARG1(*icall); 254 devman_handle_t funh = IPC_GET_ARG1(*icall); 419 255 420 256 /* … … 425 261 fibril_mutex_lock(&functions_mutex); 426 262 427 fun = driver_get_function(funh);263 ddf_fun_t *fun = driver_get_function(funh); 428 264 if (fun != NULL) 429 265 fun_add_ref(fun); … … 437 273 438 274 /* Call driver entry point */ 275 int rc; 276 439 277 if (driver->driver_ops->fun_offline != NULL) 440 278 rc = driver->driver_ops->fun_offline(fun); … … 460 298 case DRIVER_DEV_ADD: 461 299 driver_dev_add(callid, &call); 462 break;463 case DRIVER_DEV_ADDED:464 async_answer_0(callid, EOK);465 driver_dev_added(callid, &call);466 300 break; 467 301 case DRIVER_DEV_REMOVE: … … 751 585 752 586 /** Allocate driver-specific device data. */ 753 extern void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size) 754 { 755 void *data; 756 587 void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size) 588 { 757 589 assert(dev->driver_data == NULL); 758 759 data = calloc(1, size);590 591 void *data = calloc(1, size); 760 592 if (data == NULL) 761 593 return NULL; 762 594 763 595 dev->driver_data = data; 764 596 return data; … … 790 622 ddf_fun_t *ddf_fun_create(ddf_dev_t *dev, fun_type_t ftype, const char *name) 791 623 { 792 ddf_fun_t *fun; 793 794 fun = create_function(); 624 ddf_fun_t *fun = create_function(); 795 625 if (fun == NULL) 796 626 return NULL; 797 627 798 628 /* Add one reference that will be dropped by ddf_fun_destroy() */ 799 629 fun->dev = dev; 800 630 fun_add_ref(fun); 801 631 802 632 fun->bound = false; 803 633 fun->ftype = ftype; 804 634 805 635 fun->name = str_dup(name); 806 636 if (fun->name == NULL) { … … 808 638 return NULL; 809 639 } 810 640 811 641 return fun; 812 642 } 813 643 814 644 /** Allocate driver-specific function data. */ 815 extern void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size) 816 { 817 void *data; 818 645 void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size) 646 { 819 647 assert(fun->bound == false); 820 648 assert(fun->driver_data == NULL); 821 822 data = calloc(1, size);649 650 void *data = calloc(1, size); 823 651 if (data == NULL) 824 652 return NULL; 825 653 826 654 fun->driver_data = data; 827 655 return data; … … 833 661 * must not be bound. 834 662 * 835 * @param fun Function to destroy 663 * @param fun Function to destroy 664 * 836 665 */ 837 666 void ddf_fun_destroy(ddf_fun_t *fun) 838 667 { 839 668 assert(fun->bound == false); 840 669 841 670 /* 842 671 * Drop the reference added by ddf_fun_create(). This will deallocate … … 853 682 if (fun->ops == NULL) 854 683 return NULL; 684 855 685 return fun->ops->interfaces[idx]; 856 686 } … … 865 695 * the same name. 866 696 * 867 * @param fun Function to bind 868 * @return EOK on success or negative error code 697 * @param fun Function to bind 698 * 699 * @return EOK on success or negative error code 700 * 869 701 */ 870 702 int ddf_fun_bind(ddf_fun_t *fun) … … 873 705 assert(fun->name != NULL); 874 706 875 int res;876 877 707 add_to_functions_list(fun); 878 res = devman_add_function(fun->name, fun->ftype, &fun->match_ids,708 int res = devman_add_function(fun->name, fun->ftype, &fun->match_ids, 879 709 fun->dev->handle, &fun->handle); 880 710 if (res != EOK) { … … 892 722 * the function invisible to the system. 893 723 * 894 * @param fun Function to unbind 895 * @return EOK on success or negative error code 724 * @param fun Function to unbind 725 * 726 * @return EOK on success or negative error code 727 * 896 728 */ 897 729 int ddf_fun_unbind(ddf_fun_t *fun) 898 730 { 899 int res;900 901 731 assert(fun->bound == true); 902 732 903 res = devman_remove_function(fun->handle);733 int res = devman_remove_function(fun->handle); 904 734 if (res != EOK) 905 735 return res; 906 736 907 737 remove_from_functions_list(fun); 908 738 … … 913 743 /** Online function. 914 744 * 915 * @param fun Function to online 916 * @return EOK on success or negative error code 745 * @param fun Function to online 746 * 747 * @return EOK on success or negative error code 748 * 917 749 */ 918 750 int ddf_fun_online(ddf_fun_t *fun) 919 751 { 920 int res;921 922 752 assert(fun->bound == true); 923 753 924 res = devman_drv_fun_online(fun->handle);754 int res = devman_drv_fun_online(fun->handle); 925 755 if (res != EOK) 926 756 return res; … … 931 761 /** Offline function. 932 762 * 933 * @param fun Function to offline 934 * @return EOK on success or negative error code 763 * @param fun Function to offline 764 * 765 * @return EOK on success or negative error code 766 * 935 767 */ 936 768 int ddf_fun_offline(ddf_fun_t *fun) 937 769 { 938 int res;939 940 770 assert(fun->bound == true); 941 771 942 res = devman_drv_fun_offline(fun->handle);772 int res = devman_drv_fun_offline(fun->handle); 943 773 if (res != EOK) 944 774 return res; … … 952 782 * Cannot be called when the function node is bound. 953 783 * 954 * @param fun Function 955 * @param match_id_str Match string 956 * @param match_score Match score 957 * @return EOK on success, ENOMEM if out of memory. 784 * @param fun Function 785 * @param match_id_str Match string 786 * @param match_score Match score 787 * 788 * @return EOK on success. 789 * @return ENOMEM if out of memory. 790 * 958 791 */ 959 792 int ddf_fun_add_match_id(ddf_fun_t *fun, const char *match_id_str, 960 793 int match_score) 961 794 { 962 match_id_t *match_id;963 964 795 assert(fun->bound == false); 965 796 assert(fun->ftype == fun_inner); 966 797 967 match_id = create_match_id();798 match_id_t *match_id = create_match_id(); 968 799 if (match_id == NULL) 969 800 return ENOMEM; 970 801 971 802 match_id->id = str_dup(match_id_str); 972 match_id->score = 90;803 match_id->score = match_score; 973 804 974 805 add_match_id(&fun->match_ids, match_id); … … 987 818 * 988 819 * Must only be called when the function is bound. 820 * 989 821 */ 990 822 int ddf_fun_add_to_category(ddf_fun_t *fun, const char *cat_name) … … 998 830 int ddf_driver_main(driver_t *drv) 999 831 { 1000 int rc;1001 1002 832 /* 1003 833 * Remember the driver structure - driver_ops will be called by generic … … 1006 836 driver = drv; 1007 837 1008 /* Initialize the list of interrupt contexts. */ 1009 init_interrupt_context_list(&interrupt_contexts); 1010 1011 /* Set generic interrupt handler. */ 1012 async_set_interrupt_received(driver_irq_handler); 838 /* Initialize interrupt module */ 839 interrupt_init(); 1013 840 1014 841 /* … … 1016 843 * incoming connections. 1017 844 */ 1018 rc = devman_driver_register(driver->name, driver_connection); 845 async_set_client_connection(driver_connection); 846 int rc = devman_driver_register(driver->name); 1019 847 if (rc != EOK) { 1020 848 printf("Error: Failed to register driver with device manager " … … 1022 850 str_error(rc)); 1023 851 1024 return 1;852 return rc; 1025 853 } 1026 854 … … 1028 856 rc = task_retval(0); 1029 857 if (rc != EOK) 1030 return 1;1031 858 return rc; 859 1032 860 async_manager(); 1033 861 1034 862 /* Never reached. */ 1035 return 0;863 return EOK; 1036 864 } 1037 865
Note:
See TracChangeset
for help on using the changeset viewer.