Changeset 10670a5 in rtems
- Timestamp:
- 06/13/16 08:30:42 (7 years ago)
- Branches:
- 5, master
- Children:
- a0cd238d
- Parents:
- 3bf9fdb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/shared/src/irq-server.c
r3bf9fdb r10670a5 83 83 84 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 **link101 )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 = &hd111 };112 bsp_interrupt_server_entry e = {113 .vector = BSP_INTERRUPT_VECTOR_MAX + 1,114 .actions = &a115 };116 117 bsp_interrupt_server_trigger(&e);118 rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);119 }120 121 static bsp_interrupt_server_entry *bsp_interrupt_server_get_entry(void)122 {123 rtems_interrupt_lock_context lock_context;124 bsp_interrupt_server_entry *e;125 rtems_chain_control *chain;126 127 rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);128 chain = &bsp_interrupt_server_chain;129 130 if (!rtems_chain_is_empty(chain)) {131 e = (bsp_interrupt_server_entry *)132 rtems_chain_get_first_unprotected(chain);133 rtems_chain_set_off_chain(&e->node);134 } else {135 e = NULL;136 }137 138 rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context);139 140 return e;141 }142 143 static void bsp_interrupt_server_task(rtems_task_argument arg)144 {145 while (true) {146 rtems_event_set events;147 bsp_interrupt_server_entry *e;148 149 rtems_event_system_receive(150 RTEMS_EVENT_SYSTEM_SERVER,151 RTEMS_EVENT_ALL | RTEMS_WAIT,152 RTEMS_NO_TIMEOUT,153 &events154 );155 156 while ((e = bsp_interrupt_server_get_entry()) != NULL) {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 }169 }170 171 typedef struct {172 85 bsp_interrupt_server_entry *entry; 173 86 rtems_option *options; … … 209 122 } 210 123 211 rtems_status_code rtems_interrupt_server_handler_install( 212 rtems_id server, 213 rtems_vector_number vector, 214 const char *info, 215 rtems_option options, 216 rtems_interrupt_handler handler, 217 void *arg 218 ) 219 { 124 typedef struct { 125 rtems_vector_number vector; 126 rtems_option options; 127 rtems_interrupt_handler handler; 128 void *arg; 129 rtems_id task; 130 rtems_status_code sc; 131 } bsp_interrupt_server_helper_data; 132 133 static void bsp_interrupt_server_install_helper(void *arg) 134 { 135 bsp_interrupt_server_helper_data *hd = arg; 220 136 rtems_status_code sc; 221 137 bsp_interrupt_server_entry *e; … … 223 139 rtems_option trigger_options; 224 140 225 sc = bsp_interrupt_server_is_initialized();226 if (sc != RTEMS_SUCCESSFUL) {227 return sc;228 }229 230 if (server != RTEMS_ID_NONE) {231 return RTEMS_NOT_IMPLEMENTED;232 }233 234 141 a = calloc(1, sizeof(*a)); 235 142 if (a == NULL) { 236 return RTEMS_NO_MEMORY; 237 } 238 239 a->handler = handler; 240 a->arg = arg; 143 hd->sc = RTEMS_NO_MEMORY; 144 rtems_event_transient_send(hd->task); 145 return; 146 } 147 148 a->handler = hd->handler; 149 a->arg = hd->arg; 241 150 242 151 bsp_interrupt_lock(); 243 152 244 e = bsp_interrupt_server_query_entry( vector, &trigger_options);153 e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options); 245 154 if (e == NULL) { 246 155 e = calloc(1, sizeof(*e)); 247 156 if (e != NULL) { 248 e->vector = vector;157 e->vector = hd->vector; 249 158 e->actions = a; 250 159 251 160 sc = rtems_interrupt_handler_install( 252 vector,161 hd->vector, 253 162 "IRQS", 254 options & RTEMS_INTERRUPT_UNIQUE,163 hd->options & RTEMS_INTERRUPT_UNIQUE, 255 164 bsp_interrupt_server_trigger, 256 165 e … … 263 172 } 264 173 } else if ( 265 RTEMS_INTERRUPT_IS_UNIQUE( options)174 RTEMS_INTERRUPT_IS_UNIQUE(hd->options) 266 175 || RTEMS_INTERRUPT_IS_UNIQUE(trigger_options) 267 176 ) { … … 271 180 bsp_interrupt_server_action *c; 272 181 182 sc = RTEMS_SUCCESSFUL; 183 273 184 while ((c = *link) != NULL) { 274 if (c->handler == h andler && c->arg ==arg) {185 if (c->handler == hd->handler && c->arg == hd->arg) { 275 186 sc = RTEMS_TOO_MANY; 276 187 break; … … 281 192 282 193 if (sc == RTEMS_SUCCESSFUL) { 283 bsp_interrupt_server_call_helper(a, link);194 *link = a; 284 195 } 285 196 } … … 291 202 } 292 203 293 return sc; 204 hd->sc = sc; 205 rtems_event_transient_send(hd->task); 206 } 207 208 static void bsp_interrupt_server_remove_helper(void *arg) 209 { 210 bsp_interrupt_server_helper_data *hd = arg; 211 rtems_status_code sc; 212 bsp_interrupt_server_entry *e; 213 rtems_option trigger_options; 214 215 bsp_interrupt_lock(); 216 217 e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options); 218 if (e != NULL) { 219 bsp_interrupt_server_action **link = &e->actions; 220 bsp_interrupt_server_action *c; 221 222 while ((c = *link) != NULL) { 223 if (c->handler == hd->handler && c->arg == hd->arg) { 224 break; 225 } 226 227 link = &c->next; 228 } 229 230 if (c != NULL) { 231 bool remove_last = e->actions->next == NULL; 232 233 if (remove_last) { 234 rtems_interrupt_handler_remove( 235 hd->vector, 236 bsp_interrupt_server_trigger, 237 e 238 ); 239 } 240 241 *link = c->next; 242 free(c); 243 244 if (remove_last) { 245 free(e); 246 } 247 248 sc = RTEMS_SUCCESSFUL; 249 } else { 250 sc = RTEMS_UNSATISFIED; 251 } 252 } else { 253 sc = RTEMS_INVALID_ID; 254 } 255 256 bsp_interrupt_unlock(); 257 258 hd->sc = sc; 259 rtems_event_transient_send(hd->task); 260 } 261 262 static rtems_status_code bsp_interrupt_server_call_helper( 263 rtems_vector_number vector, 264 rtems_option options, 265 rtems_interrupt_handler handler, 266 void *arg, 267 void (*helper)(void *) 268 ) 269 { 270 bsp_interrupt_server_helper_data hd = { 271 .vector = vector, 272 .options = options, 273 .handler = handler, 274 .arg = arg, 275 .task = rtems_task_self() 276 }; 277 bsp_interrupt_server_action a = { 278 .handler = helper, 279 .arg = &hd 280 }; 281 bsp_interrupt_server_entry e = { 282 .vector = BSP_INTERRUPT_VECTOR_MAX + 1, 283 .actions = &a 284 }; 285 286 bsp_interrupt_server_trigger(&e); 287 rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); 288 289 return hd.sc; 290 } 291 292 static bsp_interrupt_server_entry *bsp_interrupt_server_get_entry(void) 293 { 294 rtems_interrupt_lock_context lock_context; 295 bsp_interrupt_server_entry *e; 296 rtems_chain_control *chain; 297 298 rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context); 299 chain = &bsp_interrupt_server_chain; 300 301 if (!rtems_chain_is_empty(chain)) { 302 e = (bsp_interrupt_server_entry *) 303 rtems_chain_get_first_unprotected(chain); 304 rtems_chain_set_off_chain(&e->node); 305 } else { 306 e = NULL; 307 } 308 309 rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context); 310 311 return e; 312 } 313 314 static void bsp_interrupt_server_task(rtems_task_argument arg) 315 { 316 while (true) { 317 rtems_event_set events; 318 bsp_interrupt_server_entry *e; 319 320 rtems_event_system_receive( 321 RTEMS_EVENT_SYSTEM_SERVER, 322 RTEMS_EVENT_ALL | RTEMS_WAIT, 323 RTEMS_NO_TIMEOUT, 324 &events 325 ); 326 327 while ((e = bsp_interrupt_server_get_entry()) != NULL) { 328 bsp_interrupt_server_action *action = e->actions; 329 rtems_vector_number vector = e->vector; 330 331 do { 332 bsp_interrupt_server_action *current = action; 333 action = action->next; 334 (*current->handler)(current->arg); 335 } while (action != NULL); 336 337 bsp_interrupt_vector_enable(vector); 338 } 339 } 340 } 341 342 rtems_status_code rtems_interrupt_server_handler_install( 343 rtems_id server, 344 rtems_vector_number vector, 345 const char *info, 346 rtems_option options, 347 rtems_interrupt_handler handler, 348 void *arg 349 ) 350 { 351 rtems_status_code sc; 352 353 sc = bsp_interrupt_server_is_initialized(); 354 if (sc != RTEMS_SUCCESSFUL) { 355 return sc; 356 } 357 358 if (server != RTEMS_ID_NONE) { 359 return RTEMS_NOT_IMPLEMENTED; 360 } 361 362 return bsp_interrupt_server_call_helper( 363 vector, 364 options, 365 handler, 366 arg, 367 bsp_interrupt_server_install_helper 368 ); 294 369 } 295 370 … … 302 377 { 303 378 rtems_status_code sc; 304 bsp_interrupt_server_entry *e;305 rtems_option trigger_options;306 379 307 380 sc = bsp_interrupt_server_is_initialized(); … … 314 387 } 315 388 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; 389 return bsp_interrupt_server_call_helper( 390 vector, 391 0, 392 handler, 393 arg, 394 bsp_interrupt_server_remove_helper 395 ); 358 396 } 359 397
Note: See TracChangeset
for help on using the changeset viewer.