The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/chips/nc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        nc.c,v $
   29  * Revision 2.2  93/08/10  15:18:31  mrt
   30  *      Initial check-in.
   31  *      [93/06/09  15:59:37  jcb]
   32  * 
   33  *
   34  */
   35 
   36 /*** NETWORK INTERFACE IMPLEMENTATION CORE ***/
   37 
   38 #ifndef STUB
   39 #include <chips/nc.h>
   40 #else
   41 #include "nc.h"
   42 #endif
   43 
   44 /*** Types and data structures ***/
   45 
   46 #if PRODUCTION
   47 #define MAX_HASH 701
   48 #define MAX_HOST 4000
   49 #else
   50 #define MAX_HASH 7
   51 #define MAX_HOST 4
   52 #endif
   53 
   54 nw_dev_entry_s nc_failure_entry_table =  {nc_fail, nc_fail,
   55                            nc_null, nc_null,
   56                            nc_null_poll, nc_null_send, nc_null_rpc,
   57                            nc_null_signal, nc_open_fail, nc_accept_fail,
   58                            nc_close_fail, nc_open_fail, nc_open_fail};
   59                                             
   60 nw_dev_entry_s nc_local_entry_table =  {nc_succeed, nc_succeed,
   61                            nc_null, nc_null,
   62                            nc_null_poll, nc_local_send, nc_local_rpc,
   63                            nc_null_signal, nc_open_fail, nc_accept_fail,
   64                            nc_close_fail, nc_open_fail, nc_open_fail};
   65 
   66 
   67 typedef struct {
   68   nw_address_s address;
   69   int name_next:16;
   70   int ip_next:16;
   71   int nw_next:16;
   72   nw_ep line:16;
   73 } nw_alist_s, *nw_alist_t;
   74                
   75 
   76 boolean_t nc_initialized = FALSE;
   77 nw_tx_header_s nw_tx[MAX_EP/2];
   78 nw_tx_header_t nw_free_tx_header;
   79 nw_rx_header_s nw_rx[2*MAX_EP];
   80 nw_rx_header_t nw_free_rx_header;
   81 nw_plist_s nw_peer[MAX_EP];
   82 nw_plist_t nw_free_peer;
   83 
   84 nw_devcb devct[MAX_DEV];
   85 
   86 nw_ecb ect[MAX_EP];
   87 
   88 int nw_free_ep_first, nw_free_ep_last;
   89 int nw_free_line_first, nw_free_line_last;
   90 
   91 nw_alist_s nw_address[MAX_HOST];
   92 int nw_free_address;
   93 
   94 int nw_name[MAX_HASH];
   95 int nw_ip[MAX_HASH];
   96 int nw_nw[MAX_HASH];
   97 
   98 int nw_fast_req;
   99 
  100 /*** System-independent functions ***/
  101 
  102 void nc_initialize() {
  103   int ep, last_ep;
  104   
  105   if (!nc_initialized) {
  106     last_ep = sizeof(nw_tx)/sizeof(nw_tx_header_s) - 1;
  107     for (ep = 0; ep < last_ep; ep++)
  108       nw_tx[ep].next = &nw_tx[ep+1];
  109     nw_tx[last_ep].next = NULL;
  110     nw_free_tx_header = &nw_tx[0];
  111     last_ep = sizeof(nw_rx)/sizeof(nw_rx_header_s) - 1;
  112     for (ep = 0; ep < last_ep; ep++)
  113       nw_rx[ep].next = &nw_rx[ep+1];
  114     nw_rx[last_ep].next = NULL;
  115     nw_free_rx_header = &nw_rx[0];
  116     last_ep = sizeof(nw_peer)/sizeof(nw_plist_s) - 1;
  117     for (ep = 0; ep < last_ep; ep++)
  118       nw_peer[ep].next = &nw_peer[ep+1];
  119     nw_peer[last_ep].next = NULL;
  120     nw_free_peer = &nw_peer[0];
  121     for (ep = 0; ep < MAX_DEV; ep++) {
  122       devct[ep].status = NW_FAILURE;
  123       devct[ep].type = NW_CONNECTIONLESS;
  124       devct[ep].addr = NULL;
  125       devct[ep].local_addr_1 = 0;
  126       devct[ep].local_addr_2 = 0;
  127       devct[ep].entry = &nc_failure_entry_table;
  128       devct[ep].fast_req = 0;
  129     }
  130     devct[NW_NULL].status = NW_SUCCESS;
  131     devct[NW_NULL].entry = &nc_local_entry_table;
  132     last_ep = sizeof(ect)/sizeof(nw_ecb);
  133     for (ep = 0; ep < last_ep; ep++) {
  134       ect[ep].state = NW_INEXISTENT;
  135       ect[ep].id = ep;
  136       ect[ep].seqno = 0;
  137       ect[ep].previous = ep - 1;
  138       ect[ep].next = ep + 1;
  139     }
  140     ect[0].next = ect[0].previous = 0;
  141     ect[last_ep-1].next = 0;
  142     nw_free_ep_first = 1;
  143     nw_free_ep_last = last_ep - 1;
  144     nw_free_line_first = nw_free_line_last = 0;
  145     for (ep = 0; ep < MAX_HOST; ep++) {
  146       nw_address[ep].nw_next = ep + 1;
  147     }
  148     nw_address[MAX_HOST - 1].nw_next = -1;
  149     nw_free_address = 0;
  150     for (ep = 0; ep < MAX_HASH; ep++) {
  151       nw_name[ep] = -1;
  152       nw_ip[ep] = -1;
  153       nw_nw[ep] = -1;
  154     }
  155     nw_fast_req = 0;
  156     h_initialize();
  157     nc_initialized = TRUE;
  158   }
  159 }
  160 
  161 nw_tx_header_t nc_tx_header_allocate() {
  162   nw_tx_header_t header;
  163 
  164   header = nw_free_tx_header;
  165   if (header != NULL)
  166     nw_free_tx_header = header->next;
  167   return header;
  168 }
  169 
  170 void nc_tx_header_deallocate(nw_tx_header_t header) {
  171   nw_tx_header_t first_header;
  172 
  173   first_header = header;
  174   while (header->next != NULL)
  175     header = header->next;
  176   header->next = nw_free_tx_header;
  177   nw_free_tx_header = first_header;
  178 }
  179 
  180 nw_rx_header_t nc_rx_header_allocate() {
  181   nw_rx_header_t header;
  182 
  183   header = nw_free_rx_header;
  184   if (header != NULL)
  185     nw_free_rx_header = header->next;
  186   return header;
  187 }
  188 
  189 void nc_rx_header_deallocate(nw_rx_header_t header) {
  190 
  191   header->next = nw_free_rx_header;
  192   nw_free_rx_header = header;
  193 }
  194 
  195 nw_plist_t nc_peer_allocate() {
  196   nw_plist_t peer;
  197 
  198   peer = nw_free_peer;
  199   if (peer != NULL)
  200     nw_free_peer = peer->next;
  201   return peer;
  202 }
  203 
  204 void nc_peer_deallocate(nw_plist_t peer) {
  205   nw_plist_t first_peer;
  206 
  207   first_peer = peer;
  208   while (peer->next != NULL)
  209     peer = peer->next;
  210   peer->next = nw_free_peer;
  211   nw_free_peer = first_peer;
  212 }
  213 
  214 
  215 nw_result nc_device_register(u_int dev, nw_dev_type type, char *dev_addr,
  216                              nw_dev_entry_t dev_entry_table) {
  217   nw_result rc;
  218 
  219   if (dev >= MAX_DEV) {
  220     rc = NW_FAILURE;
  221   } else {
  222     devct[dev].status = NW_SUCCESS;
  223     devct[dev].type = type;
  224     devct[dev].addr = dev_addr;
  225     devct[dev].entry = dev_entry_table;
  226     devct[dev].fast_req = 0;
  227     rc = NW_SUCCESS;
  228   }
  229   return rc;
  230 }
  231   
  232 nw_result nc_device_unregister(u_int dev, nw_result status) {
  233   nw_result rc;
  234 
  235   if (dev >= MAX_DEV) {
  236     rc = NW_FAILURE;
  237   } else {
  238     devct[dev].status = status;
  239     devct[dev].addr = NULL;
  240     devct[dev].entry = &nc_failure_entry_table;
  241     devct[dev].fast_req = 0;
  242     rc = NW_SUCCESS;
  243   }
  244   return rc;
  245 }
  246   
  247 void nc_slow_sweep() {
  248   int dev;
  249 
  250   for (dev = 0; dev < MAX_DEV; dev++) {
  251     if (devct[dev].status == NW_SUCCESS) {
  252       (*(devct[dev].entry->slow_sweep)) (dev);
  253     }
  254   }
  255 }
  256 
  257 void nc_fast_timer_set(int dev) {
  258 
  259   devct[dev].fast_req++;
  260   if (nw_fast_req++ == 0)
  261     h_fast_timer_set();
  262 }
  263 
  264 void nc_fast_timer_reset(int dev) {
  265 
  266   devct[dev].fast_req--;
  267   if (nw_fast_req-- == 0)
  268     h_fast_timer_reset();
  269 }
  270 
  271 
  272 void nc_fast_sweep() {
  273   int dev;
  274 
  275   for (dev = 0; dev < MAX_DEV; dev++) {
  276     if (devct[dev].status == NW_SUCCESS &&
  277         devct[dev].fast_req > 0) {
  278       devct[dev].fast_req = 0;
  279       (*(devct[dev].entry->fast_sweep)) (dev);
  280     }
  281   }
  282 }
  283 
  284 int nc_hash_name(char *cp) {
  285   int h;
  286   char ch;
  287   char *cp_end;
  288 
  289   cp_end = cp + 19;
  290   *cp_end = '\0';
  291   h = 0;
  292   ch = *cp++;
  293   while (ch != '\0') {
  294     h = (h << 7) + ch;
  295     ch = *cp++;
  296     if (ch != '\0') {
  297       h = (h << 7) + ch;
  298       ch = *cp++;
  299       if (ch != '\0') {
  300         h = (h << 7) + ch;
  301         ch = *cp++;
  302       }
  303     }
  304     h %= MAX_HASH;
  305   }
  306   return h;
  307 }
  308 
  309 
  310 nw_result nc_update(nw_update_type up_type, int *up_info) {
  311   nw_result rc;
  312   nw_alist_t ad;
  313   int h, slot, previous_slot, found_slot;
  314   nw_address_1 n1;
  315   nw_address_2 n2;
  316 
  317   if (up_type == NW_HOST_ADDRESS_REGISTER) {
  318     if (nw_free_address == -1) {
  319       rc = NW_NO_RESOURCES;
  320     } else {
  321       slot = nw_free_address;
  322       ad = &nw_address[slot];
  323       nw_free_address = ad->nw_next;
  324       ad->address = *((nw_address_t) up_info);
  325       h = nc_hash_name(ad->address.name);
  326       ad->name_next = nw_name[h];
  327       nw_name[h] = slot;
  328       h = ad->address.ip_addr % MAX_HASH;
  329       ad->ip_next = nw_ip[h];
  330       nw_ip[h] = slot;
  331       h = (ad->address.nw_addr_1 % MAX_HASH + ad->address.nw_addr_2)
  332               % MAX_HASH;
  333       ad->nw_next = nw_nw[h];
  334       nw_nw[h] = slot;
  335       ad->line = 0;
  336       rc = NW_SUCCESS;
  337     }
  338   } else if (up_type == NW_HOST_ADDRESS_UNREGISTER) {
  339     n1 = ((nw_address_t) up_info)->nw_addr_1;
  340     n2 = ((nw_address_t) up_info)->nw_addr_2;
  341     h = (n1 % MAX_HASH + n2) % MAX_HASH;
  342     slot = nw_nw[h];
  343     previous_slot = -1;
  344     ad = &nw_address[slot];
  345     while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
  346                           ad->address.nw_addr_2 != n2)) {
  347       previous_slot = slot;
  348       slot = ad->nw_next;
  349       ad = &nw_address[slot];
  350     }
  351     if (slot == -1) {
  352       rc = NW_BAD_ADDRESS;
  353     } else {
  354       if (previous_slot == -1)
  355         nw_nw[h] = ad->nw_next;
  356       else
  357         nw_address[previous_slot].nw_next = ad->nw_next;
  358       ad->nw_next = nw_free_address;
  359       nw_free_address = slot;
  360       found_slot = slot;
  361       if (ad->address.ip_addr != 0) {
  362         h = ad->address.ip_addr % MAX_HASH;
  363         slot = nw_ip[h];
  364         previous_slot = -1;
  365         while (slot != -1 && slot != found_slot) {
  366           previous_slot = slot;
  367           slot = nw_address[slot].ip_next;
  368         }
  369         if (slot == found_slot) {
  370           if (previous_slot == -1)
  371             nw_ip[h] = ad->ip_next;
  372           else
  373             nw_address[previous_slot].ip_next = ad->ip_next;
  374         }
  375       }
  376       if (ad->address.name[0] != '\0') {
  377         h = nc_hash_name(ad->address.name);
  378         slot = nw_name[h];
  379         previous_slot = -1;
  380         while (slot != -1 && slot != found_slot) {
  381           previous_slot = slot;
  382           slot = nw_address[slot].name_next;
  383         }
  384         if (slot == found_slot) {
  385           if (previous_slot == -1)
  386             nw_name[h] = ad->name_next;
  387           else
  388             nw_address[previous_slot].name_next = ad->name_next;
  389         }
  390       }
  391       rc = NW_SUCCESS;
  392     }
  393   } else {
  394     rc = NW_INVALID_ARGUMENT;
  395   }
  396   return rc;
  397 }
  398 
  399 nw_result nc_lookup(nw_lookup_type lt, int *look_info) {
  400   nw_result rc;
  401   nw_address_t addr;
  402   nw_alist_t ad;
  403   int h, slot;
  404   ip_address ip;
  405   nw_address_1 n1;
  406   nw_address_2 n2;
  407 
  408   if (lt == NW_HOST_ADDRESS_LOOKUP) {
  409     addr = (nw_address_t) look_info;
  410     if (addr->ip_addr != 0) {
  411       ip = addr->ip_addr;
  412       h = ip % MAX_HASH;
  413       slot = nw_ip[h];
  414       ad = &nw_address[slot];
  415       while (slot != -1 && ad->address.ip_addr != ip) {
  416         slot = ad->ip_next;
  417         ad = &nw_address[slot];
  418       }
  419       if (slot != -1) {
  420         strcpy(addr->name, ad->address.name);
  421         addr->nw_addr_1 = ad->address.nw_addr_1;
  422         addr->nw_addr_2 = ad->address.nw_addr_2;
  423         return NW_SUCCESS;
  424       }
  425     }
  426     if (addr->name[0] != '\0') {
  427       h = nc_hash_name(addr->name);
  428       slot = nw_name[h];
  429       ad = &nw_address[slot];
  430       while (slot != -1 && strcmp(ad->address.name, addr->name) != 0) {
  431         slot = ad->name_next;
  432         ad = &nw_address[slot];
  433       }
  434       if (slot != -1) {
  435         addr->ip_addr = ad->address.ip_addr;
  436         addr->nw_addr_1 = ad->address.nw_addr_1;
  437         addr->nw_addr_2 = ad->address.nw_addr_2;
  438         return NW_SUCCESS;
  439       }
  440     }
  441     if (addr->nw_addr_1 != 0 || addr->nw_addr_2 != 0) {
  442       n1 = addr->nw_addr_1;
  443       n2 = addr->nw_addr_2;
  444       h = (n1 % MAX_HASH + n2) % MAX_HASH;
  445       slot = nw_nw[h];
  446       ad = &nw_address[slot];
  447       while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
  448                             ad->address.nw_addr_2 != n2)) {
  449         slot = ad->nw_next;
  450         ad = &nw_address[slot];
  451       }
  452       if (slot != -1) {
  453         strcpy(addr->name, ad->address.name);
  454         addr->ip_addr = ad->address.ip_addr;
  455         return NW_SUCCESS;
  456       }
  457     }
  458     rc = NW_BAD_ADDRESS;
  459   } else {
  460     rc = NW_INVALID_ARGUMENT;
  461   }
  462   return rc;
  463 }
  464 
  465 nw_result nc_line_update(nw_peer_t peer, nw_ep line) {
  466   nw_result rc;
  467   nw_alist_t ad;
  468   int h, slot;
  469   nw_address_1 n1;
  470   nw_address_2 n2;
  471 
  472   n1 = peer->rem_addr_1;
  473   n2 = peer->rem_addr_2;
  474   h = (n1 % MAX_HASH + n2) % MAX_HASH;
  475   slot = nw_nw[h];
  476   ad = &nw_address[slot];
  477   while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
  478                         ad->address.nw_addr_2 != n2)) {
  479     slot = ad->nw_next;
  480     ad = &nw_address[slot];
  481   }
  482   if (slot == -1) {
  483     rc = NW_FAILURE;
  484   } else {
  485     ad->line = line;
  486     rc = NW_SUCCESS;
  487   }
  488   return rc;
  489 }
  490 
  491 nw_ep nc_line_lookup(nw_peer_t peer) {
  492   nw_ep lep;
  493   nw_alist_t ad;
  494   int h, slot;
  495   nw_address_1 n1;
  496   nw_address_2 n2;
  497 
  498   n1 = peer->rem_addr_1;
  499   n2 = peer->rem_addr_2;
  500   h = (n1 % MAX_HASH + n2) % MAX_HASH;
  501   slot = nw_nw[h];
  502   ad = &nw_address[slot];
  503   while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
  504                         ad->address.nw_addr_2 != n2)) {
  505     slot = ad->nw_next;
  506     ad = &nw_address[slot];
  507   }
  508   if (slot == -1) {
  509     lep = -1;
  510   } else {
  511     lep = ad->line;
  512   }
  513   return lep;
  514 }
  515 
  516 nw_result nc_endpoint_allocate(nw_ep_t epp, nw_protocol protocol,
  517                                nw_acceptance accept,
  518                                char *buffer_address, u_int buffer_size) {
  519   nw_result rc;
  520   nw_ep ep;
  521   nw_ecb_t ecb;
  522 
  523   if (ect[(ep = *epp)].state != NW_INEXISTENT) {
  524     rc = NW_BAD_EP;
  525   } else if (nw_free_ep_first == 0) {
  526     *epp = nw_free_line_first;
  527     rc = NW_NO_EP;
  528   } else {
  529     if (ep == 0) {
  530       ecb = &ect[nw_free_ep_first];
  531       *epp = ep = ecb->id;
  532       nw_free_ep_first = ecb->next;
  533       if (nw_free_ep_first == 0)
  534         nw_free_ep_last = 0;
  535     } else {
  536       ecb = &ect[ep];
  537       if (ecb->previous == 0)
  538         nw_free_ep_first = ecb->next;
  539       else
  540         ect[ecb->previous].next = ecb->next;
  541       if (ecb->next == 0)
  542         nw_free_ep_last = ecb->previous;
  543       else
  544         ect[ecb->next].previous = ecb->previous;
  545     }
  546     if (protocol == NW_LINE) {
  547       if (nw_free_line_last == 0)
  548         nw_free_line_first = ep;
  549       else
  550         ect[nw_free_line_last].next = ep;
  551       ecb->previous = nw_free_line_last;
  552       ecb->next = 0;
  553       nw_free_line_last = ep;
  554     }
  555     ecb->protocol = protocol;
  556     ecb->accept = accept;
  557     ecb->state = NW_UNCONNECTED;
  558     ecb->conn = NULL;
  559     ecb->buf_start = buffer_address;
  560     ecb->buf_end = buffer_address + buffer_size;
  561     ecb->free_buffer = (nw_unused_buffer_t) buffer_address;
  562     ecb->free_buffer->buf_used = 0;
  563     ecb->free_buffer->buf_length = buffer_size;
  564     ecb->free_buffer->previous = NULL;
  565     ecb->free_buffer->next = NULL;
  566     ecb->overrun = 0;
  567     ecb->seqno = 0;
  568     ecb->tx_first = NULL;
  569     ecb->tx_last = NULL;
  570     ecb->tx_initial = NULL;
  571     ecb->tx_current = NULL;
  572     ecb->rx_first = NULL;
  573     ecb->rx_last = NULL;
  574     rc = NW_SUCCESS;
  575   }
  576   return rc;
  577 }
  578 
  579 nw_result nc_endpoint_deallocate(nw_ep ep) {
  580   nw_ecb_t ecb;
  581   nw_rx_header_t rx_header;
  582 
  583   ecb = &ect[ep];
  584   if (ecb->conn != NULL) 
  585     nc_peer_deallocate(ecb->conn);
  586   if (ecb->tx_first != NULL)
  587     nc_tx_header_deallocate(ecb->tx_first);
  588   if (ecb->tx_initial != NULL)
  589     nc_tx_header_deallocate(ecb->tx_initial);
  590   while (ecb->rx_first != NULL) {
  591     rx_header = ecb->rx_first;
  592     ecb->rx_first = rx_header->next;
  593     nc_rx_header_deallocate(rx_header);
  594   }
  595   if (ecb->protocol == NW_LINE) {
  596     if (ecb->previous == 0)
  597       nw_free_line_first = ecb->next;
  598     else
  599       ect[ecb->previous].next = ecb->next;
  600     if (ecb->next == 0)
  601       nw_free_line_last = ecb->previous;
  602     else
  603       ect[ecb->next].previous = ecb->previous;
  604   }
  605   ecb->next = 0;
  606   ecb->previous = nw_free_ep_last;
  607   if (nw_free_ep_last == 0)
  608     nw_free_ep_first = ep;
  609   else
  610     ect[nw_free_ep_last].next = ep;
  611   nw_free_ep_last = ep;
  612   ecb->id = ep;
  613   ecb->state = NW_INEXISTENT;
  614   return NW_SUCCESS;
  615 }
  616 
  617 void nc_buffer_coalesce(nw_ecb_t ecb) {
  618   nw_unused_buffer_t p, q, buf_free, buf_start, buf_end;
  619 
  620   buf_start = p = (nw_unused_buffer_t) ecb->buf_start;
  621   buf_end = (nw_unused_buffer_t) ecb->buf_end;
  622   buf_free = NULL;
  623   while (p >= buf_start && p < buf_end) {
  624     if (p->buf_length & 0x3)
  625       goto trash_area;
  626     if (p->buf_used) {
  627       p = (nw_unused_buffer_t) ((char *) p + p->buf_length);
  628     } else {
  629       q = (nw_unused_buffer_t) ((char *) p + p->buf_length);
  630       while (q >= buf_start && q < buf_end && !q->buf_used) {
  631         if (q->buf_length & 0x3)
  632           goto trash_area;
  633         p->buf_length += q->buf_length;
  634         q = (nw_unused_buffer_t) ((char *) q + q->buf_length);
  635       }
  636       p->next = buf_free;
  637       p->previous = NULL;
  638       if (buf_free != NULL)
  639         buf_free->previous = p;
  640       buf_free = p;
  641       p = q;
  642     }
  643   }
  644   ecb->free_buffer = buf_free;
  645   return;
  646 
  647  trash_area:
  648   ecb->free_buffer = NULL;
  649   return;
  650 }
  651 
  652   
  653 nw_buffer_t nc_buffer_allocate(nw_ep ep, u_int size) {
  654   nw_ecb_t ecb;
  655   nw_unused_buffer_t buf, buf_start, buf_end;
  656 
  657   ecb = &ect[ep];
  658   buf_start = (nw_unused_buffer_t) ecb->buf_start;
  659   buf_end = (nw_unused_buffer_t) (ecb->buf_end - sizeof(nw_buffer_s));
  660   if (size < sizeof(nw_buffer_s))
  661     size = sizeof(nw_buffer_s);
  662   else
  663     size = ((size + 3) >> 2) << 2;
  664   buf = ecb->free_buffer;
  665   if (buf != NULL) {
  666     while (buf->buf_length < size) {
  667       buf = buf->next;
  668       if (buf < buf_start || buf > buf_end || ((int) buf & 0x3)) {
  669         buf = NULL;
  670         break;
  671       }
  672     }
  673   }
  674   if (buf == NULL) {
  675     nc_buffer_coalesce(ecb);
  676     buf = ecb->free_buffer;
  677     while (buf != NULL && buf->buf_length < size)
  678       buf = buf->next;
  679   }
  680   if (buf == NULL) {
  681     ecb->overrun = 1;
  682   } else {
  683     if (buf->buf_length < size + sizeof(nw_buffer_s)) {
  684       if (buf->previous == NULL)
  685         ecb->free_buffer = buf->next;
  686       else
  687         buf->previous->next = buf->next;
  688       if (buf->next != NULL)
  689         buf->next->previous = buf->previous;
  690     } else {
  691       buf->buf_length -= size;
  692       buf = (nw_unused_buffer_t) ((char *) buf + buf->buf_length);
  693       buf->buf_length = size;
  694     }
  695     buf->buf_used = 1;
  696   }
  697   return (nw_buffer_t) buf;
  698 }
  699 
  700 nw_result nc_buffer_deallocate(nw_ep ep, nw_buffer_t buffer) {
  701   nw_ecb_t ecb;
  702   nw_unused_buffer_t buf;
  703 
  704   ecb = &ect[ep];
  705   buf = (nw_unused_buffer_t) buffer;
  706   buf->buf_used = 0;
  707   buf->previous = NULL;
  708   buf->next = ecb->free_buffer;
  709   if (ecb->free_buffer != NULL)
  710     ecb->free_buffer->previous = buf;
  711   ecb->free_buffer = buf;
  712   return NW_SUCCESS;
  713 }
  714 
  715 nw_result nc_endpoint_status(nw_ep ep, nw_state_t state, nw_peer_t peer) {
  716   nw_result rc;
  717   nw_ecb_t ecb;
  718 
  719   ecb = &ect[ep];
  720   *state = ecb->state;
  721   if (ecb->conn)
  722     *peer = ecb->conn->peer;
  723   if (ecb->overrun) {
  724     ecb->overrun = 0;
  725     rc = NW_OVERRUN;
  726   } else if (ecb->rx_first != NULL) {
  727     rc = NW_QUEUED;
  728   } else {
  729     rc = NW_SUCCESS;
  730   }
  731   return rc;
  732 }
  733 
  734 
  735 nw_result nc_local_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
  736   nw_result rc;
  737   nw_ep receiver;
  738   int length;
  739   nw_buffer_t buffer;
  740   nw_tx_header_t first_header;
  741   nw_rx_header_t rx_header;
  742   char *bufp;
  743   nw_ecb_t ecb;
  744 
  745   receiver = header->peer.remote_ep;
  746   length = header->msg_length;
  747   buffer = nc_buffer_allocate(receiver, sizeof(nw_buffer_s) + length);
  748   if (buffer == NULL) {
  749     rc = NW_OVERRUN;
  750   } else {
  751     buffer->buf_next = NULL;
  752     buffer->block_offset = sizeof(nw_buffer_s);
  753     buffer->block_length = length;
  754     buffer->peer.rem_addr_1 = NW_NULL << 28;
  755     buffer->peer.rem_addr_2 = 0;
  756     buffer->peer.remote_ep = ep;
  757     buffer->peer.local_ep = receiver;
  758     bufp = (char *) buffer + sizeof(nw_buffer_s);
  759     first_header = header;
  760     while (header != NULL) {
  761       length = header->block_length;
  762       bcopy(header->block, bufp, length);
  763       bufp += length;
  764       if (header->buffer != NULL) 
  765         nc_buffer_deallocate(ep, header->buffer);
  766       header = header->next;
  767     }
  768     nc_tx_header_deallocate(first_header);
  769     ecb = &ect[receiver];
  770     if (options == NW_URGENT) {
  771       buffer->msg_seqno = 0;
  772       if (nc_deliver_result(receiver, NW_RECEIVE_URGENT, (int) buffer))
  773         rc = NW_SUCCESS;
  774       else
  775         rc = NW_NO_RESOURCES;
  776     } else {
  777       if (ecb->seqno == 1023)
  778         buffer->msg_seqno = ecb->seqno = 1;
  779       else
  780         buffer->msg_seqno = ++ecb->seqno;
  781       if (nc_deliver_result(receiver, NW_RECEIVE, (int) buffer)) 
  782         rc = NW_SUCCESS;
  783       else
  784         rc = NW_NO_RESOURCES;
  785     }
  786   }
  787   return rc;
  788 }
  789 
  790 nw_buffer_t nc_local_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
  791   nw_buffer_t buf;
  792   nw_ecb_t ecb;
  793   nw_rx_header_t rx_header;
  794 
  795   ecb = &ect[ep];
  796   rx_header = ecb->rx_first;
  797   if (nc_local_send(ep, header, options) != NW_SUCCESS) {
  798     buf = NW_BUFFER_ERROR;
  799   } else if (rx_header == NULL) {
  800     buf = NULL;
  801   } else {
  802     buf = rx_header->buffer;
  803     ecb->rx_first = rx_header->next;
  804     if (ecb->rx_first == NULL)
  805       ecb->rx_last = NULL;
  806     nc_rx_header_deallocate(rx_header);
  807   }
  808   return buf;
  809 }
  810                          
  811 
  812 nw_result nc_succeed(int dev) {
  813 
  814   return NW_SUCCESS;
  815 }
  816                               
  817 void nc_null(int dev) {
  818 
  819 }
  820 
  821 nw_result nc_fail(int dev) {
  822 
  823   return NW_FAILURE;
  824 }
  825 
  826 int nc_null_poll(int dev) {
  827   
  828   return 1000000;
  829 }
  830 
  831 nw_result nc_null_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
  832 
  833   return NW_FAILURE;
  834 }
  835 
  836 nw_buffer_t nc_null_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
  837 
  838   return NW_BUFFER_ERROR;
  839 }
  840 
  841 void nc_null_signal(nw_buffer_t msg) {
  842 
  843 }
  844 
  845 nw_result nc_open_fail(nw_ep lep, nw_address_1 a1,
  846                        nw_address_2 a2, nw_ep rep) {
  847 
  848   return NW_FAILURE;
  849 }
  850 
  851 nw_result nc_close_fail(nw_ep ep) {
  852 
  853   return NW_FAILURE;
  854 }
  855 
  856 nw_result nc_accept_fail(nw_ep ep, nw_buffer_t msg, nw_ep_t epp) {
  857 
  858   return NW_FAILURE;
  859 }
  860 

Cache object: 3ba7d6588a1e27d3d1b8138bb8fe92e8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.