Annotation of linux/net/tcp/dev.c, revision 1.1

1.1     ! root        1: /* dev.c */
        !             2: /*
        !             3:     Copyright (C) 1992  Ross Biro
        !             4: 
        !             5:     This program is free software; you can redistribute it and/or modify
        !             6:     it under the terms of the GNU General Public License as published by
        !             7:     the Free Software Foundation; either version 2, or (at your option)
        !             8:     any later version.
        !             9: 
        !            10:     This program is distributed in the hope that it will be useful,
        !            11:     but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            13:     GNU General Public License for more details.
        !            14: 
        !            15:     You should have received a copy of the GNU General Public License
        !            16:     along with this program; if not, write to the Free Software
        !            17:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
        !            18: 
        !            19:     The Author may be reached as bir7@leland.stanford.edu or
        !            20:     C/O Department of Mathematics; Stanford University; Stanford, CA 94305
        !            21: */
        !            22: 
        !            23: #include <asm/segment.h>
        !            24: #include <asm/system.h>
        !            25: #include <linux/types.h>
        !            26: #include <linux/kernel.h>
        !            27: #include <linux/sched.h>
        !            28: #include <linux/string.h>
        !            29: #include <linux/mm.h>
        !            30: #include <linux/socket.h>
        !            31: #include <netinet/in.h>
        !            32: #include <asm/memory.h>
        !            33: #include "dev.h"
        !            34: #include "eth.h"
        !            35: #include "timer.h"
        !            36: #include "ip.h"
        !            37: #include "tcp.h"
        !            38: #include "sock.h"
        !            39: #include <linux/errno.h>
        !            40: #include "arp.h"
        !            41: 
        !            42: #undef DEV_DEBUG
        !            43: #ifdef DEV_DEBUG
        !            44: #define PRINTK printk
        !            45: #else
        !            46: #define PRINTK dummy_routine
        !            47: #endif
        !            48: 
        !            49: 
        !            50: static  unsigned long
        !            51: min(unsigned long a, unsigned long b)
        !            52: {
        !            53:    if (a < b) return (a);
        !            54:    return (b);
        !            55: }
        !            56: 
        !            57: void
        !            58: dev_add_pack (struct packet_type *pt)
        !            59: {
        !            60:    struct packet_type *p1;
        !            61:    pt->next = ptype_base;
        !            62: 
        !            63:    /* see if we need to copy it. */
        !            64:    for (p1 = ptype_base; p1 != NULL; p1 = p1->next)
        !            65:      {
        !            66:        if (p1->type == pt->type)
        !            67:          {
        !            68:             pt->copy = 1;
        !            69:             break;
        !            70:          }
        !            71:      }
        !            72: 
        !            73:    ptype_base = pt;
        !            74:    
        !            75: }
        !            76: 
        !            77: void
        !            78: dev_remove_pack (struct packet_type *pt)
        !            79: {
        !            80:    struct packet_type *lpt, *pt1;
        !            81:    if (pt == ptype_base)
        !            82:      {
        !            83:        ptype_base = pt->next;
        !            84:        return;
        !            85:      }
        !            86: 
        !            87:    lpt = NULL;
        !            88: 
        !            89:    for (pt1 = ptype_base; pt1->next != NULL; pt1=pt1->next)
        !            90:      {
        !            91:        if (pt1->next == pt )
        !            92:          {
        !            93:             cli();
        !            94:             if (!pt->copy && lpt) 
        !            95:               lpt->copy = 0;
        !            96:             pt1->next = pt->next;
        !            97:             sti();
        !            98:             return;
        !            99:          }
        !           100: 
        !           101:        if (pt1->next -> type == pt ->type)
        !           102:          {
        !           103:             lpt = pt1->next;
        !           104:          }
        !           105:      }
        !           106: }
        !           107: 
        !           108: struct device *
        !           109: get_dev (char *name)
        !           110: {
        !           111:    struct device *dev;
        !           112:    for (dev = dev_base; dev != NULL; dev=dev->next)
        !           113:      {
        !           114:        if (strcmp (dev->name, name) == 0) return (dev);
        !           115:      }
        !           116:    return (NULL);
        !           117: }
        !           118: 
        !           119: void
        !           120: dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
        !           121: {
        !           122:   struct sk_buff *skb2;
        !           123:   PRINTK ("eth_queue_xmit (skb=%X, dev=%X, pri = %d)\n", skb, dev, pri);
        !           124:   skb->dev = dev;
        !           125:   if (pri < 0 || pri >= DEV_NUMBUFFS)
        !           126:     {
        !           127:        printk ("bad priority in dev_queue_xmit.\n");
        !           128:        pri = 1;
        !           129:     }
        !           130: 
        !           131:   if (dev->hard_start_xmit(skb, dev) == 0)
        !           132:     {
        !           133:        return;
        !           134:     }
        !           135: 
        !           136:   if (skb->next != NULL)
        !           137:     {
        !           138:        printk ("retransmitted packet still on queue. \n");
        !           139:        return;
        !           140:     }
        !           141: 
        !           142:   /* used to say it is not currently on a send list. */
        !           143:   skb->next = NULL;
        !           144: 
        !           145: 
        !           146:   /* put skb into a bidirectional circular linked list. */
        !           147:   PRINTK ("eth_queue dev->buffs[%d]=%X\n",pri, dev->buffs[pri]);
        !           148:   /* interrupts should already be cleared by hard_start_xmit. */
        !           149:   cli();
        !           150:   if (dev->buffs[pri] == NULL)
        !           151:     {
        !           152:       dev->buffs[pri]=skb;
        !           153:       skb->next = skb;
        !           154:       skb->prev = skb;
        !           155:     }
        !           156:   else
        !           157:     {
        !           158:       skb2=dev->buffs[pri];
        !           159:       skb->next = skb2;
        !           160:       skb->prev = skb2->prev;
        !           161:       skb->next->prev = skb;
        !           162:       skb->prev->next = skb;
        !           163:     }
        !           164:   sti();
        !           165: 
        !           166: }
        !           167: 
        !           168: 
        !           169: /* this routine now just gets the data out of the card and returns.
        !           170:    it's return values now mean.
        !           171: 
        !           172:    1 <- exit even if you have more packets.
        !           173:    0 <- call me again no matter what.
        !           174:   -1 <- last packet not processed, try again. */
        !           175: 
        !           176: int
        !           177: dev_rint(unsigned char *buff, unsigned long len, int flags,
        !           178:         struct device * dev)
        !           179: {
        !           180:    struct sk_buff *skb=NULL;
        !           181:    struct packet_type *ptype;
        !           182:    unsigned short type;
        !           183:    unsigned char flag =0;
        !           184:    unsigned char *to;
        !           185:    int amount;
        !           186: 
        !           187:    /* try to grab some memory. */
        !           188:    if (len > 0 && buff != NULL)
        !           189:      {
        !           190:        skb = malloc (sizeof (*skb) + len);
        !           191:        skb->mem_len = sizeof (*skb) + len;
        !           192:        skb->mem_addr = skb;
        !           193:      }
        !           194: 
        !           195:    /* firs we copy the packet into a buffer, and save it for later. */
        !           196:    if (buff != NULL && skb != NULL)
        !           197:      {
        !           198:        if ( !(flags & IN_SKBUFF))
        !           199:          {
        !           200:             to = (unsigned char *)(skb+1);
        !           201:             while (len > 0)
        !           202:               {
        !           203:                  amount = min (len, (unsigned long) dev->rmem_end -
        !           204:                                (unsigned long) buff);
        !           205:                  memcpy (to, buff, amount);
        !           206:                  len -= amount;
        !           207:                  buff += amount;
        !           208:                  to += amount;
        !           209:                  if ((unsigned long)buff == dev->rmem_end)
        !           210:                    buff = (unsigned char *)dev->rmem_start;
        !           211:               }
        !           212:          }
        !           213:        else
        !           214:          {
        !           215:             free_s (skb->mem_addr, skb->mem_len);
        !           216:             skb = (struct sk_buff *)buff;
        !           217:          }
        !           218: 
        !           219:        skb->len = len;
        !           220:        skb->dev = dev;
        !           221:        skb->sk = NULL;
        !           222: 
        !           223:        /* now add it to the dev backlog. */
        !           224:        cli();
        !           225:        if (dev-> backlog == NULL)
        !           226:          {
        !           227:             skb->prev = skb;
        !           228:             skb->next = skb;
        !           229:             dev->backlog = skb;
        !           230:          }
        !           231:        else
        !           232:          {
        !           233:             skb ->prev = dev->backlog->prev;
        !           234:             skb->next = dev->backlog;
        !           235:             skb->next->prev = skb;
        !           236:             skb->prev->next = skb;
        !           237:          }
        !           238:        sti();
        !           239:        return (0);
        !           240:      }
        !           241: 
        !           242:    if (skb != NULL) 
        !           243:      free_s (skb->mem_addr, skb->mem_len);
        !           244: 
        !           245:    /* anything left to process? */
        !           246: 
        !           247:    if (dev->backlog == NULL)
        !           248:      {
        !           249:        if (buff == NULL)
        !           250:          {
        !           251:             sti();
        !           252:             return (1);
        !           253:          }
        !           254: 
        !           255:        if (skb != NULL)
        !           256:          {
        !           257:             sti();
        !           258:             return (-1);
        !           259:          }
        !           260: 
        !           261:        sti();
        !           262:        printk ("dev_rint:Dropping packets due to lack of memory\n");
        !           263:        return (1);
        !           264:      }
        !           265: 
        !           266:    skb= dev->backlog;
        !           267:    if (skb->next == skb)
        !           268:      {
        !           269:        dev->backlog = NULL;
        !           270:      }
        !           271:    else
        !           272:      {
        !           273:        dev->backlog = skb->next;
        !           274:        skb->next->prev = skb->prev;
        !           275:        skb->prev->next = skb->next;
        !           276:      }
        !           277:    sti();
        !           278: 
        !           279:    /* bump the pointer to the next structure. */
        !           280:    skb->h.raw = (unsigned char *)(skb+1) + dev->hard_header_len;
        !           281:    skb->len -= dev->hard_header_len;
        !           282: 
        !           283:    /* convert the type to an ethernet type. */
        !           284:    type = dev->type_trans (skb, dev);
        !           285: 
        !           286:    /* if there get to be a lot of types we should changes this to
        !           287:       a bunch of linked lists like we do for ip protocols. */
        !           288:    for (ptype = ptype_base; ptype != NULL; ptype=ptype->next)
        !           289:      {
        !           290:        if (ptype->type == type)
        !           291:          {
        !           292:             struct sk_buff *skb2;
        !           293:             /* copy the packet if we need to. */
        !           294:             if (ptype->copy)
        !           295:               {
        !           296:                  skb2 = malloc (skb->mem_len);
        !           297:                  if (skb2 == NULL) continue;
        !           298:                  memcpy (skb2, skb, skb->mem_len);
        !           299:                  skb2->mem_addr = skb2;
        !           300:               }
        !           301:             else
        !           302:               {
        !           303:                  skb2 = skb;
        !           304:                  flag = 1;
        !           305:               }
        !           306:               
        !           307:             ptype->func (skb2, dev, ptype);
        !           308:          }
        !           309:      }
        !           310: 
        !           311:    if (!flag)
        !           312:      {
        !           313:        PRINTK ("discarding packet type = %X\n", type);
        !           314:        free_skb (skb, FREE_READ);
        !           315:      }
        !           316: 
        !           317:      if (buff == NULL)
        !           318:        return (0);
        !           319:      else
        !           320:        return (-1);
        !           321: }
        !           322: 
        !           323: /* This routine is called when an device interface is ready to
        !           324:    transmit a packet.  Buffer points to where the packet should
        !           325:    be put, and the routine returns the length of the packet.  A
        !           326:    length of zero is interrpreted to mean the transmit buffers
        !           327:    are empty, and the transmitter should be shut down. */
        !           328: 
        !           329: unsigned long
        !           330: dev_tint(unsigned char *buff,  struct device *dev)
        !           331: {
        !           332:   int i;
        !           333:   int tmp;
        !           334:   struct sk_buff *skb;
        !           335:   for (i=0; i < DEV_NUMBUFFS; i++)
        !           336:     {
        !           337:       while (dev->buffs[i]!=NULL)
        !           338:        {
        !           339:          cli();
        !           340:          skb=dev->buffs[i];
        !           341:          if (skb->next == skb)
        !           342:            {
        !           343:              dev->buffs[i] = NULL;
        !           344:            }
        !           345:          else
        !           346:            {
        !           347:              dev->buffs[i]=skb->next;
        !           348:              skb->prev->next = skb->next;
        !           349:              skb->next->prev = skb->prev;
        !           350:            }
        !           351:          skb->next = NULL;
        !           352:          skb->prev = NULL;
        !           353:          sti();
        !           354:          tmp = skb->len;
        !           355:          if (!skb->arp)
        !           356:            {
        !           357:               if (dev->rebuild_header (skb+1, dev))
        !           358:                 {
        !           359:                    skb->dev = dev;
        !           360:                    arp_queue (skb);
        !           361:                    continue;
        !           362:                 }
        !           363:            }
        !           364:             
        !           365:          if (tmp <= dev->mtu)
        !           366:            {
        !           367:               if (dev->send_packet != NULL)
        !           368:                 {
        !           369:                    dev->send_packet(skb, dev);
        !           370:                 }
        !           371:               if (buff != NULL)
        !           372:                 memcpy (buff, skb + 1, tmp);
        !           373: 
        !           374:               PRINTK (">>\n");
        !           375:               print_eth ((struct enet_header *)(skb+1));
        !           376:            }
        !           377:          else
        !           378:            {
        !           379:               printk ("**** bug len bigger than mtu. \n");
        !           380:            }
        !           381: 
        !           382:          if (skb->free)
        !           383:            {
        !           384:                  free_skb(skb, FREE_WRITE);
        !           385:            }
        !           386: 
        !           387:          if (tmp != 0)
        !           388:            return (tmp);
        !           389:        }
        !           390:     }
        !           391:   PRINTK ("dev_tint returning 0 \n");
        !           392:   return (0);
        !           393: }
        !           394: 

unix.superglobalmegacorp.com