static void ns_close(struct atm_vcc *vcc);
 static void fill_tst(ns_dev * card, int n, vc_map * vc);
 static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb);
+static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb);
 static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-                    struct sk_buff *skb);
+                    struct sk_buff *skb, bool may_sleep);
 static void process_tsq(ns_dev * card);
 static void drain_scq(ns_dev * card, scq_info * scq, int pos);
 static void process_rsq(ns_dev * card);
        .close = ns_close,
        .ioctl = ns_ioctl,
        .send = ns_send,
+       .send_bh = ns_send_bh,
        .phy_put = ns_phy_put,
        .phy_get = ns_phy_get,
        .proc_read = ns_proc_read,
        card->tst_addr = new_tst;
 }
 
-static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
+static int _ns_send(struct atm_vcc *vcc, struct sk_buff *skb, bool may_sleep)
 {
        ns_dev *card;
        vc_map *vc;
                scq = card->scq0;
        }
 
-       if (push_scqe(card, vc, scq, &scqe, skb) != 0) {
+       if (push_scqe(card, vc, scq, &scqe, skb, may_sleep) != 0) {
                atomic_inc(&vcc->stats->tx_err);
                dev_kfree_skb_any(skb);
                return -EIO;
        return 0;
 }
 
+static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+       return _ns_send(vcc, skb, true);
+}
+
+static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+       return _ns_send(vcc, skb, false);
+}
+
 static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-                    struct sk_buff *skb)
+                    struct sk_buff *skb, bool may_sleep)
 {
        unsigned long flags;
        ns_scqe tsr;
 
        spin_lock_irqsave(&scq->lock, flags);
        while (scq->tail == scq->next) {
-               if (in_interrupt()) {
+               if (!may_sleep) {
                        spin_unlock_irqrestore(&scq->lock, flags);
                        printk("nicstar%d: Error pushing TBD.\n", card->index);
                        return 1;
                int has_run = 0;
 
                while (scq->tail == scq->next) {
-                       if (in_interrupt()) {
+                       if (!may_sleep) {
                                data = scq_virt_to_bus(scq, scq->next);
                                ns_write_sram(card, scq->scd, &data, 1);
                                spin_unlock_irqrestore(&scq->lock, flags);
 
                kfree_skb(skb);
                return -EADDRNOTAVAIL;
        }
+       if (vcc->dev->ops->send_bh)
+               return vcc->dev->ops->send_bh(vcc, skb);
        return vcc->dev->ops->send(vcc, skb);
 }
 
        vcc->push = atm_push_raw;
        vcc->pop = atm_pop_raw;
        vcc->push_oam = NULL;
-       vcc->send = vcc->dev->ops->send;
+       if (vcc->dev->ops->send_bh)
+               vcc->send = vcc->dev->ops->send_bh;
+       else
+               vcc->send = vcc->dev->ops->send;
        return 0;
 }
 
        vcc->push = atm_push_raw;
        vcc->pop = atm_pop_raw;
        vcc->push_oam = NULL;
-       vcc->send = vcc->dev->ops->send;
+       if (vcc->dev->ops->send_bh)
+               vcc->send = vcc->dev->ops->send_bh;
+       else
+               vcc->send = vcc->dev->ops->send;
        return 0;
 }
 EXPORT_SYMBOL(atm_init_aal5);