in rio_cm.c [526:575]
static int rio_rx_data_handler(struct cm_dev *cm, void *buf)
{
struct rio_ch_chan_hdr *hdr;
struct rio_channel *ch;
hdr = buf;
riocm_debug(RX_DATA, "for ch=%d", ntohs(hdr->dst_ch));
ch = riocm_get_channel(ntohs(hdr->dst_ch));
if (!ch) {
/* Discard data message for non-existing channel */
kfree(buf);
return -ENODEV;
}
/* Place pointer to the buffer into channel's RX queue */
spin_lock(&ch->lock);
if (ch->state != RIO_CM_CONNECTED) {
/* Channel is not ready to receive data, discard a packet */
riocm_debug(RX_DATA, "ch=%d is in wrong state=%d",
ch->id, ch->state);
spin_unlock(&ch->lock);
kfree(buf);
riocm_put_channel(ch);
return -EIO;
}
if (ch->rx_ring.count == RIOCM_RX_RING_SIZE) {
/* If RX ring is full, discard a packet */
riocm_debug(RX_DATA, "ch=%d is full", ch->id);
spin_unlock(&ch->lock);
kfree(buf);
riocm_put_channel(ch);
return -ENOMEM;
}
ch->rx_ring.buf[ch->rx_ring.head] = buf;
ch->rx_ring.head++;
ch->rx_ring.count++;
ch->rx_ring.head %= RIOCM_RX_RING_SIZE;
complete(&ch->comp);
spin_unlock(&ch->lock);
riocm_put_channel(ch);
return 0;
}