⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defxx.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *   * Returns: *   Condition code *        * Arguments: *   pdev - pointer to pci device information (NULL for EISA) * * Functional Description: * * Return Codes: *   0		 - This device (fddi0, fddi1, etc) configured successfully *   -EBUSY      - Failed to get resources, or dfx_driver_init failed. * * Assumptions: *   It compiles so it should work :-( (PCI cards do :-) * * Side Effects: *   Device structures for FDDI adapters (fddi0, fddi1, etc) are *   initialized and the board resources are read and stored in *   the device structure. */static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr){	struct net_device *dev;	DFX_board_t	  *bp;			/* board pointer */	static int version_disp;	if (!version_disp)					/* display version info if adapter is found */	{		version_disp = 1;				/* set display flag to TRUE so that */		printk(version);				/* we only display this string ONCE */	}	/*	 * init_fddidev() allocates a device structure with private data, clears the device structure and private data,	 * and  calls fddi_setup() and register_netdev(). Not much left to do for us here.	 */	dev = init_fddidev( NULL, sizeof(*bp));	if (!dev) {		printk (KERN_ERR "defxx: unable to allocate fddidev, aborting\n");		return -ENOMEM;	}	bp = (DFX_board_t*)dev->priv;	if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, dev->name)) {		printk (KERN_ERR "%s: Cannot reserve I/O resource 0x%x @ 0x%lx, aborting\n",			dev->name, PFI_K_CSR_IO_LEN, ioaddr);		goto err_out;	}	/* Initialize new device structure */	dev->base_addr			= ioaddr; /* save port (I/O) base address */	dev->get_stats			= dfx_ctl_get_stats;	dev->open			= dfx_open;	dev->stop			= dfx_close;	dev->hard_start_xmit		= dfx_xmt_queue_pkt;	dev->set_multicast_list		= dfx_ctl_set_multicast_list;	dev->set_mac_address		= dfx_ctl_set_mac_address;	if (pdev == NULL) {		/* EISA board */		bp->bus_type = DFX_BUS_TYPE_EISA;		bp->next = root_dfx_eisa_dev;		root_dfx_eisa_dev = dev;	} else {		/* PCI board */		bp->bus_type = DFX_BUS_TYPE_PCI;		bp->pci_dev = pdev;		pdev->driver_data = dev;		if (pci_enable_device (pdev))			goto err_out_region;		pci_set_master (pdev);	}	if (dfx_driver_init(dev) != DFX_K_SUCCESS)		goto err_out_region;	return 0;err_out_region:	release_region(ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN);err_out:	unregister_netdev(dev);	kfree(dev);	return -ENODEV;}static int __devinit dfx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent){	return  dfx_init_one_pci_or_eisa(pdev, pci_resource_start (pdev, 1));}static int __init dfx_eisa_init(void){	int rc = -NODEV;	int i;			/* used in for loops */	u16 port;		/* temporary I/O (port) address */	u32 slot_id;		/* EISA hardware (slot) ID read from adapter */	DBG_printk("In dfx_eisa_init...\n");	/* Scan for FDDI EISA controllers */	for (i=0; i < DFX_MAX_EISA_SLOTS; i++)		/* only scan for up to 16 EISA slots */	{		port = (i << 12) + PI_ESIC_K_SLOT_ID;	/* port = I/O address for reading slot ID */		slot_id = inl(port);					/* read EISA HW (slot) ID */		if ((slot_id & 0xF0FFFFFF) == DEFEA_PRODUCT_ID)		{			port = (i << 12);					/* recalc base addr */			if (dfx_init_one_pci_or_eisa(NULL, port) == 0) rc = 0;		}	}	return rc;}/* * ================ * = dfx_bus_init = * ================ *    * Overview: *   Initializes EISA and PCI controller bus-specific logic. *   * Returns: *   None *        * Arguments: *   dev - pointer to device information * * Functional Description: *   Determine and save adapter IRQ in device table, *   then perform bus-specific logic initialization. * * Return Codes: *   None * * Assumptions: *   dev->base_addr has already been set with the proper *	 base I/O address for this device. * * Side Effects: *   Interrupts are enabled at the adapter bus-specific logic. *   Note:  Interrupts at the DMA engine (PDQ chip) are not *   enabled yet. */static void __devinit dfx_bus_init(struct net_device *dev){	DFX_board_t *bp = (DFX_board_t *)dev->priv;	u8			val;	/* used for I/O read/writes */	DBG_printk("In dfx_bus_init...\n");	/*	 * Initialize base I/O address field in bp structure	 *	 * Note: bp->base_addr is the same as dev->base_addr.	 *		 It's useful because often we'll need to read	 *		 or write registers where we already have the	 *		 bp pointer instead of the dev pointer.  Having	 *		 the base address in the bp structure will	 *		 save a pointer dereference.	 *	 *		 IMPORTANT!! This field must be defined before	 *		 any of the dfx_port_* inline functions are	 *		 called.	 */	bp->base_addr = dev->base_addr;	/* And a pointer back to the net_device struct */	bp->dev = dev;	/* Initialize adapter based on bus type */	if (bp->bus_type == DFX_BUS_TYPE_EISA)		{		/* Get the interrupt level from the ESIC chip */		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &val);		switch ((val & PI_CONFIG_STAT_0_M_IRQ) >> PI_CONFIG_STAT_0_V_IRQ)			{			case PI_CONFIG_STAT_0_IRQ_K_9:				dev->irq = 9;				break;			case PI_CONFIG_STAT_0_IRQ_K_10:				dev->irq = 10;				break;			case PI_CONFIG_STAT_0_IRQ_K_11:				dev->irq = 11;				break;			case PI_CONFIG_STAT_0_IRQ_K_15:				dev->irq = 15;				break;			}		/* Enable access to I/O on the board by writing 0x03 to Function Control Register */		dfx_port_write_byte(bp, PI_ESIC_K_FUNCTION_CNTRL, PI_ESIC_K_FUNCTION_CNTRL_IO_ENB);		/* Set the I/O decode range of the board */		val = ((dev->base_addr >> 12) << PI_IO_CMP_V_SLOT);		dfx_port_write_byte(bp, PI_ESIC_K_IO_CMP_0_1, val);		dfx_port_write_byte(bp, PI_ESIC_K_IO_CMP_1_1, val);		/* Enable access to rest of module (including PDQ and packet memory) */		dfx_port_write_byte(bp, PI_ESIC_K_SLOT_CNTRL, PI_SLOT_CNTRL_M_ENB);		/*		 * Map PDQ registers into I/O space.  This is done by clearing a bit		 * in Burst Holdoff register.		 */		dfx_port_read_byte(bp, PI_ESIC_K_BURST_HOLDOFF, &val);		dfx_port_write_byte(bp, PI_ESIC_K_BURST_HOLDOFF, (val & ~PI_BURST_HOLDOFF_M_MEM_MAP));		/* Enable interrupts at EISA bus interface chip (ESIC) */		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &val);		dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, (val | PI_CONFIG_STAT_0_M_INT_ENB));		}	else		{		struct pci_dev *pdev = bp->pci_dev;		/* Get the interrupt level from the PCI Configuration Table */		dev->irq = pdev->irq;		/* Check Latency Timer and set if less than minimal */		pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val);		if (val < PFI_K_LAT_TIMER_MIN)	/* if less than min, override with default */			{			val = PFI_K_LAT_TIMER_DEF;			pci_write_config_byte(pdev, PCI_LATENCY_TIMER, val);			}		/* Enable interrupts at PCI bus interface chip (PFI) */		dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, (PFI_MODE_M_PDQ_INT_ENB | PFI_MODE_M_DMA_ENB));		}	return;	}/* * ======================== * = dfx_bus_config_check = * ======================== *    * Overview: *   Checks the configuration (burst size, full-duplex, etc.)  If any parameters *   are illegal, then this routine will set new defaults. *   * Returns: *   None *        * Arguments: *   bp - pointer to board information * * Functional Description: *   For Revision 1 FDDI EISA, Revision 2 or later FDDI EISA with rev E or later *   PDQ, and all FDDI PCI controllers, all values are legal. * * Return Codes: *   None * * Assumptions: *   dfx_adap_init has NOT been called yet so burst size and other items have *   not been set. * * Side Effects: *   None */static void __devinit dfx_bus_config_check(DFX_board_t *bp){	int	status;				/* return code from adapter port control call */	u32	slot_id;			/* EISA-bus hardware id (DEC3001, DEC3002,...) */	u32	host_data;			/* LW data returned from port control call */	DBG_printk("In dfx_bus_config_check...\n");	/* Configuration check only valid for EISA adapter */	if (bp->bus_type == DFX_BUS_TYPE_EISA)		{		dfx_port_read_long(bp, PI_ESIC_K_SLOT_ID, &slot_id);		/*		 * First check if revision 2 EISA controller.  Rev. 1 cards used		 * PDQ revision B, so no workaround needed in this case.  Rev. 3		 * cards used PDQ revision E, so no workaround needed in this		 * case, either.  Only Rev. 2 cards used either Rev. D or E		 * chips, so we must verify the chip revision on Rev. 2 cards.		 */		if (slot_id == DEFEA_PROD_ID_2)			{			/*			 * Revision 2 FDDI EISA controller found, so let's check PDQ			 * revision of adapter.			 */			status = dfx_hw_port_ctrl_req(bp,											PI_PCTRL_M_SUB_CMD,											PI_SUB_CMD_K_PDQ_REV_GET,											0,											&host_data);			if ((status != DFX_K_SUCCESS) || (host_data == 2))				{				/*				 * Either we couldn't determine the PDQ revision, or				 * we determined that it is at revision D.  In either case,				 * we need to implement the workaround.				 */				/* Ensure that the burst size is set to 8 longwords or less */				switch (bp->burst_size)					{					case PI_PDATA_B_DMA_BURST_SIZE_32:					case PI_PDATA_B_DMA_BURST_SIZE_16:						bp->burst_size = PI_PDATA_B_DMA_BURST_SIZE_8;						break;					default:						break;					}				/* Ensure that full-duplex mode is not enabled */				bp->full_duplex_enb = PI_SNMP_K_FALSE;				}			}		}	return;	}/* * =================== * = dfx_driver_init = * =================== *    * Overview: *   Initializes remaining adapter board structure information *   and makes sure adapter is in a safe state prior to dfx_open(). *   * Returns: *   Condition code *        * Arguments: *   dev - pointer to device information * * Functional Description: *   This function allocates additional resources such as the host memory *   blocks needed by the adapter (eg. descriptor and consumer blocks). *	 Remaining bus initialization steps are also completed.  The adapter *   is also reset so that it is in the DMA_UNAVAILABLE state.  The OS *   must call dfx_open() to open the adapter and bring it on-line. * * Return Codes: *   DFX_K_SUCCESS	- initialization succeeded *   DFX_K_FAILURE	- initialization failed - could not allocate memory *						or read adapter MAC address * * Assumptions: *   Memory allocated from kmalloc() call is physically contiguous, locked *   memory whose physical address equals its virtual address. * * Side Effects: *   Adapter is reset and should be in DMA_UNAVAILABLE state before *   returning from this routine. */static int __devinit dfx_driver_init(struct net_device *dev){	DFX_board_t *bp = (DFX_board_t *)dev->priv;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -