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

📄 defxx.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
 *   will be initialized and a global flag will be set to indicate that *   dfx_probe() has already been called. * *   However...the OS doesn't know that we've already initialized *   devices fddi1 and fddi2 so dfx_probe() gets called again and again *   until it reaches the end of the device list for FDDI (presently, *   fddi7).  It's important that the driver "pretend" to probe for *   devices fddi1 and fddi2 and return success.  Devices fddi3 *   through fddi7 will return failure since they weren't initialized. * *   This algorithm seems to work for the time being.  As other FDDI *   drivers are written for Linux, a more generic approach (perhaps *   similar to the Ethernet card approach) may need to be implemented. *    * Return Codes: *   0		 - This device (fddi0, fddi1, etc) configured successfully *   -ENODEV - No devices present, or no Digital FDDI EISA or PCI device *			   present for this device name * * Assumptions: *   For the time being, DEFXX.C is the only FDDI driver under Linux. *   As this assumption changes, this routine will likely be impacted. *   Also, it is assumed that no more than eight (8) FDDI controllers *   will be configured in the system (fddi0 through fddi7).  This *   routine will not allocate new device structures.  If more than *   eight FDDI controllers need to be configured, drivers/net/Space.c *   should be updated as well as the DFX_MAX_NUM_BOARDS constant in *   DEFXX.H. * * Side Effects: *   Device structures for FDDI adapters (fddi0, fddi1, etc) are *   initialized and the board resources are read and stored in *   the device structure. */__initfunc(int dfx_probe(	struct device *dev	))	{	int				i;				/* used in for loops */	int				version_disp;	/* was version info string already displayed? */	int				port_len;		/* length of port address range (in bytes) */	u16				port;			/* temporary I/O (port) address */	struct pci_dev *		pdev = NULL;		/* PCI device record */	u16				command;		/* PCI Configuration space Command register val */	u32				slot_id;		/* EISA hardware (slot) ID read from adapter */	DFX_board_t		*bp;			/* board pointer */	DBG_printk("In dfx_probe...\n");	/*	 * Verify whether we're going through dfx_probe() again	 *	 * If so, see if we're going through for a subsequent fddi device that	 * we've already initialized.  If we are, return success (0).  If not,	 * return failure (-ENODEV).	 */	version_disp = 0;				/* default to version string not displayed */	if (already_probed)		{		DBG_printk("Already entered dfx_probe\n");		if (dev != NULL)			if ((strncmp(dev->name, "fddi", 4) == 0) && (dev->base_addr != 0))				{				DBG_printk("In dfx_probe for fddi adapter (%s) we've already initialized it, so return success\n", dev->name);				return(0);				}		return(-ENODEV);		}	already_probed = 1;			/* set global flag */	/* 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)			{			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 */				}							port = (i << 12);					/* recalc base addr */			/* Verify port address range is not already being used */			port_len = PI_ESIC_K_CSR_IO_LEN;			if (check_region(port, port_len) == 0)				{				/* Allocate a new device structure for this adapter */				dev = dfx_alloc_device(dev, port);				if (dev != NULL)					{					/* Initialize board structure with bus-specific info */					bp = (DFX_board_t *) dev->priv;					bp->dev = dev;					bp->bus_type = DFX_BUS_TYPE_EISA;					if (dfx_driver_init(dev) == DFX_K_SUCCESS)						num_boards++;		/* only increment global board count on success */					else						dev->base_addr = 0;	/* clear port address field in device structure on failure */					}				}			else				printk("I/O range allocated to adapter (0x%X-0x%X) is already being used!\n", port, (port + port_len-1));			}		}	/* Scan for FDDI PCI controllers */	if (pci_present())						/* is PCI even present? */		while ((pdev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, pdev)))			{			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 */				}			/* Verify that I/O enable bit is set (PCI slot is enabled) */			pci_read_config_word(pdev, PCI_COMMAND, &command);			if ((command & PCI_COMMAND_IO) == 0)				printk("I/O enable bit not set!  Verify that slot is enabled\n");			else				{				/* Turn off memory mapped space and enable mastering */				command |= PCI_COMMAND_MASTER;				command &= ~PCI_COMMAND_MEMORY;				pci_write_config_word(pdev, PCI_COMMAND, command);				/* Get I/O base address from PCI Configuration Space */				port = pdev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK;				/* Verify port address range is not already being used */				port_len = PFI_K_CSR_IO_LEN;				if (check_region(port, port_len) == 0)					{					/* Allocate a new device structure for this adapter */					dev = dfx_alloc_device(dev, port);					if (dev != NULL)						{						/* Initialize board structure with bus-specific info */						bp = (DFX_board_t *) dev->priv;						bp->dev = dev;						bp->bus_type = DFX_BUS_TYPE_PCI;						bp->pci_dev = pdev;						if (dfx_driver_init(dev) == DFX_K_SUCCESS)							num_boards++;		/* only increment global board count on success */						else							dev->base_addr = 0;	/* clear port address field in device structure on failure */						}					}				else					printk("I/O range allocated to adapter (0x%X-0x%X) is already being used!\n", port, (port + port_len-1));				}			}	/*	 * If we're at this point we're going through dfx_probe() for the first	 * time.  Return success (0) if we've initialized 1 or more boards.	 * Otherwise, return failure (-ENODEV).	 */	if (num_boards > 0)		return(0);	else		return(-ENODEV);	}/* * ==================== * = dfx_alloc_device = * ==================== *    * Overview: *   Allocate new device structure for adapter *   * Returns: *   Pointer to device structure for this adapter or NULL if *   none are available or could not allocate memory for *   private board structure. *        * Arguments: *   dev    - pointer to device information for last device *   iobase - base I/O address of new adapter * * Functional Description: *   The algorithm for allocating a new device structure is *   fairly simple.  Since we're presently the only FDDI driver *   under Linux, we'll find the first device structure with an *   "fddi*" device name that's free.  If we run out of devices, *   we'll fail on error.  This is simpler than trying to *   allocate the memory for a new device structure, determine *   the next free number (beyond 7) and link it into the chain *   of devices.  A user can always modify drivers/net/Space.c *   to add new FDDI device structures if necessary. * *   Beyond finding a free FDDI device structure, this routine *   initializes most of the fields, resource tags, and dispatch *   pointers in the device structure and calls the common *   fddi_setup() routine to perform the rest of the device *   structure initialization. * * Return Codes: *   None * * Assumptions: *   If additional FDDI drivers are integrated into Linux, *   we'll likely need to use a different approach to *   allocate a device structure.  Perhaps one that is *   similar to what the Ethernet drivers use. * * Side Effects: *   None */__initfunc(struct device *dfx_alloc_device(	struct device	*dev,	u16				iobase	))	{	struct device *tmp_dev;		/* pointer to a device structure */	DBG_printk("In dfx_alloc_device...\n");	/* Find next free fddi entry */	for (tmp_dev = dev; tmp_dev != NULL; tmp_dev = tmp_dev->next)		if ((strncmp(tmp_dev->name, "fddi", 4) == 0) && (tmp_dev->base_addr == 0))			break;	if (tmp_dev == NULL)		{		printk("Could not find free FDDI device structure for this adapter!\n");		return(NULL);		}	DBG_printk("Device entry free, device name = %s\n", tmp_dev->name);	/* Allocate space for private board structure */	tmp_dev->priv = (void *) kmalloc(sizeof(DFX_board_t), GFP_KERNEL);	if (tmp_dev->priv == NULL)		{		printk("Could not allocate memory for private board structure!\n");		return(NULL);		}	memset(tmp_dev->priv, 0, sizeof(DFX_board_t));	/* clear structure */	/* Initialize new device structure */	tmp_dev->rmem_end	= 0;		/* shared memory isn't used */	tmp_dev->rmem_start	= 0;		/* shared memory isn't used */	tmp_dev->mem_end	= 0;		/* shared memory isn't used */	tmp_dev->mem_start	= 0;		/* shared memory isn't used */	tmp_dev->base_addr	= iobase;	/* save port (I/O) base address */	tmp_dev->irq		= 0;		/* set in dfx_bus_init() */	tmp_dev->if_port	= 0;		/* not applicable to FDDI adapters */	tmp_dev->dma		= 0;		/* Bus Master DMA doesn't require channel */	tmp_dev->get_stats				= &dfx_ctl_get_stats;	tmp_dev->open					= &dfx_open;	tmp_dev->stop					= &dfx_close;	tmp_dev->hard_start_xmit		= &dfx_xmt_queue_pkt;	tmp_dev->hard_header			= NULL;		/* set in fddi_setup() */	tmp_dev->rebuild_header			= NULL;		/* set in fddi_setup() */	tmp_dev->set_multicast_list		= &dfx_ctl_set_multicast_list;	tmp_dev->set_mac_address		= &dfx_ctl_set_mac_address;	tmp_dev->do_ioctl			= NULL;		/* not supported for now &&& */	tmp_dev->set_config			= NULL;		/* not supported for now &&& */	tmp_dev->hard_header_cache		= NULL;		/* not supported */	tmp_dev->header_cache_update		= NULL;		/* not supported */	tmp_dev->change_mtu			= NULL;		/* set in fddi_setup() */	/* Initialize remaining device structure information */	fddi_setup(tmp_dev);	return(tmp_dev);	}/* * ================ * = 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. */__initfunc(void dfx_bus_init(	struct 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;	/* 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;

⌨️ 快捷键说明

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