drivers/net/ethernet/8390/pcnet_cs.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/8390/pcnet_cs.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/8390/pcnet_cs.c
Extension
.c
Size
62026 bytes
Lines
1718
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 pcnet_netdev_ops = {
	.ndo_open		= pcnet_open,
	.ndo_stop		= pcnet_close,
	.ndo_set_config		= set_config,
	.ndo_start_xmit 	= ei_start_xmit,
	.ndo_get_stats		= ei_get_stats,
	.ndo_eth_ioctl		= ei_ioctl,
	.ndo_set_rx_mode	= ei_set_multicast_list,
	.ndo_tx_timeout 	= ei_tx_timeout,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller 	= ei_poll,
#endif
};

static int pcnet_probe(struct pcmcia_device *link)
{
    struct pcnet_dev *info;
    struct net_device *dev;

    dev_dbg(&link->dev, "pcnet_attach()\n");

    /* Create new ethernet device */
    dev = __alloc_ei_netdev(sizeof(struct pcnet_dev));
    if (!dev) return -ENOMEM;
    info = PRIV(dev);
    info->p_dev = link;
    link->priv = dev;

    link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;

    dev->netdev_ops = &pcnet_netdev_ops;

    return pcnet_config(link);
} /* pcnet_attach */

static void pcnet_detach(struct pcmcia_device *link)
{
	struct net_device *dev = link->priv;

	dev_dbg(&link->dev, "pcnet_detach\n");

	unregister_netdev(dev);

	pcnet_release(link);

	free_netdev(dev);
} /* pcnet_detach */

/*======================================================================

    This probes for a card's hardware address, for card types that
    encode this information in their CIS.

======================================================================*/

static struct hw_info *get_hwinfo(struct pcmcia_device *link)
{
    struct net_device *dev = link->priv;
    u_char __iomem *base, *virt;
    u8 addr[ETH_ALEN];
    int i, j;

    /* Allocate a small memory window */
    link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
    link->resource[2]->start = 0; link->resource[2]->end = 0;
    i = pcmcia_request_window(link, link->resource[2], 0);
    if (i != 0)
	return NULL;

    virt = ioremap(link->resource[2]->start,
	    resource_size(link->resource[2]));
    if (unlikely(!virt)) {
	    pcmcia_release_window(link, link->resource[2]);
	    return NULL;
    }

    for (i = 0; i < NR_INFO; i++) {
	pcmcia_map_mem_page(link, link->resource[2],
		hw_info[i].offset & ~(resource_size(link->resource[2])-1));
	base = &virt[hw_info[i].offset & (resource_size(link->resource[2])-1)];
	if ((readb(base+0) == hw_info[i].a0) &&
	    (readb(base+2) == hw_info[i].a1) &&
	    (readb(base+4) == hw_info[i].a2)) {
		for (j = 0; j < 6; j++)
			addr[j] = readb(base + (j<<1));
		eth_hw_addr_set(dev, addr);
		break;
	}

Annotation

Implementation Notes