Annotation of Gnu-Mach/i386/i386at/gpl/linux/net/net_init.c, revision 1.1

1.1     ! root        1: /* netdrv_init.c: Initialization for network devices. */
        !             2: /*
        !             3:        Written 1993,1994,1995 by Donald Becker.
        !             4: 
        !             5:        The author may be reached as [email protected] or
        !             6:        C/O Center of Excellence in Space Data and Information Sciences
        !             7:                Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
        !             8: 
        !             9:        This file contains the initialization for the "pl14+" style ethernet
        !            10:        drivers.  It should eventually replace most of drivers/net/Space.c.
        !            11:        It's primary advantage is that it's able to allocate low-memory buffers.
        !            12:        A secondary advantage is that the dangerous NE*000 netcards can reserve
        !            13:        their I/O port region before the SCSI probes start.
        !            14: 
        !            15:        Modifications/additions by Bjorn Ekwall <[email protected]>:
        !            16:                ethdev_index[MAX_ETH_CARDS]
        !            17:                register_netdev() / unregister_netdev()
        !            18:                
        !            19:        Modifications by Wolfgang Walter
        !            20:                Use dev_close cleanly so we always shut things down tidily.
        !            21:                
        !            22:        Changed 29/10/95, Alan Cox to pass sockaddr's around for mac addresses.
        !            23: */
        !            24: 
        !            25: #include <linux/config.h>
        !            26: #include <linux/kernel.h>
        !            27: #include <linux/sched.h>
        !            28: #include <linux/types.h>
        !            29: #include <linux/fs.h>
        !            30: #include <linux/malloc.h>
        !            31: #include <linux/if_ether.h>
        !            32: #include <linux/if_arp.h>
        !            33: #include <linux/string.h>
        !            34: #include <linux/netdevice.h>
        !            35: #include <linux/etherdevice.h>
        !            36: #include <linux/trdevice.h>
        !            37: #ifdef CONFIG_NET_ALIAS
        !            38: #include <linux/net_alias.h>
        !            39: #endif
        !            40: 
        !            41: /* The network devices currently exist only in the socket namespace, so these
        !            42:    entries are unused.  The only ones that make sense are
        !            43:     open       start the ethercard
        !            44:     close      stop  the ethercard
        !            45:     ioctl      To get statistics, perhaps set the interface port (AUI, BNC, etc.)
        !            46:    One can also imagine getting raw packets using
        !            47:     read & write
        !            48:    but this is probably better handled by a raw packet socket.
        !            49: 
        !            50:    Given that almost all of these functions are handled in the current
        !            51:    socket-based scheme, putting ethercard devices in /dev/ seems pointless.
        !            52:    
        !            53:    [Removed all support for /dev network devices. When someone adds
        !            54:     streams then by magic we get them, but otherwise they are un-needed
        !            55:        and a space waste]
        !            56: */
        !            57: 
        !            58: /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
        !            59: #define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
        !            60: static struct device *ethdev_index[MAX_ETH_CARDS];
        !            61: 
        !            62: /* Fill in the fields of the device structure with ethernet-generic values.
        !            63: 
        !            64:    If no device structure is passed, a new one is constructed, complete with
        !            65:    a SIZEOF_PRIVATE private data area.
        !            66: 
        !            67:    If an empty string area is passed as dev->name, or a new structure is made,
        !            68:    a new name string is constructed.  The passed string area should be 8 bytes
        !            69:    long.
        !            70:  */
        !            71: 
        !            72: struct device *
        !            73: init_etherdev(struct device *dev, int sizeof_priv)
        !            74: {
        !            75:        int new_device = 0;
        !            76:        int i;
        !            77: 
        !            78:        /* Use an existing correctly named device in Space.c:dev_base. */
        !            79:        if (dev == NULL) {
        !            80:                int alloc_size = sizeof(struct device) + sizeof("eth%d  ")
        !            81:                        + sizeof_priv + 3;
        !            82:                struct device *cur_dev;
        !            83:                char pname[8];          /* Putative name for the device.  */
        !            84: 
        !            85:                for (i = 0; i < MAX_ETH_CARDS; ++i)
        !            86:                        if (ethdev_index[i] == NULL) {
        !            87:                                sprintf(pname, "eth%d", i);
        !            88:                                for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
        !            89:                                        if (strcmp(pname, cur_dev->name) == 0) {
        !            90:                                                dev = cur_dev;
        !            91:                                                dev->init = NULL;
        !            92:                                                sizeof_priv = (sizeof_priv + 3) & ~3;
        !            93:                                                dev->priv = sizeof_priv
        !            94:                                                          ? kmalloc(sizeof_priv, GFP_KERNEL)
        !            95:                                                          :     NULL;
        !            96:                                                if (dev->priv) memset(dev->priv, 0, sizeof_priv);
        !            97:                                                goto found;
        !            98:                                        }
        !            99:                        }
        !           100: 
        !           101:                alloc_size &= ~3;               /* Round to dword boundary. */
        !           102: 
        !           103:                dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
        !           104:                memset(dev, 0, alloc_size);
        !           105:                if (sizeof_priv)
        !           106:                        dev->priv = (void *) (dev + 1);
        !           107:                dev->name = sizeof_priv + (char *)(dev + 1);
        !           108:                new_device = 1;
        !           109:        }
        !           110: 
        !           111:        found:                                          /* From the double loop above. */
        !           112: 
        !           113:        if (dev->name &&
        !           114:                ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
        !           115:                for (i = 0; i < MAX_ETH_CARDS; ++i)
        !           116:                        if (ethdev_index[i] == NULL) {
        !           117:                                sprintf(dev->name, "eth%d", i);
        !           118:                                ethdev_index[i] = dev;
        !           119:                                break;
        !           120:                        }
        !           121:        }
        !           122: 
        !           123:        ether_setup(dev);       /* Hmmm, should this be called here? */
        !           124:        
        !           125:        if (new_device) {
        !           126:                /* Append the device to the device queue. */
        !           127:                struct device **old_devp = &dev_base;
        !           128:                while ((*old_devp)->next)
        !           129:                        old_devp = & (*old_devp)->next;
        !           130:                (*old_devp)->next = dev;
        !           131:                dev->next = 0;
        !           132:        }
        !           133:        return dev;
        !           134: }
        !           135: 
        !           136: 
        !           137: static int eth_mac_addr(struct device *dev, void *p)
        !           138: {
        !           139:        struct sockaddr *addr=p;
        !           140:        if(dev->start)
        !           141:                return -EBUSY;
        !           142:        memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
        !           143:        return 0;
        !           144: }
        !           145: 
        !           146: void ether_setup(struct device *dev)
        !           147: {
        !           148:        int i;
        !           149: 
        !           150:        /* Fill in the fields of the device structure with ethernet-generic values.
        !           151:           This should be in a common file instead of per-driver.  */
        !           152:        for (i = 0; i < DEV_NUMBUFFS; i++)
        !           153:                skb_queue_head_init(&dev->buffs[i]);
        !           154: 
        !           155:        /* register boot-defined "eth" devices */
        !           156:        if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
        !           157:                i = simple_strtoul(dev->name + 3, NULL, 0);
        !           158:                if (ethdev_index[i] == NULL) {
        !           159:                        ethdev_index[i] = dev;
        !           160:                }
        !           161:                else if (dev != ethdev_index[i]) {
        !           162:                        /* Really shouldn't happen! */
        !           163: #ifdef MACH
        !           164:                        panic ("ether_setup: Ouch! Someone else took %s, i = %d\n",
        !           165:                                   dev->name, i);
        !           166: #else
        !           167:                        printk("ether_setup: Ouch! Someone else took %s, i = %d\n",
        !           168:                                dev->name, i);
        !           169: #endif
        !           170:                }
        !           171:        }
        !           172: 
        !           173: #ifndef MACH
        !           174:        dev->hard_header        = eth_header;
        !           175:        dev->rebuild_header     = eth_rebuild_header;
        !           176:        dev->set_mac_address    = eth_mac_addr;
        !           177:        dev->header_cache_bind  = eth_header_cache_bind;
        !           178:        dev->header_cache_update= eth_header_cache_update;
        !           179: #endif
        !           180: 
        !           181:        dev->type               = ARPHRD_ETHER;
        !           182:        dev->hard_header_len    = ETH_HLEN;
        !           183:        dev->mtu                = 1500; /* eth_mtu */
        !           184:        dev->addr_len           = ETH_ALEN;
        !           185:        dev->tx_queue_len       = 100;  /* Ethernet wants good queues */        
        !           186:        
        !           187:        memset(dev->broadcast,0xFF, ETH_ALEN);
        !           188: 
        !           189:        /* New-style flags. */
        !           190:        dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
        !           191:        dev->family             = AF_INET;
        !           192:        dev->pa_addr    = 0;
        !           193:        dev->pa_brdaddr = 0;
        !           194:        dev->pa_mask    = 0;
        !           195:        dev->pa_alen    = 4;
        !           196: }
        !           197: 
        !           198: #ifdef CONFIG_TR
        !           199: 
        !           200: void tr_setup(struct device *dev)
        !           201: {
        !           202:        int i;
        !           203:        /* Fill in the fields of the device structure with ethernet-generic values.
        !           204:           This should be in a common file instead of per-driver.  */
        !           205:        for (i = 0; i < DEV_NUMBUFFS; i++)
        !           206:                skb_queue_head_init(&dev->buffs[i]);
        !           207: 
        !           208:        dev->hard_header        = tr_header;
        !           209:        dev->rebuild_header     = tr_rebuild_header;
        !           210: 
        !           211:        dev->type               = ARPHRD_IEEE802;
        !           212:        dev->hard_header_len    = TR_HLEN;
        !           213:        dev->mtu                = 2000; /* bug in fragmenter...*/
        !           214:        dev->addr_len           = TR_ALEN;
        !           215:        dev->tx_queue_len       = 100;  /* Long queues on tr */
        !           216:        
        !           217:        memset(dev->broadcast,0xFF, TR_ALEN);
        !           218: 
        !           219:        /* New-style flags. */
        !           220:        dev->flags              = IFF_BROADCAST;
        !           221:        dev->family             = AF_INET;
        !           222:        dev->pa_addr    = 0;
        !           223:        dev->pa_brdaddr = 0;
        !           224:        dev->pa_mask    = 0;
        !           225:        dev->pa_alen    = 4;
        !           226: }
        !           227: 
        !           228: #endif
        !           229: 
        !           230: int ether_config(struct device *dev, struct ifmap *map)
        !           231: {
        !           232:        if (map->mem_start != (u_long)(-1))
        !           233:                dev->mem_start = map->mem_start;
        !           234:        if (map->mem_end != (u_long)(-1))
        !           235:                dev->mem_end = map->mem_end;
        !           236:        if (map->base_addr != (u_short)(-1))
        !           237:                dev->base_addr = map->base_addr;
        !           238:        if (map->irq != (u_char)(-1))
        !           239:                dev->irq = map->irq;
        !           240:        if (map->dma != (u_char)(-1))
        !           241:                dev->dma = map->dma;
        !           242:        if (map->port != (u_char)(-1))
        !           243:                dev->if_port = map->port;
        !           244:        return 0;
        !           245: }
        !           246: 
        !           247: int register_netdev(struct device *dev)
        !           248: {
        !           249:        struct device *d = dev_base;
        !           250:        unsigned long flags;
        !           251:        int i=MAX_ETH_CARDS;
        !           252: 
        !           253:        save_flags(flags);
        !           254:        cli();
        !           255: 
        !           256:        if (dev && dev->init) {
        !           257:                if (dev->name &&
        !           258:                        ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
        !           259:                        for (i = 0; i < MAX_ETH_CARDS; ++i)
        !           260:                                if (ethdev_index[i] == NULL) {
        !           261:                                        sprintf(dev->name, "eth%d", i);
        !           262:                                        printk("loading device '%s'...\n", dev->name);
        !           263:                                        ethdev_index[i] = dev;
        !           264:                                        break;
        !           265:                                }
        !           266:                }
        !           267: 
        !           268:                sti();  /* device probes assume interrupts enabled */
        !           269:                if (dev->init(dev) != 0) {
        !           270:                    if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
        !           271:                        restore_flags(flags);
        !           272:                        return -EIO;
        !           273:                }
        !           274:                cli();
        !           275: 
        !           276:                /* Add device to end of chain */
        !           277:                if (dev_base) {
        !           278:                        while (d->next)
        !           279:                                d = d->next;
        !           280:                        d->next = dev;
        !           281:                }
        !           282:                else
        !           283:                        dev_base = dev;
        !           284:                dev->next = NULL;
        !           285:        }
        !           286:        restore_flags(flags);
        !           287:        return 0;
        !           288: }
        !           289: 
        !           290: void unregister_netdev(struct device *dev)
        !           291: {
        !           292:        struct device *d = dev_base;
        !           293:        unsigned long flags;
        !           294:        int i;
        !           295: 
        !           296:        save_flags(flags);
        !           297:        cli();
        !           298: 
        !           299:        if (dev == NULL) 
        !           300:        {
        !           301:                printk("was NULL\n");
        !           302:                restore_flags(flags);
        !           303:                return;
        !           304:        }
        !           305:        /* else */
        !           306:        if (dev->start)
        !           307:                printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
        !           308: 
        !           309:        /*
        !           310:         *      must jump over main_device+aliases
        !           311:         *      avoid alias devices unregistration so that only
        !           312:         *      net_alias module manages them
        !           313:         */
        !           314: #ifdef CONFIG_NET_ALIAS                
        !           315:        if (dev_base == dev)
        !           316:                dev_base = net_alias_nextdev(dev);
        !           317:        else
        !           318:        {
        !           319:                while(d && (net_alias_nextdev(d) != dev)) /* skip aliases */
        !           320:                        d = net_alias_nextdev(d);
        !           321:          
        !           322:                if (d && (net_alias_nextdev(d) == dev))
        !           323:                {
        !           324:                        /*
        !           325:                         *      Critical: Bypass by consider devices as blocks (maindev+aliases)
        !           326:                         */
        !           327:                        net_alias_nextdev_set(d, net_alias_nextdev(dev)); 
        !           328:                }
        !           329: #else
        !           330:        if (dev_base == dev)
        !           331:                dev_base = dev->next;
        !           332:        else 
        !           333:        {
        !           334:                while (d && (d->next != dev))
        !           335:                        d = d->next;
        !           336:                
        !           337:                if (d && (d->next == dev)) 
        !           338:                {
        !           339:                        d->next = dev->next;
        !           340:                }
        !           341: #endif
        !           342:                else 
        !           343:                {
        !           344:                        printk("unregister_netdev: '%s' not found\n", dev->name);
        !           345:                        restore_flags(flags);
        !           346:                        return;
        !           347:                }
        !           348:        }
        !           349:        for (i = 0; i < MAX_ETH_CARDS; ++i) 
        !           350:        {
        !           351:                if (ethdev_index[i] == dev) 
        !           352:                {
        !           353:                        ethdev_index[i] = NULL;
        !           354:                        break;
        !           355:                }
        !           356:        }
        !           357: 
        !           358:        restore_flags(flags);
        !           359: 
        !           360:        /*
        !           361:         *      You can i.e use a interfaces in a route though it is not up.
        !           362:         *      We call close_dev (which is changed: it will down a device even if
        !           363:         *      dev->flags==0 (but it will not call dev->stop if IFF_UP
        !           364:         *      is not set).
        !           365:         *      This will call notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev),
        !           366:         *      dev_mc_discard(dev), ....
        !           367:         */
        !           368:         
        !           369:        dev_close(dev);
        !           370: }
        !           371: 
        !           372: 
        !           373: /*
        !           374:  * Local variables:
        !           375:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
        !           376:  *  version-control: t
        !           377:  *  kept-new-versions: 5
        !           378:  *  tab-width: 4
        !           379:  * End:
        !           380:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.