aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/chan_alloc.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2009-08-10 13:46:55 +0200
committerHarald Welte <laforge@netfilter.org>2009-08-10 13:46:55 +0200
commitfc0d9526024d14f7c9ab8ad17d428fe0b7e21a25 (patch)
tree60321920bb365220c2f24c20f7c5e287749a680f /openbsc/src/chan_alloc.c
parent88367263486c4866272cd3d57c76097793aba654 (diff)
introduce bts->chan_alloc_reverse flag
The channel allocator can be set in ascending or descending order. Ascnending means we first try to allocate channels on TRX0, then TRX1, etc. Descending means we first try to allocate cahnnels on TRXn, then n-1 down to 0.
Diffstat (limited to 'openbsc/src/chan_alloc.c')
-rw-r--r--openbsc/src/chan_alloc.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index dd04c3e25..0cf567f8e 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -124,25 +124,46 @@ static const u_int8_t subslots_per_pchan[] = {
};
static struct gsm_lchan *
-_lc_find(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
+_lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
{
- struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
int j, ss;
- llist_for_each_entry(trx, &bts->trx_list, list) {
- for (j = 0; j < 8; j++) {
- ts = &trx->ts[j];
- if (ts->pchan != pchan)
- continue;
- /* check if all sub-slots are allocated yet */
- for (ss = 0; ss < subslots_per_pchan[pchan]; ss++) {
- struct gsm_lchan *lc = &ts->lchan[ss];
- if (lc->type == GSM_LCHAN_NONE)
- return lc;
- }
+ for (j = 0; j < 8; j++) {
+ ts = &trx->ts[j];
+ if (ts->pchan != pchan)
+ continue;
+ /* check if all sub-slots are allocated yet */
+ for (ss = 0; ss < subslots_per_pchan[pchan]; ss++) {
+ struct gsm_lchan *lc = &ts->lchan[ss];
+ if (lc->type == GSM_LCHAN_NONE)
+ return lc;
}
}
+ return NULL;
+}
+
+static struct gsm_lchan *
+_lc_find_bts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
+{
+ struct gsm_bts_trx *trx;
+ struct gsm_bts_trx_ts *ts;
+ struct gsm_lchan *lc;
+
+ if (bts->chan_alloc_reverse) {
+ llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
+ lc = _lc_find_trx(trx, pchan);
+ if (lc)
+ return lc;
+ }
+ } else {
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ lc = _lc_find_trx(trx, pchan);
+ if (lc)
+ return lc;
+ }
+ }
+
/* we cannot allocate more of these */
if (pchan == GSM_PCHAN_CCCH_SDCCH4)
return NULL;
@@ -164,15 +185,15 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type)
switch (type) {
case GSM_LCHAN_SDCCH:
- lchan = _lc_find(bts, GSM_PCHAN_CCCH_SDCCH4);
+ lchan = _lc_find_bts(bts, GSM_PCHAN_CCCH_SDCCH4);
if (lchan == NULL)
- lchan = _lc_find(bts, GSM_PCHAN_SDCCH8_SACCH8C);
+ lchan = _lc_find_bts(bts, GSM_PCHAN_SDCCH8_SACCH8C);
break;
case GSM_LCHAN_TCH_F:
- lchan = _lc_find(bts, GSM_PCHAN_TCH_F);
+ lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_F);
break;
case GSM_LCHAN_TCH_H:
- lchan =_lc_find(bts, GSM_PCHAN_TCH_H);
+ lchan =_lc_find_bts(bts, GSM_PCHAN_TCH_H);
break;
default:
fprintf(stderr, "Unknown gsm_chan_t %u\n", type);