Introduce VLANClientState::cleanup() (Mark McLoughlin)
We're currently leaking memory and file descriptors on device hot-unplug. Signed-off-by: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7160 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									1ed3d07a22
								
							
						
					
					
						commit
						a34b6eb776
					
				
							
								
								
									
										11
									
								
								hw/e1000.c
								
								
								
								
							
							
						
						
									
										11
									
								
								hw/e1000.c
								
								
								
								
							| 
						 | 
				
			
			@ -1033,6 +1033,14 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
 | 
			
		|||
                                     excluded_regs[i] - 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
e1000_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    E1000State *d = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    unregister_savevm("e1000", d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
pci_e1000_uninit(PCIDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1094,7 +1102,8 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		|||
    memset(&d->tx, 0, sizeof d->tx);
 | 
			
		||||
 | 
			
		||||
    d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 e1000_receive, e1000_can_receive, d);
 | 
			
		||||
                                 e1000_receive, e1000_can_receive,
 | 
			
		||||
                                 e1000_cleanup, d);
 | 
			
		||||
    d->vc->link_status_changed = e1000_set_link_status;
 | 
			
		||||
 | 
			
		||||
    qemu_format_nic_info_str(d->vc, nd->macaddr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1735,6 +1735,25 @@ static void nic_save(QEMUFile * f, void *opaque)
 | 
			
		|||
    qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nic_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    EEPRO100State *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    unregister_savevm(vc->model, s);
 | 
			
		||||
 | 
			
		||||
    eeprom93xx_free(s->eeprom);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pci_nic_uninit(PCIDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
    PCIEEPRO100State *d = (PCIEEPRO100State *) dev;
 | 
			
		||||
    EEPRO100State *s = &d->eepro100;
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(s->mmio_index);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, uint32_t device)
 | 
			
		||||
{
 | 
			
		||||
    PCIEEPRO100State *d;
 | 
			
		||||
| 
						 | 
				
			
			@ -1745,6 +1764,7 @@ static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, uint32_t device)
 | 
			
		|||
    d = (PCIEEPRO100State *) pci_register_device(bus, nd->model,
 | 
			
		||||
                                                 sizeof(PCIEEPRO100State), -1,
 | 
			
		||||
                                                 NULL, NULL);
 | 
			
		||||
    d->dev.unregister = pci_nic_uninit;
 | 
			
		||||
 | 
			
		||||
    s = &d->eepro100;
 | 
			
		||||
    s->device = device;
 | 
			
		||||
| 
						 | 
				
			
			@ -1775,7 +1795,8 @@ static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, uint32_t device)
 | 
			
		|||
    nic_reset(s);
 | 
			
		||||
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 nic_receive, nic_can_receive, s);
 | 
			
		||||
                                 nic_receive, nic_can_receive,
 | 
			
		||||
                                 nic_cleanup, s);
 | 
			
		||||
 | 
			
		||||
    qemu_format_nic_info_str(s->vc, s->macaddr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -554,6 +554,16 @@ static CPUWriteMemoryFunc *eth_write[] = {
 | 
			
		|||
	ð_writel,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void eth_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
        struct fs_eth *eth = vc->opaque;
 | 
			
		||||
 | 
			
		||||
        cpu_unregister_io_memory(eth->ethregs);
 | 
			
		||||
 | 
			
		||||
        qemu_free(eth->dma_out);
 | 
			
		||||
        qemu_free(eth);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *etraxfs_eth_init(NICInfo *nd, CPUState *env, 
 | 
			
		||||
		       qemu_irq *irq, target_phys_addr_t base, int phyaddr)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -585,7 +595,8 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
 | 
			
		|||
	cpu_register_physical_memory (base, 0x5c, eth->ethregs);
 | 
			
		||||
 | 
			
		||||
	eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
				       eth_receive, eth_can_receive, eth);
 | 
			
		||||
				       eth_receive, eth_can_receive,
 | 
			
		||||
				       eth_cleanup, eth);
 | 
			
		||||
	eth->vc->opaque = eth;
 | 
			
		||||
	eth->vc->link_status_changed = eth_set_link;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								hw/mcf_fec.c
								
								
								
								
							
							
						
						
									
										20
									
								
								hw/mcf_fec.c
								
								
								
								
							| 
						 | 
				
			
			@ -24,6 +24,7 @@ do { printf("mcf_fec: " fmt , ##args); } while (0)
 | 
			
		|||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    qemu_irq *irq;
 | 
			
		||||
    int mmio_index;
 | 
			
		||||
    VLANClientState *vc;
 | 
			
		||||
    uint32_t irq_state;
 | 
			
		||||
    uint32_t eir;
 | 
			
		||||
| 
						 | 
				
			
			@ -441,21 +442,30 @@ static CPUWriteMemoryFunc *mcf_fec_writefn[] = {
 | 
			
		|||
   mcf_fec_write
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mcf_fec_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    mcf_fec_state *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(s->mmio_index);
 | 
			
		||||
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
 | 
			
		||||
{
 | 
			
		||||
    mcf_fec_state *s;
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    qemu_check_nic_model(nd, "mcf_fec");
 | 
			
		||||
 | 
			
		||||
    s = (mcf_fec_state *)qemu_mallocz(sizeof(mcf_fec_state));
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, mcf_fec_readfn,
 | 
			
		||||
                                       mcf_fec_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x400, iomemtype);
 | 
			
		||||
    s->mmio_index = cpu_register_io_memory(0, mcf_fec_readfn,
 | 
			
		||||
                                           mcf_fec_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x400, s->mmio_index);
 | 
			
		||||
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 mcf_fec_receive, mcf_fec_can_receive, s);
 | 
			
		||||
                                 mcf_fec_receive, mcf_fec_can_receive,
 | 
			
		||||
                                 mcf_fec_cleanup, s);
 | 
			
		||||
    memcpy(s->macaddr, nd->macaddr, 6);
 | 
			
		||||
    qemu_format_nic_info_str(s->vc, s->macaddr);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								hw/mipsnet.c
								
								
								
								
							
							
						
						
									
										16
									
								
								hw/mipsnet.c
								
								
								
								
							| 
						 | 
				
			
			@ -33,6 +33,7 @@ typedef struct MIPSnetState {
 | 
			
		|||
    uint32_t intctl;
 | 
			
		||||
    uint8_t rx_buffer[MAX_ETH_FRAME_SIZE];
 | 
			
		||||
    uint8_t tx_buffer[MAX_ETH_FRAME_SIZE];
 | 
			
		||||
    int io_base;
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    VLANClientState *vc;
 | 
			
		||||
} MIPSnetState;
 | 
			
		||||
| 
						 | 
				
			
			@ -231,6 +232,17 @@ static int mipsnet_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mipsnet_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    MIPSnetState *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    unregister_savevm("mipsnet", s);
 | 
			
		||||
 | 
			
		||||
    isa_unassign_ioport(s->io_base, 36);
 | 
			
		||||
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
 | 
			
		||||
{
 | 
			
		||||
    MIPSnetState *s;
 | 
			
		||||
| 
						 | 
				
			
			@ -246,10 +258,12 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
 | 
			
		|||
    register_ioport_write(base, 36, 4, mipsnet_ioport_write, s);
 | 
			
		||||
    register_ioport_read(base, 36, 4, mipsnet_ioport_read, s);
 | 
			
		||||
 | 
			
		||||
    s->io_base = base;
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    if (nd && nd->vlan) {
 | 
			
		||||
        s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                     mipsnet_receive, mipsnet_can_receive, s);
 | 
			
		||||
                                     mipsnet_receive, mipsnet_can_receive,
 | 
			
		||||
                                     mipsnet_cleanup, s);
 | 
			
		||||
    } else {
 | 
			
		||||
        s->vc = NULL;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -545,6 +545,7 @@ typedef struct mv88w8618_eth_state {
 | 
			
		|||
    uint32_t smir;
 | 
			
		||||
    uint32_t icr;
 | 
			
		||||
    uint32_t imr;
 | 
			
		||||
    int mmio_index;
 | 
			
		||||
    int vlan_header;
 | 
			
		||||
    mv88w8618_tx_desc *tx_queue[2];
 | 
			
		||||
    mv88w8618_rx_desc *rx_queue[4];
 | 
			
		||||
| 
						 | 
				
			
			@ -705,20 +706,29 @@ static CPUWriteMemoryFunc *mv88w8618_eth_writefn[] = {
 | 
			
		|||
    mv88w8618_eth_write
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void eth_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    mv88w8618_eth_state *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(s->mmio_index);
 | 
			
		||||
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mv88w8618_eth_init(NICInfo *nd, uint32_t base, qemu_irq irq)
 | 
			
		||||
{
 | 
			
		||||
    mv88w8618_eth_state *s;
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    qemu_check_nic_model(nd, "mv88w8618");
 | 
			
		||||
 | 
			
		||||
    s = qemu_mallocz(sizeof(mv88w8618_eth_state));
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 eth_receive, eth_can_receive, s);
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, mv88w8618_eth_readfn,
 | 
			
		||||
                                       mv88w8618_eth_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, MP_ETH_SIZE, iomemtype);
 | 
			
		||||
                                 eth_receive, eth_can_receive,
 | 
			
		||||
                                 eth_cleanup, s);
 | 
			
		||||
    s->mmio_index = cpu_register_io_memory(0, mv88w8618_eth_readfn,
 | 
			
		||||
                                           mv88w8618_eth_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, MP_ETH_SIZE, s->mmio_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* LCD register offsets */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										28
									
								
								hw/ne2000.c
								
								
								
								
							
							
						
						
									
										28
									
								
								hw/ne2000.c
								
								
								
								
							| 
						 | 
				
			
			@ -140,6 +140,7 @@ typedef struct NE2000State {
 | 
			
		|||
    uint8_t curpag;
 | 
			
		||||
    uint8_t mult[8]; /* multicast mask array */
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    int isa_io_base;
 | 
			
		||||
    PCIDevice *pci_dev;
 | 
			
		||||
    VLANClientState *vc;
 | 
			
		||||
    uint8_t macaddr[6];
 | 
			
		||||
| 
						 | 
				
			
			@ -718,6 +719,19 @@ static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void isa_ne2000_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    NE2000State *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    unregister_savevm("ne2000", s);
 | 
			
		||||
 | 
			
		||||
    isa_unassign_ioport(s->isa_io_base, 16);
 | 
			
		||||
    isa_unassign_ioport(s->isa_io_base + 0x10, 2);
 | 
			
		||||
    isa_unassign_ioport(s->isa_io_base + 0x1f, 1);
 | 
			
		||||
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
 | 
			
		||||
{
 | 
			
		||||
    NE2000State *s;
 | 
			
		||||
| 
						 | 
				
			
			@ -736,13 +750,15 @@ void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
 | 
			
		|||
 | 
			
		||||
    register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
 | 
			
		||||
    register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
 | 
			
		||||
    s->isa_io_base = base;
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    memcpy(s->macaddr, nd->macaddr, 6);
 | 
			
		||||
 | 
			
		||||
    ne2000_reset(s);
 | 
			
		||||
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 ne2000_receive, ne2000_can_receive, s);
 | 
			
		||||
                                 ne2000_receive, ne2000_can_receive,
 | 
			
		||||
                                 isa_ne2000_cleanup, s);
 | 
			
		||||
 | 
			
		||||
    qemu_format_nic_info_str(s->vc, s->macaddr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -777,6 +793,13 @@ static void ne2000_map(PCIDevice *pci_dev, int region_num,
 | 
			
		|||
    register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ne2000_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    NE2000State *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    unregister_savevm("ne2000", s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		||||
{
 | 
			
		||||
    PCINE2000State *d;
 | 
			
		||||
| 
						 | 
				
			
			@ -802,7 +825,8 @@ PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		|||
    memcpy(s->macaddr, nd->macaddr, 6);
 | 
			
		||||
    ne2000_reset(s);
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 ne2000_receive, ne2000_can_receive, s);
 | 
			
		||||
                                 ne2000_receive, ne2000_can_receive,
 | 
			
		||||
                                 ne2000_cleanup, s);
 | 
			
		||||
 | 
			
		||||
    qemu_format_nic_info_str(s->vc, s->macaddr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										58
									
								
								hw/pcnet.c
								
								
								
								
							
							
						
						
									
										58
									
								
								hw/pcnet.c
								
								
								
								
							| 
						 | 
				
			
			@ -75,6 +75,7 @@ struct PCNetState_st {
 | 
			
		|||
    uint8_t buffer[4096];
 | 
			
		||||
    int tx_busy;
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    qemu_irq *reset_irq;
 | 
			
		||||
    void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
 | 
			
		||||
                         uint8_t *buf, int len, int do_bswap);
 | 
			
		||||
    void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
 | 
			
		||||
| 
						 | 
				
			
			@ -1929,7 +1930,15 @@ static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pcnet_common_init(PCNetState *d, NICInfo *nd)
 | 
			
		||||
static void pcnet_common_cleanup(PCNetState *d)
 | 
			
		||||
{
 | 
			
		||||
    unregister_savevm("pcnet", d);
 | 
			
		||||
 | 
			
		||||
    qemu_del_timer(d->poll_timer);
 | 
			
		||||
    qemu_free_timer(d->poll_timer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pcnet_common_init(PCNetState *d, NICInfo *nd, NetCleanup *cleanup)
 | 
			
		||||
{
 | 
			
		||||
    d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1937,7 +1946,8 @@ static void pcnet_common_init(PCNetState *d, NICInfo *nd)
 | 
			
		|||
 | 
			
		||||
    if (nd && nd->vlan) {
 | 
			
		||||
        d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                     pcnet_receive, pcnet_can_receive, d);
 | 
			
		||||
                                     pcnet_receive, pcnet_can_receive,
 | 
			
		||||
                                     cleanup, d);
 | 
			
		||||
 | 
			
		||||
        qemu_format_nic_info_str(d->vc, d->nd->macaddr);
 | 
			
		||||
    } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -1985,6 +1995,22 @@ static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
 | 
			
		|||
    cpu_physical_memory_read(addr, buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pci_pcnet_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    PCNetState *d = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    pcnet_common_cleanup(d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pci_pcnet_uninit(PCIDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
    PCNetState *d = (PCNetState *)dev;
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(d->mmio_index);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		||||
{
 | 
			
		||||
    PCNetState *d;
 | 
			
		||||
| 
						 | 
				
			
			@ -1997,7 +2023,7 @@ PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		|||
 | 
			
		||||
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
 | 
			
		||||
                                          devfn, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    d->dev.unregister = pci_pcnet_uninit;
 | 
			
		||||
    pci_conf = d->dev.config;
 | 
			
		||||
 | 
			
		||||
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
 | 
			
		||||
| 
						 | 
				
			
			@ -2031,7 +2057,8 @@ PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		|||
    d->phys_mem_write = pci_physical_memory_write;
 | 
			
		||||
    d->pci_dev = &d->dev;
 | 
			
		||||
 | 
			
		||||
    pcnet_common_init(d, nd);
 | 
			
		||||
    pcnet_common_init(d, nd, pci_pcnet_cleanup);
 | 
			
		||||
 | 
			
		||||
    return (PCIDevice *)d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2081,29 +2108,42 @@ static CPUWriteMemoryFunc *lance_mem_write[3] = {
 | 
			
		|||
    NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void lance_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    PCNetState *d = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    pcnet_common_cleanup(d);
 | 
			
		||||
 | 
			
		||||
    qemu_free_irqs(d->reset_irq);
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(d->mmio_index);
 | 
			
		||||
 | 
			
		||||
    qemu_free(d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
 | 
			
		||||
                qemu_irq irq, qemu_irq *reset)
 | 
			
		||||
{
 | 
			
		||||
    PCNetState *d;
 | 
			
		||||
    int lance_io_memory;
 | 
			
		||||
 | 
			
		||||
    qemu_check_nic_model(nd, "lance");
 | 
			
		||||
 | 
			
		||||
    d = qemu_mallocz(sizeof(PCNetState));
 | 
			
		||||
 | 
			
		||||
    lance_io_memory =
 | 
			
		||||
    d->mmio_index =
 | 
			
		||||
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
 | 
			
		||||
 | 
			
		||||
    d->dma_opaque = dma_opaque;
 | 
			
		||||
 | 
			
		||||
    *reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);
 | 
			
		||||
    d->reset_irq = qemu_allocate_irqs(parent_lance_reset, d, 1);
 | 
			
		||||
    *reset = *d->reset_irq;
 | 
			
		||||
 | 
			
		||||
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
 | 
			
		||||
    cpu_register_physical_memory(leaddr, 4, d->mmio_index);
 | 
			
		||||
 | 
			
		||||
    d->irq = irq;
 | 
			
		||||
    d->phys_mem_read = ledma_memory_read;
 | 
			
		||||
    d->phys_mem_write = ledma_memory_write;
 | 
			
		||||
 | 
			
		||||
    pcnet_common_init(d, nd);
 | 
			
		||||
    pcnet_common_init(d, nd, lance_cleanup);
 | 
			
		||||
}
 | 
			
		||||
#endif /* TARGET_SPARC */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										31
									
								
								hw/rtl8139.c
								
								
								
								
							
							
						
						
									
										31
									
								
								hw/rtl8139.c
								
								
								
								
							| 
						 | 
				
			
			@ -3414,6 +3414,33 @@ static void rtl8139_timer(void *opaque)
 | 
			
		|||
}
 | 
			
		||||
#endif /* RTL8139_ONBOARD_TIMER */
 | 
			
		||||
 | 
			
		||||
static void rtl8139_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    RTL8139State *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    if (s->cplus_txbuffer) {
 | 
			
		||||
        qemu_free(s->cplus_txbuffer);
 | 
			
		||||
        s->cplus_txbuffer = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef RTL8139_ONBOARD_TIMER
 | 
			
		||||
    qemu_del_timer(s->timer);
 | 
			
		||||
    qemu_free_timer(s->timer);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    unregister_savevm("rtl8139", s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pci_rtl8139_uninit(PCIDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
    PCIRTL8139State *d = (PCIRTL8139State *)dev;
 | 
			
		||||
    RTL8139State *s = &d->rtl8139;
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		||||
{
 | 
			
		||||
    PCIRTL8139State *d;
 | 
			
		||||
| 
						 | 
				
			
			@ -3424,6 +3451,7 @@ PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		|||
                                              "RTL8139", sizeof(PCIRTL8139State),
 | 
			
		||||
                                              devfn,
 | 
			
		||||
                                              NULL, NULL);
 | 
			
		||||
    d->dev.unregister = pci_rtl8139_uninit;
 | 
			
		||||
    pci_conf = d->dev.config;
 | 
			
		||||
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
 | 
			
		||||
    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139);
 | 
			
		||||
| 
						 | 
				
			
			@ -3450,7 +3478,8 @@ PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		|||
    memcpy(s->macaddr, nd->macaddr, 6);
 | 
			
		||||
    rtl8139_reset(s);
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 rtl8139_receive, rtl8139_can_receive, s);
 | 
			
		||||
                                 rtl8139_receive, rtl8139_can_receive,
 | 
			
		||||
                                 rtl8139_cleanup, s);
 | 
			
		||||
 | 
			
		||||
    qemu_format_nic_info_str(s->vc, s->macaddr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,7 @@ typedef struct {
 | 
			
		|||
    uint8_t int_level;
 | 
			
		||||
    uint8_t int_mask;
 | 
			
		||||
    uint8_t macaddr[6];
 | 
			
		||||
    int mmio_index;
 | 
			
		||||
} smc91c111_state;
 | 
			
		||||
 | 
			
		||||
#define RCR_SOFT_RST  0x8000
 | 
			
		||||
| 
						 | 
				
			
			@ -690,24 +691,32 @@ static CPUWriteMemoryFunc *smc91c111_writefn[] = {
 | 
			
		|||
    smc91c111_writel
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void smc91c111_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    smc91c111_state *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(s->mmio_index);
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
 | 
			
		||||
{
 | 
			
		||||
    smc91c111_state *s;
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    qemu_check_nic_model(nd, "smc91c111");
 | 
			
		||||
 | 
			
		||||
    s = (smc91c111_state *)qemu_mallocz(sizeof(smc91c111_state));
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, smc91c111_readfn,
 | 
			
		||||
                                       smc91c111_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 16, iomemtype);
 | 
			
		||||
    s->mmio_index = cpu_register_io_memory(0, smc91c111_readfn,
 | 
			
		||||
                                           smc91c111_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 16, s->mmio_index);
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    memcpy(s->macaddr, nd->macaddr, 6);
 | 
			
		||||
 | 
			
		||||
    smc91c111_reset(s);
 | 
			
		||||
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 smc91c111_receive, smc91c111_can_receive, s);
 | 
			
		||||
                                 smc91c111_receive, smc91c111_can_receive,
 | 
			
		||||
                                 smc91c111_cleanup, s);
 | 
			
		||||
    qemu_format_nic_info_str(s->vc, s->macaddr);
 | 
			
		||||
    /* ??? Save/restore.  */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,6 +69,7 @@ typedef struct {
 | 
			
		|||
    VLANClientState *vc;
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    uint8_t macaddr[6];
 | 
			
		||||
    int mmio_index;
 | 
			
		||||
} stellaris_enet_state;
 | 
			
		||||
 | 
			
		||||
static void stellaris_enet_update(stellaris_enet_state *s)
 | 
			
		||||
| 
						 | 
				
			
			@ -384,23 +385,35 @@ static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void stellaris_enet_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    stellaris_enet_state *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    unregister_savevm("stellaris_enet", s);
 | 
			
		||||
 | 
			
		||||
    cpu_unregister_io_memory(s->mmio_index);
 | 
			
		||||
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq)
 | 
			
		||||
{
 | 
			
		||||
    stellaris_enet_state *s;
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    qemu_check_nic_model(nd, "stellaris");
 | 
			
		||||
 | 
			
		||||
    s = (stellaris_enet_state *)qemu_mallocz(sizeof(stellaris_enet_state));
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, stellaris_enet_readfn,
 | 
			
		||||
                                       stellaris_enet_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
 | 
			
		||||
    s->mmio_index = cpu_register_io_memory(0, stellaris_enet_readfn,
 | 
			
		||||
                                           stellaris_enet_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x00001000, s->mmio_index);
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    memcpy(s->macaddr, nd->macaddr, 6);
 | 
			
		||||
 | 
			
		||||
    if (nd->vlan) {
 | 
			
		||||
        s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                     stellaris_enet_receive, stellaris_enet_can_receive, s);
 | 
			
		||||
                                     stellaris_enet_receive,
 | 
			
		||||
                                     stellaris_enet_can_receive,
 | 
			
		||||
                                     stellaris_enet_cleanup, s);
 | 
			
		||||
        qemu_format_nic_info_str(s->vc, s->macaddr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								hw/usb-net.c
								
								
								
								
							
							
						
						
									
										14
									
								
								hw/usb-net.c
								
								
								
								
							| 
						 | 
				
			
			@ -1415,14 +1415,20 @@ static int usbnet_can_receive(void *opaque)
 | 
			
		|||
    return !s->in_len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void usbnet_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    USBNetState *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    rndis_clear_responsequeue(s);
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void usb_net_handle_destroy(USBDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
    USBNetState *s = (USBNetState *) dev;
 | 
			
		||||
 | 
			
		||||
    /* TODO: remove the nd_table[] entry */
 | 
			
		||||
    qemu_del_vlan_client(s->vc);
 | 
			
		||||
    rndis_clear_responsequeue(s);
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
USBDevice *usb_net_init(NICInfo *nd)
 | 
			
		||||
| 
						 | 
				
			
			@ -1452,7 +1458,9 @@ USBDevice *usb_net_init(NICInfo *nd)
 | 
			
		|||
    pstrcpy(s->dev.devname, sizeof(s->dev.devname),
 | 
			
		||||
                    "QEMU USB Network Interface");
 | 
			
		||||
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                    usbnet_receive, usbnet_can_receive, s);
 | 
			
		||||
                                 usbnet_receive,
 | 
			
		||||
                                 usbnet_can_receive,
 | 
			
		||||
                                 usbnet_cleanup, s);
 | 
			
		||||
 | 
			
		||||
    qemu_format_nic_info_str(s->vc, s->mac);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -570,6 +570,21 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void virtio_net_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    VirtIONet *n = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    unregister_savevm("virtio-net", n);
 | 
			
		||||
 | 
			
		||||
    qemu_free(n->mac_table.macs);
 | 
			
		||||
    qemu_free(n->vlans);
 | 
			
		||||
 | 
			
		||||
    qemu_del_timer(n->tx_timer);
 | 
			
		||||
    qemu_free_timer(n->tx_timer);
 | 
			
		||||
 | 
			
		||||
    virtio_cleanup(&n->vdev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		||||
{
 | 
			
		||||
    VirtIONet *n;
 | 
			
		||||
| 
						 | 
				
			
			@ -598,7 +613,9 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		|||
    memcpy(n->mac, nd->macaddr, ETH_ALEN);
 | 
			
		||||
    n->status = VIRTIO_NET_S_LINK_UP;
 | 
			
		||||
    n->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
 | 
			
		||||
                                 virtio_net_receive, virtio_net_can_receive, n);
 | 
			
		||||
                                 virtio_net_receive,
 | 
			
		||||
                                 virtio_net_can_receive,
 | 
			
		||||
                                 virtio_net_cleanup, n);
 | 
			
		||||
    n->vc->link_status_changed = virtio_net_set_link_status;
 | 
			
		||||
 | 
			
		||||
    qemu_format_nic_info_str(n->vc, n->mac);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -815,6 +815,13 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
 | 
			
		|||
    virtio_update_irq(vdev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void virtio_cleanup(VirtIODevice *vdev)
 | 
			
		||||
{
 | 
			
		||||
    if (vdev->config)
 | 
			
		||||
        qemu_free(vdev->config);
 | 
			
		||||
    qemu_free(vdev->vq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,
 | 
			
		||||
                              uint16_t vendor, uint16_t device,
 | 
			
		||||
                              uint16_t subvendor, uint16_t subdevice,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,6 +117,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f);
 | 
			
		|||
 | 
			
		||||
void virtio_load(VirtIODevice *vdev, QEMUFile *f);
 | 
			
		||||
 | 
			
		||||
void virtio_cleanup(VirtIODevice *vdev);
 | 
			
		||||
 | 
			
		||||
void virtio_notify_config(VirtIODevice *vdev);
 | 
			
		||||
 | 
			
		||||
void virtio_queue_set_notification(VirtQueue *vq, int enable);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										71
									
								
								net.c
								
								
								
								
							
							
						
						
									
										71
									
								
								net.c
								
								
								
								
							| 
						 | 
				
			
			@ -329,6 +329,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
 | 
			
		|||
                                      const char *name,
 | 
			
		||||
                                      IOReadHandler *fd_read,
 | 
			
		||||
                                      IOCanRWHandler *fd_can_read,
 | 
			
		||||
                                      NetCleanup *cleanup,
 | 
			
		||||
                                      void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    VLANClientState *vc, **pvc;
 | 
			
		||||
| 
						 | 
				
			
			@ -340,6 +341,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
 | 
			
		|||
        vc->name = assign_name(vc, model);
 | 
			
		||||
    vc->fd_read = fd_read;
 | 
			
		||||
    vc->fd_can_read = fd_can_read;
 | 
			
		||||
    vc->cleanup = cleanup;
 | 
			
		||||
    vc->opaque = opaque;
 | 
			
		||||
    vc->vlan = vlan;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -358,6 +360,9 @@ void qemu_del_vlan_client(VLANClientState *vc)
 | 
			
		|||
    while (*pvc != NULL)
 | 
			
		||||
        if (*pvc == vc) {
 | 
			
		||||
            *pvc = vc->next;
 | 
			
		||||
            if (vc->cleanup) {
 | 
			
		||||
                vc->cleanup(vc);
 | 
			
		||||
            }
 | 
			
		||||
            free(vc->name);
 | 
			
		||||
            free(vc->model);
 | 
			
		||||
            free(vc);
 | 
			
		||||
| 
						 | 
				
			
			@ -517,7 +522,7 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
 | 
			
		|||
        slirp_init(slirp_restrict, slirp_ip);
 | 
			
		||||
    }
 | 
			
		||||
    slirp_vc = qemu_new_vlan_client(vlan, model, name,
 | 
			
		||||
                                    slirp_receive, NULL, NULL);
 | 
			
		||||
                                    slirp_receive, NULL, NULL, NULL);
 | 
			
		||||
    slirp_vc->info_str[0] = '\0';
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -698,6 +703,8 @@ typedef struct TAPState {
 | 
			
		|||
    char down_script_arg[128];
 | 
			
		||||
} TAPState;
 | 
			
		||||
 | 
			
		||||
static int launch_script(const char *setup_script, const char *ifname, int fd);
 | 
			
		||||
 | 
			
		||||
static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
 | 
			
		||||
                               int iovcnt)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -744,6 +751,18 @@ static void tap_send(void *opaque)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tap_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    TAPState *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    if (s->down_script[0])
 | 
			
		||||
        launch_script(s->down_script, s->down_script_arg, s->fd);
 | 
			
		||||
 | 
			
		||||
    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
 | 
			
		||||
    close(s->fd);
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* fd support */
 | 
			
		||||
 | 
			
		||||
static TAPState *net_tap_fd_init(VLANState *vlan,
 | 
			
		||||
| 
						 | 
				
			
			@ -755,7 +774,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
 | 
			
		|||
 | 
			
		||||
    s = qemu_mallocz(sizeof(TAPState));
 | 
			
		||||
    s->fd = fd;
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive, NULL, s);
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive,
 | 
			
		||||
                                 NULL, tap_cleanup, s);
 | 
			
		||||
    s->vc->fd_readv = tap_receive_iov;
 | 
			
		||||
    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
 | 
			
		||||
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
 | 
			
		||||
| 
						 | 
				
			
			@ -1054,6 +1074,14 @@ static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void vde_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    VDEState *s = vc->opaque;
 | 
			
		||||
    qemu_set_fd_handler(vde_datafd(s->vde), NULL, NULL, NULL);
 | 
			
		||||
    vde_close(s->vde);
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int net_vde_init(VLANState *vlan, const char *model,
 | 
			
		||||
                        const char *name, const char *sock,
 | 
			
		||||
                        int port, const char *group, int mode)
 | 
			
		||||
| 
						 | 
				
			
			@ -1074,7 +1102,8 @@ static int net_vde_init(VLANState *vlan, const char *model,
 | 
			
		|||
        free(s);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, vde_from_qemu, NULL, s);
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, vde_from_qemu,
 | 
			
		||||
                                 NULL, vde_cleanup, s);
 | 
			
		||||
    qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
 | 
			
		||||
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
 | 
			
		||||
             sock, vde_datafd(s->vde));
 | 
			
		||||
| 
						 | 
				
			
			@ -1259,6 +1288,14 @@ fail:
 | 
			
		|||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void net_socket_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    NetSocketState *s = vc->opaque;
 | 
			
		||||
    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
 | 
			
		||||
    close(s->fd);
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
 | 
			
		||||
                                                const char *model,
 | 
			
		||||
                                                const char *name,
 | 
			
		||||
| 
						 | 
				
			
			@ -1303,7 +1340,8 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
 | 
			
		|||
    s = qemu_mallocz(sizeof(NetSocketState));
 | 
			
		||||
    s->fd = fd;
 | 
			
		||||
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive_dgram, NULL, s);
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive_dgram,
 | 
			
		||||
                                 NULL, net_socket_cleanup, s);
 | 
			
		||||
    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 | 
			
		||||
 | 
			
		||||
    /* mcast: save bound address as dst */
 | 
			
		||||
| 
						 | 
				
			
			@ -1330,8 +1368,8 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
 | 
			
		|||
    NetSocketState *s;
 | 
			
		||||
    s = qemu_mallocz(sizeof(NetSocketState));
 | 
			
		||||
    s->fd = fd;
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name,
 | 
			
		||||
                                 net_socket_receive, NULL, s);
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive,
 | 
			
		||||
                                 NULL, net_socket_cleanup, s);
 | 
			
		||||
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
 | 
			
		||||
             "socket: fd=%d", fd);
 | 
			
		||||
    if (is_connected) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1893,27 +1931,18 @@ void net_cleanup(void)
 | 
			
		|||
{
 | 
			
		||||
    VLANState *vlan;
 | 
			
		||||
 | 
			
		||||
#if !defined(_WIN32)
 | 
			
		||||
    /* close network clients */
 | 
			
		||||
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
 | 
			
		||||
        VLANClientState *vc;
 | 
			
		||||
        VLANClientState *vc = vlan->first_client;
 | 
			
		||||
 | 
			
		||||
        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
 | 
			
		||||
            if (vc->fd_read == tap_receive) {
 | 
			
		||||
                TAPState *s = vc->opaque;
 | 
			
		||||
        while (vc) {
 | 
			
		||||
            VLANClientState *next = vc->next;
 | 
			
		||||
 | 
			
		||||
                if (s->down_script[0])
 | 
			
		||||
                    launch_script(s->down_script, s->down_script_arg, s->fd);
 | 
			
		||||
            }
 | 
			
		||||
#if defined(CONFIG_VDE)
 | 
			
		||||
            if (vc->fd_read == vde_from_qemu) {
 | 
			
		||||
                VDEState *s = vc->opaque;
 | 
			
		||||
                vde_close(s->vde);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            qemu_del_vlan_client(vc);
 | 
			
		||||
 | 
			
		||||
            vc = next;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void net_client_check(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								net.h
								
								
								
								
							
							
						
						
									
										3
									
								
								net.h
								
								
								
								
							| 
						 | 
				
			
			@ -9,6 +9,7 @@ typedef ssize_t (IOReadvHandler)(void *, const struct iovec *, int);
 | 
			
		|||
 | 
			
		||||
typedef struct VLANClientState VLANClientState;
 | 
			
		||||
 | 
			
		||||
typedef void (NetCleanup) (VLANClientState *);
 | 
			
		||||
typedef void (LinkStatusChanged)(VLANClientState *);
 | 
			
		||||
 | 
			
		||||
struct VLANClientState {
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +18,7 @@ struct VLANClientState {
 | 
			
		|||
    /* Packets may still be sent if this returns zero.  It's used to
 | 
			
		||||
       rate-limit the slirp code.  */
 | 
			
		||||
    IOCanRWHandler *fd_can_read;
 | 
			
		||||
    NetCleanup *cleanup;
 | 
			
		||||
    LinkStatusChanged *link_status_changed;
 | 
			
		||||
    int link_down;
 | 
			
		||||
    void *opaque;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +42,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
 | 
			
		|||
                                      const char *name,
 | 
			
		||||
                                      IOReadHandler *fd_read,
 | 
			
		||||
                                      IOCanRWHandler *fd_can_read,
 | 
			
		||||
                                      NetCleanup *cleanup,
 | 
			
		||||
                                      void *opaque);
 | 
			
		||||
void qemu_del_vlan_client(VLANClientState *vc);
 | 
			
		||||
VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								tap-win32.c
								
								
								
								
							
							
						
						
									
										15
									
								
								tap-win32.c
								
								
								
								
							| 
						 | 
				
			
			@ -639,6 +639,18 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
 | 
			
		|||
     tap_win32_overlapped_t *handle;
 | 
			
		||||
 } TAPState;
 | 
			
		||||
 | 
			
		||||
static void tap_cleanup(VLANClientState *vc)
 | 
			
		||||
{
 | 
			
		||||
    TAPState *s = vc->opaque;
 | 
			
		||||
 | 
			
		||||
    qemu_del_wait_object(s->handle->tap_semaphore, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    /* FIXME: need to kill thread and close file handle:
 | 
			
		||||
       tap_win32_close(s);
 | 
			
		||||
    */
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tap_receive(void *opaque, const uint8_t *buf, int size)
 | 
			
		||||
{
 | 
			
		||||
    TAPState *s = opaque;
 | 
			
		||||
| 
						 | 
				
			
			@ -673,7 +685,8 @@ int tap_win32_init(VLANState *vlan, const char *model,
 | 
			
		|||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive, NULL, s);
 | 
			
		||||
    s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive,
 | 
			
		||||
                                 NULL, tap_cleanup, s);
 | 
			
		||||
 | 
			
		||||
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
 | 
			
		||||
             "tap: ifname=%s", ifname);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue