static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo) { SCSIBus *scsibus; SCSIDevice *scsidev; scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus)); if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) { qemu_error("Device is not a SCSI adapter\n"); return -1; } /* * drive_init() tries to find a default for dinfo->unit. Doesn't * work at all for hotplug though as we assign the device to a * specific bus instead of the first bus with spare scsi ids. * * Ditch the calculated value and reload from option string (if * specified). */ dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit); if (printinfo) qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id); return 0; }
static struct ioreq *ioreq_start(struct XenBlkDev *blkdev) { struct ioreq *ioreq = NULL; if (QLIST_EMPTY(&blkdev->freelist)) { if (blkdev->requests_total >= max_requests) { goto out; } /* allocate new struct */ ioreq = g_malloc0(sizeof(*ioreq)); ioreq->blkdev = blkdev; blkdev->requests_total++; qemu_iovec_init(&ioreq->v, BLKIF_MAX_SEGMENTS_PER_REQUEST); } else { /* get one from freelist */ ioreq = QLIST_FIRST(&blkdev->freelist); QLIST_REMOVE(ioreq, list); qemu_iovec_reset(&ioreq->v); } QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list); blkdev->requests_inflight++; out: return ioreq; }
static XenBlockRequest *xen_block_start_request(XenBlockDataPlane *dataplane) { XenBlockRequest *request = NULL; if (QLIST_EMPTY(&dataplane->freelist)) { if (dataplane->requests_total >= dataplane->max_requests) { goto out; } /* allocate new struct */ request = g_malloc0(sizeof(*request)); request->dataplane = dataplane; /* * We cannot need more pages per requests than this, and since we * re-use requests, allocate the memory once here. It will be freed * xen_block_dataplane_destroy() when the request list is freed. */ request->buf = qemu_memalign(XC_PAGE_SIZE, BLKIF_MAX_SEGMENTS_PER_REQUEST * XC_PAGE_SIZE); dataplane->requests_total++; qemu_iovec_init(&request->v, 1); } else { /* get one from freelist */ request = QLIST_FIRST(&dataplane->freelist); QLIST_REMOVE(request, list); } QLIST_INSERT_HEAD(&dataplane->inflight, request, list); dataplane->requests_inflight++; out: return request; }
static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket) { int i; for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) { if (!QLIST_EMPTY(&qdict->table[i])) { return QLIST_FIRST(&qdict->table[i]); } } return NULL; }
void drive_hot_add(Monitor *mon, const QDict *qdict) { int dom, pci_bus; unsigned slot; int type, bus; PCIDevice *dev; DriveInfo *dinfo = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); const char *opts = qdict_get_str(qdict, "opts"); BusState *scsibus; dinfo = add_init_drive(opts); if (!dinfo) goto err; if (dinfo->devaddr) { monitor_printf(mon, "Parameter addr not supported\n"); goto err; } type = dinfo->type; bus = drive_get_max_bus (type); switch (type) { case IF_SCSI: if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) { goto err; } dev = pci_find_device(pci_bus, slot, 0); if (!dev) { monitor_printf(mon, "no pci device with address %s\n", pci_addr); goto err; } scsibus = QLIST_FIRST(&dev->qdev.child_bus); scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus), dinfo, dinfo->unit); monitor_printf(mon, "OK bus %d, unit %d\n", dinfo->bus, dinfo->unit); break; case IF_NONE: monitor_printf(mon, "OK\n"); break; default: monitor_printf(mon, "Can't hot-add drive to type %d\n", type); goto err; } return; err: if (dinfo) drive_uninit(dinfo); return; }
/* walk finished list, send outstanding responses, free requests */ static void blk_send_response_all(struct XenBlkDev *blkdev) { struct ioreq *ioreq; int send_notify = 0; while (!QLIST_EMPTY(&blkdev->finished)) { ioreq = QLIST_FIRST(&blkdev->finished); send_notify += blk_send_response_one(ioreq); ioreq_release(ioreq); } if (send_notify) xen_be_send_notify(&blkdev->xendev); }
static int blk_free(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); struct ioreq *ioreq; while (!QLIST_EMPTY(&blkdev->freelist)) { ioreq = QLIST_FIRST(&blkdev->freelist); QLIST_REMOVE(ioreq, list); qemu_iovec_destroy(&ioreq->v); qemu_free(ioreq); } qemu_free(blkdev->params); qemu_free(blkdev->mode); qemu_free(blkdev->type); qemu_free(blkdev->dev); qemu_free(blkdev->devtype); qemu_bh_delete(blkdev->bh); return 0; }
static void qdict_destroy_obj(QObject *obj) { int i; QDict *qdict; assert(obj != NULL); qdict = qobject_to_qdict(obj); for (i = 0; i < QDICT_HASH_SIZE; i++) { QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); while (entry) { QDictEntry *tmp = QLIST_NEXT(entry, next); QLIST_REMOVE(entry, next); qentry_destroy(entry); entry = tmp; } } qemu_free(qdict); }
static int scsi_hot_add(Monitor *mon, DeviceState *adapter, DriveInfo *dinfo, int printinfo) { SCSIBus *scsibus; SCSIDevice *scsidev; Error *local_err = NULL; scsibus = (SCSIBus *) object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)), TYPE_SCSI_BUS); if (!scsibus) { error_report("Device is not a SCSI adapter"); return -1; } /* * drive_init() tries to find a default for dinfo->unit. Doesn't * work at all for hotplug though as we assign the device to a * specific bus instead of the first bus with spare scsi ids. * * Ditch the calculated value and reload from option string (if * specified). */ dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); dinfo->bus = scsibus->busnr; scsidev = scsi_bus_legacy_add_drive(scsibus, blk_by_legacy_dinfo(dinfo), dinfo->unit, false, -1, NULL, &local_err); if (!scsidev) { error_report_err(local_err); return -1; } dinfo->unit = scsidev->id; if (printinfo) monitor_printf(mon, "OK bus %d, unit %d\n", scsibus->busnr, scsidev->id); return 0; }
static void qdict_put_obj_test(void) { QInt *qi; QDict *qdict; QDictEntry *ent; const int num = 42; qdict = qdict_new(); // key "" will have tdb hash 12345 qdict_put_obj(qdict, "", QOBJECT(qint_from_int(num))); g_assert(qdict_size(qdict) == 1); ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]); qi = qobject_to_qint(ent->value); g_assert(qint_get_int(qi) == num); // destroy doesn't exit yet QDECREF(qi); g_free(ent->key); g_free(ent); g_free(qdict); }
void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane) { XenBlockRequest *request; if (!dataplane) { return; } while (!QLIST_EMPTY(&dataplane->freelist)) { request = QLIST_FIRST(&dataplane->freelist); QLIST_REMOVE(request, list); qemu_iovec_destroy(&request->v); qemu_vfree(request->buf); g_free(request); } qemu_bh_delete(dataplane->bh); if (dataplane->iothread) { object_unref(OBJECT(dataplane->iothread)); } g_free(dataplane); }