in drivers/vector_kern.c [1214:1327]
static int vector_net_open(struct net_device *dev)
{
struct vector_private *vp = netdev_priv(dev);
unsigned long flags;
int err = -EINVAL;
struct vector_device *vdevice;
spin_lock_irqsave(&vp->lock, flags);
if (vp->opened) {
spin_unlock_irqrestore(&vp->lock, flags);
return -ENXIO;
}
vp->opened = true;
spin_unlock_irqrestore(&vp->lock, flags);
vp->bpf = uml_vector_user_bpf(get_bpf_file(vp->parsed));
vp->fds = uml_vector_user_open(vp->unit, vp->parsed);
if (vp->fds == NULL)
goto out_close;
if (build_transport_data(vp) < 0)
goto out_close;
if ((vp->options & VECTOR_RX) > 0) {
vp->rx_queue = create_queue(
vp,
get_depth(vp->parsed),
vp->rx_header_size,
MAX_IOV_SIZE
);
vp->rx_queue->queue_depth = get_depth(vp->parsed);
} else {
vp->header_rxbuffer = kmalloc(
vp->rx_header_size,
GFP_KERNEL
);
if (vp->header_rxbuffer == NULL)
goto out_close;
}
if ((vp->options & VECTOR_TX) > 0) {
vp->tx_queue = create_queue(
vp,
get_depth(vp->parsed),
vp->header_size,
MAX_IOV_SIZE
);
} else {
vp->header_txbuffer = kmalloc(vp->header_size, GFP_KERNEL);
if (vp->header_txbuffer == NULL)
goto out_close;
}
/* READ IRQ */
err = um_request_irq(
irq_rr + VECTOR_BASE_IRQ, vp->fds->rx_fd,
IRQ_READ, vector_rx_interrupt,
IRQF_SHARED, dev->name, dev);
if (err < 0) {
netdev_err(dev, "vector_open: failed to get rx irq(%d)\n", err);
err = -ENETUNREACH;
goto out_close;
}
vp->rx_irq = irq_rr + VECTOR_BASE_IRQ;
dev->irq = irq_rr + VECTOR_BASE_IRQ;
irq_rr = (irq_rr + 1) % VECTOR_IRQ_SPACE;
/* WRITE IRQ - we need it only if we have vector TX */
if ((vp->options & VECTOR_TX) > 0) {
err = um_request_irq(
irq_rr + VECTOR_BASE_IRQ, vp->fds->tx_fd,
IRQ_WRITE, vector_tx_interrupt,
IRQF_SHARED, dev->name, dev);
if (err < 0) {
netdev_err(dev,
"vector_open: failed to get tx irq(%d)\n", err);
err = -ENETUNREACH;
goto out_close;
}
vp->tx_irq = irq_rr + VECTOR_BASE_IRQ;
irq_rr = (irq_rr + 1) % VECTOR_IRQ_SPACE;
}
if ((vp->options & VECTOR_QDISC_BYPASS) != 0) {
if (!uml_raw_enable_qdisc_bypass(vp->fds->rx_fd))
vp->options |= VECTOR_BPF;
}
if (((vp->options & VECTOR_BPF) != 0) && (vp->bpf == NULL))
vp->bpf = uml_vector_default_bpf(dev->dev_addr);
if (vp->bpf != NULL)
uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
netif_start_queue(dev);
/* clear buffer - it can happen that the host side of the interface
* is full when we get here. In this case, new data is never queued,
* SIGIOs never arrive, and the net never works.
*/
vector_rx(vp);
vector_reset_stats(vp);
vdevice = find_device(vp->unit);
vdevice->opened = 1;
if ((vp->options & VECTOR_TX) != 0)
add_timer(&vp->tl);
return 0;
out_close:
vector_net_close(dev);
return err;
}