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

📄 lanstreamer.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *   lanstreamer.c -- driver for the IBM Auto LANStreamer PCI Adapter * *  Written By: Mike Sullivan, IBM Corporation * *  Copyright (C) 1999 IBM Corporation * *  Linux driver for IBM PCI tokenring cards based on the LanStreamer MPC *  chipset.  * *  This driver is based on the olympic driver for IBM PCI TokenRing cards (Pit/Pit-Phy/Olympic *  chipsets) written  by: *      1999 Peter De Schrijver All Rights Reserved *	1999 Mike Phillips (phillim@amtrak.com) * *  Base Driver Skeleton: *      Written 1993-94 by Donald Becker. * *      Copyright 1993 United States Government as represented by the *      Director, National Security Agency. * * This program is free software; you can redistribute it and/or modify       * it under the terms of the GNU General Public License as published by       * the Free Software Foundation; either version 2 of the License, or          * (at your option) any later version.                                        *                                                                            * This program is distributed in the hope that it will be useful,            * but WITHOUT ANY WARRANTY; without even the implied warranty of             * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              * GNU General Public License for more details.                               *                                                                            * NO WARRANTY                                                                * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR         * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT       * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,       * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is     * solely responsible for determining the appropriateness of using and        * distributing the Program and assumes all risks associated with its         * exercise of rights under this Agreement, including but not limited to      * the risks and costs of program errors, damage to or loss of data,          * programs or equipment, and unavailability or interruption of operations.   *                                                                            * DISCLAIMER OF LIABILITY                                                    * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY    * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL         * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR      * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE     * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED   * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES              *                                                                            * You should have received a copy of the GNU General Public License          * along with this program; if not, write to the Free Software                * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  *                                                                            *  *  12/10/99 - Alpha Release 0.1.0 *            First release to the public *  03/03/00 - Merged to kernel, indented -kr -i8 -bri0, fixed some missing *		malloc free checks, reviewed code. <alan@redhat.com> *  03/13/00 - Added spinlocks for smp *  03/08/01 - Added support for module_init() and module_exit() *   *  To Do: * * *  If Problems do Occur *  Most problems can be rectified by either closing and opening the interface *  (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult *  if compiled into the kernel). *//* Change STREAMER_DEBUG to 1 to get verbose, and I mean really verbose, messages */#define STREAMER_DEBUG 0#define STREAMER_DEBUG_PACKETS 0/* Change STREAMER_NETWORK_MONITOR to receive mac frames through the arb channel. * Will also create a /proc/net/streamer_tr entry if proc_fs is compiled into the * kernel. * Intended to be used to create a ring-error reporting network module  * i.e. it will give you the source address of beaconers on the ring  */#define STREAMER_NETWORK_MONITOR 0#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/timer.h>#include <linux/in.h>#include <linux/ioport.h>#include <linux/string.h>#include <linux/proc_fs.h>#include <linux/ptrace.h>#include <linux/skbuff.h>#include <linux/interrupt.h>#include <linux/delay.h>#include <linux/netdevice.h>#include <linux/trdevice.h>#include <linux/stddef.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/spinlock.h>#include <net/checksum.h>#include <asm/io.h>#include <asm/system.h>#include <asm/bitops.h>#include "lanstreamer.h"/* I've got to put some intelligence into the version number so that Peter and I know * which version of the code somebody has got.  * Version Number = a.b.c.d  where a.b.c is the level of code and d is the latest author. * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike *  * Official releases will only have an a.b.c version number format. */static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan";static struct pci_device_id streamer_pci_tbl[] __initdata = {	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},	{}	/* terminating entry */};MODULE_DEVICE_TABLE(pci,streamer_pci_tbl);static char *open_maj_error[] = {	"No error", "Lobe Media Test", "Physical Insertion",	"Address Verification", "Neighbor Notification (Ring Poll)",	"Request Parameters", "FDX Registration Request",	"FDX Lobe Media Test", "FDX Duplicate Address Check",	"Unknown stage"};static char *open_min_error[] = {	"No error", "Function Failure", "Signal Lost", "Wire Fault",	"Ring Speed Mismatch", "Timeout", "Ring Failure", "Ring Beaconing",	"Duplicate Node Address", "Request Parameters", "Remove Received",	"Reserved", "Reserved", "No Monitor Detected for RPL",	"Monitor Contention failer for RPL", "FDX Protocol Error"};/* Module paramters *//* Ring Speed 0,4,16 * 0 = Autosense          * 4,16 = Selected speed only, no autosense * This allows the card to be the first on the ring * and become the active monitor. * * WARNING: Some hubs will allow you to insert * at the wrong speed */static int ringspeed[STREAMER_MAX_ADAPTERS] = { 0, };MODULE_PARM(ringspeed, "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");/* Packet buffer size */static int pkt_buf_sz[STREAMER_MAX_ADAPTERS] = { 0, };MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");/* Message Level */static int message_level[STREAMER_MAX_ADAPTERS] = { 1, };MODULE_PARM(message_level,	    "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");static int streamer_reset(struct net_device *dev);static int streamer_open(struct net_device *dev);static int streamer_xmit(struct sk_buff *skb, struct net_device *dev);static int streamer_close(struct net_device *dev);static void streamer_set_rx_mode(struct net_device *dev);static void streamer_interrupt(int irq, void *dev_id,			       struct pt_regs *regs);static struct net_device_stats *streamer_get_stats(struct net_device *dev);static int streamer_set_mac_address(struct net_device *dev, void *addr);static void streamer_arb_cmd(struct net_device *dev);static int streamer_change_mtu(struct net_device *dev, int mtu);static void streamer_srb_bh(struct net_device *dev);static void streamer_asb_bh(struct net_device *dev);#if STREAMER_NETWORK_MONITOR#ifdef CONFIG_PROC_FSstatic int streamer_proc_info(char *buffer, char **start, off_t offset,			      int length, int *eof, void *data);static int sprintf_info(char *buffer, struct net_device *dev);struct streamer_private *dev_streamer=NULL;#endif#endifstatic int __devinit streamer_init_one(struct pci_dev *pdev,				       const struct pci_device_id *ent){  struct net_device *dev=NULL;	struct streamer_private *streamer_priv;  __u32 pio_start, pio_end, pio_flags, pio_len;  __u32 mmio_start, mmio_end, mmio_flags, mmio_len;  int rc=0;  static int card_no=-1;#if STREAMER_DEBUG  printk("lanstreamer::streamer_init_one, entry pdev %p\n",pdev);#endif				card_no++;  dev=init_trdev(dev, sizeof(*streamer_priv));  if(dev==NULL) {				printk(KERN_ERR "lanstreamer: out of memory.\n");    return -ENOMEM;			}			SET_MODULE_OWNER(dev);  streamer_priv=dev->priv;#if STREAMER_NETWORK_MONITOR#ifdef CONFIG_PROC_FS  if (!dev_streamer) {    create_proc_read_entry("net/streamer_tr",0,0,streamer_proc_info,NULL);   }  streamer_priv->next=dev_streamer;  dev_streamer=streamer_priv;#endif#endif    if (pci_enable_device(pdev)) {    printk(KERN_ERR "lanstreamer: unable to enable pci device\n");    rc=-EIO;    goto err_out;  }    pci_set_master(pdev);    pio_start = pci_resource_start(pdev, 0);  pio_end = pci_resource_end(pdev, 0);  pio_flags = pci_resource_flags(pdev, 0);  pio_len = pci_resource_len(pdev, 0);    mmio_start = pci_resource_start(pdev, 1);  mmio_end = pci_resource_end(pdev, 1);  mmio_flags = pci_resource_flags(pdev, 1);  mmio_len = pci_resource_len(pdev, 1);  #if STREAMER_DEBUG  printk("lanstreamer: pio_start %x pio_end %x pio_len %x pio_flags %x\n",	 pio_start, pio_end, pio_len, pio_flags);  printk("lanstreamer: mmio_start %x mmio_end %x mmio_len %x mmio_flags %x\n",	 mmio_start, mmio_end, mmio_flags, mmio_len);#endif  if (!request_region(pio_start, pio_len, "lanstreamer")) {    printk(KERN_ERR "lanstreamer: unable to get pci io addr %x\n",pio_start);    rc= -EBUSY;    goto err_out;  }  if (!request_mem_region(mmio_start, mmio_len, "lanstreamer")) {    printk(KERN_ERR "lanstreamer: unable to get pci mmio addr %x\n",mmio_start);    rc= -EBUSY;    goto err_out_free_pio;  }  streamer_priv->streamer_mmio=ioremap(mmio_start, mmio_len);  if (streamer_priv->streamer_mmio == NULL) {    printk(KERN_ERR "lanstreamer: unable to remap MMIO %x\n",mmio_start);    rc= -EIO;    goto err_out_free_mmio;			}  init_waitqueue_head(&streamer_priv->srb_wait);  init_waitqueue_head(&streamer_priv->trb_wait);			dev->open = &streamer_open;			dev->hard_start_xmit = &streamer_xmit;			dev->change_mtu = &streamer_change_mtu;			dev->stop = &streamer_close;			dev->do_ioctl = NULL;			dev->set_multicast_list = &streamer_set_rx_mode;			dev->get_stats = &streamer_get_stats;			dev->set_mac_address = &streamer_set_mac_address;  dev->irq = pdev->irq;  dev->base_addr=pio_start;    streamer_priv->streamer_card_name = (char *)pdev->resource[0].name;  streamer_priv->pci_dev=pdev;    if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000))    streamer_priv->pkt_buf_sz = PKT_BUF_SZ;  else    streamer_priv->pkt_buf_sz = pkt_buf_sz[card_no];    streamer_priv->streamer_ring_speed = ringspeed[card_no];  streamer_priv->streamer_message_level = message_level[card_no];  pci_set_drvdata(pdev, dev);  spin_lock_init(&streamer_priv->streamer_lock);    printk("%s \n", version);  printk("%s: %s. I/O at %hx, MMIO at %p, using irq %d\n",dev->name,	 streamer_priv->streamer_card_name,	 (unsigned int) dev->base_addr,	 streamer_priv->streamer_mmio, 	 dev->irq);  if (!streamer_reset(dev)) {    return 0;  }  iounmap(streamer_priv->streamer_mmio);err_out_free_mmio:  release_mem_region(mmio_start, mmio_len);err_out_free_pio:  release_region(pio_start, pio_len);err_out:  unregister_trdev(dev);  kfree(dev);#if STREAMER_DEBUG  printk("lanstreamer: Exit error %x\n",rc);#endif  return rc;}static void __devexit streamer_remove_one(struct pci_dev *pdev) {  struct net_device *dev=pci_get_drvdata(pdev);  struct streamer_private *streamer_priv;#if STREAMER_DEBUG  printk("lanstreamer::streamer_remove_one entry pdev %p\n",pdev);#endif  if (dev == NULL) {    printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev is NULL\n");    return;		}  streamer_priv=dev->priv;  if (streamer_priv == NULL) {    printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev->priv is NULL\n");    return;	}#if STREAMER_NETWORK_MONITOR#ifdef CONFIG_PROC_FS  {    struct streamer_private *slast;    struct streamer_private *scurrent;    if (streamer_priv == dev_streamer) {      dev_streamer=dev_streamer->next;    } else {      for(slast=scurrent=dev_streamer; dev_streamer; slast=scurrent, scurrent=scurrent->next) {	if (scurrent == streamer_priv) {	  slast->next=scurrent->next;	  break;	}      }    }    if (!dev_streamer) {      remove_proc_entry("net/streamer_tr", NULL);

⌨️ 快捷键说明

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