drivers/net/ethernet/sis/sis900.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sis/sis900.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sis/sis900.c
Extension
.c
Size
75090 bytes
Lines
2559
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 sis900_netdev_ops = {
	.ndo_open		 = sis900_open,
	.ndo_stop		= sis900_close,
	.ndo_start_xmit		= sis900_start_xmit,
	.ndo_set_config		= sis900_set_config,
	.ndo_set_rx_mode	= set_rx_mode,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_eth_ioctl		= mii_ioctl,
	.ndo_tx_timeout		= sis900_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller	= sis900_poll,
#endif
};

/**
 *	sis900_probe - Probe for sis900 device
 *	@pci_dev: the sis900 pci device
 *	@pci_id: the pci device ID
 *
 *	Check and probe sis900 net device for @pci_dev.
 *	Get mac address according to the chip revision,
 *	and assign SiS900-specific entries in the device structure.
 *	ie: sis900_open(), sis900_start_xmit(), sis900_close(), etc.
 */

static int sis900_probe(struct pci_dev *pci_dev,
			const struct pci_device_id *pci_id)
{
	struct sis900_private *sis_priv;
	struct net_device *net_dev;
	struct pci_dev *dev;
	dma_addr_t ring_dma;
	void *ring_space;
	void __iomem *ioaddr;
	int i, ret;
	const char *card_name = card_names[pci_id->driver_data];
	const char *dev_name = pci_name(pci_dev);

	/* setup various bits in PCI command register */
	ret = pcim_enable_device(pci_dev);
	if(ret) return ret;

	i = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32));
	if(i){
		printk(KERN_ERR "sis900.c: architecture does not support "
			"32bit PCI busmaster DMA\n");
		return i;
	}

	pci_set_master(pci_dev);

	net_dev = alloc_etherdev(sizeof(struct sis900_private));
	if (!net_dev)
		return -ENOMEM;
	SET_NETDEV_DEV(net_dev, &pci_dev->dev);

	/* We do a request_region() to register /proc/ioports info. */
	ret = pcim_request_all_regions(pci_dev, "sis900");
	if (ret)
		goto err_out;

	/* IO region. */
	ioaddr = pci_iomap(pci_dev, 0, 0);
	if (!ioaddr) {
		ret = -ENOMEM;
		goto err_out;
	}

	sis_priv = netdev_priv(net_dev);
	sis_priv->ioaddr = ioaddr;
	sis_priv->pci_dev = pci_dev;
	spin_lock_init(&sis_priv->lock);

	sis_priv->eeprom_size = 24;

	pci_set_drvdata(pci_dev, net_dev);

	ring_space = dma_alloc_coherent(&pci_dev->dev, TX_TOTAL_SIZE,
					&ring_dma, GFP_KERNEL);
	if (!ring_space) {
		ret = -ENOMEM;
		goto err_out_unmap;
	}
	sis_priv->tx_ring = ring_space;
	sis_priv->tx_ring_dma = ring_dma;

	ring_space = dma_alloc_coherent(&pci_dev->dev, RX_TOTAL_SIZE,
					&ring_dma, GFP_KERNEL);
	if (!ring_space) {

Annotation

Implementation Notes