drivers/net/eql.c

Source file repositories/reference/linux-study-clean/drivers/net/eql.c

File Facts

System
Linux kernel
Corpus path
drivers/net/eql.c
Extension
.c
Size
15179 bytes
Lines
612
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops eql_netdev_ops = {
	.ndo_open	= eql_open,
	.ndo_stop	= eql_close,
	.ndo_siocdevprivate = eql_siocdevprivate,
	.ndo_start_xmit	= eql_slave_xmit,
};

static void __init eql_setup(struct net_device *dev)
{
	equalizer_t *eql = netdev_priv(dev);

	timer_setup(&eql->timer, eql_timer, 0);
	eql->timer.expires  	= jiffies + EQL_DEFAULT_RESCHED_IVAL;

	spin_lock_init(&eql->queue.lock);
	INIT_LIST_HEAD(&eql->queue.all_slaves);
	eql->queue.master_dev	= dev;

	dev->netdev_ops		= &eql_netdev_ops;

	/*
	 *	Now we undo some of the things that eth_setup does
	 * 	that we don't like
	 */

	dev->mtu        	= EQL_DEFAULT_MTU;	/* set to 576 in if_eql.h */
	dev->flags      	= IFF_MASTER;

	dev->type       	= ARPHRD_SLIP;
	dev->tx_queue_len 	= 5;		/* Hands them off fast */
	netif_keep_dst(dev);
}

static int eql_open(struct net_device *dev)
{
	equalizer_t *eql = netdev_priv(dev);

	/* XXX We should force this off automatically for the user. */
	netdev_info(dev,
		    "remember to turn off Van-Jacobson compression on your slave devices\n");

	BUG_ON(!list_empty(&eql->queue.all_slaves));

	eql->min_slaves = 1;
	eql->max_slaves = EQL_DEFAULT_MAX_SLAVES; /* 4 usually... */

	add_timer(&eql->timer);

	return 0;
}

static void eql_kill_one_slave(slave_queue_t *queue, slave_t *slave)
{
	list_del(&slave->list);
	queue->num_slaves--;
	slave->dev->flags &= ~IFF_SLAVE;
	netdev_put(slave->dev, &slave->dev_tracker);
	kfree(slave);
}

static void eql_kill_slave_queue(slave_queue_t *queue)
{
	struct list_head *head, *tmp, *this;

	spin_lock_bh(&queue->lock);

	head = &queue->all_slaves;
	list_for_each_safe(this, tmp, head) {
		slave_t *s = list_entry(this, slave_t, list);

		eql_kill_one_slave(queue, s);
	}

	spin_unlock_bh(&queue->lock);
}

static int eql_close(struct net_device *dev)
{
	equalizer_t *eql = netdev_priv(dev);

	/*
	 *	The timer has to be stopped first before we start hacking away
	 *	at the data structure it scans every so often...
	 */

	timer_delete_sync(&eql->timer);

	eql_kill_slave_queue(&eql->queue);

	return 0;

Annotation

Implementation Notes