static void ergo_irq_bh(struct work_struct *ugli_api) { hysdn_card * card = container_of(ugli_api, hysdn_card, irq_queue); tErgDpram *dpr; int again; unsigned long flags; if (card->state != CARD_STATE_RUN) return; /* invalid call */ dpr = card->dpram; /* point to DPRAM */ spin_lock_irqsave(&card->hysdn_lock, flags); if (card->hw_lock) { spin_unlock_irqrestore(&card->hysdn_lock, flags); /* hardware currently unavailable */ return; } card->hw_lock = 1; /* we now lock the hardware */ do { sti(); /* reenable other ints */ again = 0; /* assume loop not to be repeated */ if (!dpr->ToHyFlag) { /* we are able to send a buffer */ if (hysdn_sched_tx(card, dpr->ToHyBuf, &dpr->ToHySize, &dpr->ToHyChannel, ERG_TO_HY_BUF_SIZE)) { dpr->ToHyFlag = 1; /* enable tx */ again = 1; /* restart loop */ } } /* we are able to send a buffer */ if (dpr->ToPcFlag) { /* a message has arrived for us, handle it */ if (hysdn_sched_rx(card, dpr->ToPcBuf, dpr->ToPcSize, dpr->ToPcChannel)) { dpr->ToPcFlag = 0; /* we worked the data */ again = 1; /* restart loop */ } } /* a message has arrived for us */ cli(); /* no further ints */ if (again) { dpr->ToHyInt = 1; dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ } else card->hw_lock = 0; /* free hardware again */ } while (again); /* until nothing more to do */ spin_unlock_irqrestore(&card->hysdn_lock, flags); } /* ergo_irq_bh */
static void ergo_irq_bh(struct work_struct *ugli_api) { hysdn_card * card = container_of(ugli_api, hysdn_card, irq_queue); tErgDpram *dpr; int again; unsigned long flags; if (card->state != CARD_STATE_RUN) return; dpr = card->dpram; spin_lock_irqsave(&card->hysdn_lock, flags); if (card->hw_lock) { spin_unlock_irqrestore(&card->hysdn_lock, flags); return; } card->hw_lock = 1; do { again = 0; if (!dpr->ToHyFlag) { if (hysdn_sched_tx(card, dpr->ToHyBuf, &dpr->ToHySize, &dpr->ToHyChannel, ERG_TO_HY_BUF_SIZE)) { dpr->ToHyFlag = 1; again = 1; } } if (dpr->ToPcFlag) { if (hysdn_sched_rx(card, dpr->ToPcBuf, dpr->ToPcSize, dpr->ToPcChannel)) { dpr->ToPcFlag = 0; again = 1; } } if (again) { dpr->ToHyInt = 1; dpr->ToPcInt = 1; } else card->hw_lock = 0; } while (again); spin_unlock_irqrestore(&card->hysdn_lock, flags); }