drivers/net/wan/n2.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wan/n2.c
Extension
.c
Size
13333 bytes
Lines
547
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 n2_ops = {
	.ndo_open       = n2_open,
	.ndo_stop       = n2_close,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_siocwandev = n2_ioctl,
	.ndo_siocdevprivate = n2_siocdevprivate,
};

static int __init n2_run(unsigned long io, unsigned long irq,
			 unsigned long winbase, long valid0, long valid1)
{
	card_t *card;
	u8 cnt, pcr;
	int i;

	if (io < 0x200 || io > 0x3FF || (io % N2_IOPORTS) != 0) {
		pr_err("invalid I/O port value\n");
		return -ENODEV;
	}

	if (irq < 3 || irq > 15 || irq == 6) /* FIXME */ {
		pr_err("invalid IRQ value\n");
		return -ENODEV;
	}

	if (winbase < 0xA0000 || winbase > 0xFFFFF || (winbase & 0xFFF) != 0) {
		pr_err("invalid RAM value\n");
		return -ENODEV;
	}

	card = kzalloc_obj(card_t);
	if (!card)
		return -ENOBUFS;

	card->ports[0].dev = alloc_hdlcdev(&card->ports[0]);
	card->ports[1].dev = alloc_hdlcdev(&card->ports[1]);
	if (!card->ports[0].dev || !card->ports[1].dev) {
		pr_err("unable to allocate memory\n");
		n2_destroy_card(card);
		return -ENOMEM;
	}

	if (!request_region(io, N2_IOPORTS, devname)) {
		pr_err("I/O port region in use\n");
		n2_destroy_card(card);
		return -EBUSY;
	}
	card->io = io;

	if (request_irq(irq, sca_intr, 0, devname, card)) {
		pr_err("could not allocate IRQ\n");
		n2_destroy_card(card);
		return -EBUSY;
	}
	card->irq = irq;

	if (!request_mem_region(winbase, USE_WINDOWSIZE, devname)) {
		pr_err("could not request RAM window\n");
		n2_destroy_card(card);
		return -EBUSY;
	}
	card->phy_winbase = winbase;
	card->winbase = ioremap(winbase, USE_WINDOWSIZE);
	if (!card->winbase) {
		pr_err("ioremap() failed\n");
		n2_destroy_card(card);
		return -EFAULT;
	}

	outb(0, io + N2_PCR);
	outb(winbase >> 12, io + N2_BAR);

	switch (USE_WINDOWSIZE) {
	case 16384:
		outb(WIN16K, io + N2_PSR);
		break;

	case 32768:
		outb(WIN32K, io + N2_PSR);
		break;

	case 65536:
		outb(WIN64K, io + N2_PSR);
		break;

	default:
		pr_err("invalid window size\n");
		n2_destroy_card(card);
		return -ENODEV;
	}

Annotation

Implementation Notes