int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb) { struct raw_hdr raw; unsigned char ftr = 0x7e; unsigned sz; sz = skb->len + sizeof(raw) + 1; if (fifo_space(&mc->raw_tx) < sz) { MODEM_COUNT(mc, tx_fifo_full); return -1; } raw.start = 0x7f; raw.len = 6 + skb->len; raw.channel = RAW_CH_VNET0; raw.control = 0; fifo_write(&mc->raw_tx, &raw, sizeof(raw)); fifo_write(&mc->raw_tx, skb->data, skb->len); fifo_write(&mc->raw_tx, &ftr, 1); mc->ndev->stats.tx_packets++; mc->ndev->stats.tx_bytes += skb->len; mc->mmio_signal_bits |= MBD_SEND_RAW; dev_kfree_skb_irq(skb); return 0; }
void modem_update_pipe(struct m_pipe *pipe) { unsigned long flags; spin_lock_irqsave(&pipe->mc->lock, flags); pipe->tx->avail = fifo_space(pipe->tx); pipe->rx->avail = fifo_count(pipe->rx); if (pipe->rx->avail) wake_lock(&pipe->wakelock); else wake_unlock(&pipe->wakelock); spin_unlock_irqrestore(&pipe->mc->lock, flags); }
/* Called with mc->lock held whenever we gain access * to the mmio region. */ void modem_update_state(struct modemctl *mc) { /* update our idea of space available in fifos */ mc->packet_tx.avail = fifo_space(&mc->packet_tx); mc->packet_rx.avail = fifo_count(&mc->packet_rx); if (mc->packet_rx.avail) wake_lock(&mc->packet_pipe.wakelock); else wake_unlock(&mc->packet_pipe.wakelock); /* wake up blocked or polling read/write operations */ wake_up(&mc->wq); }