Annotation of Gnu-Mach/i386/i386at/gpl/linux/net/net_init.c, revision 1.1.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.