Import 2.1.15
[davej-history.git] / drivers / net / eql.c
blob2d70f4ddaf49c55965c58f13a7e081d5dc59329b
1 /*
2 * Equalizer Load-balancer for serial network interfaces.
4 * (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
5 * NCM: Network and Communications Management, Inc.
8 * This software may be used and distributed according to the terms
9 * of the GNU Public License, incorporated herein by reference.
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
19 static const char*version =
20 "Equalizer1996: $Revision: 1.2.1 $ $Date: 1996/09/22 13:52:00 $ Simon Janes (simon@ncm.com)\n";
23 * Sources:
24 * skeleton.c by Donald Becker.
25 * Inspirations:
26 * The Harried and Overworked Alan Cox
27 * Conspiracies:
28 * The Alan Cox and Mike McLagan plot to get someone else to do the code,
29 * which turned out to be me.
33 * $Log: eql.c,v $
34 * Revision 1.2 1996/04/11 17:51:52 guru
35 * Added one-line eql_remove_slave patch.
37 * Revision 1.1 1996/04/11 17:44:17 guru
38 * Initial revision
40 * Revision 3.13 1996/01/21 15:17:18 alan
41 * tx_queue_len changes.
42 * reformatted.
44 * Revision 3.12 1995/03/22 21:07:51 anarchy
45 * Added suser() checks on configuration.
46 * Moved header file.
48 * Revision 3.11 1995/01/19 23:14:31 guru
49 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
50 * (priority_Bps) + bytes_queued * 8;
52 * Revision 3.10 1995/01/19 23:07:53 guru
53 * back to
54 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
55 * (priority_Bps) + bytes_queued;
57 * Revision 3.9 1995/01/19 22:38:20 guru
58 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
59 * (priority_Bps) + bytes_queued * 4;
61 * Revision 3.8 1995/01/19 22:30:55 guru
62 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) -
63 * (priority_Bps) + bytes_queued * 2;
65 * Revision 3.7 1995/01/19 21:52:35 guru
66 * printk's trimmed out.
68 * Revision 3.6 1995/01/19 21:49:56 guru
69 * This is working pretty well. I gained 1 K/s in speed.. now it's just
70 * robustness and printk's to be diked out.
72 * Revision 3.5 1995/01/18 22:29:59 guru
73 * still crashes the kernel when the lock_wait thing is woken up.
75 * Revision 3.4 1995/01/18 21:59:47 guru
76 * Broken set-bit locking snapshot
78 * Revision 3.3 1995/01/17 22:09:18 guru
79 * infinite sleep in a lock somewhere..
81 * Revision 3.2 1995/01/15 16:46:06 guru
82 * Log trimmed of non-pertinent 1.x branch messages
84 * Revision 3.1 1995/01/15 14:41:45 guru
85 * New Scheduler and timer stuff...
87 * Revision 1.15 1995/01/15 14:29:02 guru
88 * Will make 1.14 (now 1.15) the 3.0 branch, and the 1.12 the 2.0 branch, the one
89 * with the dumber scheduler
91 * Revision 1.14 1995/01/15 02:37:08 guru
92 * shock.. the kept-new-versions could have zonked working
93 * stuff.. shudder
95 * Revision 1.13 1995/01/15 02:36:31 guru
96 * big changes
98 * scheduler was torn out and replaced with something smarter
100 * global names not prefixed with eql_ were renamed to protect
101 * against namespace collisions
103 * a few more abstract interfaces were added to facilitate any
104 * potential change of datastructure. the driver is still using
105 * a linked list of slaves. going to a heap would be a bit of
106 * an overkill.
108 * this compiles fine with no warnings.
110 * the locking mechanism and timer stuff must be written however,
111 * this version will not work otherwise
115 #include <linux/module.h>
117 #include <linux/kernel.h>
118 #include <linux/sched.h>
119 #include <linux/types.h>
120 #include <linux/fcntl.h>
121 #include <linux/interrupt.h>
122 #include <linux/ptrace.h>
123 #include <linux/ioport.h>
124 #include <linux/in.h>
125 #include <linux/malloc.h>
126 #include <linux/string.h>
127 #include <asm/system.h>
128 #include <asm/bitops.h>
129 #include <asm/io.h>
130 #include <asm/dma.h>
131 #include <asm/uaccess.h>
132 #include <linux/errno.h>
134 #include <linux/netdevice.h>
135 #include <linux/if.h>
136 #include <linux/if_arp.h>
137 #include <linux/timer.h>
139 #include <linux/if_eql.h>
141 #ifndef EQL_DEBUG
142 /* #undef EQL_DEBUG -* print nothing at all, not even a boot-banner */
143 /* #define EQL_DEBUG 1 -* print only the boot-banner */
144 /* #define EQL_DEBUG 5 -* print major function entries */
145 /* #define EQL_DEBUG 20 -* print subfunction entries */
146 /* #define EQL_DEBUG 50 -* print utility entries */
147 /* #define EQL_DEBUG 100 -* print voluminous function entries */
148 #define EQL_DEBUG 1
149 #endif
150 static unsigned int eql_debug = EQL_DEBUG;
152 inteql_init(struct device *dev);/* */
153 static inteql_open(struct device *dev);/* */
154 static inteql_close(struct device *dev);/* */
155 static inteql_ioctl(struct device *dev,struct ifreq *ifr,int cmd);/* */
156 static inteql_slave_xmit(struct sk_buff *skb,struct device *dev);/* */
158 static struct enet_statistics *eql_get_stats(struct device *dev);/* */
160 /* ioctl() handlers
161 ---------------- */
162 static inteql_enslave(struct device *dev, slaving_request_t *srq);/* */
163 static inteql_emancipate(struct device *dev, slaving_request_t *srq);/* */
165 static inteql_g_slave_cfg(struct device *dev, slave_config_t *sc);/* */
166 static inteql_s_slave_cfg(struct device *dev, slave_config_t *sc);/* */
168 static inteql_g_master_cfg(struct device *dev, master_config_t *mc);/* */
169 static inteql_s_master_cfg(struct device *dev, master_config_t *mc);/* */
171 staticinlineinteql_is_slave(struct device *dev);/* */
172 staticinlineinteql_is_master(struct device *dev);/* */
174 static slave_t *eql_new_slave(void);/* */
175 static voideql_delete_slave(slave_t *slave);/* */
177 /* static long eql_slave_priority(slave_t *slave); -* */
178 staticinlineinteql_number_slaves(slave_queue_t *queue);/* */
180 staticinlineinteql_is_empty(slave_queue_t *queue);/* */
181 staticinlineinteql_is_full(slave_queue_t *queue);/* */
183 static slave_queue_t *eql_new_slave_queue(struct device *dev);/* */
184 static voideql_delete_slave_queue(slave_queue_t *queue);/* */
186 static inteql_insert_slave(slave_queue_t *queue, slave_t *slave);/* */
187 static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave);/* */
189 /* static int eql_insert_slave_dev(slave_queue_t *queue, struct device *dev); -* */
190 static inteql_remove_slave_dev(slave_queue_t *queue,struct device *dev);/* */
192 staticinlinestruct device *eql_best_slave_dev(slave_queue_t *queue);/* */
193 staticinline slave_t *eql_best_slave(slave_queue_t *queue);/* */
194 staticinline slave_t *eql_first_slave(slave_queue_t *queue);/* */
195 staticinline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave);/* */
197 staticinlinevoideql_set_best_slave(slave_queue_t *queue, slave_t *slave);/* */
198 staticinlinevoideql_schedule_slaves(slave_queue_t *queue);/* */
200 static slave_t *eql_find_slave_dev(slave_queue_t *queue,struct device *dev);/* */
202 /* static inline eql_lock_slave_queue(slave_queue_t *queue); -* */
203 /* static inline eql_unlock_slave_queue(slave_queue_t *queue); -* */
205 static voideql_timer(unsigned long param);/* */
207 /* struct device * interface functions
208 ---------------------------------------------------------
211 inteql_init(struct device *dev)
213 static unsigned version_printed =0;
214 /* static unsigned num_masters = 0; */
215 equalizer_t *eql =0;
216 int i;
218 if( version_printed++ ==0&& eql_debug >0)
219 printk(version);
221 * Initialize the device structure.
223 dev->priv =kmalloc(sizeof(equalizer_t), GFP_KERNEL);
224 if(dev->priv == NULL)
225 return-ENOMEM;
226 memset(dev->priv,0,sizeof(equalizer_t));
227 eql = (equalizer_t *) dev->priv;
229 eql->stats =kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
230 if(eql->stats == NULL)
232 kfree(dev->priv);
233 dev->priv = NULL;
234 return-ENOMEM;
236 memset(eql->stats,0,sizeof(struct enet_statistics));
238 init_timer(&eql->timer);
239 eql->timer.data = (unsigned long) dev->priv;
240 eql->timer.expires = jiffies+EQL_DEFAULT_RESCHED_IVAL;
241 eql->timer.function = &eql_timer;
242 eql->timer_on =0;
244 dev->open = eql_open;
245 dev->stop = eql_close;
246 dev->do_ioctl = eql_ioctl;
247 dev->hard_start_xmit = eql_slave_xmit;
248 dev->get_stats = eql_get_stats;
251 * Fill in the fields of the device structure with
252 * eql-generic values. This should be in a common
253 * file instead of per-driver.
256 for(i =0; i < DEV_NUMBUFFS; i++)
257 skb_queue_head_init(&dev->buffs[i]);
260 * Now we undo some of the things that eth_setup does
261 * that we don't like
264 dev->mtu = EQL_DEFAULT_MTU;/* set to 576 in eql.h */
265 dev->flags = IFF_MASTER;
267 dev->family = AF_INET;
268 dev->pa_addr =0;
269 dev->pa_brdaddr =0;
270 dev->pa_mask =0;
271 dev->pa_alen =4;
273 dev->type = ARPHRD_SLIP;
274 dev->tx_queue_len =5;/* Hands them off fast */
276 return0;
279 static inteql_open(struct device *dev)
281 equalizer_t *eql = (equalizer_t *) dev->priv;
282 slave_queue_t *new_queue;
284 #ifdef EQL_DEBUG
285 if(eql_debug >=5)
286 printk("%s: open\n", dev->name);
287 #endif
289 printk("%s: remember to turn off Van-Jacobson compression on your slave devices.\n", dev->name);
291 new_queue =eql_new_slave_queue(dev);
293 if(new_queue !=0)
295 new_queue->master_dev = dev;
296 eql->queue = new_queue;
297 eql->queue->lock =0;
298 eql->min_slaves =1;
299 eql->max_slaves = EQL_DEFAULT_MAX_SLAVES;/* 4 usually... */
301 printk("%s: adding timer\n", dev->name);
302 eql->timer_on =1;
303 add_timer(&eql->timer);
305 MOD_INC_USE_COUNT;
306 return0;
308 return1;
312 static inteql_close(struct device *dev)
314 equalizer_t *eql = (equalizer_t *) dev->priv;
316 #ifdef EQL_DEBUG
317 if( eql_debug >=5)
318 printk("%s: close\n", dev->name);
319 #endif
321 * The timer has to be stopped first before we start hacking away
322 * at the data structure it scans every so often...
325 #ifdef EQL_DEBUG
326 printk("%s: stopping timer\n", dev->name);
327 #endif
328 eql->timer_on =0;
329 del_timer(&eql->timer);
331 eql_delete_slave_queue(eql->queue);
333 MOD_DEC_USE_COUNT;
334 return0;
338 static inteql_ioctl(struct device *dev,struct ifreq *ifr,int cmd)
340 if(!suser() && cmd!=EQL_GETMASTRCFG && cmd!=EQL_GETSLAVECFG)
341 return-EPERM;
342 switch(cmd)
344 case EQL_ENSLAVE:
345 returneql_enslave(dev, (slaving_request_t *) ifr->ifr_data);
346 case EQL_EMANCIPATE:
347 returneql_emancipate(dev, (slaving_request_t *) ifr->ifr_data);
348 case EQL_GETSLAVECFG:
349 returneql_g_slave_cfg(dev, (slave_config_t *) ifr->ifr_data);
350 case EQL_SETSLAVECFG:
351 returneql_s_slave_cfg(dev, (slave_config_t *) ifr->ifr_data);
352 case EQL_GETMASTRCFG:
353 returneql_g_master_cfg(dev, (master_config_t *) ifr->ifr_data);
354 case EQL_SETMASTRCFG:
355 returneql_s_master_cfg(dev, (master_config_t *) ifr->ifr_data);
356 default:
357 return-EOPNOTSUPP;
362 static inteql_slave_xmit(struct sk_buff *skb,struct device *dev)
364 equalizer_t *eql = (equalizer_t *) dev->priv;
365 struct device *slave_dev =0;
366 slave_t *slave;
368 if(skb == NULL)
369 return0;
371 eql_schedule_slaves(eql->queue);
373 slave_dev =eql_best_slave_dev(eql->queue);
374 slave =eql_best_slave(eql->queue);
376 if( slave_dev !=0)
378 #ifdef EQL_DEBUG
379 if(eql_debug >=100)
380 printk("%s: %d slaves xmitng %ld B %s\n",
381 dev->name,eql_number_slaves(eql->queue), skb->len,
382 slave_dev->name);
383 #endif
384 skb->dev = slave_dev;
385 skb->priority =1;
386 dev_queue_xmit(skb);
387 eql->stats->tx_packets++;
388 slave->bytes_queued += skb->len;
390 else
393 * The alternative for this is the return 1 and have
394 * dev_queue_xmit just queue it up on the eql's queue.
397 eql->stats->tx_dropped++;
398 dev_kfree_skb(skb, FREE_WRITE);
400 return0;
404 static struct enet_statistics *eql_get_stats(struct device *dev)
406 equalizer_t *eql = (equalizer_t *) dev->priv;
407 return eql->stats;
411 * Private ioctl functions
414 static inteql_enslave(struct device *dev, slaving_request_t *srqp)
416 struct device *master_dev;
417 struct device *slave_dev;
418 slaving_request_t srq;
419 int err;
421 err =verify_area(VERIFY_READ, (void*)srqp,sizeof(slaving_request_t));
422 if(err)
424 #ifdef EQL_DEBUG
425 if(eql_debug >=20)
426 printk("EQL enslave: error detected by verify_area\n");
427 #endif
428 return err;
430 copy_from_user(&srq, srqp,sizeof(slaving_request_t));
432 #ifdef EQL_DEBUG
433 if(eql_debug >=20)
434 printk("%s: enslave '%s' %ld bps\n", dev->name,
435 srq.slave_name, srq.priority);
436 #endif
437 master_dev = dev;/* for "clarity" */
438 slave_dev =dev_get(srq.slave_name);
440 if(master_dev !=0&& slave_dev !=0)
442 if((master_dev->flags & IFF_UP) == IFF_UP)
444 /*slave is not a master & not already a slave:*/
445 if(!eql_is_master(slave_dev) &&
446 !eql_is_slave(slave_dev) )
448 slave_t *s =eql_new_slave();
449 equalizer_t *eql =
450 (equalizer_t *) master_dev->priv;
451 s->dev = slave_dev;
452 s->priority = srq.priority;
453 s->priority_bps = srq.priority;
454 s->priority_Bps = srq.priority /8;
455 slave_dev->flags |= IFF_SLAVE;
456 eql_insert_slave(eql->queue, s);
457 return0;
459 #ifdef EQL_DEBUG
460 else if(eql_debug >=20)
461 printk("EQL enslave: slave is master or slave is already slave\n");
462 #endif
464 #ifdef EQL_DEBUG
465 else if(eql_debug >=20)
466 printk("EQL enslave: master device not up!\n");
467 #endif
469 #ifdef EQL_DEBUG
470 else if(eql_debug >=20)
471 printk("EQL enslave: master or slave are NULL");
472 #endif
473 return-EINVAL;
476 static inteql_emancipate(struct device *dev, slaving_request_t *srqp)
478 struct device *master_dev;
479 struct device *slave_dev;
480 slaving_request_t srq;
481 int err;
483 err =verify_area(VERIFY_READ, (void*)srqp,sizeof(slaving_request_t));
484 if(err)
485 return err;
487 copy_from_user(&srq, srqp,sizeof(slaving_request_t));
488 #ifdef EQL_DEBUG
489 if(eql_debug >=20)
490 printk("%s: emancipate `%s`\n", dev->name, srq.slave_name);
491 #endif
492 master_dev = dev;/* for "clarity" */
493 slave_dev =dev_get(srq.slave_name);
495 if(eql_is_slave(slave_dev) )/* really is a slave */
497 equalizer_t *eql = (equalizer_t *) master_dev->priv;
498 slave_dev->flags = slave_dev->flags & ~IFF_SLAVE;
499 eql_remove_slave_dev(eql->queue, slave_dev);
500 return0;
502 return-EINVAL;
506 static inteql_g_slave_cfg(struct device *dev, slave_config_t *scp)
508 slave_t *slave;
509 equalizer_t *eql;
510 struct device *slave_dev;
511 slave_config_t sc;
512 int err;
514 err =verify_area(VERIFY_READ, (void*)scp,sizeof(slave_config_t));
515 if(err)
516 return err;
518 copy_from_user(&sc, scp,sizeof(slave_config_t));
519 #ifdef EQL_DEBUG
520 if(eql_debug >=20)
521 printk("%s: get config for slave `%s'\n", dev->name, sc.slave_name);
522 #endif
523 eql = (equalizer_t *) dev->priv;
524 slave_dev =dev_get(sc.slave_name);
526 if(eql_is_slave(slave_dev) )
528 slave =eql_find_slave_dev(eql->queue, slave_dev);
529 if(slave !=0)
531 sc.priority = slave->priority;
532 err =verify_area(VERIFY_WRITE, (void*)scp,sizeof(slave_config_t));
533 if(err)
534 return err;
535 copy_to_user(scp, &sc,sizeof(slave_config_t));
536 return0;
539 return-EINVAL;
543 static inteql_s_slave_cfg(struct device *dev, slave_config_t *scp)
545 slave_t *slave;
546 equalizer_t *eql;
547 struct device *slave_dev;
548 slave_config_t sc;
549 int err;
551 err =verify_area(VERIFY_READ, (void*)scp,sizeof(slave_config_t));
552 if(err)
553 return err;
555 #ifdef EQL_DEBUG
556 if(eql_debug >=20)
557 printk("%s: set config for slave `%s'\n", dev->name, sc.slave_name);
558 #endif
560 copy_from_user(&sc, scp,sizeof(slave_config_t));
562 eql = (equalizer_t *) dev->priv;
563 slave_dev =dev_get(sc.slave_name);
565 if(eql_is_slave(slave_dev) )
567 slave =eql_find_slave_dev(eql->queue, slave_dev);
568 if(slave !=0)
570 slave->priority = sc.priority;
571 slave->priority_bps = sc.priority;
572 slave->priority_Bps = sc.priority /8;
573 return0;
576 return-EINVAL;
580 static inteql_g_master_cfg(struct device *dev, master_config_t *mcp)
582 equalizer_t *eql;
583 master_config_t mc;
585 #if EQL_DEBUG
586 if(eql_debug >=20)
587 printk("%s: get master config\n", dev->name);
588 #endif
590 if(eql_is_master(dev) )
592 int err;
593 err =verify_area(VERIFY_WRITE, (void*)mcp,sizeof(master_config_t));
594 if(err)
595 return err;
596 eql = (equalizer_t *) dev->priv;
597 mc.max_slaves = eql->max_slaves;
598 mc.min_slaves = eql->min_slaves;
599 copy_to_user(mcp, &mc,sizeof(master_config_t));
600 return0;
602 return-EINVAL;
606 static inteql_s_master_cfg(struct device *dev, master_config_t *mcp)
608 equalizer_t *eql;
609 master_config_t mc;
610 int err;
612 err =verify_area(VERIFY_READ, (void*)mcp,sizeof(master_config_t));
613 if(err)
614 return err;
615 #if EQL_DEBUG
616 if(eql_debug >=20)
617 printk("%s: set master config\n", dev->name);
618 #endif
619 copy_from_user(&mc, mcp,sizeof(master_config_t));
620 if(eql_is_master(dev) )
622 eql = (equalizer_t *) dev->priv;
623 eql->max_slaves = mc.max_slaves;
624 eql->min_slaves = mc.min_slaves;
625 return0;
627 return-EINVAL;
631 * Private device support functions
634 staticinlineinteql_is_slave(struct device *dev)
636 if(dev)
638 if((dev->flags & IFF_SLAVE) == IFF_SLAVE)
639 return1;
641 return0;
645 staticinlineinteql_is_master(struct device *dev)
647 if(dev)
649 if((dev->flags & IFF_MASTER) == IFF_MASTER)
650 return1;
652 return0;
656 static slave_t *eql_new_slave(void)
658 slave_t *slave;
660 slave = (slave_t *)kmalloc(sizeof(slave_t), GFP_KERNEL);
661 if(slave)
663 memset(slave,0,sizeof(slave_t));
664 return slave;
666 return0;
670 static voideql_delete_slave(slave_t *slave)
672 kfree(slave);
676 #if 0/* not currently used, will be used
677 when we really use a priority queue */
678 static longslave_Bps(slave_t *slave)
680 return(slave->priority_Bps);
683 static longslave_bps(slave_t *slave)
685 return(slave->priority_bps);
688 #endif
690 staticinlineinteql_number_slaves(slave_queue_t *queue)
692 return queue->num_slaves;
695 staticinlineinteql_is_empty(slave_queue_t *queue)
697 if(eql_number_slaves(queue) ==0)
698 return1;
699 return0;
702 staticinlineinteql_is_full(slave_queue_t *queue)
704 equalizer_t *eql = (equalizer_t *) queue->master_dev->priv;
706 if(eql_number_slaves(queue) == eql->max_slaves)
707 return1;
708 return0;
711 static slave_queue_t *eql_new_slave_queue(struct device *dev)
713 slave_queue_t *queue;
714 slave_t *head_slave;
715 slave_t *tail_slave;
717 queue = (slave_queue_t *)kmalloc(sizeof(slave_queue_t), GFP_KERNEL);
718 if(queue == NULL)
719 return0;
720 memset(queue,0,sizeof(slave_queue_t));
721 head_slave =eql_new_slave();
722 tail_slave =eql_new_slave();
724 if( head_slave !=0&&
725 tail_slave !=0)
727 head_slave->next = tail_slave;
728 tail_slave->next =0;
729 queue->head = head_slave;
730 queue->num_slaves =0;
731 queue->master_dev = dev;
733 else
735 if(head_slave)
736 kfree(head_slave);
737 if(tail_slave)
738 kfree(tail_slave);
739 kfree(queue);
740 return0;
742 return queue;
746 static voideql_delete_slave_queue(slave_queue_t *queue)
748 slave_t *zapped;
750 * This should only be called when there isn't a
751 * timer running that scans the data periodically..
752 * dev_close stops the timer...
755 while( !eql_is_empty(queue) )
757 zapped =eql_remove_slave(queue, queue->head->next);
758 eql_delete_slave(zapped);
760 kfree(queue->head->next);
761 kfree(queue->head);
762 kfree(queue);
765 static inteql_insert_slave(slave_queue_t *queue, slave_t *slave)
767 cli();
769 if( !eql_is_full(queue) )
771 slave_t *duplicate_slave =0;
772 duplicate_slave =eql_find_slave_dev(queue, slave->dev);
773 if(duplicate_slave !=0)
775 /* printk ("%s: found a duplicate, killing it and replacing\n",
776 queue->master_dev->name); */
777 eql_delete_slave(eql_remove_slave(queue, duplicate_slave));
779 slave->next = queue->head->next;
780 queue->head->next = slave;
781 queue->num_slaves++;
782 sti();
783 return0;
785 sti();
786 return1;
790 static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave)
792 slave_t *prev;
793 slave_t *curr;
795 cli();
797 prev = queue->head;
798 curr = queue->head->next;
799 while(curr != slave &&
800 curr->dev !=0)
802 /* printk ("%s: remove_slave; searching...\n", queue->master_dev->name); */
803 prev = curr;
804 curr = curr->next;
807 if(curr == slave)
809 prev->next = curr->next;
810 queue->num_slaves--;
811 curr->dev->flags = curr->dev->flags & ~IFF_SLAVE;
812 sti();
813 return curr;
815 sti();
816 return0;/* not found */
820 static inteql_remove_slave_dev(slave_queue_t *queue,struct device *dev)
822 slave_t *prev;
823 slave_t *curr;
824 slave_t *target;
826 target =eql_find_slave_dev(queue, dev);
828 if(target !=0)
830 cli();
831 prev = queue->head;
832 curr = prev->next;
833 while(curr != target)
835 prev = curr;
836 curr = curr->next;
838 prev->next = curr->next;
839 queue->num_slaves--;
840 sti();
841 eql_delete_slave(curr);
842 return0;
844 return1;
848 staticinlinestruct device *eql_best_slave_dev(slave_queue_t *queue)
850 if(queue->best_slave !=0)
852 if(queue->best_slave->dev !=0)
853 return queue->best_slave->dev;
854 else
855 return0;
857 else
858 return0;
862 staticinline slave_t *eql_best_slave(slave_queue_t *queue)
864 return queue->best_slave;
867 staticinlinevoideql_schedule_slaves(slave_queue_t *queue)
869 struct device *master_dev = queue->master_dev;
870 slave_t *best_slave =0;
871 slave_t *slave_corpse =0;
873 #ifdef EQL_DEBUG
874 if(eql_debug >=100)
875 printk("%s: schedule %d slaves\n",
876 master_dev->name,eql_number_slaves(queue));
877 #endif
878 if(eql_is_empty(queue) )
881 * No slaves to play with
883 eql_set_best_slave(queue, (slave_t *)0);
884 return;
886 else
889 * Make a pass to set the best slave
891 unsigned long best_load = (unsigned long) ULONG_MAX;
892 slave_t *slave =0;
893 int i;
895 cli();
896 for(i =1, slave =eql_first_slave(queue);
897 i <=eql_number_slaves(queue);
898 i++, slave =eql_next_slave(queue, slave))
901 * Go through the slave list once, updating best_slave
902 * whenever a new best_load is found, whenever a dead
903 * slave is found, it is marked to be pulled out of the
904 * queue
907 unsigned long slave_load;
908 unsigned long bytes_queued;
909 unsigned long priority_Bps;
911 if(slave !=0)
913 bytes_queued = slave->bytes_queued;
914 priority_Bps = slave->priority_Bps;
915 if( slave->dev !=0)
917 if((slave->dev->flags & IFF_UP) == IFF_UP )
919 slave_load = (ULONG_MAX - (ULONG_MAX /2)) -
920 (priority_Bps) + bytes_queued *8;
922 if(slave_load < best_load)
924 best_load = slave_load;
925 best_slave = slave;
928 else/* we found a dead slave */
931 * We only bury one slave at a time, if more than
932 * one slave dies, we will bury him on the next
933 * reschedule. slaves don't die all at once that
934 * much anyway
936 slave_corpse = slave;
940 }/* for */
941 sti();
942 eql_set_best_slave(queue, best_slave);
943 }/* else */
944 if(slave_corpse !=0)
946 printk("eql: scheduler found dead slave, burying...\n");
947 eql_delete_slave(eql_remove_slave(queue, slave_corpse));
949 return;
953 static slave_t *eql_find_slave_dev(slave_queue_t *queue,struct device *dev)
955 slave_t *slave =0;
956 slave =eql_first_slave(queue);
958 while(slave !=0&& slave->dev != dev && slave !=0)
960 #if 0
961 if(slave->dev !=0)
962 printk("eql: find_slave_dev; looked at '%s'...\n", slave->dev->name);
963 else
964 printk("eql: find_slave_dev; looked at nothing...\n");
965 #endif
966 slave = slave->next;
968 return slave;
972 staticinline slave_t *eql_first_slave(slave_queue_t *queue)
974 return queue->head->next;
978 staticinline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave)
980 return slave->next;
983 staticinlinevoideql_set_best_slave(slave_queue_t *queue, slave_t *slave)
985 queue->best_slave = slave;
988 static voideql_timer(unsigned long param)
990 equalizer_t *eql = (equalizer_t *) param;
991 slave_t *slave;
992 slave_t *slave_corpse =0;
993 int i;
995 if( !eql_is_empty(eql->queue) )
997 cli();
998 for(i =1, slave =eql_first_slave(eql->queue);
999 i <=eql_number_slaves(eql->queue);
1000 i++, slave =eql_next_slave(eql->queue, slave))
1002 if(slave !=0)
1004 if((slave->dev->flags & IFF_UP) == IFF_UP )
1006 slave->bytes_queued -= slave->priority_Bps;
1007 if(slave->bytes_queued <0)
1008 slave->bytes_queued =0;
1010 else
1011 slave_corpse = slave;
1014 sti();
1015 if(slave_corpse !=0)
1017 printk("eql: timer found dead slave, burying...\n");
1018 eql_delete_slave(eql_remove_slave(eql->queue, slave_corpse));
1022 if(eql->timer_on !=0)
1024 eql->timer.expires = jiffies+EQL_DEFAULT_RESCHED_IVAL;
1025 add_timer(&eql->timer);
1029 #ifdef MODULE
1030 static struct device dev_eql =
1032 "eql",0,0,0,0,0,0,0,0,0, NULL, eql_init
1035 intinit_module(void)
1037 if(register_netdev(&dev_eql) !=0) {
1038 printk("eql: register_netdev() returned non-zero.\n");
1039 return-EIO;
1041 return0;
1044 voidcleanup_module(void)
1046 unregister_netdev(&dev_eql);
1048 #endif/* MODULE */
1051 * Local Variables:
1052 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c eql.c"
1053 * version-control: t
1054 * kept-new-versions: 20
1055 * End:
close