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

📄 skfddi.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	/*	 * If we're at this point we're going through skfp_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 {		printk("no SysKonnect FDDI adapter found\n");		return (-ENODEV);	}}				// skfp_probe/************************ * * Search the entire 'fddi' device list for a fixed probe. If a match isn't * found then check for an autoprobe or unused device location. If they * are not available then insert a new device structure at the end of * the current list. * ************************/static struct net_device *alloc_device(struct net_device *dev, u_long iobase){	struct net_device *adev = NULL;	int fixed = 0, new_dev = 0;	PRINTK(KERN_INFO "entering alloc_device\n");	if (!dev)		return dev;	num_fddi = fddi_dev_index(dev->name);	if (loading_module) {		num_fddi++;		dev = insert_device(dev, skfp_probe);		return dev;	}	while (1) {		if (((dev->base_addr == NO_ADDRESS) ||		     (dev->base_addr == 0)) && !adev) {			adev = dev;		} else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {			fixed = 1;		} else {			if (dev->next == NULL) {				new_dev = 1;			} else if (strncmp(dev->next->name, "fddi", 4) != 0) {				new_dev = 1;			}		}		if ((dev->next == NULL) || new_dev || fixed)			break;		dev = dev->next;		num_fddi++;	}			// while (1)	if (adev && !fixed) {		dev = adev;		num_fddi = fddi_dev_index(dev->name);		new_dev = 0;	}	if (((dev->next == NULL) && ((dev->base_addr != NO_ADDRESS) &&				     (dev->base_addr != 0)) && !fixed) ||	    new_dev) {		num_fddi++;	/* New device */		dev = insert_device(dev, skfp_probe);	}	if (dev) {		if (!dev->priv) {			/* Allocate space for private board structure */			dev->priv = (void *) kmalloc(sizeof(struct s_smc),						     GFP_KERNEL);			if (dev->priv == NULL) {				printk("%s: Could not allocate memory for",					dev->name);				printk(" private board structure!\n");				return (NULL);			}			/* clear structure */			memset(dev->priv, 0, sizeof(struct s_smc));		}	}	return dev;}				// alloc_device/************************ * * Initialize device structure * ************************/static void init_dev(struct net_device *dev, u_long iobase){	/* Initialize new device structure */	dev->rmem_end = 0;	/* shared memory isn't used */	dev->rmem_start = 0;	/* shared memory isn't used */	dev->mem_end = 0;	/* shared memory isn't used */	dev->mem_start = 0;	/* shared memory isn't used */	dev->base_addr = iobase;	/* save port (I/O) base address */	dev->if_port = 0;	/* not applicable to FDDI adapters */	dev->dma = 0;		/* Bus Master DMA doesn't require channel */	dev->irq = 0;	netif_start_queue(dev);	dev->get_stats = &skfp_ctl_get_stats;	dev->open = &skfp_open;	dev->stop = &skfp_close;	dev->hard_start_xmit = &skfp_send_pkt;	dev->hard_header = NULL;	/* set in fddi_setup() */	dev->rebuild_header = NULL;	/* set in fddi_setup() */	dev->set_multicast_list = &skfp_ctl_set_multicast_list;	dev->set_mac_address = &skfp_ctl_set_mac_address;	dev->do_ioctl = &skfp_ioctl;	dev->set_config = NULL;	/* not supported for now &&& */	dev->header_cache_update = NULL;	/* not supported */	dev->change_mtu = NULL;	/* set in fddi_setup() */	/* Initialize remaining device structure information */	fddi_setup(dev);}				// init_device/************************ * * If at end of fddi device list and can't use current entry, malloc * one up. If memory could not be allocated, print an error message. *************************/static struct net_device *insert_device(struct net_device *dev,				    int (*init) (struct net_device *)){	struct net_device *new;	int len;	PRINTK(KERN_INFO "entering insert_device\n");	len = sizeof(struct net_device) + sizeof(struct s_smc);	new = (struct net_device *) kmalloc(len, GFP_KERNEL);	if (new == NULL) {		printk("fddi%d: Device not initialised, insufficient memory\n",		       num_fddi);		return NULL;	} else {		memset((char *) new, 0, len);		new->priv = (struct s_smc *) (new + 1);		new->init = init;	/* initialisation routine */		if (!loading_module) {			new->next = dev->next;			dev->next = new;		}		/* create new device name */		if (num_fddi > 999) {			sprintf(new->name, "fddi????");		} else {			sprintf(new->name, "fddi%d", num_fddi);		}	}	return new;}				// insert_device/************************ * * Get the number of a "fddiX" string * ************************/static int fddi_dev_index(unsigned char *s){	int i = 0, j = 0;	for (; *s; s++) {		if (isdigit(*s)) {			j = 1;			i = (i * 10) + (*s - '0');		} else if (j)			break;	}	return i;}				// fddi_dev_index/************************ * * Used if loaded as module only. Link the device structures * together. Needed to release them all at unload. *************************/static void link_modules(struct net_device *dev, struct net_device *tmp){	struct net_device *p = dev;	if (p) {		while (((struct s_smc *) (p->priv))->os.next_module) {			p = ((struct s_smc *) (p->priv))->os.next_module;		}		if (dev != tmp) {			((struct s_smc *) (p->priv))->os.next_module = tmp;		} else {			((struct s_smc *) (p->priv))->os.next_module = NULL;		}	}	return;}				// link_modules/* * ==================== * = skfp_driver_init = * ==================== *    * Overview: *   Initializes remaining adapter board structure information *   and makes sure adapter is in a safe state prior to skfp_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. *   The adapter is also reset. The OS must call skfp_open() to open  *   the adapter and bring it on-line. * * Return Codes: *    0 - initialization succeeded *   -1 - initialization failed */static int skfp_driver_init(struct net_device *dev){	struct s_smc *smc = (struct s_smc *) dev->priv;	skfddi_priv *bp = PRIV(dev);	u8 val;			/* used for I/O read/writes */	PRINTK(KERN_INFO "entering skfp_driver_init\n");	// set the io address in private structures	bp->base_addr = dev->base_addr;	smc->hw.iop = dev->base_addr;	// Get the interrupt level from the PCI Configuration Table	val = dev->irq;	smc->hw.irq = val;	spin_lock_init(&bp->DriverLock);		// Allocate invalid frame	bp->LocalRxBuffer = pci_alloc_consistent(&bp->pdev, MAX_FRAME_SIZE, &bp->LocalRxBufferDMA);	if (!bp->LocalRxBuffer) {		printk("could not allocate mem for ");		printk("LocalRxBuffer: %d byte\n", MAX_FRAME_SIZE);		goto fail;	}	// Determine the required size of the 'shared' memory area.	bp->SharedMemSize = mac_drv_check_space();	PRINTK(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);	if (bp->SharedMemSize > 0) {		bp->SharedMemSize += 16;	// for descriptor alignment		bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev,							 bp->SharedMemSize,							 &bp->SharedMemDMA);		if (!bp->SharedMemSize) {			printk("could not allocate mem for ");			printk("hardware module: %ld byte\n",			       bp->SharedMemSize);			goto fail;		}		bp->SharedMemHeap = 0;	// Nothing used yet.	} else {		bp->SharedMemAddr = NULL;		bp->SharedMemHeap = 0;	}			// SharedMemSize > 0	memset(bp->SharedMemAddr, 0, bp->SharedMemSize);	card_stop(smc);		// Reset adapter.	PRINTK(KERN_INFO "mac_drv_init()..\n");	if (mac_drv_init(smc) != 0) {		PRINTK(KERN_INFO "mac_drv_init() failed.\n");		goto fail;	}	read_address(smc, NULL);	PRINTK(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",	       smc->hw.fddi_canon_addr.a[0],	       smc->hw.fddi_canon_addr.a[1],	       smc->hw.fddi_canon_addr.a[2],	       smc->hw.fddi_canon_addr.a[3],	       smc->hw.fddi_canon_addr.a[4],	       smc->hw.fddi_canon_addr.a[5]);	memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6);	smt_reset_defaults(smc, 0);	return (0);fail:	if (bp->SharedMemAddr) {		pci_free_consistent(&bp->pdev,				    bp->SharedMemSize,				    bp->SharedMemAddr,				    bp->SharedMemDMA);		bp->SharedMemAddr = NULL;	}	if (bp->LocalRxBuffer) {		pci_free_consistent(&bp->pdev, MAX_FRAME_SIZE,				    bp->LocalRxBuffer, bp->LocalRxBufferDMA);		bp->LocalRxBuffer = NULL;	}	return (-1);}				// skfp_driver_init/* * ============= * = skfp_open = * ============= *    * Overview: *   Opens the adapter *   * Returns: *   Condition code *        * Arguments: *   dev - pointer to device information * * Functional Description: *   This function brings the adapter to an operational state. * * Return Codes: *   0           - Adapter was successfully opened *   -EAGAIN - Could not register IRQ */static int skfp_open(struct net_device *dev){	struct s_smc *smc = (struct s_smc *) dev->priv;	PRINTK(KERN_INFO "entering skfp_open\n");	/* Register IRQ - support shared interrupts by passing device ptr */	if (request_irq(dev->irq, (void *) skfp_interrupt, SA_SHIRQ,			dev->name, dev)) {		printk("%s: Requested IRQ %d is busy\n", dev->name, dev->irq);		return (-EAGAIN);	}	/*	 * Set current address to factory MAC address	 *	 * Note: We've already done this step in skfp_driver_init.	 *       However, it's possible that a user has set a node	 *               address override, then closed and reopened the	 *               adapter.  Unless we reset the device address field	 *               now, we'll continue to use the existing modified	 *               address.	 */	read_address(smc, NULL);	memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6);	init_smt(smc, NULL);	smt_online(smc, 1);	STI_FBI();	MOD_INC_USE_COUNT;	/* Clear local multicast address tables */	mac_clear_multicast(smc);	/* Disable promiscuous filter settings */	mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);	return (0);}				// skfp_open/* * ============== * = skfp_close = * ============== *    * Overview: *   Closes the device/module. *   * Returns: *   Condition code *        * Arguments: *   dev - pointer to device information * * Functional Description: *   This routine closes the adapter and brings it to a safe state. *   The interrupt service routine is deregistered with the OS. *   The adapter can be opened again with another call to skfp_open(). * * Return Codes: *   Always return 0. * * Assumptions: *   No further requests for this adapter are made after this routine is *   called.  skfp_open() can be called to reset and reinitialize the *   adapter. */static int skfp_close(struct net_device *dev){	struct s_smc *smc = (struct s_smc *) dev->priv;	struct sk_buff *skb;	skfddi_priv *bp = PRIV(dev);	CLI_FBI();	smt_reset_defaults(smc, 1);	card_stop(smc);	mac_drv_clear_tx_queue(smc);	mac_drv_clear_rx_queue(smc);	netif_stop_queue(dev);

⌨️ 快捷键说明

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