drivers/net/wan/farsync.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wan/farsync.c
Extension
.c
Size
70620 bytes
Lines
2593
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 fst_ops = {
	.ndo_open       = fst_open,
	.ndo_stop       = fst_close,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_siocwandev	= fst_ioctl,
	.ndo_siocdevprivate = fst_siocdevprivate,
	.ndo_tx_timeout = fst_tx_timeout,
};

/*      Initialise card when detected.
 *      Returns 0 to indicate success, or errno otherwise.
 */
static int
fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	static int no_of_cards_added;
	struct fst_card_info *card;
	int err = 0;
	int i;

	printk_once(KERN_INFO
		    pr_fmt("FarSync WAN driver " FST_USER_VERSION
			   " (c) 2001-2004 FarSite Communications Ltd.\n"));
#if FST_DEBUG
	dbg(DBG_ASS, "The value of debug mask is %x\n", fst_debug_mask);
#endif
	/* We are going to be clever and allow certain cards not to be
	 * configured.  An exclude list can be provided in /etc/modules.conf
	 */
	if (fst_excluded_cards != 0) {
		/* There are cards to exclude
		 *
		 */
		for (i = 0; i < fst_excluded_cards; i++) {
			if (pdev->devfn >> 3 == fst_excluded_list[i]) {
				pr_info("FarSync PCI device %d not assigned\n",
					(pdev->devfn) >> 3);
				return -EBUSY;
			}
		}
	}

	/* Allocate driver private data */
	card = kzalloc_obj(struct fst_card_info);
	if (!card)
		return -ENOMEM;

	/* Try to enable the device */
	err = pci_enable_device(pdev);
	if (err) {
		pr_err("Failed to enable card. Err %d\n", -err);
		goto enable_fail;
	}

	err = pci_request_regions(pdev, "FarSync");
	if (err) {
		pr_err("Failed to allocate regions. Err %d\n", -err);
		goto regions_fail;
	}

	/* Get virtual addresses of memory regions */
	card->pci_conf = pci_resource_start(pdev, 1);
	card->phys_mem = pci_resource_start(pdev, 2);
	card->phys_ctlmem = pci_resource_start(pdev, 3);
	card->mem = ioremap(card->phys_mem, FST_MEMSIZE);
	if (!card->mem) {
		pr_err("Physical memory remap failed\n");
		err = -ENODEV;
		goto ioremap_physmem_fail;
	}
	card->ctlmem = ioremap(card->phys_ctlmem, 0x10);
	if (!card->ctlmem) {
		pr_err("Control memory remap failed\n");
		err = -ENODEV;
		goto ioremap_ctlmem_fail;
	}
	dbg(DBG_PCI, "kernel mem %p, ctlmem %p\n", card->mem, card->ctlmem);

	/* Register the interrupt handler */
	if (request_irq(pdev->irq, fst_intr, IRQF_SHARED, FST_DEV_NAME, card)) {
		pr_err("Unable to register interrupt %d\n", card->irq);
		err = -ENODEV;
		goto irq_fail;
	}

	/* Record info we need */
	card->irq = pdev->irq;
	card->type = ent->driver_data;
	card->family = ((ent->driver_data == FST_TYPE_T2P) ||
			(ent->driver_data == FST_TYPE_T4P))

Annotation

Implementation Notes