Annotation of qemu/hw/pci-hotplug.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * QEMU PCI hotplug support
                      3:  *
                      4:  * Copyright (c) 2004 Fabrice Bellard
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
                     25: #include "hw.h"
                     26: #include "boards.h"
                     27: #include "pci.h"
                     28: #include "net.h"
                     29: #include "sysemu.h"
                     30: #include "pc.h"
1.1.1.4 ! root       31: #include "monitor.h"
1.1       root       32: #include "block_int.h"
                     33: #include "virtio-blk.h"
                     34: 
                     35: #if defined(TARGET_I386) || defined(TARGET_X86_64)
1.1.1.4 ! root       36: static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
        !            37:                                        const char *devaddr, const char *opts)
1.1       root       38: {
                     39:     int ret;
                     40: 
1.1.1.4 ! root       41:     ret = net_client_init(mon, "nic", opts);
1.1.1.3   root       42:     if (ret < 0)
1.1       root       43:         return NULL;
1.1.1.4 ! root       44:     if (nd_table[ret].devaddr) {
        !            45:         monitor_printf(mon, "Parameter addr not supported\n");
        !            46:         return NULL;
        !            47:     }
        !            48:     return pci_nic_init(&nd_table[ret], "rtl8139", devaddr);
1.1       root       49: }
                     50: 
1.1.1.4 ! root       51: void drive_hot_add(Monitor *mon, const char *pci_addr, const char *opts)
1.1       root       52: {
                     53:     int dom, pci_bus;
                     54:     unsigned slot;
                     55:     int drive_idx, type, bus;
                     56:     int success = 0;
                     57:     PCIDevice *dev;
                     58: 
1.1.1.4 ! root       59:     if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
1.1       root       60:         return;
                     61:     }
                     62: 
                     63:     dev = pci_find_device(pci_bus, slot, 0);
                     64:     if (!dev) {
1.1.1.4 ! root       65:         monitor_printf(mon, "no pci device with address %s\n", pci_addr);
1.1       root       66:         return;
                     67:     }
                     68: 
                     69:     drive_idx = add_init_drive(opts);
                     70:     if (drive_idx < 0)
                     71:         return;
1.1.1.4 ! root       72:     if (drives_table[drive_idx].devaddr) {
        !            73:         monitor_printf(mon, "Parameter addr not supported\n");
        !            74:         return;
        !            75:     }
1.1       root       76:     type = drives_table[drive_idx].type;
                     77:     bus = drive_get_max_bus (type);
                     78: 
                     79:     switch (type) {
                     80:     case IF_SCSI:
                     81:         success = 1;
1.1.1.4 ! root       82:         lsi_scsi_attach(&dev->qdev, drives_table[drive_idx].bdrv,
        !            83:                         drives_table[drive_idx].unit);
1.1       root       84:         break;
                     85:     default:
1.1.1.4 ! root       86:         monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
1.1       root       87:     }
                     88: 
                     89:     if (success)
1.1.1.4 ! root       90:         monitor_printf(mon, "OK bus %d, unit %d\n",
        !            91:                        drives_table[drive_idx].bus,
        !            92:                        drives_table[drive_idx].unit);
1.1       root       93:     return;
                     94: }
                     95: 
1.1.1.4 ! root       96: static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
        !            97:                                            const char *devaddr,
        !            98:                                            const char *opts)
1.1       root       99: {
1.1.1.4 ! root      100:     PCIDevice *dev;
1.1       root      101:     int type = -1, drive_idx = -1;
                    102:     char buf[128];
                    103: 
                    104:     if (get_param_value(buf, sizeof(buf), "if", opts)) {
                    105:         if (!strcmp(buf, "scsi"))
                    106:             type = IF_SCSI;
                    107:         else if (!strcmp(buf, "virtio")) {
                    108:             type = IF_VIRTIO;
1.1.1.2   root      109:         } else {
1.1.1.4 ! root      110:             monitor_printf(mon, "type %s not a hotpluggable PCI device.\n", buf);
        !           111:             return NULL;
1.1       root      112:         }
                    113:     } else {
1.1.1.4 ! root      114:         monitor_printf(mon, "no if= specified\n");
        !           115:         return NULL;
1.1       root      116:     }
                    117: 
                    118:     if (get_param_value(buf, sizeof(buf), "file", opts)) {
                    119:         drive_idx = add_init_drive(opts);
                    120:         if (drive_idx < 0)
1.1.1.4 ! root      121:             return NULL;
        !           122:         if (drives_table[drive_idx].devaddr) {
        !           123:             monitor_printf(mon, "Parameter addr not supported\n");
        !           124:             return NULL;
        !           125:         }
1.1       root      126:     } else if (type == IF_VIRTIO) {
1.1.1.4 ! root      127:         monitor_printf(mon, "virtio requires a backing file/device.\n");
        !           128:         return NULL;
1.1       root      129:     }
                    130: 
                    131:     switch (type) {
                    132:     case IF_SCSI:
1.1.1.4 ! root      133:         dev = pci_create("lsi53c895a", devaddr);
1.1       root      134:         break;
                    135:     case IF_VIRTIO:
1.1.1.4 ! root      136:         dev = pci_create("virtio-blk-pci", devaddr);
1.1       root      137:         break;
1.1.1.4 ! root      138:     default:
        !           139:         dev = NULL;
1.1       root      140:     }
1.1.1.4 ! root      141:     if (dev)
        !           142:         qdev_init(&dev->qdev);
        !           143:     return dev;
1.1       root      144: }
                    145: 
