Commit 5851e08cb8df5c9d0c69fb5259ee6174ee651fae

Authored by aliguori
1 parent 51bf9e7e

qemu: add pci_unregister_device (Marcelo Tosatti)

Unregister the pci device, unassign its IO and memory regions, and free
associated data.

Add a callback so drivers can free device state.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6603 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 45 additions and 5 deletions
hw/pci.c
@@ -196,6 +196,48 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, @@ -196,6 +196,48 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
196 return pci_dev; 196 return pci_dev;
197 } 197 }
198 198
  199 +static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
  200 +{
  201 + return addr + pci_mem_base;
  202 +}
  203 +
  204 +static void pci_unregister_io_regions(PCIDevice *pci_dev)
  205 +{
  206 + PCIIORegion *r;
  207 + int i;
  208 +
  209 + for(i = 0; i < PCI_NUM_REGIONS; i++) {
  210 + r = &pci_dev->io_regions[i];
  211 + if (!r->size || r->addr == -1)
  212 + continue;
  213 + if (r->type == PCI_ADDRESS_SPACE_IO) {
  214 + isa_unassign_ioport(r->addr, r->size);
  215 + } else {
  216 + cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
  217 + r->size,
  218 + IO_MEM_UNASSIGNED);
  219 + }
  220 + }
  221 +}
  222 +
  223 +int pci_unregister_device(PCIDevice *pci_dev)
  224 +{
  225 + int ret = 0;
  226 +
  227 + if (pci_dev->unregister)
  228 + ret = pci_dev->unregister(pci_dev);
  229 + if (ret)
  230 + return ret;
  231 +
  232 + pci_unregister_io_regions(pci_dev);
  233 +
  234 + qemu_free_irqs(pci_dev->irq);
  235 + pci_irq_index--;
  236 + pci_dev->bus->devices[pci_dev->devfn] = NULL;
  237 + qemu_free(pci_dev);
  238 + return 0;
  239 +}
  240 +
199 void pci_register_io_region(PCIDevice *pci_dev, int region_num, 241 void pci_register_io_region(PCIDevice *pci_dev, int region_num,
200 uint32_t size, int type, 242 uint32_t size, int type,
201 PCIMapIORegionFunc *map_func) 243 PCIMapIORegionFunc *map_func)
@@ -218,11 +260,6 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num, @@ -218,11 +260,6 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num,
218 *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type); 260 *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
219 } 261 }
220 262
221 -static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)  
222 -{  
223 - return addr + pci_mem_base;  
224 -}  
225 -  
226 static void pci_update_mappings(PCIDevice *d) 263 static void pci_update_mappings(PCIDevice *d)
227 { 264 {
228 PCIIORegion *r; 265 PCIIORegion *r;
hw/pci.h
@@ -125,6 +125,7 @@ typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, @@ -125,6 +125,7 @@ typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
125 uint32_t address, int len); 125 uint32_t address, int len);
126 typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, 126 typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
127 uint32_t addr, uint32_t size, int type); 127 uint32_t addr, uint32_t size, int type);
  128 +typedef int PCIUnregisterFunc(PCIDevice *pci_dev);
128 129
129 #define PCI_ADDRESS_SPACE_MEM 0x00 130 #define PCI_ADDRESS_SPACE_MEM 0x00
130 #define PCI_ADDRESS_SPACE_IO 0x01 131 #define PCI_ADDRESS_SPACE_IO 0x01
@@ -189,6 +190,7 @@ struct PCIDevice { @@ -189,6 +190,7 @@ struct PCIDevice {
189 /* do not access the following fields */ 190 /* do not access the following fields */
190 PCIConfigReadFunc *config_read; 191 PCIConfigReadFunc *config_read;
191 PCIConfigWriteFunc *config_write; 192 PCIConfigWriteFunc *config_write;
  193 + PCIUnregisterFunc *unregister;
192 /* ??? This is a PC-specific hack, and should be removed. */ 194 /* ??? This is a PC-specific hack, and should be removed. */
193 int irq_index; 195 int irq_index;
194 196
@@ -203,6 +205,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, @@ -203,6 +205,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
203 int instance_size, int devfn, 205 int instance_size, int devfn,
204 PCIConfigReadFunc *config_read, 206 PCIConfigReadFunc *config_read,
205 PCIConfigWriteFunc *config_write); 207 PCIConfigWriteFunc *config_write);
  208 +int pci_unregister_device(PCIDevice *pci_dev);
206 209
207 void pci_register_io_region(PCIDevice *pci_dev, int region_num, 210 void pci_register_io_region(PCIDevice *pci_dev, int region_num,
208 uint32_t size, int type, 211 uint32_t size, int type,