Changes in uspace/lib/drv/generic/driver.c [77a69ea:bf31e3f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r77a69ea rbf31e3f 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 *); … … 92 78 static remote_handler_t *function_get_default_handler(ddf_fun_t *); 93 79 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); 94 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 = irq_register(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 = irq_unregister(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 80 223 81 static void add_to_functions_list(ddf_fun_t *fun) … … 737 595 738 596 /** Allocate driver-specific device data. */ 739 externvoid *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size)597 void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size) 740 598 { 741 599 void *data; … … 799 657 800 658 /** Allocate driver-specific function data. */ 801 externvoid *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size)659 void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size) 802 660 { 803 661 void *data; … … 992 850 driver = drv; 993 851 994 /* Initialize the list of interrupt contexts. */ 995 init_interrupt_context_list(&interrupt_contexts); 996 997 /* Set generic interrupt handler. */ 998 async_set_interrupt_received(driver_irq_handler); 852 /* Initialize interrupt module */ 853 interrupt_init(); 999 854 1000 855 /*
Note:
See TracChangeset
for help on using the changeset viewer.