/[dynamips]/trunk/dev_c7200.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

Diff of /trunk/dev_c7200.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

upstream/dynamips-0.2.7/dev_c7200.c revision 10 by dpavlin, Sat Oct 6 16:29:14 2007 UTC upstream/dynamips-0.2.8-RC1/dev_c7200.c revision 11 by dpavlin, Sat Oct 6 16:33:40 2007 UTC
# Line 178  static struct cisco_eeprom c7200_pem_eep Line 178  static struct cisco_eeprom c7200_pem_eep
178  /* ======================================================================== */  /* ======================================================================== */
179  /* Port Adapter Drivers                                                     */  /* Port Adapter Drivers                                                     */
180  /* ======================================================================== */  /* ======================================================================== */
181  static struct c7200_pa_driver *pa_drivers[] = {  static struct cisco_card_driver *pa_drivers[] = {
182     &dev_c7200_iocard_fe_driver,     &dev_c7200_iocard_fe_driver,
183     &dev_c7200_iocard_2fe_driver,     &dev_c7200_iocard_2fe_driver,
184     &dev_c7200_iocard_ge_e_driver,     &dev_c7200_iocard_ge_e_driver,
# Line 238  static struct c7200_npe_driver npe_drive Line 238  static struct c7200_npe_driver npe_drive
238  /* Cisco 7200 router instances                                              */  /* Cisco 7200 router instances                                              */
239  /* ======================================================================== */  /* ======================================================================== */
240    
241    /* Initialize default parameters for a C7200 */
242    static void c7200_init_defaults(c7200_t *router);
243    
244  /* Directly extract the configuration from the NVRAM device */  /* Directly extract the configuration from the NVRAM device */
245  ssize_t c7200_nvram_extract_config(vm_instance_t *vm,char **buffer)  static ssize_t c7200_nvram_extract_config(vm_instance_t *vm,u_char **buffer)
246  {    {  
247     u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;     u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;
248     m_uint32_t start,end,nvlen,clen;     m_uint32_t start,end,nvlen,clen;
# Line 303  ssize_t c7200_nvram_extract_config(vm_in Line 306  ssize_t c7200_nvram_extract_config(vm_in
306  }  }
307    
308  /* Directly push the IOS configuration to the NVRAM device */  /* Directly push the IOS configuration to the NVRAM device */
309  int c7200_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len)  static int c7200_nvram_push_config(vm_instance_t *vm,u_char *buffer,size_t len)
310  {    {  
311     u_char *base_ptr,*ios_ptr,*cfg_ptr;     u_char *base_ptr,*ios_ptr,*cfg_ptr;
312     m_uint32_t cfg_addr,cfg_offset;     m_uint32_t cfg_addr,cfg_offset;
# Line 388  static int c7200_burn_mac_addr(c7200_t * Line 391  static int c7200_burn_mac_addr(c7200_t *
391  static void c7200_free_hw_ressources(c7200_t *router)  static void c7200_free_hw_ressources(c7200_t *router)
392  {  {
393     /* Shutdown all Port Adapters */     /* Shutdown all Port Adapters */
394     c7200_pa_shutdown_all(router);     vm_slot_shutdown_all(router->vm);
395    
396     /* Inactivate the PCMCIA bus */     /* Inactivate the PCMCIA bus */
397     router->pcmcia_bus = NULL;     router->pcmcia_bus = NULL;
# Line 401  static void c7200_free_hw_ressources(c72 Line 404  static void c7200_free_hw_ressources(c72
404  }  }
405    
406  /* Create a new router instance */  /* Create a new router instance */
407  c7200_t *c7200_create_instance(char *name,int instance_id)  static int c7200_create_instance(vm_instance_t *vm)
408  {  {
409     c7200_t *router;     c7200_t *router;
410    
411     if (!(router = malloc(sizeof(*router)))) {     if (!(router = malloc(sizeof(*router)))) {
412        fprintf(stderr,"C7200 '%s': Unable to create new instance!\n",name);        fprintf(stderr,"C7200 '%s': Unable to create new instance!\n",vm->name);
413        return NULL;        return(-1);
414     }     }
     
    memset(router,0,sizeof(*router));  
415    
416     if (!(router->vm = vm_create(name,instance_id,VM_TYPE_C7200))) {     memset(router,0,sizeof(*router));
417        fprintf(stderr,"C7200 '%s': unable to create VM instance!\n",name);     router->vm = vm;
418        goto err_vm;     vm->hw_data = router;
419     }     vm->elf_machine_id = C7200_ELF_MACHINE_ID;
420    
421     c7200_init_defaults(router);     c7200_init_defaults(router);
422     router->vm->hw_data = router;     return(0);
    router->vm->elf_machine_id = C7200_ELF_MACHINE_ID;  
    return router;  
   
  err_vm:  
    free(router);  
    return NULL;  
423  }  }
424    
425  /* Free resources used by a router instance */  /* Free resources used by a router instance */
426  static int c7200_free_instance(void *data,void *arg)  static int c7200_delete_instance(vm_instance_t *vm)
427  {  {
428     vm_instance_t *vm = data;     c7200_t *router = VM_C7200(vm);
    c7200_t *router;  
429     int i;     int i;
430    
431     if (vm->type == VM_TYPE_C7200) {     /* Stop all CPUs */
432        router = VM_C7200(vm);     if (vm->cpu_group != NULL) {
433          vm_stop(vm);
434    
435        /* Stop all CPUs */        if (cpu_group_sync_state(vm->cpu_group) == -1) {
436        if (vm->cpu_group != NULL) {           vm_error(vm,"unable to sync with system CPUs.\n");
437           vm_stop(vm);           return(FALSE);
   
          if (cpu_group_sync_state(vm->cpu_group) == -1) {  
             vm_error(vm,"unable to sync with system CPUs.\n");  
             return(FALSE);  
          }  
438        }        }
439       }
440    
441        /* Remove NIO bindings */     /* Remove NIO bindings */
442        for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<vm->nr_slots;i++)
443           c7200_pa_remove_all_nio_bindings(router,i);        vm_slot_remove_all_nio_bindings(vm,i);
   
       /* Free specific HW resources */  
       c7200_free_hw_ressources(router);  
   
       /* Free EEPROMs */  
       cisco_eeprom_free(&router->cpu_eeprom);  
       cisco_eeprom_free(&router->mp_eeprom);  
       cisco_eeprom_free(&router->pem_eeprom);  
   
       /* Free all resources used by VM */  
       vm_free(vm);  
444    
445        /* Free the router structure */     /* Free specific HW resources */
446        free(router);     c7200_free_hw_ressources(router);
       return(TRUE);  
    }  
447    
448     return(FALSE);     /* Free EEPROMs */
449  }     cisco_eeprom_free(&router->cpu_eeprom);
450       cisco_eeprom_free(&router->mp_eeprom);
451       cisco_eeprom_free(&router->pem_eeprom);
452    
453  /* Delete a router instance */     /* Free all resources used by VM */
454  int c7200_delete_instance(char *name)     vm_free(vm);
 {  
    return(registry_delete_if_unused(name,OBJ_TYPE_VM,  
                                     c7200_free_instance,NULL));  
 }  
455    
456  /* Delete all router instances */     /* Free the router structure */
457  int c7200_delete_all_instances(void)     free(router);
458  {     return(TRUE);
    return(registry_delete_type(OBJ_TYPE_VM,c7200_free_instance,NULL));  
459  }  }
460    
461  /* Save configuration of a C7200 instance */  /* Save configuration of a C7200 instance */
462  void c7200_save_config(c7200_t *router,FILE *fd)  static void c7200_save_config(vm_instance_t *vm,FILE *fd)
463  {  {
464     vm_instance_t *vm = router->vm;     c7200_t *router = VM_C7200(vm);
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
    int i;  
   
    /* General settings */  
    fprintf(fd,"c7200 create %s %u\n",vm->name,vm->instance_id);  
465    
466     fprintf(fd,"c7200 set_npe %s %s\n",vm->name,router->npe_driver->npe_type);     fprintf(fd,"c7200 set_npe %s %s\n",vm->name,router->npe_driver->npe_type);
467     fprintf(fd,"c7200 set_midplane %s %s\n",vm->name,router->midplane_type);     fprintf(fd,"c7200 set_midplane %s %s\n\n",vm->name,router->midplane_type);
   
    /* VM configuration */  
    vm_save_config(vm,fd);  
   
    /* Port Adapter settings */  
    for(i=0;i<C7200_MAX_PA_BAYS;i++) {  
       if (!(bay = c7200_pa_get_info(router,i)))  
          continue;  
   
       if (bay->dev_type) {  
          fprintf(fd,"c7200 add_pa_binding %s %u %s\n",  
                  vm->name,i,bay->dev_type);  
       }  
   
       for(nb=bay->nio_list;nb;nb=nb->next) {  
          fprintf(fd,"c7200 add_nio_binding %s %u %u %s\n",  
                  vm->name,i,nb->port_id,nb->nio->name);  
       }  
    }  
   
    fprintf(fd,"\n");  
468  }  }
469    
470  /* Save configurations of all C7200 instances */  /* Set EEPROM for the specified slot */
471  static void c7200_reg_save_config(registry_entry_t *entry,void *opt,int *err)  int c7200_set_slot_eeprom(c7200_t *router,u_int slot,
472                              struct cisco_eeprom *eeprom)
473  {  {
474     vm_instance_t *vm = entry->data;     if (slot >= C7200_MAX_PA_BAYS)
475     c7200_t *router = VM_C7200(vm);        return(-1);
476    
477     if (vm->type == VM_TYPE_C7200)     switch(slot) {
478        c7200_save_config(router,(FILE *)opt);        /* Group 1: bays 0, 1, 3, 4 */
479  }        case 0:
480             router->pa_eeprom_g1.eeprom[0] = eeprom;
481             break;
482          case 1:
483             router->pa_eeprom_g1.eeprom[1] = eeprom;
484             break;
485          case 3:
486             router->pa_eeprom_g1.eeprom[2] = eeprom;
487             break;
488          case 4:
489             router->pa_eeprom_g1.eeprom[3] = eeprom;
490             break;
491    
492  void c7200_save_config_all(FILE *fd)        /* Group 2: bays 2, 5, 6 */
493  {        case 2:
494     registry_foreach_type(OBJ_TYPE_VM,c7200_reg_save_config,fd,NULL);           router->pa_eeprom_g2.eeprom[0] = eeprom;
495             break;        
496          case 5:
497             router->pa_eeprom_g2.eeprom[1] = eeprom;
498             break;
499          case 6:
500             router->pa_eeprom_g2.eeprom[2] = eeprom;
501             break;
502       }
503    
504       return(0);
505  }  }
506    
507  /* Get slot/port corresponding to specified network IRQ */  /* Get slot/port corresponding to specified network IRQ */
# Line 592  static int c7200_pem_set_eeprom(c7200_t Line 562  static int c7200_pem_set_eeprom(c7200_t
562     return(0);     return(0);
563  }  }
564    
 /* Set PA EEPROM definition */  
 int c7200_pa_set_eeprom(c7200_t *router,u_int pa_bay,  
                         const struct cisco_eeprom *eeprom)  
 {  
    if (pa_bay >= C7200_MAX_PA_BAYS) {  
       vm_error(router->vm,"c7200_pa_set_eeprom: invalid PA Bay %u.\n",pa_bay);  
       return(-1);  
    }  
   
    if (cisco_eeprom_copy(&router->pa_bay[pa_bay].eeprom,eeprom) == -1) {  
       vm_error(router->vm,"c7200_pa_set_eeprom: no memory.\n");  
       return(-1);  
    }  
   
    return(0);  
 }  
   
 /* Unset PA EEPROM definition (empty bay) */  
 int c7200_pa_unset_eeprom(c7200_t *router,u_int pa_bay)  
 {  
    if (pa_bay >= C7200_MAX_PA_BAYS) {  
       vm_error(router->vm,"c7200_pa_set_eeprom: invalid PA Bay %u.\n",pa_bay);  
       return(-1);  
    }  
     
    cisco_eeprom_free(&router->pa_bay[pa_bay].eeprom);  
    return(0);  
 }  
   
 /* Check if a bay has a port adapter */  
 int c7200_pa_check_eeprom(c7200_t *router,u_int pa_bay)  
 {  
    if (pa_bay >= C7200_MAX_PA_BAYS)  
       return(FALSE);  
   
    return(cisco_eeprom_valid(&router->pa_bay[pa_bay].eeprom));  
 }  
   
 /* Get bay info */  
 struct c7200_pa_bay *c7200_pa_get_info(c7200_t *router,u_int pa_bay)  
 {  
    if (pa_bay >= C7200_MAX_PA_BAYS)  
       return NULL;  
   
    return(&router->pa_bay[pa_bay]);  
 }  
   
 /* Get PA type */  
 char *c7200_pa_get_type(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_pa_bay *bay;  
   
    bay = c7200_pa_get_info(router,pa_bay);  
    return((bay != NULL) ? bay->dev_type : NULL);  
 }  
   
 /* Get driver info about the specified slot */  
 void *c7200_pa_get_drvinfo(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_pa_bay *bay;  
   
    bay = c7200_pa_get_info(router,pa_bay);  
    return((bay != NULL) ? bay->drv_info : NULL);  
 }  
   
 /* Set driver info for the specified slot */  
 int c7200_pa_set_drvinfo(c7200_t *router,u_int pa_bay,void *drv_info)  
 {  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    bay->drv_info = drv_info;  
    return(0);  
 }  
   
 /* Get a PA driver */  
 static struct c7200_pa_driver *c7200_pa_get_driver(char *dev_type)  
 {  
    int i;  
   
    for(i=0;pa_drivers[i];i++)  
       if (!strcmp(pa_drivers[i]->dev_type,dev_type))  
          return pa_drivers[i];  
   
    return NULL;  
 }  
   
 /* Add a PA binding */  
 int c7200_pa_add_binding(c7200_t *router,char *dev_type,u_int pa_bay)  
 {    
    struct c7200_pa_driver *pa_driver;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that this bay is empty */  
    if (bay->dev_type != NULL) {  
       vm_error(router->vm,"a PA already exists in slot %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* find the PA driver */  
    if (!(pa_driver = c7200_pa_get_driver(dev_type))) {  
       vm_error(router->vm,"unknown PA type '%s'.\n",dev_type);  
       return(-1);  
    }  
   
    bay->dev_type = pa_driver->dev_type;  
    bay->pa_driver = pa_driver;  
    return(0);    
 }  
   
 /* Remove a PA binding */  
 int c7200_pa_remove_binding(c7200_t *router,u_int pa_bay)  
 {    
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* stop if this bay is still active */  
    if (bay->drv_info != NULL) {  
       vm_error(router->vm,"slot %u still active.\n",pa_bay);  
       return(-1);  
    }  
   
    /* check that this bay is not empty */  
    if (bay->dev_type == NULL) {  
       vm_error(router->vm,"slot %u is empty.\n",pa_bay);  
       return(-1);  
    }  
     
    /* remove all NIOs bindings */  
    c7200_pa_remove_all_nio_bindings(router,pa_bay);  
   
    bay->dev_type  = NULL;  
    bay->pa_driver = NULL;  
    return(0);  
 }  
   
 /* Find a NIO binding */  
 struct c7200_nio_binding *  
 c7200_pa_find_nio_binding(c7200_t *router,u_int pa_bay,u_int port_id)  
 {    
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return NULL;  
   
    for(nb=bay->nio_list;nb;nb=nb->next)  
       if (nb->port_id == port_id)  
          return nb;  
   
    return NULL;  
 }  
   
 /* Add a network IO binding */  
 int c7200_pa_add_nio_binding(c7200_t *router,u_int pa_bay,u_int port_id,  
                              char *nio_name)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
    netio_desc_t *nio;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that a NIO is not already bound to this port */  
    if (c7200_pa_find_nio_binding(router,pa_bay,port_id) != NULL) {  
       vm_error(router->vm,"a NIO already exists for interface %u/%u\n",  
                pa_bay,port_id);  
       return(-1);  
    }  
   
    /* acquire a reference on the NIO object */  
    if (!(nio = netio_acquire(nio_name))) {  
       vm_error(router->vm,"unable to find NIO '%s'.\n",nio_name);  
       return(-1);  
    }  
   
    /* create a new binding */  
    if (!(nb = malloc(sizeof(*nb)))) {  
       vm_error(router->vm,"unable to create NIO binding "  
                "for interface %u/%u.\n",pa_bay,port_id);  
       netio_release(nio_name);  
       return(-1);  
    }  
   
    memset(nb,0,sizeof(*nb));  
    nb->nio       = nio;  
    nb->port_id   = port_id;  
    nb->next      = bay->nio_list;  
    if (nb->next) nb->next->prev = nb;  
    bay->nio_list = nb;  
    return(0);  
 }  
   
 /* Remove a NIO binding */  
 int c7200_pa_remove_nio_binding(c7200_t *router,u_int pa_bay,u_int port_id)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
     
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    if (!(nb = c7200_pa_find_nio_binding(router,pa_bay,port_id)))  
       return(-1);   /* no nio binding for this slot/port */  
   
    /* tell the PA driver to stop using this NIO */  
    if (bay->pa_driver)  
       bay->pa_driver->pa_unset_nio(router,pa_bay,port_id);  
   
    /* remove this entry from the double linked list */  
    if (nb->next)  
       nb->next->prev = nb->prev;  
   
    if (nb->prev) {  
       nb->prev->next = nb->next;  
    } else {  
       bay->nio_list = nb->next;  
    }  
   
    /* unreference NIO object */  
    netio_release(nb->nio->name);  
    free(nb);  
    return(0);  
 }  
   
 /* Remove all NIO bindings for the specified PA */  
 int c7200_pa_remove_all_nio_bindings(c7200_t *router,u_int pa_bay)  
 {    
    struct c7200_nio_binding *nb,*next;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    for(nb=bay->nio_list;nb;nb=next) {  
       next = nb->next;  
   
       /* tell the PA driver to stop using this NIO */  
       if (bay->pa_driver)  
          bay->pa_driver->pa_unset_nio(router,pa_bay,nb->port_id);  
   
       /* unreference NIO object */  
       netio_release(nb->nio->name);  
       free(nb);  
    }  
   
    bay->nio_list = NULL;  
    return(0);  
 }  
   
 /* Enable a Network IO descriptor for a Port Adapter */  
 int c7200_pa_enable_nio(c7200_t *router,u_int pa_bay,u_int port_id)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that we have an NIO binding for this interface */  
    if (!(nb = c7200_pa_find_nio_binding(router,pa_bay,port_id)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    return(bay->pa_driver->pa_set_nio(router,pa_bay,port_id,nb->nio));  
 }  
   
 /* Disable Network IO descriptor of a Port Adapter */  
 int c7200_pa_disable_nio(c7200_t *router,u_int pa_bay,u_int port_id)  
 {  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    return(bay->pa_driver->pa_unset_nio(router,pa_bay,port_id));  
 }  
   
 /* Enable all NIO of the specified PA */  
 int c7200_pa_enable_all_nio(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    for(nb=bay->nio_list;nb;nb=nb->next)  
       bay->pa_driver->pa_set_nio(router,pa_bay,nb->port_id,nb->nio);  
   
    return(0);  
 }  
   
 /* Disable all NIO of the specified PA */  
 int c7200_pa_disable_all_nio(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    for(nb=bay->nio_list;nb;nb=nb->next)  
       bay->pa_driver->pa_unset_nio(router,pa_bay,nb->port_id);  
   
    return(0);  
 }  
   
 /* Initialize a Port Adapter */  
 int c7200_pa_init(c7200_t *router,u_int pa_bay)  
 {    
    struct c7200_pa_bay *bay;  
    size_t len;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* Check that a device type is defined for this bay */  
    if (!bay->dev_type || !bay->pa_driver) {  
       vm_error(router->vm,"trying to init empty slot %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* Allocate device name */  
    len = strlen(bay->dev_type) + 10;  
    if (!(bay->dev_name = malloc(len))) {  
       vm_error(router->vm,"unable to allocate device name.\n");  
       return(-1);  
    }  
   
    snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,pa_bay);  
   
    /* Initialize PA driver */  
    if (bay->pa_driver->pa_init(router,bay->dev_name,pa_bay) == -1) {  
       vm_error(router->vm,"unable to initialize PA %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* Enable all NIO */  
    c7200_pa_enable_all_nio(router,pa_bay);  
    return(0);  
 }  
   
 /* Shutdown a Port Adapter */  
 int c7200_pa_shutdown(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* Check that a device type is defined for this bay */    
    if (!bay->dev_type || !bay->pa_driver) {  
       vm_error(router->vm,"trying to shut down an empty bay %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* Disable all NIO */  
    c7200_pa_disable_all_nio(router,pa_bay);  
   
    /* Shutdown the PA driver */  
    if (bay->drv_info && (bay->pa_driver->pa_shutdown(router,pa_bay) == -1)) {  
       vm_error(router->vm,"unable to shutdown PA %u.\n",pa_bay);  
       return(-1);  
    }  
   
    free(bay->dev_name);  
    bay->dev_name = NULL;  
    bay->drv_info = NULL;  
    return(0);  
 }  
   
 /* Shutdown all PA of a router */  
 int c7200_pa_shutdown_all(c7200_t *router)  
 {  
    int i;  
   
    for(i=0;i<C7200_MAX_PA_BAYS;i++) {  
       if (!router->pa_bay[i].dev_type)  
          continue;  
   
       c7200_pa_shutdown(router,i);  
    }  
   
    return(0);  
 }  
   
 /* Show info about all NMs */  
 int c7200_pa_show_all_info(c7200_t *router)  
 {  
    struct c7200_pa_bay *bay;  
    int i;  
   
    for(i=0;i<C7200_MAX_PA_BAYS;i++) {  
       if (!(bay = c7200_pa_get_info(router,i)) || !bay->pa_driver)  
          continue;  
   
       if (bay->pa_driver->pa_show_info != NULL)  
          bay->pa_driver->pa_show_info(router,i);  
    }  
   
    return(0);  
 }  
   
 /* Maximum number of tokens in a PA description */  
 #define PA_DESC_MAX_TOKENS  8  
   
 /* Create a Port Adapter (command line) */  
 int c7200_cmd_pa_create(c7200_t *router,char *str)  
 {  
    char *tokens[PA_DESC_MAX_TOKENS];  
    int i,count,res;  
    u_int pa_bay;  
   
    /* A port adapter description is like "1:PA-FE-TX" */  
    if ((count = m_strsplit(str,':',tokens,PA_DESC_MAX_TOKENS)) != 2) {  
       vm_error(router->vm,"unable to parse PA description '%s'.\n",str);  
       return(-1);  
    }  
   
    /* Parse the PA bay id */  
    pa_bay = atoi(tokens[0]);  
   
    /* Add this new PA to the current PA list */  
    res = c7200_pa_add_binding(router,tokens[1],pa_bay);  
   
    /* The complete array was cleaned by strsplit */  
    for(i=0;i<PA_DESC_MAX_TOKENS;i++)  
       free(tokens[i]);  
   
    return(res);  
 }  
   
 /* Add a Network IO descriptor binding (command line) */  
 int c7200_cmd_add_nio(c7200_t *router,char *str)  
 {  
    char *tokens[PA_DESC_MAX_TOKENS];  
    int i,count,nio_type,res=-1;  
    u_int pa_bay,port_id;  
    netio_desc_t *nio;  
    char nio_name[128];  
   
    /* A port adapter description is like "1:3:tap:tap0" */  
    if ((count = m_strsplit(str,':',tokens,PA_DESC_MAX_TOKENS)) < 3) {  
       vm_error(router->vm,"unable to parse NIO description '%s'.\n",str);  
       return(-1);  
    }  
   
    /* Parse the PA bay */  
    pa_bay = atoi(tokens[0]);  
   
    /* Parse the PA port id */  
    port_id = atoi(tokens[1]);  
   
    /* Autogenerate a NIO name */  
    snprintf(nio_name,sizeof(nio_name),"c7200-i%u/%u/%u",  
             router->vm->instance_id,pa_bay,port_id);  
   
    /* Create the Network IO descriptor */  
    nio = NULL;  
    nio_type = netio_get_type(tokens[2]);  
   
    switch(nio_type) {  
       case NETIO_TYPE_UNIX:  
          if (count != 5) {  
             vm_error(router->vm,  
                      "invalid number of arguments for UNIX NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_unix(nio_name,tokens[3],tokens[4]);  
          break;  
   
       case NETIO_TYPE_VDE:  
          if (count != 5) {  
             vm_error(router->vm,  
                      "invalid number of arguments for VDE NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_vde(nio_name,tokens[3],tokens[4]);  
          break;  
   
       case NETIO_TYPE_TAP:  
          if (count != 4) {  
             vm_error(router->vm,  
                      "invalid number of arguments for TAP NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_tap(nio_name,tokens[3]);  
          break;  
   
       case NETIO_TYPE_UDP:  
          if (count != 6) {  
             vm_error(router->vm,  
                      "invalid number of arguments for UDP NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_udp(nio_name,atoi(tokens[3]),  
                                      tokens[4],atoi(tokens[5]));  
          break;  
   
       case NETIO_TYPE_TCP_CLI:  
          if (count != 5) {  
             vm_error(router->vm,  
                      "invalid number of arguments for TCP CLI NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_tcp_cli(nio_name,tokens[3],tokens[4]);  
          break;  
   
       case NETIO_TYPE_TCP_SER:  
          if (count != 4) {  
             vm_error(router->vm,  
                      "invalid number of arguments for TCP SER NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_tcp_ser(nio_name,tokens[3]);  
          break;  
   
       case NETIO_TYPE_NULL:  
          nio = netio_desc_create_null(nio_name);  
          break;  
   
 #ifdef LINUX_ETH  
       case NETIO_TYPE_LINUX_ETH:  
          if (count != 4) {  
             vm_error(router->vm,  
                      "invalid number of arguments for Linux Eth NIO '%s'\n",  
                      str);  
             goto done;  
          }  
           
          nio = netio_desc_create_lnxeth(nio_name,tokens[3]);  
          break;  
 #endif  
   
 #ifdef GEN_ETH  
       case NETIO_TYPE_GEN_ETH:  
          if (count != 4) {  
             vm_error(router->vm,"invalid number of "  
                      "arguments for Generic Eth NIO '%s'\n",str);  
             goto done;  
          }  
           
          nio = netio_desc_create_geneth(nio_name,tokens[3]);  
          break;  
 #endif  
   
       default:  
          vm_error(router->vm,"unknown NETIO type '%s'\n",tokens[2]);  
          goto done;  
    }  
   
    if (!nio) {  
       fprintf(stderr,"c7200_cmd_add_nio: unable to create NETIO "  
               "descriptor for PA bay %u\n",pa_bay);  
       goto done;  
    }  
   
    if (c7200_pa_add_nio_binding(router,pa_bay,port_id,nio_name) == -1) {  
       vm_error(router->vm,"unable to add NETIO binding for slot %u\n",pa_bay);  
       netio_release(nio_name);  
       netio_delete(nio_name);  
       goto done;  
    }  
     
    netio_release(nio_name);  
    res = 0;  
   
  done:  
    /* The complete array was cleaned by strsplit */  
    for(i=0;i<PA_DESC_MAX_TOKENS;i++)  
       free(tokens[i]);  
   
    return(res);  
 }  
   
 /* Show the list of available PA drivers */  
 void c7200_pa_show_drivers(void)  
 {  
    int i;  
   
    printf("Available C7200 Port Adapter drivers:\n");  
   
    for(i=0;pa_drivers[i];i++) {  
       printf("  * %s %s\n",  
              pa_drivers[i]->dev_type,  
              !pa_drivers[i]->supported ? "(NOT WORKING)" : "");  
    }  
     
    printf("\n");  
 }  
   
565  /* Get an NPE driver */  /* Get an NPE driver */
566  struct c7200_npe_driver *c7200_npe_get_driver(char *npe_type)  struct c7200_npe_driver *c7200_npe_get_driver(char *npe_type)
567  {  {
# Line 1248  int c7200_npe_set_type(c7200_t *router,c Line 597  int c7200_npe_set_type(c7200_t *router,c
597        return(-1);        return(-1);
598     }     }
599    
600       /* Use a C7200-IO-FE by default in slot 0 if an I/O card is required */
601       if (driver->iocard_required) {
602          vm_slot_add_binding(router->vm,"C7200-IO-FE",0,0);
603          vm_slot_set_flag(router->vm,0,0,CISCO_CARD_FLAG_OVERRIDE);
604       }
605     return(0);     return(0);
606  }  }
607    
608  /* Show the list of available NPE drivers */  /* Show the list of available NPE drivers */
609  void c7200_npe_show_drivers(void)  static void c7200_npe_show_drivers(void)
610  {  {
611     int i;     int i;
612    
# Line 1408  static int c7200_pa_create_pci_busses(c7 Line 762  static int c7200_pa_create_pci_busses(c7
762  static int c7200_pa_init_pci_bridge(c7200_t *router,u_int pa_bay,  static int c7200_pa_init_pci_bridge(c7200_t *router,u_int pa_bay,
763                                      struct pci_bus *pci_bus,int pci_device)                                      struct pci_bus *pci_bus,int pci_device)
764  {  {
765       struct pci_bus *pa_bus;
766    
767       pa_bus = router->vm->slots_pci_bus[pa_bay];
768    
769     switch(router->midplane_version) {     switch(router->midplane_version) {
770        case 0:        case 0:
771        case 1:        case 1:
772           dev_dec21050_init(pci_bus,pci_device,router->pa_bay[pa_bay].pci_map);           dev_dec21050_init(pci_bus,pci_device,pa_bus);
773           break;           break;
774        default:        default:
775           dev_dec21150_init(pci_bus,pci_device,router->pa_bay[pa_bay].pci_map);           dev_dec21150_init(pci_bus,pci_device,pa_bus);
776     }     }
777     return(0);     return(0);
778  }  }
# Line 1485  int c7200_init_npe100(c7200_t *router) Line 843  int c7200_init_npe100(c7200_t *router)
843     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);
844    
845     /* Map the PA PCI busses */     /* Map the PA PCI busses */
846     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
847    
848     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
849        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
850    
851     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
852     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1533  int c7200_init_npe150(c7200_t *router) Line 891  int c7200_init_npe150(c7200_t *router)
891     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);
892    
893     /* Map the PA PCI busses */       /* Map the PA PCI busses */  
894     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
895    
896     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
897        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
898    
899     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
900     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1586  int c7200_init_npe175(c7200_t *router) Line 944  int c7200_init_npe175(c7200_t *router)
944    
945     /* Map the PA PCI busses */     /* Map the PA PCI busses */
946     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
947        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
948    
949     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
950     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);
# Line 1634  int c7200_init_npe200(c7200_t *router) Line 992  int c7200_init_npe200(c7200_t *router)
992     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);
993    
994     /* Map the PA PCI busses */     /* Map the PA PCI busses */
995     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
996    
997     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
998        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
999    
1000     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1001     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1687  int c7200_init_npe225(c7200_t *router) Line 1045  int c7200_init_npe225(c7200_t *router)
1045    
1046     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1047     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
1048        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1049    
1050     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1051     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);
# Line 1744  int c7200_init_npe300(c7200_t *router) Line 1102  int c7200_init_npe300(c7200_t *router)
1102    
1103     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1104     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
1105        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1106    
1107     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1108     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1795  int c7200_init_npe400(c7200_t *router) Line 1153  int c7200_init_npe400(c7200_t *router)
1153    
1154     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1155     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
1156        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1157    
1158     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1159     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);
# Line 1850  int c7200_init_npeg1(c7200_t *router) Line 1208  int c7200_init_npeg1(c7200_t *router)
1208     c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);     c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);
1209    
1210     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1211     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
1212    
1213     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
1214        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1215    
1216     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1217     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1896  int c7200_init_npeg2(c7200_t *router) Line 1254  int c7200_init_npeg2(c7200_t *router)
1254     c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);     c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);
1255    
1256     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1257     router->pa_bay[0].pci_map = vm->pci_bus_pool[0];     vm->slots_pci_bus[0] = vm->pci_bus_pool[0];
1258    
1259     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
1260        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1261    
1262     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1263     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1936  void c7200_show_hardware(c7200_t *router Line 1294  void c7200_show_hardware(c7200_t *router
1294  }  }
1295    
1296  /* Initialize default parameters for a C7200 */  /* Initialize default parameters for a C7200 */
1297  void c7200_init_defaults(c7200_t *router)  static void c7200_init_defaults(c7200_t *router)
1298  {  {
1299     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1300     n_eth_addr_t *m;     n_eth_addr_t *m;
1301     m_uint16_t pid;     m_uint16_t pid;
1302    
1303       /* Set platform slots characteristics */
1304       vm->nr_slots   = C7200_MAX_PA_BAYS;
1305       vm->slots_type = CISCO_CARD_TYPE_PA;
1306       vm->slots_drivers = pa_drivers;
1307    
1308     pid = (m_uint16_t)getpid();     pid = (m_uint16_t)getpid();
1309    
1310     /* Generate a chassis MAC address based on the instance ID */     /* Generate a chassis MAC address based on the instance ID */
# Line 1953  void c7200_init_defaults(c7200_t *router Line 1316  void c7200_init_defaults(c7200_t *router
1316     m->eth_addr_byte[4] = 0x00;     m->eth_addr_byte[4] = 0x00;
1317     m->eth_addr_byte[5] = 0x00;     m->eth_addr_byte[5] = 0x00;
1318    
1319     c7200_init_eeprom_groups(router);     c7200_init_sys_eeprom_groups(router);
1320       c7200_init_mp_eeprom_groups(router);
1321     c7200_npe_set_type(router,C7200_DEFAULT_NPE_TYPE);     c7200_npe_set_type(router,C7200_DEFAULT_NPE_TYPE);
1322     c7200_midplane_set_type(router,C7200_DEFAULT_MIDPLANE);     c7200_midplane_set_type(router,C7200_DEFAULT_MIDPLANE);
1323    
# Line 1968  void c7200_init_defaults(c7200_t *router Line 1332  void c7200_init_defaults(c7200_t *router
1332    
1333     vm->pcmcia_disk_size[0] = C7200_DEFAULT_DISK0_SIZE;     vm->pcmcia_disk_size[0] = C7200_DEFAULT_DISK0_SIZE;
1334     vm->pcmcia_disk_size[1] = C7200_DEFAULT_DISK1_SIZE;     vm->pcmcia_disk_size[1] = C7200_DEFAULT_DISK1_SIZE;
   
    /* Enable NVRAM operations to load/store configs */  
    vm->nvram_extract_config = c7200_nvram_extract_config;  
    vm->nvram_push_config = c7200_nvram_push_config;  
1335  }  }
1336    
1337  /* Run the checklist */  /* Run the checklist */
# Line 1994  static int c7200_checklist(c7200_t *rout Line 1354  static int c7200_checklist(c7200_t *rout
1354  /* Initialize Port Adapters */  /* Initialize Port Adapters */
1355  static int c7200_init_platform_pa(c7200_t *router)  static int c7200_init_platform_pa(c7200_t *router)
1356  {  {
1357     vm_instance_t *vm = router->vm;     return(vm_slot_init_all(router->vm));
    struct c7200_pa_bay *pa_bay;  
    int i;  
   
    /* Initialize Port Adapters */  
    for(i=0;i<C7200_MAX_PA_BAYS;i++) {  
       pa_bay = &router->pa_bay[i];  
   
       if (!pa_bay->dev_type)  
          continue;  
   
       if (c7200_pa_init(router,i) == -1) {  
          vm_error(vm,"unable to create Port Adapter \"%s\"\n",  
                   pa_bay->dev_type);  
          return(-1);  
       }  
    }  
   
    /*  
     * By default, initialize a C7200-IO-FE in slot 0 if nothing found.  
     * We only do that for NPEs that require an IO card (all excepted G1/G2).  
     */  
    if (router->npe_driver->iocard_required && !router->pa_bay[0].drv_info) {  
       c7200_pa_add_binding(router,"C7200-IO-FE",0);  
       c7200_pa_init(router,0);  
    }  
   
    return(0);  
1358  }  }
1359    
1360  /* Initialize the C7200 Platform (MIPS) */  /* Initialize the C7200 Platform (MIPS) */
# Line 2085  static int c7200m_init_platform(c7200_t Line 1418  static int c7200m_init_platform(c7200_t
1418     /* Remote emulator control */     /* Remote emulator control */
1419     dev_remote_control_init(vm,0x16000000,0x1000);     dev_remote_control_init(vm,0x16000000,0x1000);
1420    
1421     /* Bootflash */     /* Bootflash (8 Mb) */
1422     dev_bootflash_init(vm,"bootflash",C7200_BOOTFLASH_ADDR,(8 * 1048576));     dev_bootflash_init(vm,"bootflash","c7200-bootflash-8mb",
1423                          C7200_BOOTFLASH_ADDR);
1424    
1425     /* NVRAM and calendar */     /* NVRAM and calendar */
1426     dev_nvram_init(vm,"nvram",router->npe_driver->nvram_addr,     dev_nvram_init(vm,"nvram",router->npe_driver->nvram_addr,
# Line 2209  static int c7200p_init_platform(c7200_t Line 1543  static int c7200p_init_platform(c7200_t
1543     /* Remote emulator control */     /* Remote emulator control */
1544     dev_remote_control_init(vm,0xf6000000,0x1000);     dev_remote_control_init(vm,0xf6000000,0x1000);
1545    
1546     /* Bootflash */     /* Bootflash (64 Mb) */
1547     dev_bootflash_init(vm,"bootflash",C7200_G2_BOOTFLASH_ADDR,(64 * 1048576));     dev_bootflash_init(vm,"bootflash","c7200-bootflash-64mb",
1548                          C7200_G2_BOOTFLASH_ADDR);
1549    
1550     /* NVRAM and calendar */     /* NVRAM and calendar */
1551     vm->nvram_size = C7200_G2_NVRAM_SIZE / 1024;     vm->nvram_size = C7200_G2_NVRAM_SIZE / 1024;
# Line 2266  static int c7200p_init_platform(c7200_t Line 1601  static int c7200p_init_platform(c7200_t
1601     router->mpfpga_data = obj->data;     router->mpfpga_data = obj->data;
1602    
1603     /* If we have nothing in slot 0, the console is handled by the MV64460 */     /* If we have nothing in slot 0, the console is handled by the MV64460 */
1604     if (!c7200_pa_check_eeprom(router,0)) {     if (!vm_slot_get_card_ptr(vm,0)) {
1605        vm_log(vm,"CONSOLE","console managed by NPE-G2 board\n");        vm_log(vm,"CONSOLE","console managed by NPE-G2 board\n");
1606        mv64460_sdma_bind_vtty(router->mv64460_sysctr,0,vm->vtty_con);        mv64460_sdma_bind_vtty(router->mv64460_sysctr,0,vm->vtty_con);
1607        mv64460_sdma_bind_vtty(router->mv64460_sysctr,1,vm->vtty_aux);        mv64460_sdma_bind_vtty(router->mv64460_sysctr,1,vm->vtty_aux);
# Line 2585  static int c7200p_init_instance(c7200_t Line 1920  static int c7200p_init_instance(c7200_t
1920  }  }
1921    
1922  /* Initialize a Cisco 7200 instance */  /* Initialize a Cisco 7200 instance */
1923  int c7200_init_instance(c7200_t *router)  static int c7200_init_instance(vm_instance_t *vm)
1924  {  {
1925       c7200_t *router = VM_C7200(vm);
1926    
1927     switch(router->npe_driver->npe_family) {     switch(router->npe_driver->npe_family) {
1928        case C7200_NPE_FAMILY_MIPS:        case C7200_NPE_FAMILY_MIPS:
1929           return(c7200m_init_instance(router));           return(c7200m_init_instance(router));
# Line 2602  int c7200_init_instance(c7200_t *router) Line 1939  int c7200_init_instance(c7200_t *router)
1939  }  }
1940    
1941  /* Stop a Cisco 7200 instance */  /* Stop a Cisco 7200 instance */
1942  int c7200_stop_instance(c7200_t *router)  static int c7200_stop_instance(vm_instance_t *vm)
1943  {  {
    vm_instance_t *vm = router->vm;  
   
1944     printf("\nC7200 '%s': stopping simulation.\n",vm->name);     printf("\nC7200 '%s': stopping simulation.\n",vm->name);
1945     vm_log(vm,"C7200_STOP","stopping simulation.\n");     vm_log(vm,"C7200_STOP","stopping simulation.\n");
1946    
# Line 2620  int c7200_stop_instance(c7200_t *router) Line 1955  int c7200_stop_instance(c7200_t *router)
1955     }     }
1956    
1957     /* Free resources that were used during execution to emulate hardware */     /* Free resources that were used during execution to emulate hardware */
1958     c7200_free_hw_ressources(router);     c7200_free_hw_ressources(VM_C7200(vm));
1959     vm_hardware_shutdown(vm);     vm_hardware_shutdown(vm);
1960     return(0);     return(0);
1961  }  }
# Line 2659  int c7200_pa_init_online(c7200_t *router Line 1994  int c7200_pa_init_online(c7200_t *router
1994     }     }
1995    
1996     /* Add the new hardware elements */     /* Add the new hardware elements */
1997     if (c7200_pa_init(router,pa_bay) == -1)     if (vm_slot_init(vm,pa_bay) == -1)
1998        return(-1);        return(-1);
1999    
2000     /* Resume normal operations */     /* Resume normal operations */
# Line 2674  int c7200_pa_init_online(c7200_t *router Line 2009  int c7200_pa_init_online(c7200_t *router
2009  int c7200_pa_stop_online(c7200_t *router,u_int pa_bay)  int c7200_pa_stop_online(c7200_t *router,u_int pa_bay)
2010  {    {  
2011     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
    struct c7200_pa_bay *bay;  
2012    
2013     if (!pa_bay) {     if (!pa_bay) {
2014        vm_error(vm,"OIR not supported on slot 0.\n");        vm_error(vm,"OIR not supported on slot 0.\n");
2015        return(-1);        return(-1);
2016     }     }
2017    
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
2018     /* The PA driver must be initialized */     /* The PA driver must be initialized */
2019     if (!bay->dev_type || !bay->pa_driver) {     if (!vm_slot_get_card_ptr(vm,pa_bay)) {
2020        vm_error(vm,"trying to shut down empty slot %u.\n",pa_bay);        vm_error(vm,"trying to shut down empty slot %u.\n",pa_bay);
2021        return(-1);        return(-1);
2022     }     }
2023    
2024     /* Disable all NIOs to stop traffic forwarding */     /* Disable all NIOs to stop traffic forwarding */
2025     c7200_pa_disable_all_nio(router,pa_bay);     vm_slot_disable_all_nio(vm,pa_bay);
2026    
2027     /* We can safely trigger the OIR event */     /* We can safely trigger the OIR event */
2028     c7200_trigger_oir_event(router,1 << pa_bay);     c7200_trigger_oir_event(router,1 << pa_bay);
# Line 2703  int c7200_pa_stop_online(c7200_t *router Line 2034  int c7200_pa_stop_online(c7200_t *router
2034     vm_suspend(vm);     vm_suspend(vm);
2035    
2036     /* Device removal */     /* Device removal */
2037     c7200_pa_shutdown(router,pa_bay);     vm_slot_shutdown(vm,pa_bay);
2038    
2039     /* Resume normal operations */     /* Resume normal operations */
2040     vm_resume(vm);     vm_resume(vm);
2041     return(0);     return(0);
2042  }  }
2043    
2044    /* Get MAC address MSB */
2045    static u_int c7200_get_mac_addr_msb(void)
2046    {
2047       return(0xCA);
2048    }
2049    
2050    /* Parse specific options for the Cisco 7200 platform */
2051    static int c7200_cli_parse_options(vm_instance_t *vm,int option)
2052    {
2053       c7200_t *router = VM_C7200(vm);
2054    
2055       switch(option) {
2056          /* NPE type */
2057          case 't':
2058             c7200_npe_set_type(router,optarg);
2059             break;
2060    
2061          /* Midplane type */
2062          case 'M':
2063             c7200_midplane_set_type(router,optarg);
2064             break;
2065    
2066          /* Set the base MAC address */
2067          case 'm':
2068             if (!c7200_midplane_set_mac_addr(router,optarg))
2069                printf("MAC address set to '%s'.\n",optarg);
2070             break;
2071    
2072          /* Unknown option */
2073          default:
2074             return(-1);
2075       }
2076    
2077       return(0);
2078    }
2079    
2080    /* Show specific CLI options */
2081    static void c7200_cli_show_options(vm_instance_t *vm)
2082    {
2083       printf("  -t <npe_type>      : Select NPE type (default: \"%s\")\n"
2084              "  -M <midplane>      : Select Midplane (\"std\" or \"vxr\")\n"
2085              "  -p <pa_desc>       : Define a Port Adapter\n"
2086              "  -s <pa_nio>        : Bind a Network IO interface to a "
2087              "Port Adapter\n",
2088              C7200_DEFAULT_NPE_TYPE);
2089    }
2090    
2091    /* Platform definition */
2092    static vm_platform_t c7200_platform = {
2093       "c7200", "C7200", "7200",
2094       c7200_create_instance,
2095       c7200_delete_instance,
2096       c7200_init_instance,
2097       c7200_stop_instance,
2098       c7200_nvram_extract_config,
2099       c7200_nvram_push_config,
2100       c7200_get_mac_addr_msb,
2101       c7200_save_config,
2102       c7200_cli_parse_options,
2103       c7200_cli_show_options,
2104       c7200_npe_show_drivers,
2105    };
2106    
2107    /* Register the c7200 platform */
2108    int c7200_platform_register(void)
2109    {
2110       if (vm_platform_register(&c7200_platform) == -1)
2111          return(-1);
2112    
2113       return(hypervisor_c7200_init(&c7200_platform));
2114    }

Legend:
Removed from v.10  
changed lines
  Added in v.11

  ViewVC Help
Powered by ViewVC 1.1.26