Changeset d9bd59da in rtems for c/src/lib/libbsp/shared/src/irq-server.c
- Timestamp:
- 11/03/15 10:44:11 (8 years ago)
- Branches:
- 5, master
- Children:
- 811885cb
- Parents:
- ac84d42e
- git-author:
- Sebastian Huber <sebastian.huber@…> (11/03/15 10:44:11)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (01/20/16 09:15:56)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/shared/src/irq-server.c
rac84d42e rd9bd59da 8 8 9 9 /* 10 * Copyright (c) 2009, 201 5embedded brains GmbH. All rights reserved.10 * Copyright (c) 2009, 2016 embedded brains GmbH. All rights reserved. 11 11 * 12 12 * embedded brains GmbH … … 25 25 #include <rtems.h> 26 26 #include <rtems/chain.h> 27 #include <rtems/score/assert.h> 27 28 28 29 #include <bsp/irq-generic.h> … … 34 35 ) 35 36 36 typedef struct bsp_interrupt_server_entry { 37 typedef struct bsp_interrupt_server_action { 38 struct bsp_interrupt_server_action *next; 39 rtems_interrupt_handler handler; 40 void *arg; 41 } bsp_interrupt_server_action; 42 43 typedef struct { 37 44 rtems_chain_node node; 38 45 rtems_vector_number vector; 39 rtems_interrupt_handler handler; 40 void *arg; 46 bsp_interrupt_server_action *actions; 41 47 } bsp_interrupt_server_entry; 42 48 … … 74 80 75 81 rtems_event_system_send(bsp_interrupt_server_id, RTEMS_EVENT_SYSTEM_SERVER); 82 } 83 84 typedef struct { 85 bsp_interrupt_server_action *action; 86 bsp_interrupt_server_action **link; 87 rtems_id task; 88 } bsp_interrupt_server_helper_data; 89 90 static void bsp_interrupt_server_helper(void *arg) 91 { 92 bsp_interrupt_server_helper_data *hd = arg; 93 94 *hd->link = hd->action; 95 rtems_event_transient_send(hd->task); 96 } 97 98 static void bsp_interrupt_server_call_helper( 99 bsp_interrupt_server_action *action, 100 bsp_interrupt_server_action **link 101 ) 102 { 103 bsp_interrupt_server_helper_data hd = { 104 .action = action, 105 .link = link, 106 .task = rtems_task_self() 107 }; 108 bsp_interrupt_server_action a = { 109 .handler = bsp_interrupt_server_helper, 110 .arg = &hd 111 }; 112 bsp_interrupt_server_entry e = { 113 .vector = BSP_INTERRUPT_VECTOR_MAX + 1, 114 .actions = &a 115 }; 116 117 bsp_interrupt_server_trigger(&e); 118 rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); 76 119 } 77 120 … … 100 143 static void bsp_interrupt_server_task(rtems_task_argument arg) 101 144 { 102 rtems_status_code sc = RTEMS_SUCCESSFUL;103 104 145 while (true) { 105 rtems_event_set events = 0;106 bsp_interrupt_server_entry *e = NULL;107 108 sc =rtems_event_system_receive(146 rtems_event_set events; 147 bsp_interrupt_server_entry *e; 148 149 rtems_event_system_receive( 109 150 RTEMS_EVENT_SYSTEM_SERVER, 110 151 RTEMS_EVENT_ALL | RTEMS_WAIT, … … 112 153 &events 113 154 ); 114 if (sc != RTEMS_SUCCESSFUL) {115 break;116 }117 155 118 156 while ((e = bsp_interrupt_server_get_entry()) != NULL) { 119 (*e->handler)(e->arg); 120 121 bsp_interrupt_vector_enable(e->vector); 122 } 123 } 124 125 rtems_task_delete(RTEMS_SELF); 157 bsp_interrupt_server_action *action = e->actions; 158 rtems_vector_number vector = e->vector; 159 160 do { 161 bsp_interrupt_server_action *current = action; 162 action = action->next; 163 (*current->handler)(current->arg); 164 } while (action != NULL); 165 166 bsp_interrupt_vector_enable(vector); 167 } 168 } 126 169 } 127 170 128 171 typedef struct { 129 rtems_interrupt_handler handler;130 void *arg;131 172 bsp_interrupt_server_entry *entry; 173 rtems_option *options; 132 174 } bsp_interrupt_server_iterate_entry; 133 175 … … 140 182 ) 141 183 { 142 bsp_interrupt_server_iterate_entry *ie = iterate_arg;143 bsp_interrupt_server_entry *e = handler_arg;144 145 184 if (handler == bsp_interrupt_server_trigger) { 146 if (e->handler == ie->handler && e->arg == ie->arg) { 147 ie->entry = e; 148 } 149 } 185 bsp_interrupt_server_iterate_entry *ie = iterate_arg; 186 187 ie->entry = handler_arg; 188 *ie->options = options; 189 } 190 } 191 192 static bsp_interrupt_server_entry *bsp_interrupt_server_query_entry( 193 rtems_vector_number vector, 194 rtems_option *trigger_options 195 ) 196 { 197 bsp_interrupt_server_iterate_entry ie = { 198 .entry = NULL, 199 .options = trigger_options 200 }; 201 202 rtems_interrupt_handler_iterate( 203 vector, 204 bsp_interrupt_server_per_handler_routine, 205 &ie 206 ); 207 208 return ie.entry; 150 209 } 151 210 … … 159 218 ) 160 219 { 161 rtems_status_code sc = RTEMS_SUCCESSFUL; 162 bsp_interrupt_server_entry *e = NULL; 220 rtems_status_code sc; 221 bsp_interrupt_server_entry *e; 222 bsp_interrupt_server_action *a; 223 rtems_option trigger_options; 163 224 164 225 sc = bsp_interrupt_server_is_initialized(); … … 171 232 } 172 233 173 if (RTEMS_INTERRUPT_IS_SHARED(options)) { 174 return RTEMS_NOT_IMPLEMENTED; 175 } 176 177 e = calloc(1, sizeof(*e)); 234 a = calloc(1, sizeof(*a)); 235 if (a == NULL) { 236 return RTEMS_NO_MEMORY; 237 } 238 239 a->handler = handler; 240 a->arg = arg; 241 242 bsp_interrupt_lock(); 243 244 e = bsp_interrupt_server_query_entry(vector, &trigger_options); 178 245 if (e == NULL) { 179 return RTEMS_NO_MEMORY; 180 } 181 182 e->vector = vector; 183 e->handler = handler; 184 e->arg = arg; 185 186 sc = rtems_interrupt_handler_install( 187 vector, 188 info, 189 options, 190 bsp_interrupt_server_trigger, 191 e 192 ); 246 e = calloc(1, sizeof(*e)); 247 if (e != NULL) { 248 e->vector = vector; 249 e->actions = a; 250 251 sc = rtems_interrupt_handler_install( 252 vector, 253 "IRQS", 254 options & RTEMS_INTERRUPT_UNIQUE, 255 bsp_interrupt_server_trigger, 256 e 257 ); 258 if (sc != RTEMS_SUCCESSFUL) { 259 free(e); 260 } 261 } else { 262 sc = RTEMS_NO_MEMORY; 263 } 264 } else if ( 265 RTEMS_INTERRUPT_IS_UNIQUE(options) 266 || RTEMS_INTERRUPT_IS_UNIQUE(trigger_options) 267 ) { 268 sc = RTEMS_RESOURCE_IN_USE; 269 } else { 270 bsp_interrupt_server_action **link = &e->actions; 271 bsp_interrupt_server_action *c; 272 273 while ((c = *link) != NULL) { 274 if (c->handler == handler && c->arg == arg) { 275 sc = RTEMS_TOO_MANY; 276 break; 277 } 278 279 link = &c->next; 280 } 281 282 if (sc == RTEMS_SUCCESSFUL) { 283 bsp_interrupt_server_call_helper(a, link); 284 } 285 } 286 287 bsp_interrupt_unlock(); 288 193 289 if (sc != RTEMS_SUCCESSFUL) { 194 free(e); 195 196 return sc; 197 } 198 199 return RTEMS_SUCCESSFUL; 290 free(a); 291 } 292 293 return sc; 200 294 } 201 295 … … 207 301 ) 208 302 { 209 rtems_status_code sc = RTEMS_SUCCESSFUL; 210 bsp_interrupt_server_iterate_entry ie = { 211 .handler = handler, 212 .arg = arg, 213 .entry = NULL 214 }; 303 rtems_status_code sc; 304 bsp_interrupt_server_entry *e; 305 rtems_option trigger_options; 215 306 216 307 sc = bsp_interrupt_server_is_initialized(); … … 223 314 } 224 315 225 /* Query corresponding interrupt server entry */ 226 sc = rtems_interrupt_handler_iterate( 227 vector, 228 bsp_interrupt_server_per_handler_routine, 229 &ie 230 ); 231 if (sc != RTEMS_SUCCESSFUL) { 232 return sc; 233 } else if (ie.entry == NULL) { 234 return RTEMS_INVALID_ID; 235 } 236 237 sc = rtems_interrupt_handler_remove( 238 vector, 239 bsp_interrupt_server_trigger, 240 ie.entry 241 ); 242 if (sc != RTEMS_SUCCESSFUL) { 243 return sc; 244 } 245 246 free(ie.entry); 247 248 return RTEMS_SUCCESSFUL; 316 bsp_interrupt_lock(); 317 318 e = bsp_interrupt_server_query_entry(vector, &trigger_options); 319 if (e != NULL) { 320 bsp_interrupt_server_action **link = &e->actions; 321 bsp_interrupt_server_action *c; 322 323 while ((c = *link) != NULL) { 324 if (c->handler == handler && c->arg == arg) { 325 break; 326 } 327 328 link = &c->next; 329 } 330 331 if (c != NULL) { 332 bool remove_last = e->actions->next == NULL; 333 334 if (remove_last) { 335 rtems_interrupt_handler_remove( 336 vector, 337 bsp_interrupt_server_trigger, 338 e 339 ); 340 } 341 342 bsp_interrupt_server_call_helper(c->next, link); 343 free(c); 344 345 if (remove_last) { 346 free(e); 347 } 348 } else { 349 sc = RTEMS_UNSATISFIED; 350 } 351 } else { 352 sc = RTEMS_INVALID_ID; 353 } 354 355 bsp_interrupt_unlock(); 356 357 return sc; 249 358 } 250 359 … … 280 389 0 281 390 ); 282 if (sc != RTEMS_SUCCESSFUL) { 283 /* In this case we could also panic */ 284 rtems_task_delete(bsp_interrupt_server_id); 285 bsp_interrupt_server_id = RTEMS_ID_NONE; 286 287 return RTEMS_TOO_MANY; 288 } 391 _Assert(sc == RTEMS_SUCCESSFUL); 289 392 290 393 return RTEMS_SUCCESSFUL;
Note: See TracChangeset
for help on using the changeset viewer.