diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/char/escc.c | 79 | ||||
| -rw-r--r-- | hw/core/qdev-properties-system.c | 8 | ||||
| -rw-r--r-- | hw/net/vhost_net.c | 7 | ||||
| -rw-r--r-- | hw/nvme/ctrl.c | 34 | ||||
| -rw-r--r-- | hw/nvme/ns.c | 53 | ||||
| -rw-r--r-- | hw/nvme/subsys.c | 6 | ||||
| -rw-r--r-- | hw/sparc64/niagara.c | 6 |
7 files changed, 174 insertions, 19 deletions
diff --git a/hw/char/escc.c b/hw/char/escc.c index 17a908c59b..4f3872bfe9 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -31,6 +31,8 @@ #include "qemu/module.h" #include "hw/char/escc.h" #include "ui/console.h" + +#include "qemu/cutils.h" #include "trace.h" /* @@ -190,6 +192,7 @@ #define R_MISC1I 14 #define R_EXTINT 15 +static uint8_t sunkbd_layout_dip_switch(const char *sunkbd_layout); static void handle_kbd_command(ESCCChannelState *s, int val); static int serial_can_receive(void *opaque); static void serial_receive_byte(ESCCChannelState *s, int ch); @@ -846,6 +849,79 @@ static QemuInputHandler sunkbd_handler = { .event = sunkbd_handle_event, }; +static uint8_t sunkbd_layout_dip_switch(const char *kbd_layout) +{ + /* Return the value of the dip-switches in a SUN Type 5 keyboard */ + static uint8_t ret = 0xff; + + if ((ret == 0xff) && kbd_layout) { + int i; + struct layout_values { + const char *lang; + uint8_t dip; + } languages[] = + /* + * Dip values from table 3-16 Layouts for Type 4, 5 and 5c Keyboards + */ + { + {"en-us", 0x21}, /* U.S.A. (US5.kt) */ + /* 0x22 is some other US (US_UNIX5.kt) */ + {"fr", 0x23}, /* France (France5.kt) */ + {"da", 0x24}, /* Denmark (Denmark5.kt) */ + {"de", 0x25}, /* Germany (Germany5.kt) */ + {"it", 0x26}, /* Italy (Italy5.kt) */ + {"nl", 0x27}, /* The Netherlands (Netherland5.kt) */ + {"no", 0x28}, /* Norway (Norway.kt) */ + {"pt", 0x29}, /* Portugal (Portugal5.kt) */ + {"es", 0x2a}, /* Spain (Spain5.kt) */ + {"sv", 0x2b}, /* Sweden (Sweden5.kt) */ + {"fr-ch", 0x2c}, /* Switzerland/French (Switzer_Fr5.kt) */ + {"de-ch", 0x2d}, /* Switzerland/German (Switzer_Ge5.kt) */ + {"en-gb", 0x2e}, /* Great Britain (UK5.kt) */ + {"ko", 0x2f}, /* Korea (Korea5.kt) */ + {"tw", 0x30}, /* Taiwan (Taiwan5.kt) */ + {"ja", 0x31}, /* Japan (Japan5.kt) */ + {"fr-ca", 0x32}, /* Canada/French (Canada_Fr5.kt) */ + {"hu", 0x33}, /* Hungary (Hungary5.kt) */ + {"pl", 0x34}, /* Poland (Poland5.kt) */ + {"cz", 0x35}, /* Czech (Czech5.kt) */ + {"ru", 0x36}, /* Russia (Russia5.kt) */ + {"lv", 0x37}, /* Latvia (Latvia5.kt) */ + {"tr", 0x38}, /* Turkey-Q5 (TurkeyQ5.kt) */ + {"gr", 0x39}, /* Greece (Greece5.kt) */ + {"ar", 0x3a}, /* Arabic (Arabic5.kt) */ + {"lt", 0x3b}, /* Lithuania (Lithuania5.kt) */ + {"nl-be", 0x3c}, /* Belgium (Belgian5.kt) */ + {"be", 0x3c}, /* Belgium (Belgian5.kt) */ + }; + + for (i = 0; + i < sizeof(languages) / sizeof(struct layout_values); + i++) { + if (!strcmp(kbd_layout, languages[i].lang)) { + ret = languages[i].dip; + return ret; + } + } + + /* Found no known language code */ + if ((kbd_layout[0] >= '0') && (kbd_layout[0] <= '9')) { + unsigned int tmp; + + /* As a fallback we also accept numeric dip switch value */ + if (!qemu_strtoui(kbd_layout, NULL, 0, &tmp)) { + ret = tmp; + } + } + } + + if (ret == 0xff) { + /* Final fallback if keyboard_layout was not set or recognized */ + ret = 0x21; /* en-us layout */ + } + return ret; +} + static void handle_kbd_command(ESCCChannelState *s, int val) { trace_escc_kbd_command(val); @@ -867,7 +943,7 @@ static void handle_kbd_command(ESCCChannelState *s, int val) case 0xf: clear_queue(s); put_queue(s, 0xfe); - put_queue(s, 0x21); /* en-us layout */ + put_queue(s, sunkbd_layout_dip_switch(s->sunkbd_layout)); break; default: break; @@ -976,6 +1052,7 @@ static Property escc_properties[] = { DEFINE_PROP_UINT32("chnAtype", ESCCState, chn[1].type, 0), DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr), DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr), + DEFINE_PROP_STRING("chnA-sunkbd-layout", ESCCState, chn[1].sunkbd_layout), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index d42493f630..6d5d43eda2 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -143,11 +143,15 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name, * aware of iothreads require their BlockBackends to be in the main * AioContext. */ - ctx = iothread ? bdrv_get_aio_context(bs) : qemu_get_aio_context(); - blk = blk_new(ctx, 0, BLK_PERM_ALL); + ctx = bdrv_get_aio_context(bs); + blk = blk_new(iothread ? ctx : qemu_get_aio_context(), + 0, BLK_PERM_ALL); blk_created = true; + aio_context_acquire(ctx); ret = blk_insert_bs(blk, bs, errp); + aio_context_release(ctx); + if (ret < 0) { goto fail; } diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 6db23ca323..6b958d6363 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -507,7 +507,12 @@ VHostNetState *get_vhost_net(NetClientState *nc) switch (nc->info->type) { case NET_CLIENT_DRIVER_TAP: vhost_net = tap_get_vhost_net(nc); - assert(vhost_net); + /* + * tap_get_vhost_net() can return NULL if a tap net-device backend is + * created with 'vhost=off' option, 'vhostforce=off' or no vhost or + * vhostforce or vhostfd options at all. Please see net_init_tap_one(). + * Hence, we omit the assertion here. + */ break; #ifdef CONFIG_VHOST_NET_USER case NET_CLIENT_DRIVER_VHOST_USER: diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index fd917fcda1..355668bdf8 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -43,7 +43,14 @@ * subsys=<subsys_id> * -device nvme-ns,drive=<drive_id>,bus=<bus_name>,nsid=<nsid>,\ * zoned=<true|false[optional]>, \ - * subsys=<subsys_id>,detached=<true|false[optional]> + * subsys=<subsys_id>,shared=<true|false[optional]>, \ + * detached=<true|false[optional]>, \ + * zoned.zone_size=<N[optional]>, \ + * zoned.zone_capacity=<N[optional]>, \ + * zoned.descr_ext_size=<N[optional]>, \ + * zoned.max_active=<N[optional]>, \ + * zoned.max_open=<N[optional]>, \ + * zoned.cross_read=<true|false[optional]> * * Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at * offset 0 in BAR2 and supports only WDS, RDS and SQS for now. By default, the @@ -1748,6 +1755,7 @@ static void nvme_aio_err(NvmeRequest *req, int ret) case NVME_CMD_WRITE: case NVME_CMD_WRITE_ZEROES: case NVME_CMD_ZONE_APPEND: + case NVME_CMD_COPY: status = NVME_WRITE_FAULT; break; default: @@ -2847,6 +2855,25 @@ static void nvme_copy_source_range_parse(void *ranges, int idx, uint8_t format, } } +static inline uint16_t nvme_check_copy_mcl(NvmeNamespace *ns, + NvmeCopyAIOCB *iocb, uint16_t nr) +{ + uint32_t copy_len = 0; + + for (int idx = 0; idx < nr; idx++) { + uint32_t nlb; + nvme_copy_source_range_parse(iocb->ranges, idx, iocb->format, NULL, + &nlb, NULL, NULL, NULL); + copy_len += nlb + 1; + } + + if (copy_len > ns->id_ns.mcl) { + return NVME_CMD_SIZE_LIMIT | NVME_DNR; + } + + return NVME_SUCCESS; +} + static void nvme_copy_out_completed_cb(void *opaque, int ret) { NvmeCopyAIOCB *iocb = opaque; @@ -3159,6 +3186,11 @@ static uint16_t nvme_copy(NvmeCtrl *n, NvmeRequest *req) } } + status = nvme_check_copy_mcl(ns, iocb, nr); + if (status) { + goto invalid; + } + iocb->req = req; iocb->ret = 0; iocb->nr = nr; diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c index 547c0b1543..44aba8f4d9 100644 --- a/hw/nvme/ns.c +++ b/hw/nvme/ns.c @@ -400,8 +400,9 @@ static bool nvme_ns_init_fdp(NvmeNamespace *ns, Error **errp) NvmeRuHandle *ruh; uint8_t lbafi = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas); g_autofree unsigned int *ruhids = NULL; - unsigned int *ruhid; - char *r, *p, *token; + unsigned int n, m, *ruhid; + const char *endptr, *token; + char *r, *p; uint16_t *ph; if (!ns->params.fdp.ruhs) { @@ -438,23 +439,55 @@ static bool nvme_ns_init_fdp(NvmeNamespace *ns, Error **errp) /* parse the placement handle identifiers */ while ((token = qemu_strsep(&p, ";")) != NULL) { - ns->fdp.nphs += 1; - if (ns->fdp.nphs > NVME_FDP_MAXPIDS || - ns->fdp.nphs == endgrp->fdp.nruh) { - error_setg(errp, "too many placement handles"); + if (qemu_strtoui(token, &endptr, 0, &n) < 0) { + error_setg(errp, "cannot parse reclaim unit handle identifier"); free(r); return false; } - if (qemu_strtoui(token, NULL, 0, ruhid++) < 0) { - error_setg(errp, "cannot parse reclaim unit handle identifier"); - free(r); - return false; + m = n; + + /* parse range */ + if (*endptr == '-') { + token = endptr + 1; + + if (qemu_strtoui(token, NULL, 0, &m) < 0) { + error_setg(errp, "cannot parse reclaim unit handle identifier"); + free(r); + return false; + } + + if (m < n) { + error_setg(errp, "invalid reclaim unit handle identifier range"); + free(r); + return false; + } + } + + for (; n <= m; n++) { + if (ns->fdp.nphs++ == endgrp->fdp.nruh) { + error_setg(errp, "too many placement handles"); + free(r); + return false; + } + + *ruhid++ = n; } } free(r); + /* verify that the ruhids are unique */ + for (unsigned int i = 0; i < ns->fdp.nphs; i++) { + for (unsigned int j = i + 1; j < ns->fdp.nphs; j++) { + if (ruhids[i] == ruhids[j]) { + error_setg(errp, "duplicate reclaim unit handle identifier: %u", + ruhids[i]); + return false; + } + } + } + ph = ns->fdp.phs = g_new(uint16_t, ns->fdp.nphs); ruhid = ruhids; diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c index 24ddec860e..d30bb8bfd5 100644 --- a/hw/nvme/subsys.c +++ b/hw/nvme/subsys.c @@ -158,8 +158,10 @@ static bool nvme_subsys_setup_fdp(NvmeSubsystem *subsys, Error **errp) endgrp->fdp.nrg = subsys->params.fdp.nrg; - if (!subsys->params.fdp.nruh) { - error_setg(errp, "fdp.nruh must be non-zero"); + if (!subsys->params.fdp.nruh || + subsys->params.fdp.nruh > NVME_FDP_MAXPIDS) { + error_setg(errp, "fdp.nruh must be non-zero and less than %u", + NVME_FDP_MAXPIDS); return false; } diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c index 6725cc61fd..ab3c4ec346 100644 --- a/hw/sparc64/niagara.c +++ b/hw/sparc64/niagara.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "block/block_int-common.h" #include "qemu/units.h" #include "cpu.h" #include "hw/boards.h" @@ -143,9 +144,10 @@ static void niagara_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), NIAGARA_VDISK_BASE, &s->vdisk_ram); dinfo->is_default = 1; - rom_add_file_fixed(blk_name(blk), NIAGARA_VDISK_BASE, -1); + rom_add_file_fixed(blk_bs(blk)->filename, NIAGARA_VDISK_BASE, -1); } else { - error_report("could not load ram disk '%s'", blk_name(blk)); + error_report("could not load ram disk '%s'", + blk_bs(blk)->filename); exit(1); } } |