void *_talloc_zero(void *ctx, unsigned int size, const char *name) { unsigned long flags; unsigned int i; local_firq_save(flags); if (size > sizeof(struct msgb) + MSGB_DATA_SIZE) goto panic; for (i = 0; i < ARRAY_SIZE(msgs); i++) { if (!msgs[i].allocated) { msgs[i].allocated = 1; memset(&msgs[i].msg, 0, sizeof(msgs[i].msg)); memset(&msgs[i].buf, 0, sizeof(msgs[i].buf)); local_irq_restore(flags); return &msgs[i].msg; } } panic: cons_puts("unable to allocate msgb\n"); while (1); return NULL; /* not reached */ }
/* safely enable a message into the L1S TX queue */ void l1a_txq_msgb_enq(struct llist_head *queue, struct msgb *msg) { unsigned long flags; local_firq_save(flags); msgb_enqueue(queue, msg); local_irq_restore(flags); }
/* flush all pending msgb */ void l1a_txq_msgb_flush(struct llist_head *queue) { struct msgb *msg; unsigned long flags; local_firq_save(flags); while ((msg = msgb_dequeue(queue))) msgb_free(msg); local_irq_restore(flags); }
/* Execute pending L1A completions */ void l1a_compl_execute(void) { unsigned long flags; unsigned int scheduled; unsigned int i; /* get and reset the currently scheduled tasks */ local_firq_save(flags); scheduled = l1s.scheduled_compl; l1s.scheduled_compl = 0; local_irq_restore(flags); /* Iterate over list of scheduled completions, call their * respective completion handler */ for (i = 0; i < 32; i++) { if (!(scheduled & (1 << i))) continue; /* call completion function */ l1s.completion[i](i); } }
/* request a RACH request at the next multiframe T3 = fn51 */ void l1a_rach_req(uint16_t offset, uint8_t combined, uint8_t ra) { uint32_t fn_sched; unsigned long flags; offset += 3; local_firq_save(flags); if (combined) { /* add elapsed RACH slots to offset */ offset += t3_to_rach_comb[l1s.current_time.t3]; /* offset is the number of RACH slots in the future */ fn_sched = l1s.current_time.fn - l1s.current_time.t3; fn_sched += offset / 27 * 51; fn_sched += rach_to_t3_comb[offset % 27]; } else fn_sched = l1s.current_time.fn + offset; l1s.rach.ra = ra; sched_gsmtime(rach_sched_set_ul, fn_sched, 0); local_irq_restore(flags); memset(&last_rach, 0, sizeof(last_rach)); }