/[dynamips]/trunk/cisco_card.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/cisco_card.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 25302 byte(s)
make working copy

1 dpavlin 11 /*
2     * Cisco router simulation platform.
3     * Copyright (c) 2007 Christophe Fillot (cf@utc.fr)
4     *
5     * Generic Cisco card routines and definitions.
6     */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10     #include <string.h>
11     #include <unistd.h>
12     #include <sys/types.h>
13     #include <assert.h>
14    
15     #include "cpu.h"
16     #include "vm.h"
17     #include "dynamips.h"
18     #include "memory.h"
19     #include "device.h"
20     #include "cisco_card.h"
21    
22     /* Get cisco card type description */
23     char *cisco_card_get_type_desc(int dev_type)
24     {
25     switch(dev_type) {
26     case CISCO_CARD_TYPE_PA:
27     return("Port Adapter (PA)");
28     case CISCO_CARD_TYPE_NM:
29     return("Network Module (NM)");
30     case CISCO_CARD_TYPE_WIC:
31     return("WAN Interface Card (WIC)");
32     default:
33     return("Unknown");
34     }
35     }
36    
37     /* Set EEPROM definition for the specified Cisco card */
38     int cisco_card_set_eeprom(vm_instance_t *vm,struct cisco_card *card,
39     const struct cisco_eeprom *eeprom)
40     {
41     if (!eeprom)
42     return(0);
43    
44     if (cisco_eeprom_copy(&card->eeprom,eeprom) == -1) {
45     vm_error(vm,"cisco_card_set_eeprom: no memory (eeprom=%p).\n",eeprom);
46     return(-1);
47     }
48    
49     return(0);
50     }
51    
52     /* Unset EEPROM definition */
53     int cisco_card_unset_eeprom(struct cisco_card *card)
54     {
55     cisco_eeprom_free(&card->eeprom);
56     return(0);
57     }
58    
59     /* Check if a card has a valid EEPROM defined */
60     int cisco_card_check_eeprom(struct cisco_card *card)
61     {
62     return(cisco_eeprom_valid(&card->eeprom));
63     }
64    
65     /* Create a card structure */
66     static inline struct cisco_card *cisco_card_create(u_int card_type)
67     {
68     struct cisco_card *card;
69    
70     if ((card = malloc(sizeof(*card))) != NULL) {
71     memset(card,0,sizeof(*card));
72     card->card_type = card_type;
73     }
74    
75     return card;
76     }
77    
78     /* Find a NIO binding */
79     static struct cisco_nio_binding *
80     cisco_card_find_nio_binding(struct cisco_card *card,u_int port_id)
81     {
82     struct cisco_nio_binding *nb;
83    
84     if (!card)
85     return NULL;
86    
87     for(nb=card->nio_list;nb;nb=nb->next)
88     if (nb->port_id == port_id)
89     return nb;
90    
91     return NULL;
92     }
93    
94     /* Remove all NIO bindings */
95     static void
96     cisco_card_remove_all_nio_bindings(vm_instance_t *vm,struct cisco_card *card)
97     {
98     struct cisco_nio_binding *nb,*next;
99    
100     for(nb=card->nio_list;nb;nb=next) {
101     next = nb->next;
102    
103     /* tell the slot driver to stop using this NIO */
104     if (card->driver)
105     card->driver->card_unset_nio(vm,card,nb->port_id);
106    
107     /* unreference NIO object */
108     netio_release(nb->nio->name);
109     free(nb);
110     }
111    
112     card->nio_list = NULL;
113     }
114    
115     /* Enable all NIO for the specified card */
116     static inline
117     void cisco_card_enable_all_nio(vm_instance_t *vm,struct cisco_card *card)
118     {
119     struct cisco_nio_binding *nb;
120    
121     if (card && card->driver && card->drv_info)
122     for(nb=card->nio_list;nb;nb=nb->next)
123     card->driver->card_set_nio(vm,card,nb->port_id,nb->nio);
124     }
125    
126     /* Disable all NIO for the specified card */
127     static inline
128     void cisco_card_disable_all_nio(vm_instance_t *vm,struct cisco_card *card)
129     {
130     struct cisco_nio_binding *nb;
131    
132     if (card && card->driver && card->drv_info)
133     for(nb=card->nio_list;nb;nb=nb->next)
134     card->driver->card_unset_nio(vm,card,nb->port_id);
135     }
136    
137     /* Initialize a card */
138     static inline
139     int cisco_card_init(vm_instance_t *vm,struct cisco_card *card,u_int id)
140     {
141     size_t len;
142    
143     /* Check that a device type is defined for this card */
144     if (!card || !card->dev_type || !card->driver)
145     return(-1);
146    
147     /* Allocate device name */
148     len = strlen(card->dev_type) + 10;
149     if (!(card->dev_name = malloc(len))) {
150     vm_error(vm,"unable to allocate device name.\n");
151     return(-1);
152     }
153    
154     snprintf(card->dev_name,len,"%s(%u)",card->dev_type,id);
155    
156     /* Initialize card driver */
157     if (card->driver->card_init(vm,card) == -1) {
158     vm_error(vm,"unable to initialize card type '%s' (id %u)\n",
159     card->dev_type,id);
160     return(-1);
161     }
162    
163     return(0);
164     }
165    
166     /* Shutdown card */
167     static int cisco_card_shutdown(vm_instance_t *vm,struct cisco_card *card)
168     {
169     /* Check that a device type is defined for this card */
170     if (!card || !card->dev_type || !card->driver)
171     return(-1);
172    
173     /* Shutdown the NM driver */
174     if (card->drv_info && (card->driver->card_shutdown(vm,card) == -1)) {
175     vm_error(vm,"unable to shutdown card type '%s' (slot %u/%u)\n",
176     card->dev_type,card->slot_id,card->subslot_id);
177     return(-1);
178     }
179    
180     free(card->dev_name);
181     card->dev_name = NULL;
182     card->drv_info = NULL;
183     return(0);
184     }
185    
186     /* Show info for the specified card */
187     static int cisco_card_show_info(vm_instance_t *vm,struct cisco_card *card)
188     {
189     /* Check that a device type is defined for this card */
190     if (!card || !card->driver || !card->driver->card_show_info)
191     return(-1);
192    
193     card->driver->card_show_info(vm,card);
194     return(0);
195     }
196    
197     /* Save config for the specified card */
198     static int cisco_card_save_config(vm_instance_t *vm,struct cisco_card *card,
199     FILE *fd)
200     {
201     struct cisco_nio_binding *nb;
202    
203     fprintf(fd,"vm add_slot_binding %s %u %u %s\n",
204     vm->name,card->slot_id,card->subslot_id,card->dev_type);
205    
206     for(nb=card->nio_list;nb;nb=nb->next) {
207     fprintf(fd,"vm add_nio_binding %s %u %u %s\n",
208     vm->name,card->slot_id,nb->orig_port_id,nb->nio->name);
209     }
210    
211     return(0);
212     }
213    
214     /* Find a driver in a driver array */
215     static struct cisco_card_driver *
216     cisco_card_find_driver(struct cisco_card_driver **array,char *dev_type)
217     {
218     int i;
219    
220     for(i=0;array[i]!=NULL;i++)
221     if (!strcmp(array[i]->dev_type,dev_type))
222     return array[i];
223    
224     return NULL;
225     }
226    
227     /* ======================================================================== */
228     /* High level routines for managing VM slots. */
229     /* ======================================================================== */
230    
231     /* Get slot info */
232     struct cisco_card *vm_slot_get_card_ptr(vm_instance_t *vm,u_int slot_id)
233     {
234     if (slot_id >= vm->nr_slots)
235     return NULL;
236    
237     return(vm->slots[slot_id]);
238     }
239    
240     /* Get info for a slot/port (with sub-cards) */
241     static int vm_slot_get_info(vm_instance_t *vm,u_int slot_id,u_int port_id,
242     struct cisco_card ***rc,u_int *real_port_id)
243     {
244     struct cisco_card *card;
245     u_int wic_id,card_type;
246    
247     if (slot_id >= VM_MAX_SLOTS) {
248     *rc = NULL;
249     return(-1);
250     }
251    
252     *rc = &vm->slots[slot_id];
253     card = vm->slots[slot_id];
254    
255     card_type = (card != NULL) ? card->card_type : CISCO_CARD_TYPE_UNDEF;
256    
257     switch(card_type) {
258     /*
259     * Handle WICs which are sub-slots for Network Modules (NM).
260     * Numbering: wic #0 => port_id = 0x10
261     * wic #1 => port_id = 0x20
262     */
263     case CISCO_CARD_TYPE_NM:
264     wic_id = port_id >> 4;
265    
266     if (wic_id >= (CISCO_CARD_MAX_WIC+1)) {
267     vm_error(vm,"Invalid wic_id %u (slot %u)\n",wic_id,slot_id);
268     return(-1);
269     }
270    
271     if (wic_id >= 0x01) {
272     /* wic card */
273     *rc = &card->sub_slots[wic_id - 1];
274     *real_port_id = port_id & 0x0F;
275     } else {
276     /* main card */
277     *real_port_id = port_id;
278     }
279     return(0);
280    
281     /* No translation for Cisco 7200 Port Adapters and WICs */
282     case CISCO_CARD_TYPE_PA:
283     case CISCO_CARD_TYPE_WIC:
284     *real_port_id = port_id;
285     return(0);
286    
287     /* Not initialized yet */
288     default:
289     *real_port_id = port_id;
290     return(0);
291     }
292     }
293    
294     /* Translate a port ID (for sub-cards) */
295     static u_int
296     vm_slot_translate_port_id(vm_instance_t *vm,u_int slot_id,u_int port_id,
297     struct cisco_card **rc)
298     {
299     struct cisco_card **tmp;
300     u_int real_port_id = 0;
301    
302     vm_slot_get_info(vm,slot_id,port_id,&tmp,&real_port_id);
303     *rc = *tmp;
304     return(real_port_id);
305     }
306    
307     /* Check if a slot has an active card */
308     int vm_slot_active(vm_instance_t *vm,u_int slot_id,u_int port_id)
309     {
310     struct cisco_card **rc;
311     u_int real_port_id;
312    
313     if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
314     return(FALSE);
315    
316     if ((*rc == NULL) || ((*rc)->dev_type == NULL))
317     return(FALSE);
318    
319     return(TRUE);
320     }
321    
322     /* Set a flag for a card */
323     int vm_slot_set_flag(vm_instance_t *vm,u_int slot_id,u_int port_id,u_int flag)
324     {
325     struct cisco_card **rc;
326     u_int real_port_id;
327    
328     if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
329     return(FALSE);
330    
331     if (*rc == NULL)
332     return(FALSE);
333    
334     (*rc)->card_flags |= flag;
335     return(TRUE);
336     }
337    
338     /* Add a slot binding */
339     int vm_slot_add_binding(vm_instance_t *vm,char *dev_type,
340     u_int slot_id,u_int port_id)
341     {
342     struct cisco_card_driver *driver,**drv_array;
343     struct cisco_card **rc,*card,*nc,*parent;
344     u_int real_port_id,card_type,card_id;
345    
346     if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
347     return(-1);
348    
349     /* check that this bay is empty */
350     if (*rc != NULL) {
351     if ((*rc)->card_flags & CISCO_CARD_FLAG_OVERRIDE) {
352     vm_slot_remove_binding(vm,slot_id,port_id);
353     } else {
354     vm_error(vm,"a card already exists in slot %u/%u (%s)\n",
355     slot_id,port_id,(*rc)->dev_type);
356     return(-1);
357     }
358     }
359    
360     card = vm->slots[slot_id];
361    
362     if (!card || (card == *rc)) {
363     /* Main slot */
364     drv_array = vm->slots_drivers;
365     card_type = vm->slots_type;
366     card_id = slot_id;
367     parent = NULL;
368     } else {
369     /* Subslot */
370     if (!card->driver->card_get_sub_info) {
371     vm_error(vm,"no sub-slot possible for slot %u/%u.\n",slot_id,port_id);
372     return(-1);
373     }
374    
375     if (card->driver->card_get_sub_info(vm,card,port_id,
376     &drv_array,&card_type) == -1)
377     {
378     vm_error(vm,"no sub-slot info for slot %u/%u.\n",slot_id,port_id);
379     return(-1);
380     }
381    
382     card_id = port_id;
383     parent = card;
384     }
385    
386     assert(drv_array != NULL);
387    
388     /* Find the card driver */
389     if (!(driver = cisco_card_find_driver(drv_array,dev_type))) {
390     vm_error(vm,"unknown card type '%s' for slot %u/%u.\n",
391     dev_type,slot_id,port_id);
392     return(-1);
393     }
394    
395     /* Allocate new card info */
396     if (!(nc = cisco_card_create(card_type)))
397     return(-1);
398    
399     nc->slot_id = slot_id;
400     nc->subslot_id = port_id;
401     nc->card_id = card_id;
402     nc->dev_type = driver->dev_type;
403     nc->driver = driver;
404     nc->parent = parent;
405     *rc = nc;
406     return(0);
407     }
408    
409     /* Remove a slot binding */
410     int vm_slot_remove_binding(vm_instance_t *vm,u_int slot_id,u_int port_id)
411     {
412     struct cisco_card **rc,*sc;
413     u_int i,real_port_id;
414    
415     if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
416     return(-1);
417    
418     if (*rc == NULL)
419     return(-1);
420    
421     if ((*rc)->drv_info != NULL) {
422     vm_error(vm,"slot %u/%u is still active\n",slot_id,port_id);
423     return(-1);
424     }
425    
426     for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) {
427     if ((sc = (*rc)->sub_slots[i]) != NULL) {
428     vm_error(vm,"sub-slot %u/%u is still active\n",
429     slot_id,sc->subslot_id);
430     return(-1);
431     }
432     }
433    
434     /* Remove all NIOs bindings */
435     vm_slot_remove_all_nio_bindings(vm,slot_id);
436    
437     /* Free the card info structure */
438     free(*rc);
439     *rc = NULL;
440     return(0);
441     }
442    
443     /* Add a network IO binding */
444     int vm_slot_add_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id,
445     char *nio_name)
446     {
447     struct cisco_nio_binding *nb;
448     struct cisco_card *card,*rc;
449     u_int real_port_id;
450     netio_desc_t *nio;
451    
452     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
453     return(-1);
454    
455     /* Get the real card (in case this is a sub-slot) */
456     real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
457    
458     if (rc == NULL)
459     return(-1);
460    
461     /* check that a NIO is not already bound to this port */
462     if (cisco_card_find_nio_binding(rc,real_port_id) != NULL) {
463     vm_error(vm,"a NIO already exists for interface %u/%u.\n",
464     slot_id,port_id);
465     return(-1);
466     }
467    
468     /* acquire a reference on the NIO object */
469     if (!(nio = netio_acquire(nio_name))) {
470     vm_error(vm,"unable to find NIO '%s'.\n",nio_name);
471     return(-1);
472     }
473    
474     /* create a new binding */
475     if (!(nb = malloc(sizeof(*nb)))) {
476     vm_error(vm,"unable to create NIO binding for interface %u/%u.\n",
477     slot_id,port_id);
478     netio_release(nio_name);
479     return(-1);
480     }
481    
482     memset(nb,0,sizeof(*nb));
483     nb->nio = nio;
484     nb->port_id = real_port_id;
485     nb->orig_port_id = port_id;
486    
487     nb->next = rc->nio_list;
488     if (nb->next) nb->next->prev = nb;
489     rc->nio_list = nb;
490     return(0);
491     }
492    
493     /* Remove a NIO binding */
494     int vm_slot_remove_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id)
495     {
496     struct cisco_nio_binding *nb;
497     struct cisco_card *card,*rc;
498     u_int real_port_id;
499    
500     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
501     return(-1);
502    
503     /* Get the real card (in case this is a sub-slot) */
504     real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
505    
506     if (rc == NULL)
507     return(-1);
508    
509     /* no nio binding for this slot/port ? */
510     if (!(nb = cisco_card_find_nio_binding(rc,real_port_id)))
511     return(-1);
512    
513     /* tell the NM driver to stop using this NIO */
514     if (rc->driver)
515     rc->driver->card_unset_nio(vm,rc,port_id);
516    
517     /* remove this entry from the double linked list */
518     if (nb->next)
519     nb->next->prev = nb->prev;
520    
521     if (nb->prev) {
522     nb->prev->next = nb->next;
523     } else {
524     rc->nio_list = nb->next;
525     }
526    
527     /* unreference NIO object */
528     netio_release(nb->nio->name);
529     free(nb);
530     return(0);
531     }
532    
533     /* Remove all NIO bindings for the specified slot (sub-slots included) */
534     int vm_slot_remove_all_nio_bindings(vm_instance_t *vm,u_int slot_id)
535     {
536     struct cisco_card *card,*sc;
537     int i;
538    
539     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
540     return(-1);
541    
542     /* Remove NIO bindings for the main slot */
543     cisco_card_remove_all_nio_bindings(vm,card);
544    
545     /* Remove NIO bindings for all sub-slots */
546     for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) {
547     if ((sc = card->sub_slots[i]) != NULL)
548     cisco_card_remove_all_nio_bindings(vm,sc);
549     }
550    
551     return(0);
552     }
553    
554     /* Enable a Network IO descriptor for the specified slot */
555     int vm_slot_enable_nio(vm_instance_t *vm,u_int slot_id,u_int port_id)
556     {
557     struct cisco_nio_binding *nb;
558     struct cisco_card *card,*rc;
559     u_int real_port_id;
560    
561     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
562     return(-1);
563    
564     /* Get the real card (in case this is a sub-slot) */
565     real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
566    
567     if (rc == NULL)
568     return(-1);
569    
570     /* no nio binding for this slot/port ? */
571     if (!(nb = cisco_card_find_nio_binding(rc,real_port_id)))
572     return(-1);
573    
574     /* check that the driver is defined and successfully initialized */
575     if (!rc->driver || !rc->drv_info)
576     return(-1);
577    
578     return(rc->driver->card_set_nio(vm,rc,port_id,nb->nio));
579     }
580    
581     /* Disable Network IO descriptor for the specified slot */
582     int vm_slot_disable_nio(vm_instance_t *vm,u_int slot_id,u_int port_id)
583     {
584     struct cisco_nio_binding *nb;
585     struct cisco_card *card,*rc;
586     u_int real_port_id;
587    
588     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
589     return(-1);
590    
591     /* Get the real card (in case this is a sub-slot) */
592     real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
593    
594     if (rc == NULL)
595     return(-1);
596    
597     /* no nio binding for this slot/port ? */
598     if (!(nb = cisco_card_find_nio_binding(rc,real_port_id)))
599     return(-1);
600    
601     /* check that the driver is defined and successfully initialized */
602     if (!rc->driver || !rc->drv_info)
603     return(-1);
604    
605     return(rc->driver->card_unset_nio(vm,rc,port_id));
606     }
607    
608     /* Enable all NIO for the specified slot (sub-slots included) */
609     int vm_slot_enable_all_nio(vm_instance_t *vm,u_int slot_id)
610     {
611     struct cisco_card *card;
612     int i;
613    
614     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
615     return(-1);
616    
617     /* Enable slot NIOs */
618     cisco_card_enable_all_nio(vm,card);
619    
620     /* Enable NIO of sub-slots */
621     for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
622     cisco_card_enable_all_nio(vm,card->sub_slots[i]);
623    
624     return(0);
625     }
626    
627     /* Disable all NIO for the specified slot (sub-slots included) */
628     int vm_slot_disable_all_nio(vm_instance_t *vm,u_int slot_id)
629     {
630     struct cisco_card *card;
631     int i;
632    
633     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
634     return(-1);
635    
636     /* Disable slot NIOs */
637     cisco_card_disable_all_nio(vm,card);
638    
639     /* Disable NIO of sub-slots */
640     for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
641     cisco_card_disable_all_nio(vm,card->sub_slots[i]);
642    
643     return(0);
644     }
645    
646     /* Initialize the specified slot (sub-slots included) */
647     int vm_slot_init(vm_instance_t *vm,u_int slot_id)
648     {
649     struct cisco_card *card;
650     int i;
651    
652     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
653     return(0);
654    
655     /* Initialize card main module */
656     cisco_card_init(vm,card,slot_id);
657    
658     /* Initialize sub-slots */
659     for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
660     cisco_card_init(vm,card->sub_slots[i],slot_id);
661    
662     /* Enable all NIO */
663     vm_slot_enable_all_nio(vm,slot_id);
664     return(0);
665     }
666    
667     /* Initialize all slots of a VM */
668     int vm_slot_init_all(vm_instance_t *vm)
669     {
670     int i;
671    
672     for(i=0;i<vm->nr_slots;i++) {
673     if (vm_slot_init(vm,i) == -1) {
674     vm_error(vm,"unable to initialize slot %u\n",i);
675     return(-1);
676     }
677     }
678    
679     return(0);
680     }
681    
682     /* Shutdown the specified slot (sub-slots included) */
683     int vm_slot_shutdown(vm_instance_t *vm,u_int slot_id)
684     {
685     struct cisco_card *card;
686     int i;
687    
688     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
689     return(-1);
690    
691     /* Disable all NIO */
692     vm_slot_disable_all_nio(vm,slot_id);
693    
694     /* Shutdown sub-slots */
695     for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
696     cisco_card_shutdown(vm,card->sub_slots[i]);
697    
698     /* Shutdown card main module */
699     cisco_card_shutdown(vm,card);
700     return(0);
701     }
702    
703     /* Shutdown all slots of a VM */
704     int vm_slot_shutdown_all(vm_instance_t *vm)
705     {
706     int i;
707    
708     for(i=0;i<vm->nr_slots;i++)
709     vm_slot_shutdown(vm,i);
710    
711     return(0);
712     }
713    
714     /* Show info about the specified slot (sub-slots included) */
715     int vm_slot_show_info(vm_instance_t *vm,u_int slot_id)
716     {
717     struct cisco_card *card;
718    
719     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
720     return(-1);
721    
722     cisco_card_show_info(vm,card);
723     return(0);
724     }
725    
726     /* Show info about all slots */
727     int vm_slot_show_all_info(vm_instance_t *vm)
728     {
729     int i;
730    
731     for(i=0;i<vm->nr_slots;i++)
732     vm_slot_show_info(vm,i);
733    
734     return(0);
735     }
736    
737     /* Check if the specified slot has a valid EEPROM defined */
738     int vm_slot_check_eeprom(vm_instance_t *vm,u_int slot_id,u_int port_id)
739     {
740     struct cisco_card *card,*rc;
741    
742     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
743     return(FALSE);
744    
745     /* Get the real card (in case this is a sub-slot) */
746     vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
747    
748     if (rc == NULL)
749     return(FALSE);
750    
751     return(cisco_card_check_eeprom(rc));
752     }
753    
754     /* Returns the EEPROM data of the specified slot */
755     struct cisco_eeprom *
756     vm_slot_get_eeprom(vm_instance_t *vm,u_int slot_id,u_int port_id)
757     {
758     struct cisco_card *card,*rc;
759    
760     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
761     return NULL;
762    
763     /* Get the real card (in case this is a sub-slot) */
764     vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
765    
766     if (rc == NULL)
767     return NULL;
768    
769     return(&rc->eeprom);
770     }
771    
772     /* Save config for the specified slot (sub-slots included) */
773     int vm_slot_save_config(vm_instance_t *vm,u_int slot_id,FILE *fd)
774     {
775     struct cisco_card *card;
776     int i;
777    
778     if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
779     return(-1);
780    
781     /* Main slot info */
782     cisco_card_save_config(vm,card,fd);
783    
784     /* Shutdown sub-slots */
785     for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
786     cisco_card_save_config(vm,card->sub_slots[i],fd);
787    
788     return(0);
789     }
790    
791     /* Save config for all slots */
792     int vm_slot_save_all_config(vm_instance_t *vm,FILE *fd)
793     {
794     int i;
795    
796     for(i=0;i<vm->nr_slots;i++)
797     vm_slot_save_config(vm,i,fd);
798    
799     return(0);
800     }
801    
802     /* Show slot drivers */
803     int vm_slot_show_drivers(vm_instance_t *vm)
804     {
805     char *slot_type;
806     int i;
807    
808     if (!vm->slots_drivers)
809     return(-1);
810    
811     slot_type = cisco_card_get_type_desc(vm->slots_type);
812    
813     printf("Available %s %s drivers:\n",vm->platform->log_name,slot_type);
814    
815     for(i=0;vm->slots_drivers[i];i++) {
816     printf(" * %s %s\n",
817     vm->slots_drivers[i]->dev_type,
818     !vm->slots_drivers[i]->supported ? "(NOT WORKING)" : "");
819     }
820    
821     printf("\n");
822     return(0);
823     }
824    
825     /* Maximum number of tokens in a slot description */
826     #define SLOT_DESC_MAX_TOKENS 8
827    
828     /* Create a Network Module (command line) */
829     int vm_slot_cmd_create(vm_instance_t *vm,char *str)
830     {
831     char *tokens[SLOT_DESC_MAX_TOKENS];
832     int i,count,res;
833     u_int slot_id,port_id;
834    
835     /* A port adapter description is like "1:0:NM-1FE" */
836     count = m_strsplit(str,':',tokens,SLOT_DESC_MAX_TOKENS);
837    
838     if ((count < 2) || (count > 3)) {
839     vm_error(vm,"unable to parse slot description '%s'.\n",str);
840     return(-1);
841     }
842    
843     /* Parse the slot id */
844     slot_id = atoi(tokens[0]);
845    
846     /* Parse the sub-slot id */
847     if (count == 3)
848     port_id = atoi(tokens[1]);
849     else
850     port_id = 0;
851    
852     /* Add this new slot to the current slot list */
853     res = vm_slot_add_binding(vm,tokens[count-1],slot_id,port_id);
854    
855     /* The complete array was cleaned by strsplit */
856     for(i=0;i<SLOT_DESC_MAX_TOKENS;i++)
857     free(tokens[i]);
858    
859     return(res);
860     }
861    
862     /* Add a Network IO descriptor binding (command line) */
863     int vm_slot_cmd_add_nio(vm_instance_t *vm,char *str)
864     {
865     char *tokens[SLOT_DESC_MAX_TOKENS];
866     int i,count,nio_type,res=-1;
867     u_int slot_id,port_id;
868     netio_desc_t *nio;
869     char nio_name[128];
870    
871     /* A NIO binding description is like "1:3:tap:tap0" */
872     if ((count = m_strsplit(str,':',tokens,SLOT_DESC_MAX_TOKENS)) < 3) {
873     vm_error(vm,"unable to parse NIO description '%s'.\n",str);
874     return(-1);
875     }
876    
877     /* Parse the slot id */
878     slot_id = atoi(tokens[0]);
879    
880     /* Parse the port id */
881     port_id = atoi(tokens[1]);
882    
883     /* Autogenerate a NIO name */
884     snprintf(nio_name,sizeof(nio_name),"%s-i%u/%u/%u",
885     vm_get_type(vm),vm->instance_id,slot_id,port_id);
886    
887     /* Create the Network IO descriptor */
888     nio = NULL;
889     nio_type = netio_get_type(tokens[2]);
890    
891     switch(nio_type) {
892     case NETIO_TYPE_UNIX:
893     if (count != 5) {
894     vm_error(vm,"invalid number of arguments for UNIX NIO '%s'\n",str);
895     goto done;
896     }
897    
898     nio = netio_desc_create_unix(nio_name,tokens[3],tokens[4]);
899     break;
900    
901     case NETIO_TYPE_VDE:
902     if (count != 5) {
903     vm_error(vm,"invalid number of arguments for VDE NIO '%s'\n",str);
904     goto done;
905     }
906    
907     nio = netio_desc_create_vde(nio_name,tokens[3],tokens[4]);
908     break;
909    
910     case NETIO_TYPE_TAP:
911     if (count != 4) {
912     vm_error(vm,"invalid number of arguments for TAP NIO '%s'\n",str);
913     goto done;
914     }
915    
916     nio = netio_desc_create_tap(nio_name,tokens[3]);
917     break;
918    
919     case NETIO_TYPE_UDP:
920     if (count != 6) {
921     vm_error(vm,"invalid number of arguments for UDP NIO '%s'\n",str);
922     goto done;
923     }
924    
925     nio = netio_desc_create_udp(nio_name,atoi(tokens[3]),
926     tokens[4],atoi(tokens[5]));
927     break;
928    
929     case NETIO_TYPE_TCP_CLI:
930     if (count != 5) {
931     vm_error(vm,"invalid number of arguments for TCP CLI NIO '%s'\n",
932     str);
933     goto done;
934     }
935    
936     nio = netio_desc_create_tcp_cli(nio_name,tokens[3],tokens[4]);
937     break;
938    
939     case NETIO_TYPE_TCP_SER:
940     if (count != 4) {
941     vm_error(vm,"invalid number of arguments for TCP SER NIO '%s'\n",
942     str);
943     goto done;
944     }
945    
946     nio = netio_desc_create_tcp_ser(nio_name,tokens[3]);
947     break;
948    
949     case NETIO_TYPE_NULL:
950     nio = netio_desc_create_null(nio_name);
951     break;
952    
953     #ifdef LINUX_ETH
954     case NETIO_TYPE_LINUX_ETH:
955     if (count != 4) {
956     vm_error(vm,"invalid number of arguments for Linux Eth NIO '%s'\n",
957     str);
958     goto done;
959     }
960    
961     nio = netio_desc_create_lnxeth(nio_name,tokens[3]);
962     break;
963     #endif
964    
965     #ifdef GEN_ETH
966     case NETIO_TYPE_GEN_ETH:
967     if (count != 4) {
968     vm_error(vm,
969     "invalid number of arguments for Generic Eth NIO '%s'\n",
970     str);
971     goto done;
972     }
973    
974     nio = netio_desc_create_geneth(nio_name,tokens[3]);
975     break;
976     #endif
977    
978     default:
979     vm_error(vm,"unknown NETIO type '%s'\n",tokens[2]);
980     goto done;
981     }
982    
983     if (!nio) {
984     vm_error(vm,"unable to create NETIO descriptor for slot %u\n",slot_id);
985     goto done;
986     }
987    
988     if (vm_slot_add_nio_binding(vm,slot_id,port_id,nio_name) == -1) {
989     vm_error(vm,"unable to add NETIO binding for slot %u\n",slot_id);
990     netio_release(nio_name);
991     netio_delete(nio_name);
992     goto done;
993     }
994    
995     netio_release(nio_name);
996     res = 0;
997    
998     done:
999     /* The complete array was cleaned by strsplit */
1000     for(i=0;i<SLOT_DESC_MAX_TOKENS;i++)
1001     free(tokens[i]);
1002    
1003     return(res);
1004     }

  ViewVC Help
Powered by ViewVC 1.1.26