root/drivers/net/eql.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. eql_init
  2. eql_open
  3. eql_close
  4. eql_ioctl
  5. eql_slave_xmit
  6. eql_get_stats
  7. eql_header
  8. eql_rebuild_header
  9. eql_enslave
  10. eql_emancipate
  11. eql_g_slave_cfg
  12. eql_s_slave_cfg
  13. eql_g_master_cfg
  14. eql_s_master_cfg
  15. eql_is_slave
  16. eql_is_master
  17. eql_new_slave
  18. eql_delete_slave
  19. slave_Bps
  20. slave_bps
  21. eql_number_slaves
  22. eql_is_empty
  23. eql_is_full
  24. eql_new_slave_queue
  25. eql_delete_slave_queue
  26. eql_insert_slave
  27. eql_remove_slave
  28. eql_insert_slave_dev
  29. eql_remove_slave_dev
  30. eql_best_slave_dev
  31. eql_best_slave
  32. eql_schedule_slaves
  33. eql_find_slave_dev
  34. eql_first_slave
  35. eql_next_slave
  36. eql_set_best_slave
  37. eql_lock_slave_queue
  38. eql_unlock_slave_queue
  39. eql_is_locked_slave_queue
  40. eql_timer

   1 /*
   2  * Equalizer Load-balancer for serial network interfaces.
   3  *
   4  * (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
   5  * NCM: Network and Communications Mangement, Inc.
   6  *
   7  *
   8  *      This software may be used and distributed according to the terms
   9  *      of the GNU Public License, incorporated herein by reference.
  10  * 
  11  * The author may be reached as simon@ncm.com, or C/O
  12  *    NCM
  13  *    Attn: Simon Janes
  14  *    6803 Whittier Ave
  15  *    McLean VA 22101
  16  *    Phone: 1-703-847-0040 ext 103
  17  */
  18 
  19 static char *version = 
  20         "Equalizer: $Revision: 3.12 $ $Date: 1995/01/19 $ Simon Janes (simon@ncm.com)\n";
  21 
  22 #include <linux/config.h>
  23 
  24 /*
  25  * Sources:
  26  *   skeleton.c by Donald Becker.
  27  * Inspirations:
  28  *   The Harried and Overworked Alan Cox
  29  * Conspiracies:
  30  *   The Alan Cox and Arisian plot to get someone else to do the code, which
  31  *   turned out to be me.
  32  */
  33 
  34 /*
  35  * $Log: eql.c,v $
  36  * Revision 3.12  1995/03/22  21:07:51  anarchy
  37  * Added suser() checks on configuration.
  38  * Moved header file.
  39  *
  40  * Revision 3.11  1995/01/19  23:14:31  guru
  41  *                    slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
  42  *                      (priority_Bps) + bytes_queued * 8;
  43  *
  44  * Revision 3.10  1995/01/19  23:07:53  guru
  45  * back to
  46  *                    slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
  47  *                      (priority_Bps) + bytes_queued;
  48  *
  49  * Revision 3.9  1995/01/19  22:38:20  guru
  50  *                    slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
  51  *                      (priority_Bps) + bytes_queued * 4;
  52  *
  53  * Revision 3.8  1995/01/19  22:30:55  guru
  54  *       slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
  55  *                      (priority_Bps) + bytes_queued * 2;
  56  *
  57  * Revision 3.7  1995/01/19  21:52:35  guru
  58  * printk's trimmed out.
  59  *
  60  * Revision 3.6  1995/01/19  21:49:56  guru
  61  * This is working pretty well. I gained 1 K/s in speed.. now its just
  62  * robustness and printk's to be diked out.
  63  *
  64  * Revision 3.5  1995/01/18  22:29:59  guru
  65  * still crashes the kernel when the lock_wait thing is woken up.
  66  *
  67  * Revision 3.4  1995/01/18  21:59:47  guru
  68  * Broken set-bit locking snapshot
  69  *
  70  * Revision 3.3  1995/01/17  22:09:18  guru
  71  * infinite sleep in a lock somewhere..
  72  *
  73  * Revision 3.2  1995/01/15  16:46:06  guru
  74  * Log trimmed of non-pertinant 1.x branch messages
  75  *
  76  * Revision 3.1  1995/01/15  14:41:45  guru
  77  * New Scheduler and timer stuff...
  78  *
  79  * Revision 1.15  1995/01/15  14:29:02  guru
  80  * Will make 1.14 (now 1.15) the 3.0 branch, and the 1.12 the 2.0 branch, the one
  81  * with the dumber scheduler
  82  *
  83  * Revision 1.14  1995/01/15  02:37:08  guru
  84  * shock.. the kept-new-versions could have zonked working
  85  * stuff.. shudder
  86  *
  87  * Revision 1.13  1995/01/15  02:36:31  guru
  88  * big changes
  89  *
  90  *      scheduler was torn out and replaced with something smarter
  91  *
  92  *      global names not prefixed with eql_ were renamed to protect
  93  *      against namespace collisions
  94  *
  95  *      a few more abstract interfaces were added to facilitate any
  96  *      potential change of datastructure.  the driver is still using
  97  *      a linked list of slaves.  going to a heap would be a bit of
  98  *      an overkill.
  99  *
 100  *      this compiles fine with no warnings.
 101  *
 102  *      the locking mechanism and timer stuff must be written however,
 103  *      this version will not work otherwise
 104  *
 105  */
 106 
 107 #include <linux/kernel.h>
 108 #include <linux/sched.h>
 109 #include <linux/types.h>
 110 #include <linux/fcntl.h>
 111 #include <linux/interrupt.h>
 112 #include <linux/ptrace.h>
 113 #include <linux/ioport.h>
 114 #include <linux/in.h>
 115 #include <linux/malloc.h>
 116 #include <linux/string.h>
 117 #include <asm/system.h>
 118 #include <asm/bitops.h>
 119 #include <asm/io.h>
 120 #include <asm/dma.h>
 121 #include <linux/errno.h>              
 122 
 123 #include <linux/netdevice.h>
 124 #include <linux/if.h>
 125 #include <linux/timer.h>
 126 
 127 #include <linux/if_eql.h>
 128 
 129 #ifndef EQL_DEBUG
 130 /* #undef EQL_DEBUG      -* print nothing at all, not even a boot-banner */
 131 /* #define EQL_DEBUG 1   -* print only the boot-banner */
 132 /* #define EQL_DEBUG 5   -* print major function entries */
 133 /* #define EQL_DEBUG 20  -* print subfunction entries */
 134 /* #define EQL_DEBUG 50  -* print utility entries */
 135 /* #define EQL_DEBUG 100 -* print voluminous function entries */
 136 #define EQL_DEBUG 1
 137 #endif
 138 static unsigned int eql_debug = EQL_DEBUG;
 139 
 140 int        eql_init(struct device *dev); /*  */
 141 static int eql_open(struct device *dev); /*  */
 142 static int eql_close(struct device *dev); /*  */
 143 static int eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd); /*  */
 144 static int eql_slave_xmit(struct sk_buff *skb, struct device *dev); /*  */
 145 
 146 static struct enet_statistics *eql_get_stats(struct device *dev); /*  */
 147 static int eql_header(struct sk_buff *skb, struct device *dev, 
 148                       unsigned short type, void *daddr, void *saddr, 
 149                       unsigned len); /*  */
 150 static int eql_rebuild_header(void *buff, struct device *dev, 
 151                               unsigned long raddr, struct sk_buff *skb); /*  */
 152 
 153 /* ioctl() handlers
 154    ---------------- */
 155 static int eql_enslave(struct device *dev,  slaving_request_t *srq); /*  */
 156 static int eql_emancipate(struct device *dev, slaving_request_t *srq); /*  */
 157 
 158 static int eql_g_slave_cfg(struct device *dev, slave_config_t *sc); /*  */
 159 static int eql_s_slave_cfg(struct device *dev, slave_config_t *sc); /*  */
 160 
 161 static int eql_g_master_cfg(struct device *dev, master_config_t *mc); /*  */
 162 static int eql_s_master_cfg(struct device *dev, master_config_t *mc); /*  */
 163 
 164 static inline int eql_is_slave(struct device *dev); /*  */
 165 static inline int eql_is_master(struct device *dev); /*  */
 166 
 167 static slave_t *eql_new_slave(void); /*  */
 168 static void eql_delete_slave(slave_t *slave); /*  */
 169 
 170 /* static long eql_slave_priority(slave_t *slave); -*  */
 171 static inline int eql_number_slaves(slave_queue_t *queue); /*  */
 172 
 173 static inline int eql_is_empty(slave_queue_t *queue); /*  */
 174 static inline int eql_is_full(slave_queue_t *queue); /*  */
 175 
 176 static slave_queue_t *eql_new_slave_queue(struct device *dev); /*  */
 177 static void eql_delete_slave_queue(slave_queue_t *queue); /*  */
 178 
 179 static int eql_insert_slave(slave_queue_t *queue, slave_t *slave); /*  */
 180 static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave); /*  */
 181 
 182 /* static int eql_insert_slave_dev(slave_queue_t *queue, struct device *dev); -*  */
 183 static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev); /*  */
 184 
 185 static inline struct device *eql_best_slave_dev(slave_queue_t *queue); /*  */
 186 static inline slave_t *eql_best_slave(slave_queue_t *queue); /*  */
 187 static inline slave_t *eql_first_slave(slave_queue_t *queue); /*  */
 188 static inline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave); /*  */
 189 
 190 static inline void eql_set_best_slave(slave_queue_t *queue, slave_t *slave); /*  */
 191 static inline void eql_schedule_slaves(slave_queue_t *queue); /*  */
 192 
 193 static slave_t *eql_find_slave_dev(slave_queue_t *queue, struct device *dev); /*  */
 194 
 195 /* static inline eql_lock_slave_queue(slave_queue_t *queue); -*  */
 196 /* static inline eql_unlock_slave_queue(slave_queue_t *queue); -*  */
 197 
 198 static void eql_timer(unsigned long param);     /*  */
 199 
 200 /* struct device * interface functions 
 201    ---------------------------------------------------------
 202    */
 203 
 204 int
 205 eql_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207   static unsigned version_printed = 0;
 208   /* static unsigned num_masters     = 0; */
 209   equalizer_t *eql = 0;
 210   int i;
 211 
 212   if ( version_printed++ == 0 && eql_debug > 0)
 213     printk(version);
 214 
 215   /* Initialize the device structure. */
 216   dev->priv = kmalloc (sizeof (equalizer_t), GFP_KERNEL);
 217   memset (dev->priv, 0, sizeof (equalizer_t));
 218   eql = (equalizer_t *) dev->priv;
 219 
 220   eql->stats = kmalloc (sizeof (struct enet_statistics), GFP_KERNEL);
 221   memset (eql->stats, 0, sizeof (struct enet_statistics));
 222 
 223   init_timer (&eql->timer);
 224   eql->timer.data     = (unsigned long) dev->priv;
 225   eql->timer.expires  = EQL_DEFAULT_RESCHED_IVAL;
 226   eql->timer.function = &eql_timer;
 227   eql->timer_on       = 0;
 228 
 229   dev->open             = eql_open;
 230   dev->stop             = eql_close;
 231   dev->do_ioctl         = eql_ioctl;
 232   dev->hard_start_xmit  = eql_slave_xmit;
 233   dev->get_stats        = eql_get_stats;
 234   
 235   /* Fill in the fields of the device structure with ethernet-generic values.
 236      This should be in a common file instead of per-driver.  */
 237 
 238   for (i = 0; i < DEV_NUMBUFFS; i++)
 239     skb_queue_head_init(&dev->buffs[i]);
 240 
 241   dev->hard_header    = eql_header; 
 242   dev->rebuild_header = eql_rebuild_header;
 243 
 244   /* now we undo some of the things that eth_setup does that we don't like */
 245   dev->mtu        = EQL_DEFAULT_MTU;    /* set to 576 in eql.h */
 246   dev->flags      = IFF_MASTER;
 247 
 248   dev->family     = AF_INET;
 249   dev->pa_addr    = 0;
 250   dev->pa_brdaddr = 0;
 251   dev->pa_mask    = 0;
 252   dev->pa_alen    = 4;
 253 
 254   dev->type       = ARPHRD_SLIP;
 255 
 256   return 0;
 257 }
 258 
 259 
 260 static
 261 int
 262 eql_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 263 {
 264   equalizer_t *eql = (equalizer_t *) dev->priv;
 265   slave_queue_t *new_queue;
 266 
 267 #ifdef EQL_DEBUG
 268   if (eql_debug >= 5)
 269     printk ("%s: open\n", dev->name);
 270 #endif
 271 
 272    new_queue = eql_new_slave_queue (dev);
 273     
 274     if (new_queue != 0)
 275       {
 276         new_queue->master_dev = dev;
 277         eql->queue = new_queue;
 278         eql->queue->lock = 0;
 279         eql->min_slaves = 1;
 280         eql->max_slaves = EQL_DEFAULT_MAX_SLAVES; /* 4 usually... */
 281 
 282         printk ("%s: adding timer\n", dev->name);
 283         eql->timer_on = 1;
 284         add_timer (&eql->timer);
 285 
 286         return 0;
 287       }
 288   return 1;
 289 }
 290 
 291 
 292 static
 293 int
 294 eql_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 295 {
 296   equalizer_t *eql = (equalizer_t *) dev->priv;
 297 
 298 #ifdef EQL_DEBUG
 299   if ( eql_debug >= 5)
 300     printk ("%s: close\n", dev->name);
 301 #endif
 302   /* The timer has to be stopped first before we start hacking away
 303      at the data structure it scans every so often... */
 304   printk ("%s: stopping timer\n", dev->name);
 305   eql->timer_on = 0;
 306   del_timer (&eql->timer);
 307 
 308   eql_delete_slave_queue (eql->queue);
 309 
 310   return 0;
 311 }
 312 
 313 
 314 static
 315 int
 316 eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 317 {  
 318   if(!suser() && cmd!=EQL_GETMASTRCFG && cmd!=EQL_GETSLAVECFG)
 319         return -EPERM;
 320   switch (cmd)
 321     {
 322     case EQL_ENSLAVE:
 323       return eql_enslave (dev, (slaving_request_t *) ifr->ifr_data);
 324     case EQL_EMANCIPATE:
 325       return eql_emancipate (dev, (slaving_request_t *) ifr->ifr_data);
 326 
 327     case EQL_GETSLAVECFG:
 328       return eql_g_slave_cfg (dev, (slave_config_t *) ifr->ifr_data);
 329     case EQL_SETSLAVECFG:
 330       return eql_s_slave_cfg (dev, (slave_config_t *) ifr->ifr_data);
 331 
 332     case EQL_GETMASTRCFG:
 333       return eql_g_master_cfg (dev, (master_config_t *) ifr->ifr_data);
 334     case EQL_SETMASTRCFG:
 335       return eql_s_master_cfg (dev, (master_config_t *) ifr->ifr_data);
 336 
 337     default:
 338       return -EOPNOTSUPP;
 339     }
 340 }
 341 
 342 
 343 static
 344 int
 345 eql_slave_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347   equalizer_t *eql = (equalizer_t *) dev->priv;
 348   struct device *slave_dev = 0;
 349   slave_t *slave;
 350 
 351   if (skb == NULL)
 352     {
 353       return 0;
 354     }
 355 
 356   eql_schedule_slaves (eql->queue);
 357   
 358   slave_dev = eql_best_slave_dev (eql->queue);
 359   slave = eql_best_slave (eql->queue); 
 360 
 361   if ( slave_dev != 0 )
 362     {
 363 #ifdef EQL_DEBUG
 364       if (eql_debug >= 100)
 365         printk ("%s: %d slaves xmitng %ld B %s\n", 
 366                 dev->name, eql_number_slaves (eql->queue), skb->len,
 367                 slave_dev->name);
 368 #endif
 369       
 370       dev_queue_xmit (skb, slave_dev, 1);
 371       eql->stats->tx_packets++;
 372       slave->bytes_queued += skb->len; 
 373     }
 374   else
 375     {
 376       /* The alternative for this is the return 1 and have
 377          dev_queue_xmit just queue it up on the eql's queue. */
 378 
 379       eql->stats->tx_dropped++;
 380       dev_kfree_skb(skb, FREE_WRITE);
 381     }     
 382   return 0;
 383 }
 384 
 385 
 386 static
 387 struct enet_statistics *
 388 eql_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 389 {
 390   equalizer_t *eql = (equalizer_t *) dev->priv;
 391 
 392   return eql->stats;
 393 }
 394 
 395 
 396 static 
 397 int 
 398 eql_header(struct sk_buff *skb, struct device *dev, 
     /* [previous][next][first][last][top][bottom][index][help] */
 399            unsigned short type, void *daddr, void *saddr, 
 400            unsigned len)
 401 {
 402   return 0;
 403 }
 404 
 405 
 406 static 
 407 int 
 408 eql_rebuild_header(void *buff, struct device *dev, 
     /* [previous][next][first][last][top][bottom][index][help] */
 409                    unsigned long raddr, struct sk_buff *skb)
 410 {
 411   return 0;
 412 }
 413 
 414 
 415 
 416 
 417 /* private ioctl functions
 418    -----------------------------------------------------------------
 419    */
 420 
 421 static int 
 422 eql_enslave(struct device *dev, slaving_request_t *srqp)
     /* [previous][next][first][last][top][bottom][index][help] */
 423 {
 424   struct device *master_dev;
 425   struct device *slave_dev;
 426   slaving_request_t srq;
 427   int err;
 428 
 429   err = verify_area(VERIFY_READ, (void *)srqp, sizeof (slaving_request_t));
 430   if (err) return err;
 431 
 432   memcpy_fromfs (&srq, srqp, sizeof (slaving_request_t));
 433 
 434 #ifdef EQL_DEBUG
 435   if (eql_debug >= 20)
 436     printk ("%s: enslave '%s' %ld bps\n", dev->name, 
 437             srq.slave_name, srq.priority);
 438 #endif
 439   
 440   master_dev = dev;             /* for "clarity" */
 441   slave_dev  = dev_get (srq.slave_name);
 442 
 443   if (master_dev != 0 && slave_dev != 0)
 444     {
 445       if (! eql_is_master (slave_dev)  &&   /* slave is not a master */
 446           ! eql_is_slave (slave_dev)      ) /* slave is not already a slave */
 447         {
 448           slave_t *s = eql_new_slave ();
 449           equalizer_t *eql = (equalizer_t *) master_dev->priv;
 450 
 451           s->dev = slave_dev;
 452           s->priority = srq.priority;
 453           s->priority_bps = srq.priority;
 454           s->priority_Bps = srq.priority / 8;
 455 
 456           slave_dev->flags |= IFF_SLAVE;
 457 
 458           eql_insert_slave (eql->queue, s);
 459 
 460           return 0;
 461         }
 462       return -EINVAL;
 463     }
 464   return -EINVAL;
 465 }
 466 
 467 
 468 
 469 static 
 470 int 
 471 eql_emancipate(struct device *dev, slaving_request_t *srqp)
     /* [previous][next][first][last][top][bottom][index][help] */
 472 {
 473   struct device *master_dev;
 474   struct device *slave_dev;
 475   slaving_request_t srq;
 476   int err;
 477 
 478   err = verify_area(VERIFY_READ, (void *)srqp, sizeof (slaving_request_t));
 479   if (err) return err;
 480 
 481   memcpy_fromfs (&srq, srqp, sizeof (slaving_request_t));
 482 
 483 #ifdef EQL_DEBUG
 484   if (eql_debug >= 20)
 485     printk ("%s: emancipate `%s`\n", dev->name, srq.slave_name);
 486 #endif
 487 
 488 
 489   master_dev = dev;             /* for "clarity" */
 490   slave_dev  = dev_get (srq.slave_name);
 491 
 492   if ( eql_is_slave (slave_dev) )       /* really is a slave */
 493     {
 494       equalizer_t *eql = (equalizer_t *) master_dev->priv;
 495       slave_dev->flags = slave_dev->flags & ~IFF_SLAVE;
 496 
 497       eql_remove_slave_dev (eql->queue, slave_dev);
 498 
 499       return 0;
 500     }
 501   return -EINVAL;
 502 }
 503 
 504 
 505 static 
 506 int 
 507 eql_g_slave_cfg(struct device *dev, slave_config_t *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
 508 {
 509   slave_t *slave;
 510   equalizer_t *eql;
 511   struct device *slave_dev;
 512   slave_config_t sc;
 513   int err;
 514 
 515   err = verify_area(VERIFY_READ, (void *)scp, sizeof (slave_config_t));
 516   if (err) return err;
 517 
 518   memcpy_fromfs (&sc, scp, sizeof (slave_config_t));
 519 
 520 #ifdef EQL_DEBUG
 521   if (eql_debug >= 20)
 522     printk ("%s: get config for slave `%s'\n", dev->name, sc.slave_name);
 523 #endif
 524 
 525   eql = (equalizer_t *) dev->priv;
 526   slave_dev = dev_get (sc.slave_name);
 527 
 528   if ( eql_is_slave (slave_dev) )
 529     {
 530       slave = eql_find_slave_dev (eql->queue,  slave_dev);
 531       if (slave != 0)
 532         {
 533           sc.priority = slave->priority;
 534 
 535           err = verify_area(VERIFY_WRITE, (void *)scp, sizeof (slave_config_t));
 536           if (err) return err;
 537 
 538           memcpy_tofs (scp, &sc, sizeof (slave_config_t));
 539           return 0;
 540         }
 541     }
 542   return -EINVAL;
 543 }
 544 
 545 
 546 static 
 547 int 
 548 eql_s_slave_cfg(struct device *dev, slave_config_t *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
 549 {
 550   slave_t *slave;
 551   equalizer_t *eql;
 552   struct device *slave_dev;
 553   slave_config_t sc;
 554   int err;
 555 
 556   err = verify_area(VERIFY_READ, (void *)scp, sizeof (slave_config_t));
 557   if (err) return err;
 558 
 559 #ifdef EQL_DEBUG
 560   if (eql_debug >= 20)
 561     printk ("%s: set config for slave `%s'\n", dev->name, sc.slave_name);
 562 #endif
 563   
 564   memcpy_fromfs (&sc, scp, sizeof (slave_config_t));
 565 
 566   eql = (equalizer_t *) dev->priv;
 567   slave_dev = dev_get (sc.slave_name);
 568 
 569   if ( eql_is_slave (slave_dev) )
 570     {
 571       slave = eql_find_slave_dev (eql->queue, slave_dev);
 572       if (slave != 0)
 573         {
 574           slave->priority = sc.priority;
 575           slave->priority_bps = sc.priority;
 576           slave->priority_Bps = sc.priority / 8;
 577           return 0;
 578         }
 579     }
 580   return -EINVAL;
 581 }
 582 
 583 
 584 static 
 585 int 
 586 eql_g_master_cfg(struct device *dev, master_config_t *mcp)
     /* [previous][next][first][last][top][bottom][index][help] */
 587 {
 588   equalizer_t *eql;
 589   master_config_t mc;
 590 
 591 #if EQL_DEBUG
 592   if (eql_debug >= 20)
 593     printk ("%s: get master config\n", dev->name);
 594 #endif
 595 
 596   if ( eql_is_master (dev) )
 597     {
 598       int err;
 599 
 600       err = verify_area(VERIFY_WRITE, (void *)mcp, sizeof (master_config_t));
 601       if (err) return err;
 602 
 603       eql = (equalizer_t *) dev->priv;
 604       mc.max_slaves = eql->max_slaves;
 605       mc.min_slaves = eql->min_slaves;
 606       memcpy_tofs (mcp, &mc, sizeof (master_config_t));
 607       return 0;
 608     }
 609   return -EINVAL;
 610 }
 611 
 612 
 613 static 
 614 int 
 615 eql_s_master_cfg(struct device *dev, master_config_t *mcp)
     /* [previous][next][first][last][top][bottom][index][help] */
 616 {
 617   equalizer_t *eql;
 618   master_config_t mc;
 619  int err;
 620 
 621  err = verify_area(VERIFY_READ, (void *)mcp, sizeof (master_config_t));
 622  if (err) return err;
 623 
 624 #if EQL_DEBUG
 625   if (eql_debug >= 20)
 626     printk ("%s: set master config\n", dev->name);
 627 #endif
 628 
 629   memcpy_fromfs (&mc, mcp, sizeof (master_config_t));
 630 
 631   if ( eql_is_master (dev) )
 632     {
 633       eql = (equalizer_t *) dev->priv;
 634       eql->max_slaves = mc.max_slaves;
 635       eql->min_slaves = mc.min_slaves;
 636       return 0;
 637     }
 638   return -EINVAL;
 639 }
 640 
 641 /* private device support functions
 642    ------------------------------------------------------------------
 643    */
 644 
 645 static inline
 646 int 
 647 eql_is_slave(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 648 {
 649   if (dev)
 650     {
 651       if ((dev->flags & IFF_SLAVE) == IFF_SLAVE)
 652         return 1;
 653     }
 654   return 0;
 655 }
 656 
 657 
 658 static inline
 659 int 
 660 eql_is_master(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 661 {
 662   if (dev)
 663     {
 664       if ((dev->flags & IFF_MASTER) == IFF_MASTER)
 665         return 1;
 666     }
 667   return 0;
 668 }
 669 
 670 
 671 static 
 672 slave_t *
 673 eql_new_slave(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 674 {
 675   slave_t *slave;
 676 
 677   slave = (slave_t *) kmalloc (sizeof (slave_t), GFP_KERNEL);
 678   if (slave)
 679     {
 680       memset(slave, 0, sizeof (slave_t));
 681       return slave;
 682     }
 683   return 0;
 684 }
 685 
 686 
 687 static 
 688 void
 689 eql_delete_slave(slave_t *slave)
     /* [previous][next][first][last][top][bottom][index][help] */
 690 {
 691   kfree (slave);
 692 }
 693 
 694 
 695 #if 0                           /* not currently used, will be used
 696                                    when we realy use a priority queue */
 697 static
 698 long
 699 slave_Bps(slave_t *slave)
     /* [previous][next][first][last][top][bottom][index][help] */
 700 {
 701   return (slave->priority_Bps);
 702 }
 703 
 704 static 
 705 long
 706 slave_bps(slave_t *slave)
     /* [previous][next][first][last][top][bottom][index][help] */
 707 {
 708   return (slave->priority_bps);
 709 }
 710 #endif
 711 
 712 
 713 static inline
 714 int 
 715 eql_number_slaves(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 716 {
 717   return queue->num_slaves;
 718 }
 719 
 720 
 721 static inline 
 722 int 
 723 eql_is_empty(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 724 {
 725   if (eql_number_slaves (queue) == 0)
 726     return 1;
 727   return 0;
 728 }
 729 
 730 
 731 static inline
 732 int 
 733 eql_is_full(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 734 {
 735   equalizer_t *eql = (equalizer_t *) queue->master_dev->priv;
 736 
 737   if (eql_number_slaves (queue) == eql->max_slaves)
 738     return 1;
 739   return 0;
 740 }
 741 
 742 
 743 static
 744 slave_queue_t *
 745 eql_new_slave_queue(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 746 {
 747   slave_queue_t *queue;
 748   slave_t *head_slave;
 749   slave_t *tail_slave;
 750 
 751   queue = (slave_queue_t *) kmalloc (sizeof (slave_queue_t), GFP_KERNEL);
 752   memset (queue, 0, sizeof (slave_queue_t));
 753 
 754   head_slave = eql_new_slave ();
 755   tail_slave = eql_new_slave ();
 756   
 757   if ( head_slave != 0 &&
 758        tail_slave != 0 )
 759     {
 760       head_slave->next = tail_slave;
 761       tail_slave->next = 0;
 762       queue->head = head_slave;
 763       queue->num_slaves = 0;
 764       queue->master_dev = dev;
 765     }
 766   else
 767     {
 768       kfree (queue);
 769       return 0;
 770     }
 771   return queue;
 772 }
 773 
 774 
 775 static
 776 void
 777 eql_delete_slave_queue(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 778 { 
 779   slave_t *zapped;
 780 
 781   /* this should only be called when there isn't a timer running that scans
 782      the data periodicaly.. dev_close stops the timer... */
 783 
 784   while ( ! eql_is_empty (queue) )
 785     {
 786       zapped = eql_remove_slave (queue, queue->head->next);
 787       eql_delete_slave (zapped);
 788     }
 789   kfree (queue->head->next);
 790   kfree (queue->head);
 791   kfree (queue);
 792 }
 793 
 794 
 795 static
 796 int
 797 eql_insert_slave(slave_queue_t *queue, slave_t *slave)
     /* [previous][next][first][last][top][bottom][index][help] */
 798 {
 799   cli ();
 800 
 801   if ( ! eql_is_full (queue) )
 802     {
 803       slave_t *duplicate_slave = 0;
 804 
 805       duplicate_slave = eql_find_slave_dev (queue, slave->dev);
 806 
 807       if (duplicate_slave != 0)
 808         {
 809 /*        printk ("%s: found a duplicate, killing it and replacing\n",
 810                   queue->master_dev->name); */
 811           eql_delete_slave (eql_remove_slave (queue, duplicate_slave));
 812         }
 813 
 814       slave->next = queue->head->next;
 815       queue->head->next = slave;
 816       queue->num_slaves++;
 817       sti ();
 818       return 0;
 819     }
 820 
 821   sti ();
 822 
 823   return 1;
 824 }
 825 
 826 
 827 static
 828 slave_t *
 829 eql_remove_slave(slave_queue_t *queue, slave_t *slave)
     /* [previous][next][first][last][top][bottom][index][help] */
 830 {
 831   slave_t *prev;
 832   slave_t *current;
 833 
 834   cli ();
 835 
 836   prev = queue->head;
 837   current = queue->head->next;
 838   while (current != slave && 
 839          current->dev != 0 )
 840     {
 841 /* printk ("%s: remove_slave; searching...\n", queue->master_dev->name); */
 842       prev = current;
 843       current = current->next;
 844     }
 845 
 846   if (current == slave)
 847     {
 848       prev->next = current->next;
 849       queue->num_slaves--;
 850       return current;
 851     }
 852 
 853   sti ();
 854 
 855   return 0;                     /* not found */
 856 }
 857 
 858 
 859 #if 0
 860 static 
 861 int 
 862 eql_insert_slave_dev(slave_queue_t *queue, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 863 {
 864   slave_t *slave;
 865 
 866   cli ();
 867 
 868   if ( ! eql_is_full (queue) )
 869     {
 870       slave = eql_new_slave ();
 871       slave->dev = dev;
 872       slave->priority = EQL_DEFAULT_SLAVE_PRIORITY;
 873       slave->priority_bps = EQL_DEFAULT_SLAVE_PRIORITY;
 874       slave->priority_Bps = EQL_DEFAULT_SLAVE_PRIORITY / 8;
 875       slave->next = queue->head->next;
 876       queue->head->next = slave;
 877       sti ();
 878       return 0;
 879     }
 880   sti ();
 881   return 1;
 882 }
 883 #endif
 884 
 885 
 886 static
 887 int
 888 eql_remove_slave_dev(slave_queue_t *queue, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 889 {
 890   slave_t *prev;
 891   slave_t *current;
 892   slave_t *target;
 893 
 894   target = eql_find_slave_dev (queue, dev);
 895 
 896   if (target != 0)
 897     {
 898       cli ();
 899 
 900       prev = queue->head;
 901       current = prev->next;
 902       while (current != target)
 903         {
 904           prev = current;
 905           current = current->next;
 906         }
 907       prev->next = current->next;
 908       queue->num_slaves--;
 909 
 910       sti ();
 911 
 912       eql_delete_slave (current);
 913       return 0;
 914     }
 915   return 1;
 916 }
 917 
 918 
 919 static inline
 920 struct device *
 921 eql_best_slave_dev(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 922 {
 923   if (queue->best_slave != 0)
 924     {
 925       if (queue->best_slave->dev != 0)
 926         return queue->best_slave->dev;
 927       else
 928         return 0;
 929     }
 930   else
 931     return 0;
 932 }
 933 
 934 
 935 static inline
 936 slave_t *
 937 eql_best_slave(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 938 {
 939   return queue->best_slave;
 940 }
 941 
 942 static inline
 943 void
 944 eql_schedule_slaves(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 945 {
 946   struct device *master_dev = queue->master_dev;
 947   slave_t *best_slave = 0;
 948   slave_t *slave_corpse = 0;
 949 
 950 #ifdef EQL_DEBUG
 951   if (eql_debug >= 100)
 952     printk ("%s: schedule %d slaves\n", 
 953             master_dev->name, eql_number_slaves (queue));
 954 #endif
 955 
 956   if ( eql_is_empty (queue) )
 957     {
 958       /* no slaves to play with */
 959       eql_set_best_slave (queue, (slave_t *) 0);
 960       return;
 961     }
 962   else
 963     {                           /* make a pass to set the best slave */
 964       unsigned long best_load = (unsigned long) ULONG_MAX;
 965       slave_t *slave = 0;
 966       int i;
 967 
 968       cli ();
 969 
 970       for (i = 1, slave = eql_first_slave (queue);
 971            i <= eql_number_slaves (queue);
 972            i++, slave = eql_next_slave (queue, slave))
 973         {
 974           /* go through the slave list once, updating best_slave 
 975              whenever a new best_load is found, whenever a dead
 976              slave is found, it is marked to be pulled out of the 
 977              queue */
 978 
 979           unsigned long slave_load;
 980           unsigned long bytes_queued; 
 981           unsigned long priority_Bps; 
 982           
 983           if (slave != 0)
 984             {
 985               bytes_queued = slave->bytes_queued;
 986               priority_Bps = slave->priority_Bps;    
 987 
 988               if ( slave->dev != 0)
 989                 {
 990                   if ((slave->dev->flags & IFF_UP) == IFF_UP )
 991                     {
 992                       slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - 
 993                         (priority_Bps) + bytes_queued * 8;
 994                       
 995                       if (slave_load < best_load)
 996                         {
 997                           best_load = slave_load;
 998                           best_slave = slave;
 999                         }
1000                     }
1001                   else          /* we found a dead slave */
1002                     {
1003                       /* we only bury one slave at a time, if more than
1004                          one slave dies, we will bury him on the next 
1005                          reschedule. slaves don't die all at once that much
1006                          anyway */
1007                       slave_corpse = slave;
1008                     }
1009                 }
1010             }
1011         } /* for */
1012 
1013            sti ();
1014            
1015       eql_set_best_slave (queue, best_slave);
1016     } /* else */
1017 
1018   if (slave_corpse != 0)
1019     {
1020       printk ("eql: scheduler found dead slave, burying...\n");
1021       eql_delete_slave (eql_remove_slave (queue, slave_corpse));
1022     }
1023 
1024   return;
1025 }
1026 
1027 
1028 static
1029 slave_t *
1030 eql_find_slave_dev(slave_queue_t *queue, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1031 {
1032   slave_t *slave = 0;
1033 
1034   slave = eql_first_slave(queue);
1035 
1036   while (slave != 0 && slave->dev != dev && slave != 0)
1037     {
1038 #if 0
1039       if (slave->dev != 0)
1040         printk ("eql: find_slave_dev; looked at '%s'...\n", slave->dev->name);
1041       else
1042         printk ("eql: find_slave_dev; looked at nothing...\n");
1043 #endif
1044 
1045       slave = slave->next;
1046     }
1047 
1048   return slave;
1049 }
1050 
1051 
1052 static inline
1053 slave_t *
1054 eql_first_slave(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
1055 {
1056   return queue->head->next;
1057 }
1058 
1059 
1060 static inline
1061 slave_t *
1062 eql_next_slave(slave_queue_t *queue, slave_t *slave)
     /* [previous][next][first][last][top][bottom][index][help] */
1063 {
1064   return slave->next;
1065 }
1066 
1067 
1068 static inline
1069 void
1070 eql_set_best_slave(slave_queue_t *queue, slave_t *slave)
     /* [previous][next][first][last][top][bottom][index][help] */
1071 {
1072   queue->best_slave = slave;
1073 }
1074 
1075 
1076 #if 0
1077 static inline
1078 int
1079 eql_lock_slave_queue(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
1080 {
1081   int result = 0;
1082 
1083   printk ("eql: lock == %d\n", queue->lock);
1084   if (queue->lock)
1085     {
1086       printk ("eql: lock_slave-q sleeping for lock\n");
1087       sleep_on (&eql_queue_lock);
1088       printk ("eql: lock_slave-q woken up\n");
1089       queue->lock = 1;
1090     }
1091   queue->lock = 1;
1092   return result;
1093 }
1094 
1095 static inline
1096 int
1097 eql_unlock_slave_queue(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
1098 {
1099   int result = 0;
1100 
1101   if (queue->lock != 0)
1102     {
1103       queue->lock = 0;
1104       printk ("eql: unlock_slave-q waking up lock waiters\n");
1105       wake_up (&eql_queue_lock);
1106     }
1107   return result;
1108 }
1109 #endif 
1110 
1111 static inline
1112 int
1113 eql_is_locked_slave_queue(slave_queue_t *queue)
     /* [previous][next][first][last][top][bottom][index][help] */
1114 {
1115   return test_bit(1, (void *) &queue->lock);
1116 }
1117 
1118 static 
1119 void
1120 eql_timer(unsigned long param)
     /* [previous][next][first][last][top][bottom][index][help] */
1121 {
1122   equalizer_t *eql = (equalizer_t *) param;
1123   slave_t *slave;
1124   slave_t *slave_corpse = 0;
1125   int i;
1126 
1127   if ( ! eql_is_empty (eql->queue) )
1128     {
1129       cli ();
1130 
1131       for (i = 1, slave = eql_first_slave (eql->queue);
1132            i <= eql_number_slaves (eql->queue);
1133            i++, slave = eql_next_slave (eql->queue, slave))
1134         {
1135           if (slave != 0)
1136             {
1137               if ((slave->dev->flags & IFF_UP) == IFF_UP )
1138                 {
1139                   slave->bytes_queued -= slave->priority_Bps;
1140               
1141                   if (slave->bytes_queued < 0)
1142                     slave->bytes_queued = 0;
1143                 }
1144               else
1145                 {
1146                   slave_corpse = slave;
1147                 }
1148             }
1149         }
1150 
1151       sti ();
1152       
1153       if (slave_corpse != 0)
1154         {
1155           printk ("eql: timer found dead slave, burying...\n");
1156           eql_delete_slave (eql_remove_slave (eql->queue, slave_corpse));
1157         }
1158 
1159     }
1160 
1161   if (eql->timer_on != 0) 
1162     {
1163       eql->timer.expires = EQL_DEFAULT_RESCHED_IVAL;
1164       add_timer (&eql->timer);
1165     }
1166 }
1167 
1168 /*
1169  * Local Variables: 
1170  * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c eql.c"
1171  * version-control: t
1172  * kept-new-versions: 20
1173  * End:
1174  */

/* [previous][next][first][last][top][bottom][index][help] */