1.1.1.4 ! root      146: void pci_device_hot_add(Monitor *mon, const char *pci_addr, const char *type,
        !           147:                         const char *opts)
1.1       root      148: {
                    149:     PCIDevice *dev = NULL;
                    150: 
1.1.1.4 ! root      151:     /* strip legacy tag */
        !           152:     if (!strncmp(pci_addr, "pci_addr=", 9)) {
        !           153:         pci_addr += 9;
1.1       root      154:     }
                    155: 
1.1.1.4 ! root      156:     if (!opts) {
        !           157:         opts = "";
1.1       root      158:     }
                    159: 
1.1.1.4 ! root      160:     if (!strcmp(pci_addr, "auto"))
        !           161:         pci_addr = NULL;
        !           162: 
1.1       root      163:     if (strcmp(type, "nic") == 0)
1.1.1.4 ! root      164:         dev = qemu_pci_hot_add_nic(mon, pci_addr, opts);
1.1       root      165:     else if (strcmp(type, "storage") == 0)
1.1.1.4 ! root      166:         dev = qemu_pci_hot_add_storage(mon, pci_addr, opts);
1.1       root      167:     else
1.1.1.4 ! root      168:         monitor_printf(mon, "invalid type: %s\n", type);
1.1       root      169: 
                    170:     if (dev) {
1.1.1.4 ! root      171:         qemu_system_device_hot_add(pci_bus_num(dev->bus),
        !           172:                                    PCI_SLOT(dev->devfn), 1);
        !           173:         monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
        !           174:                        0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
        !           175:                        PCI_FUNC(dev->devfn));
1.1       root      176:     } else
1.1.1.4 ! root      177:         monitor_printf(mon, "failed to add %s\n", opts);
1.1       root      178: }
                    179: #endif
                    180: 
1.1.1.4 ! root      181: void pci_device_hot_remove(Monitor *mon, const char *pci_addr)
1.1       root      182: {
                    183:     PCIDevice *d;
                    184:     int dom, bus;
                    185:     unsigned slot;
                    186: 
1.1.1.4 ! root      187:     if (pci_read_devaddr(mon, pci_addr, &dom, &bus, &slot)) {
1.1       root      188:         return;
                    189:     }
                    190: 
                    191:     d = pci_find_device(bus, slot, 0);
                    192:     if (!d) {
1.1.1.4 ! root      193:         monitor_printf(mon, "slot %d empty\n", slot);
1.1       root      194:         return;
                    195:     }
                    196: 
                    197:     qemu_system_device_hot_add(bus, slot, 0);
                    198: }
                    199: 
                    200: static int pci_match_fn(void *dev_private, void *arg)
                    201: {
                    202:     PCIDevice *dev = dev_private;
                    203:     PCIDevice *match = arg;
                    204: 
                    205:     return (dev == match);
                    206: }
                    207: 
                    208: /*
                    209:  * OS has executed _EJ0 method, we now can remove the device
                    210:  */
                    211: void pci_device_hot_remove_success(int pcibus, int slot)
                    212: {
                    213:     PCIDevice *d = pci_find_device(pcibus, slot, 0);
                    214:     int class_code;
                    215: 
                    216:     if (!d) {
1.1.1.4 ! root      217:         monitor_printf(cur_mon, "invalid slot %d\n", slot);
1.1       root      218:         return;
                    219:     }
                    220: 
                    221:     class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
                    222: 
                    223:     switch(class_code) {
                    224:     case PCI_BASE_CLASS_STORAGE:
                    225:         destroy_bdrvs(pci_match_fn, d);
                    226:         break;
                    227:     case PCI_BASE_CLASS_NETWORK:
                    228:         destroy_nic(pci_match_fn, d);
                    229:         break;
                    230:     }
                    231: 
                    232:     pci_unregister_device(d);
                    233: }
                    234: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.