Changeset cfb79747 in mainline for uspace/lib/drv/generic/driver.c
- Timestamp:
- 2012-02-14T22:06:15Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a31aad1
- Parents:
- 199112e4 (diff), e10d41a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r199112e4 rcfb79747 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 0,83 NULL,84 sizeof(default_cmds) / sizeof(irq_cmd_t),85 default_cmds86 };87 88 72 static ddf_dev_t *create_device(void); 89 73 static void delete_device(ddf_dev_t *); … … 95 79 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); 96 80 97 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)98 {99 int id = (int)IPC_GET_IMETHOD(*icall);100 interrupt_context_t *ctx;101 102 ctx = find_interrupt_context_by_id(&interrupt_contexts, id);103 if (ctx != NULL && ctx->handler != NULL)104 (*ctx->handler)(ctx->dev, iid, icall);105 }106 107 interrupt_context_t *create_interrupt_context(void)108 {109 interrupt_context_t *ctx;110 111 ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));112 if (ctx != NULL)113 memset(ctx, 0, sizeof(interrupt_context_t));114 115 return ctx;116 }117 118 void delete_interrupt_context(interrupt_context_t *ctx)119 {120 if (ctx != NULL)121 free(ctx);122 }123 124 void init_interrupt_context_list(interrupt_context_list_t *list)125 {126 memset(list, 0, sizeof(interrupt_context_list_t));127 fibril_mutex_initialize(&list->mutex);128 list_initialize(&list->contexts);129 }130 131 void132 add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)133 {134 fibril_mutex_lock(&list->mutex);135 ctx->id = list->curr_id++;136 list_append(&ctx->link, &list->contexts);137 fibril_mutex_unlock(&list->mutex);138 }139 140 void remove_interrupt_context(interrupt_context_list_t *list,141 interrupt_context_t *ctx)142 {143 fibril_mutex_lock(&list->mutex);144 list_remove(&ctx->link);145 fibril_mutex_unlock(&list->mutex);146 }147 148 interrupt_context_t *149 find_interrupt_context_by_id(interrupt_context_list_t *list, int id)150 {151 interrupt_context_t *ctx;152 153 fibril_mutex_lock(&list->mutex);154 155 list_foreach(list->contexts, link) {156 ctx = list_get_instance(link, interrupt_context_t, link);157 if (ctx->id == id) {158 fibril_mutex_unlock(&list->mutex);159 return ctx;160 }161 }162 163 fibril_mutex_unlock(&list->mutex);164 return NULL;165 }166 167 interrupt_context_t *168 find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)169 {170 interrupt_context_t *ctx;171 172 fibril_mutex_lock(&list->mutex);173 174 list_foreach(list->contexts, link) {175 ctx = list_get_instance(link, interrupt_context_t, link);176 if (ctx->irq == irq && ctx->dev == dev) {177 fibril_mutex_unlock(&list->mutex);178 return ctx;179 }180 }181 182 fibril_mutex_unlock(&list->mutex);183 return NULL;184 }185 186 187 int188 register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,189 irq_code_t *pseudocode)190 {191 interrupt_context_t *ctx = create_interrupt_context();192 193 ctx->dev = dev;194 ctx->irq = irq;195 ctx->handler = handler;196 197 add_interrupt_context(&interrupt_contexts, ctx);198 199 if (pseudocode == NULL)200 pseudocode = &default_pseudocode;201 202 int res = irq_register(irq, dev->handle, ctx->id, pseudocode);203 if (res != EOK) {204 remove_interrupt_context(&interrupt_contexts, ctx);205 delete_interrupt_context(ctx);206 }207 208 return res;209 }210 211 int unregister_interrupt_handler(ddf_dev_t *dev, int irq)212 {213 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,214 dev, irq);215 int res = irq_unregister(irq, dev->handle);216 217 if (ctx != NULL) {218 remove_interrupt_context(&interrupt_contexts, ctx);219 delete_interrupt_context(ctx);220 }221 222 return res;223 }224 225 81 static void add_to_functions_list(ddf_fun_t *fun) 226 82 { … … 303 159 304 160 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 161 } 316 162 … … 462 308 case DRIVER_DEV_ADD: 463 309 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 310 break; 469 311 case DRIVER_DEV_REMOVE: … … 753 595 754 596 /** Allocate driver-specific device data. */ 755 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) 756 598 { 757 599 void *data; … … 815 657 816 658 /** Allocate driver-specific function data. */ 817 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) 818 660 { 819 661 void *data; … … 1008 850 driver = drv; 1009 851 1010 /* Initialize the list of interrupt contexts. */ 1011 init_interrupt_context_list(&interrupt_contexts); 1012 1013 /* Set generic interrupt handler. */ 1014 async_set_interrupt_received(driver_irq_handler); 852 /* Initialize interrupt module */ 853 interrupt_init(); 1015 854 1016 855 /*
Note:
See TracChangeset
for help on using the changeset viewer.